본문 바로가기

워게임

Lord of SQL Injection - 23번 문제풀이

[23번 문제 - hell_fire]

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/i'$_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}";
  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_hell_fire where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'=== $_GET['email'])) solve("hell_fire");
  highlight_file(__FILE__);
?>
cs

해당 문제부터는 좀 새로운 유형으로 보인다. order by 절이 있는걸로 봐서 서브쿼리를 이용해서 풀 수 있을거 같다.

서브쿼리 작성은 SQL 문법들을 여러개 검색하면서 조합하고 실제 MySQL 서버에서 적용도 해가면서 알아냈다.

 

우선 order by 1을 하게되면 id, email, score 정보를 알 수 있고, 이걸 나중에 비교하고 정렬하는데 사용할 수 있다.

 

내가 사용한 서브쿼리는 SELECT문 안에서 IF 함수와 SLEEP 함수를 이용해서 email 값을 찾아냈다.

order by (select if(ord(mid(email,1,1))='97',sleep(1),0))

서브 쿼리문의 내용은 지금까지 조건문을 줘서 Blind SQL Injection을 시도한 방법들을 약간씩 조합한걸로 쉽게 이해할 수 있을 것이다.

 

이 쿼리를 이용해서 자동화 스크립트를 작성했는데, 문제가 발생했다.

아스키 코드값이 낮은 문자들이 먼저 출력되면서 중복되는 값들이 조금씩 섞여있었고, 한 개의 email 주소만 출력되는 불상사가 일어났다.

그걸 비교할려고 기존에 order by 1로 했을 때 나오는 id=rubiya의 email을 스크립트 결과로 나온 값과 수동으로 비교해가면서 문제를 풀긴했다. 파이썬썬 코드로는 어떻게 알아내는지 좀 찾아내봐야겠다..

 

[문제 풀이 구문]

https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php?email=admin_secure_email@emai1.com