index.phps를 보라고 주석에 되있으니 보자....
<html> <head> <title>Challenge 27</title> </head> <body> <h1>SQL INJECTION</h1> <form method=get action=index.php> <input type=text name=no><input type=submit> </form> <? if($_GET[no]) { if(eregi("#|union|from|challenge|select|\(|\t|/|limit|=|0x",$_GET[no])) exit("no hack"); $q=@mysql_fetch_array(mysql_query("select id from challenge27_table where id='guest' and no=($_GET[no])")) or die("query error"); if($q[id]=="guest") echo("guest"); if($q[id]=="admin") @solve(); } ?> <!-- index.phps --> </body> </html>
no라는 값을 GET으로 넘겨야되는데 골때리는게
정말 select를 위해 필요한녀석들을 다 필터링해놨다. 그렇지만 admin으로 패스해야하니 짱구를 굴려보자
사실 이 문제는 이 문제와 굉장히 닮았다. 그래서 귀찮은마음에 답을 복사해서 넣어봤더니... ㅎㅎ 당연히 안된다.
원리는 똑같다. 앞선 데이터를 무효화하고 admin으로 로그인하면된다.
우선 admin의 row를 알아야내야하는데, 0은 반응없고 1일때는 true, 2일때는 query error가 난다. 2가 admin인가보다.
no=의 값이 괄호 처리 되어 있기때문에 괄호부터 깨준다.
-1) 를 넣어주고(1만 아니면 뭐든 상관없다)
그다음에 우리가 원하는 2를 넣어준다. 근데 no=2를 하고 싶지만 =가 필터링되고 있다.
그래서 잘 써먹던 in을 적어줘봤다. -1) or no in(2) 그치만 내가 못읽은... '(' 가 필터링 되고 있다
그래서 like를 써보기로 하고, 주석처리를 해준다.
mysql은 #과 -- 를 주석으로 쓸 수 있다.
고로 대강 쿼리를 만들어보면
0) or no like 2 --
요런 모양이 된다.