wargame 풀이/webhacking.kr
challenge (old-18)
yehey
2020. 10. 17. 15:15
18번 풀이
이번에는 대놓고 SQL injection을 이용하라고 하는 것 같다.
view-source 버튼을 이용해서 해당 페이지의 소스코드를 보았다.
그 중에서도 SQL injection 공격에 필요한 부분만 가져와봤다.
<?php
if($_GET['no']){
$db = dbconnect();
if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2
if($result['id']=="guest") echo "hi guest";
if($result['id']=="admin"){
solve(18);
echo "hi admin!";
}
}
?>
preg_match에서 스페이스바(공백), /, (, ), |, &, select, from, 0x 등을 필터링하고 있다.
얘네를 사용하면 no hack을 출력하고 exit 한다.
solve 조건은 id='admin'이다.
그런데 sql 쿼리문에는 id='quest'와 no가 and 연산으로 묶여있기 때문에 이를 부정하는 no값을 넣어주어야하고
id='admin'으로 만들어주어야한다.
따라서 no값에는 0을 넣어주고 id='admin'을 or 연산으로 묶어주면 앞의 id='guest' and no=0이 거짓이 되기 때문에 id='admin'인 사용자를 전달하게 된다.
(admin의 no가 2라고 했으니 no=2를 넣어주면 id=admin인 사용자를 반환할 것!)
0 or no=2을 전달하려고 했으나 공백을 허용하지 않기 때문에 같은 역할을 하는 tab(%09)을 이용하자
0%09or%09no=2을 입력란에 넣어주었는데, 다음과 같이 실행되지 않았다.
우리가 보낸 %09에서 %도 문자로 인식을 해서 %를 나타내는 %25가 붙어서 %09로 인식하지 않았기 때문에 쿼리문이 유효하지 않게 되었다.
그래서 입력란말고 URL을 통해 직접 전달하는 방식을 사용했다.
?no=0%09or%09no=2를 전송하면 문제가 해결된다!