728x90
<?php
include "./config.php";
login_chk();
$db = dbconnect();
$_GET['id'] = strrev(addslashes($_GET['id']));
$_GET['pw'] = strrev(addslashes($_GET['pw']));
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_zombie_assassin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("zombie_assassin");
highlight_file(__FILE__);
?>
addslashes 함수는 ', ", \, NULL 문자를 escape 처리함.
즉, '\'를 앞에 붙여서 기존의 역할을 못하게 문자 그 자체로 만든다.
strrev 함수는 문자열의 순서를 거꾸로 만드는 함수.
ex)strrev('abc') -> cba
id에 %00(NULL 문자), pw에 %23 1 ro 대입하자.
php 코드를 해석하면 id는 addslashes 한 \0에 strrev에서 0\이 됨.
pw는 addslashes 해도 그대로인데 strrev 해서 or 1 #이 됨.
query : select id from prob_zombie_assassin where id='0\' and pw='or 1=1 #'
id는 초록색 문자열인 0' and pw= 이 된다. 두 번째 '가 이스케이프 처리 되기 때문이다.
or 뒤에 1은 DB의 모든 행에 대하여 참이 된다.
결과적으로 어떤 id 한 개가 조회됨.
답: ?id=%00&pw=%23 1 ro
728x90