반응형

0. 주제 선정

 SQL Injection에 대해 공부하는데 방어 기법으로 addslashes()와 mysql_real_escape_string()이 등장하였습니다. 그런데 책에서는 이 두가지 함수로 SQL Injection을 모두 방어할 수 있는 것처럼 나와있었습니다. 하지만 해킹이 어떤 분야입니까? 막으면 뚫는 분야 아닙니까!?

 그래서 과연 이 두 함수라면 SQL Injection을 모두 막을 수 있는지? 우회할 수 있다면 어떤 식으로 우회가 가능한지 알아보고자 이 주제를 발표 주제로 선정하였습니다.


1. addslashes()와 mysql_real_escape_string()

(1) addslashes()란?

 - 데이터베이스 질의 등에서 처리할 필요가 있는 문자 앞에 백슬래시를 붙인 문자열을 반환한다.

 - 처리할 필요가 있는 문자 = 겉따옴표('), 겹따옴표("), 백슬래시(\), NUL(NULL 바이트)

 - 예를 들어 don't 를 데이터베이스에 넣으려고 할 때 ' 앞에 \를 붙여서 don\'t 이 저장되는 겁니다. 이를 다시 웹에서 보여줄 때는 ' 앞에 있는 \가 없어져야하기 때문에 이때는 백슬래쉬를 제거해주는 stripslashes() 함수를 사용하는 겁니다.

 - magic_quotes_gpc는 기본값으로 on이 되어있는 설정으로, 자동적으로 모든 GET, POST, COOKIE 데이터에 addslashes()를 실행합니다. 따라서 magic_quoties_gpc가 설정되어있을 때에는 addslashes()를 사용하지 마세요. 그렇게 되면 \가 두번 붙으니까요.


(2) mysql_real_escape_string()이란?

 - 간단히 말해 위에서 다룬 addslashes()의 확장(?) 버전이라고 생각하시면 편합니다. 기능은 모두 동일하고 처리하는 문자가 더 많아집니다.

 - 처리하는 문자 = \x00, \n, \r, \r, \, ', ", \x1a

 - \x1a는 EOF(End Of a File)를 뜻합니다. ( CTRL+Z 기능)


2. SQL Injection 방어

 비박스의 실습을 이용하여 진행해보도록 하겠습니다.



 먼저 아무런 보안 조치가 되어있지 않은 경우입니다. 이 때는 항상 참이 되는 문장과 or을 하여 모든 데이터가 출력되도록 하였습니다.



 해당 php 소스코드입니다. security_level에 따라 보안조치가 다른데 위에서 본 경우는 security_level이 0인 경우였습니다. 

 다음으로 1과 2가 있는데 1은 sqli_check_1으로, 2의 경우는 sqli_check_2의 함수로 보안조치를 한 것을 볼 수 있습니다. 해당 함수들의 기능을 찾아봅시다.



 해당 함수들의 기능입니다. 간단하게 한줄로 구현되어있죠.

 security_level이 1인 경우일 때 설정한 sqli_check_1 함수는 addslashes() 함수로 보안조치를 하였습니다. 

 다음으로 security_level이 2인 경우일 때 설정한 sqli_check_2 함수는 mysql_real_escape_string() 함수로 보안조치를 한 것을 볼 수 있습니다.



 정말 SQL Injection이 되지 않는지 실제로 공격을 해보면 이와 같이 공격이 통하지 않는 것을 볼 수 있습니다.

 책에서는 SQL Injection의 대응방안이라면서 해당 두 함수를 알려주고는 끝을 냈습니다. 저는 이 함수들을 우회하는 것은 없는지 알아보았습니다.


3. 대응방안 우회하기

 찾아본 결과 특정 조건 하에서는 우회가 가능했습니다. 그것은 바로 멀티바이트를 사용하는 언어로 인코딩을 할 때입니다. 

멀티바이트를 사용하는 언어셋 환경에서는 백슬래시 앞에 %a1~%fe의 값이 들어오면 해당 값과 \에 해당하는 %5c가 합쳐져서 하나의 문자를 나타내게 됩니다. 따라서 SQL Injection 방어를 위해 생성한 \가 사라져 버려서 공격이 되는거죠.


 이것을 실제로 실습해보겠습니다. (출처 : http://dydgh499.tistory.com/32)



PHP 코드를 이와 같이 작성하였습니다.

GET 방식을 통해 입력받은 것을 mysql_real_escape_string을 거쳐 before에 출력시키고 이것을 mb_convert_encoding 함수를 통해 인코딩을 하고나서 after에 출력시키는 것으로 구현하였습니다.


* mb_convert_encoding 함수 = 인코딩해주는 함수

 - string mb_convert_encoding(string $str, string $to_encoding, [$from_encoding])

 ex) mb_convert_encoding($input, "UTF-8", "EUC-KR") = $input 문자열을 EUC-KR에서 UTF-8로 인코딩



입력창에 겉따옴표( ' )을 입력해보았습니다.



그 결과 mysql_real_escape_string 함수를 지나 ' 앞에 백슬래시(\)가 붙은 것을 볼 수 있습니다. 



이 때 input 변수 앞에 %f1을 넣게 되면 결과적으로 %f1%5c%27 이 되고 멀티바이트 언어셋인 UTF-8에서는 %f1%5c를 하나의 문자로 보게 되어 이 둘을 하나로 묶고 %27만을 남겨둡니다. 

 따라서 after 부분을 보게 되면 백슬래시가 사라지고 '가 남아있는 것을 볼 수 있습니다. 이를 통해 공격자는 '를 사용할 수 있게 되고 이를 이용하여 SQL Injection 공격이 가능하게 되는 것입니다.



참고 )

http://blog.naver.com/PostView.nhn?blogId=skinfosec2000&logNo=220535626029&parentCategoryNo=&categoryNo=12&viewDate=&isShowPopularPosts=false&from=postView


http://dydgh499.tistory.com/32


http://limjunyoung.tistory.com/101

반응형

'Hacking > Web' 카테고리의 다른 글

매직해시(Magic Hashes) 취약점  (0) 2017.02.16
A3. 크로스 사이트 스크립팅  (0) 2017.02.09
A1-injection  (0) 2017.02.01
해킹맛보기 웹 해킹 파트 정리  (0) 2017.01.08
구글 고급 연산자  (0) 2017.01.08
블로그 이미지

rootable

,