이런게 있구나, 신박하고 어렵고 재밌던 문제

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\\.|rollup|join|@/i', $_GET['pw'])) exit("No Hack ~_~");
  $query = "select pw from prob_ouroboros where pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['pw']) echo "<h2>Pw : {$result[pw]}</h2>";
  if(($result['pw']) && ($result['pw'] === $_GET['pw'])) solve("ouroboros");
  highlight_file(__FILE__);
?>

pw 입력해보면, db에 아무것도 없다.

즉, 내가 입력한 pw와 return 되는 pw 값이 같아야 한다.


이런 기법을 Quine라고 부른다고 한다.

언어별로 많은 연구가 되어 있으며, 인터넷을 통해 쉽게 찾아볼 수 있다.

SQL에서 Quine의 원형은 다음과 같다.

select replace(replace('select replace(replace("$",char(34),char(39)),char(36),"$")',char(34),char(39)),char(36),'select replace(replace("$",char(34),char(39)),char(36),"$")');

문제는 이거다.

우리는 단순히 말장난을 치는게 아니라, injection을 해야하기 때문에 문법도 맞아야 하면서 원하는 결과도 나와야 한다는 것이다.