본문 바로가기

워게임

Lord of SQL Injection - 24번 문제풀이

[24번 문제 - evil_wizard]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|proc|union|sleep|benchmark/i'$_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_evil_wizard where 1 order by {$_GET[order]}"// same with hell_fire? really?
  echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
  $rows = mysqli_query($db,$query);
  while(($result = mysqli_fetch_array($rows))){
    if($result['id'== "admin"$result['email'= "**************";
    echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
  }
  echo "</table><hr>query : <strong>{$query}</strong><hr>";
 
  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_evil_wizard where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'=== $_GET['email'])) solve("evil_wizard");
  highlight_file(__FILE__);
?>
cs

이번 문제는 23번 문제인 hell_fire 와 비슷해 보이긴 하지만, sleep 과 benchmark 함수를 필터링 해서 시간 지연 함수를 사용하지 못하게 막고 있다.

 

그래서 이번 문제를 풀 때 참과 거짓을 확인하기 위해 IF 함수를 사용해 참일 경우 Error를 발생시키고, 거짓일 경우엔 정상적인 결과가 나오도록 해서 문제를 풀었다.

 

?order=(select if(ascii(mid(email, 1, 1))=97, 9e307*2, 1)) 라는 값을 넣었을 경우 ID=admin 인 계정의 email 의 첫 글자가 'a' 이므로 참인 결과로 9e307*2 라는 값을 반환하게 되고 이 값은 에러를 발생시켜서 화면에 ID, Email, Score 항목만 나오고 row는 출력되지 않는다. 거짓인 결과가 나오게 되면 1을 반환해서 ID, Email, Score 항목의 2개의 row가 출력된다.

 

이 방법을 이용해서 자동화 스크립트로 값을 돌린 후 중복되는 문자들은 수동으로 직접 찾아내서 다른 값들을 대입해서 문제를 풀었다.

 

이 문제를 풀면서 의문이였던게 IF 조건에서 참인 결과에 1을 넣고 거짓인 결과에 9e307*2 를 넣었을 경우엔 참과 거짓이 모호하게 나오는 결과를 확인했었는데 (이 부분에서 시간을 좀 많이 뺏겼다..)

왜 그런지는 아직도 정확히 모르겠다.. 결국엔 저 방법에서 반대로 참인 결과에 9e307*2를 넣고 거짓인 결과에 1을 넣음으로써 문제를 푸는 실마리가 되었으니 다행이긴 하다.

 

[문제 풀이 구문]

https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php?email=aasup3r_secure_email@emai1.com