본문 바로가기
해킹 공부/웹해킹

Union Select SQL injection,주석,addslashes 우회,공백 우회,url encoding

by zzzmilky 2021. 2. 3.

 

 

450점짜리 50번 문제

 

 

50번 문제의 view-source는 위와 같았다. 

문제를 풀어보니, 크게 5가지 내용에 대해 공부할 수 있었다.

1. Union Select SQL Injection

2. 주석 /**/와 #, --

3. 띄어쓰기 우회

4. addslashes 우회 (EUC-KR을 UTF-8로 인코딩 할때)

5. url encoding

 

 

첫째, Union Select SQL Injection과 관련해서, 

$result = mysqli_fetch_array(mysqli_query($db,"select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));

이 코드를 주목할 필요가 있다. 위 SQL 문에 Union Select SQL injection을 할 수 있는데,

id='/*

이고, 

pw=*/ union select 3#

또는 pw=*/ union select 3-- 

이면 된다. pw 맨끝에 '는 붙여도 되고 안 붙여도 된다. (그런데 어차피 주석 이후의 내용은 무시되므로 굳이 안 붙여도 된다. 나중에 다른 사람들 풀이보니까 붙이길래....)

 

우선 그 이유를 살펴보면,

select lv from chall50 where id=''/* and pw=md5('*/ union select 3#')) 라는 sql 문이 성립하고,

주석인 /* */와, #를 제외하고 보면 select lv from chall50 where id=''/* and pw=md5('*/ union select 3#')) 가 성립한다. 

 

그렇다면 Union Select SQL Injection에 대해 살펴보자.

Union은 각 테이블에서 반환하는 컬럼의 개수가 같고 합쳐지는 각 열의 자료형이 같을때 (mysql의 경우는 자동 형 변환이 된다) 두개의 테이블 결과값을 하나의 테이블에 출력할때 사용하는 연산자이다.

 

Union을 이용해서 데이터를 추출(Select)을 하려면, 기존 SELECT 문의 출력에 공격자가 원하는 데이터를 합쳐서 출력이 가능하다. Union은 이처럼 두개 이상의 SELECT 문의 행을 합치는 역할을 한다.

 

따라서 다음과 같은 chal50이라는 테이블이 있고, SQL injection을 위와 같이 시행했을때 해당 결과들이 나온다.

 

 

 

 

 

 

$result['lv']=="3"이 성립할 것이므로 solve(50) 이 될 것이다.

 

그래서 사용되는게 /* */ 주석과, # 주석, -- 주석이다.

/* */ 주석은 말그대로 해당 주석의 사이에 있는 내용들이 무시되는 거고,

#와 -- 주석은 해당 주석 뒷부분의 내용이 무시된다.

#은 특히 줄바꿈인 %0a가 등장할때 까지 주석처리 되고, %0a 다음 내용들은 무시되지 않는다.

#와 --주석의 또 다른 차이중 하나는, -- 주석은 뒤에 반드시 공백이 와야한다. 나중에 또 언급할 것이다.

 

 

자 그렇다면, 다음으로 따져야할 것이 필터링이다.

foreach($_GET as $ck) if(preg_match("/from|pw|\(|\)| |%|=|>|</i",$ck)) exit();

위와 같이 from, pw 등등 문자들이 필터링 되는데, 이중에서 공백이 필터링 된다는 것을 주목해야 한다.

공백이 필터링 된다면, 우회하는 방법으로

\n을 의미하는(url encoding한 결과인) %0a를 사용하거나,

TAB를 의미하는 %09를 사용하면 된다.

따라서 삽입할 SQL 문의 공백을 모두 %0a로 대체하면 된다.

preg_match를 우회하기 위해선 HEX, BIN, ASCII등의 우회 방법을 사용할 수도 있다.

 

 

다음으로, addslashes 함수를 살펴보자.

$_GET['id'] = addslashes($_GET['id']); 
$_GET['pw'] = addslashes($_GET['pw']);

addslashes 함수는 ' 이라는 따옴표가 있을때, SQL injection을 막기 위해, ' 앞에 slash(/)를 붙이는 방법이다. 그런데, 이 문제에서는 slash 앞에 %a1 ~ %fe 중 하나가 붙으면, slash가 하나의 문자가 되어 버려 우회를 할 수 있다. 그 이유는, mb_convert_encoding 함수 때문이다. 이 함수는 EUC-KR을 UTF-8로 인코딩해주는데, 이 환경에서는 멀티 바이트 문자 처리 버그가 일어나서 addslashes 함수 우회가 된다. 자세한 내용은 m.blog.naver.com/PostView.nhn?blogId=crehacktive3&logNo=221104369034&proxyReferer=https:%2F%2Fwww.google.com%2F 에서 확인 가능. 따라서 ' 앞에 %bf를 붙임으로써 addslashes 함수를 우회할 수 있다.

 

PHP 환경에서 addslashes() 함수, mysql_real_escape_string() 함수, magic_quotes_gpc 우회, 그리고 대응 방안

이스케이프 처리 함수, 그리고 개념 PHP 환경에서 이스케이프 처리 시 사용되는 addslashes() 함수 혹은...

blog.naver.com

 

 

따라서

id='/*
pw=*/ union select 3# 을

www.w3schools.com/tags/ref_urlencode.ASP 을 참고하거나 인코더를 사용해 url encoding을 하면, 

 

HTML URL Encoding Reference

HTML URL Encoding Reference URL - Uniform Resource Locator Web browsers request pages from web servers by using a URL. The URL is the address of a web page, like: https://www.w3schools.com. URL Encoding (Percent Encoding) URL encoding converts characters i

www.w3schools.com

url 뒷부분은 ?id=%bf%27%2F%2A&pw=%2A%2Funion%0aselect%0a3%23 와 같다 (GET 방식). 그래서 url 뒷부분을 이렇게 바꿔주면 solve가 된다.

 

또한, 

id='/* 
pw=*/ union select 3-- 

을 url encoding을 시도해 보았는데, --이 %2D%2D 이고, --주석은 #주석과 다르게 공백이 있어야 하므로 뒤에 %0a를 붙여서 ?id=%bf%27%2F%2A&pw=%2A%2Funion%0aselect%0a3%2D%2D%0a  를 시도해봤는데, Wrong이라고 계속 떴다. 알고보니, -- 주석 뒤에 공백은 %0a(\n)가 아닌, %09(TAB)만 와야하는 거였다. 신기해.....

그래서 url 뒷부분을 ?id=%bf%27%2F%2A&pw=%2A%2Funion%0aselect%0a3%2D%2D%09 로 해주었더니 문제가 solve 되었다!

'해킹 공부 > 웹해킹' 카테고리의 다른 글

[web] suninatas  (0) 2021.11.16
XSS (base tag url)  (0) 2021.11.10
SQL injection, MD5 raw  (0) 2021.02.02
레이스 컨디션 (race condition) 공격이란?  (0) 2021.01.27
Burp Suite Intruder, SQL injection  (0) 2021.01.25

댓글