<?phpinclude"./config.php";
login_chk();
$db = mssql_connect();
if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['id'])) exit("No Hack ~_~");
if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['pw'])) exit("No Hack ~_~");
$query = "select * from prob_revenant where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
echo"<hr>query : <strong>{$query}</strong><hr><br>";
sqlsrv_query($db,$query);
if(sqlsrv_errors()) exit(mssql_error(sqlsrv_errors()));
$query = "select * from prob_revenant where id='admin'";
$result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
if($result['4'] === $_GET['pw']) solve("revenant"); // you have to pwn 5th column
highlight_file(__FILE__);
?>
공격 백터
id
pw
공격 백터에 대한 검증
id : master, sys, infomation, prob, ;, waitfor, _
pw : master, sys, infomation, prob, ;, waitfor, _
코드 설명
$db = mssql_connect();
MsSQL로 이루어진 문제이다.
$query = "select * from prob_revenant where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
echo"<hr>query : <strong>{$query}</strong><hr><br>";
sqlsrv_query($db,$query);
if(sqlsrv_errors()) exit(mssql_error(sqlsrv_errors()));
필터링에 통과한 공격 백터 id와 pw는 SELECT * FROM porb_revenant WHERE id='공격 백터 id' and pw='공격 백터 pw'에 들어가게 된다. 반환되는 컬럼이 *인 이유는 이 문제를 클리어하기 위한 조건이 5번째 컬럼에 들어 있기 때문이다.
반환 값에 대한 출력이 안 되고, Error 메시지는 출력이 된다. 즉, Error Based SQLi로 문제를 풀면 될 듯 싶다.
$query = "select * from prob_revenant where id='admin'";
$result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
if($result['4'] === $_GET['pw']) solve("revenant"); // you have to pwn 5th column
이후 id가 admin인 5번째 컬럼의 값과 공격 백터 pw이 같으면 문제가 클리어 된다.
문제 풀이
현 문제는 쿼리문을 통해 Column을 찾을 방법은 필터링으로 통제하고 있다. 이러한 이유 때문에 MySQL로도 방법이 생각이 안 났다. 일단 MsSQL의 SQLi 사례를 찾아서 방법을 찾아보겠다.