Level 46
<form method=get action=index.php> level : <input name=lv value=1><input type=submit> </form> <? if(time()<1256900400) exit(); $_GET[lv]=str_replace(" ","",$_GET[lv]); $_GET[lv]=str_replace("/","",$_GET[lv]); $_GET[lv]=str_replace("*","",$_GET[lv]); $_GET[lv]=str_replace("%","",$_GET[lv]); if(eregi("union",$_GET[lv])) exit(); if(eregi("select",$_GET[lv])) exit(); if(eregi("from",$_GET[lv])) exit(); if(eregi("challenge",$_GET[lv])) exit(); if(eregi("0x",$_GET[lv])) exit(); if(eregi("limit",$_GET[lv])) exit(); if(eregi("cash",$_GET[lv])) exit(); $q=@mysql_fetch_array(mysql_query("select id,cash from members where lv=$_GET[lv]")); if($q && $_GET[lv]) { echo("$q[0] information<br><br>money : $q[1]"); if($q[0]=="admin") @solve(); } ?>
index.phps 파일을 보면, 특정 필터링이 일어나고, 쿼리문을 통해 얻은 값이 'admin'이면 문제가 풀린다.
1을 넣어보니 위와 같이 출력되었다.
lv 파라미터를 통해 'admin'의 데이터를 추출해야 하므로 다음과 같은 방법을 사용하면 될것 같았다.
위 그림을 통해 'admin'이 출력되는 것을 볼 수 있다.
그러면 lv값에는 무엇을 넣어야 되는지 궁금할 수 있다.
위 사진처럼 lv값에 상관없이 'admin'의 값이 먼저 출력된다. 이런 경우라면 lv의 무엇이든 상관 없다.
하지만, 대상 시스템에서는 어떻게 출력 될지 모르므로 확실하게 앞부분을 False로 만들고 'admin' 데이터만 출력하게 하는 것이 좋다.
(실제 이문제에서도 lv값이 False일 때 풀리게 된다.)
이제 필터링 되는 문자들의 대안을 찾아보자.
필터링에 걸리는 거라 해봣자 공백 밖에 없는것 같다.
공백은 %20인데 %0a(개행)으로 바꿔도 상관 없다.
magic_quotes_gpc는 php에서 싱글쿼터('), 더블쿼터("), 이스케이프(), NULL(%00) 갑에 대해 앞에 문자 '\'를 붙임으로써 공격을 방지하는 기능을 가지고 있다.
char()함수에는 입력하고자 하는 문자열의 ascii값을 넣으면 된다.
'admin' = char(97,100,109,105,110)