| MySQL에서 보안위해 load_file() 경로 제한하기 | 작성일 : 2010/05/27 21:02 |
| 조회수 : 28341 |
|
제 목 : MySQL에서 보안위해 load_file() 경로 제한하기 작성자 : 좋은진호(truefeel, http://coffeenix.net/ ) 작성일 : 2009.12.1(화) 정리일 : 2010.5.14(금) 1. SQL Injection에서 load_file() 함수의 위험 SQL Injection(SQL 인젝션) 공격에 대처하기 위해서는 다음과 같은 조치가 필요하다. - SQL Injection공격 등 웹취약성이 없도록 프로그래밍을 하는게 우선이다. (그러나 많은 사이트에서 이부분은 뒷전이다.) - 주기적으로 모의 테스트를 한다. - 웹방화벽에서 UNION SELECT, UNION ALL SELECT, LOAD_FILE() 등 다양한 SQL Injection 공격 유형을 차단한다. - 그리고, load_file() 함수의 경로 제한도 고려한다. MySQL의 SELECT LOAD_FILE() 함수, LOAD DATA는 서버내에 있는 파일을 읽어들이는 명령이다. MySQL 데몬이 파일을 읽을 권한이 있다면, 서버내의 경로와 상관없이 어떠한 파일이라도 읽을 수 있다. 웹페이지가 SQL Injection 공격의 취약점이 있다고 할 때 다음과 같은 형식으로 쉽게 웹에서 서버 내의 파일을 확인할 수 있는 위험성이 존재한다.
이 함수가 편리성, 활용성 측면에서는 좋을 수 있지만, 보안에는 취약한 통로를 제공하는 셈이다. 최근(2009월 말) 루마니아의 Unu 해커는 세계 주요 사이트와 국내 보안 업체 사이트를 SQL Injection공격으로 해킹을 했다. 그리고, MySQL의 load_file() 함수로 서버의 /etc/ 파일까지 캡쳐하여 블로그에 공개한 적이 있다. 이 글에서는 작은 부분인 load_file() 함수의 경로 제한에 대해서 얘기할 것이다. 2. MySQL서버로 직접적 접근이 불가능해도 DB서버의 파일을 볼 수 있다.
위처럼 웹서버와 MySQL서버가 분리되어 있을 때, 웹서버에서 load_file("/etc/passwd") 함수를 호출했다면 어떤 서버의 파일을 보여줄까? MySQL 데몬이 local 파일에 접근하여 보여주는 것이므로, B서버의 파일이 된다. 그러므로 외부에서 MySQL서버로의 직접적인 접근이 불가능하더라도, load_file()함수를 이용할 수 있다면 DB서버 내부의 파일을 볼 수 있다. 3. MySQL에서 load_file() 함수의 경로를 제한하는 방법 ![]() MySQL 매뉴얼을 살펴보자.
위처럼 MySQL 5.1.17부터는 LOAD_FILE() 함수, LOAD DATA, SELECT ... OUTFILE을 특정 디렉토리내의 파일만 허용하도록 설정할 수 있다. --secure-file-priv 옵션은 동적으로는 설정값을 변경할 수가 없다. my.conf 의 '[mysqld]' 섹션에 다음과 같은 설정을 한다. (경로는 운영 환경에 맞게 할 것)
위처럼 설정하고 MySQL 데몬을 실행하면 load_file()을 사용할 수 있는 경로가 /var/tmp으로 제한이 된다. 4. secure-file-priv 설정 적용 전/후 비교 1) secure-file-priv= 적용전 ① SELECT 결과를 /tmp/result.txt 파일로 저장
② 권한이 있는 파일을 load_file()로 읽으면 화면에 파일 내용이 그대로 출력된다. (결과 화면은 생략) ③ 권한이 없는 파일을 load_file()로 읽을 면 NULL만 표시된다.
2) secure-file-priv= 적용후 ① 설정값 확인
② 경로를 /var/tmp/ 로 제한했으므로, /etc/ 아래 파일은 NULL로 표시된다. (/etc/protocols 파일은 누구나 읽기 권한이 있음)
③ SELECT ... INTO OUTFILE 사용할 때 에러가 발생한다.
5. 참고 자료 1) MySQL 관련 * MySQL 사용자매뉴얼 - 명령어 옵션 http://www.mysqlkorea.co.kr/sub.html?mcode=manual&scode=user&m_no=23109&cat1=&cat2=&cat3=〈=k&ver_name=USER * MYSQL 5.1 매뉴얼 - 5.1.2. Server Command Options ( --secure-file-priv=path ) http://dev.mysql.com/doc/refman/5.1/en/server-options.html * MYSQL LOAD_FILE SQL Injection http://www.tullyrankin.com/mysql-load_file-sql-injection LOAD_FILE 함수는 16진수 문자열로 파일을 읽을 수도 있다. (예) /etc/passwd 는 0x2f6574632f706173737764. LOAD_FILE(0x2f6574632f706173737764) ※ 이 URL에 소개된 perl스크립트 4번째 줄의 0x$encn"; 은 0x$enc\n"; 를 잘 못 표기한 것임 2) SQL Injection 관련 * SQL Injection Cheat Sheet http://michaeldaw.org/sql-injection-cheat-sheet * Backdoor webserver using MySQL SQL Injection http://www.greensql.net/publications/backdoor-webserver-using-mysql-sql-injection * 12.22~23 커피닉스 이야기 (Intel사이트 SQL Injection등) (2009.12.24) http://coffeenix.net/bbs/viewtopic.php?p=5988#5988 * 대량 SQL Injection 공격 주의 (2009.12.11) http://coffeenix.net/bbs/viewtopic.php?p=5978#5978 * nProtect 웹사이트, SQL Injection공격 당해 (2009.11.30) http://truefeel.tistory.com/171 |
||||||||||||||||||||||||||||
|
|