이런게 있구나, 신박하고 어렵고 재밌던 문제
<?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을 해야하기 때문에 문법도 맞아야 하면서 원하는 결과도 나와야 한다는 것이다.