false = 0
이다.<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)|#|-/i', $_GET[pw])) exit("No Hack ~_~");
if(strlen($_GET[pw])>6) exit("No Hack ~_~");
$query = "select id from prob_nightmare where pw=('{$_GET[pw]}') and id!='admin'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("nightmare");
highlight_file(__FILE__);
?>
소스 코드를 보게되면 매우 간결하다. #
필터링을 제외하면 큰 문제는 없어 보인다.
하지만 다음 줄 strlen($_GET[pw])>6
때문에 모든 것이 꼬여버린다.
쿼리 뒷부분 때문에 주석처리가 필수지만 기존에 사용하던--+
은 너무 길어서 안 되고 #
필터링에 걸리기 때문에 새로운 방식의 주석이 필요하다.
일단 pw
에서 탈출하려면 ')
는 필수이다. 이때 pw=('')
이므로 힌트에서 말했듯이 0으로 취급할 수 있다.
따라서 앞부분 쿼리를 참으로 만드는데 필수적인 값은 ')<1
로 총 4글자가 사용되었다.
따라서 나머지 2칸은 주석을 사용할때 활용할 수 있는 칸임을 알 수 있다.
SQL 쿼리문을 작성하면 우리는 항상 ;
을 이용하여서 한 쿼리의 끝을 알린다.
이에 기반하여;;
를 입력해도 문제는 해결되지 않는다.
왜냐하면, 우리가 찍은;;
에는 NULL
값이 오고 SQL은;%00
값을 확인하면 작동을 멈추게 된다.
따라서 위에 앞 부분 쿼리를 참으로 만드는데 필수적인 값과 주석 값을 합친 6자리 문자를 입력하면 문제는 해결된다.
https://los.rubiya.kr/chall/nightmare_be1285a95aa20e8fa154cb977c37fee5.php?pw=%27)%3C1;%00