워게임

Lord of SQL Injection - 21번 문제풀이

풉키홍키 2023. 5. 15. 11:58

[21번 문제 - iron_golem]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
  include "./config.php"
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i'$_GET[pw])) exit("No Hack ~_~");
  if(preg_match('/sleep|benchmark/i'$_GET[pw])) exit("HeHe");
  $query = "select id from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(mysqli_error($db)) exit(mysqli_error($db));
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  
  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'== $_GET['pw'])) solve("iron_golem");
  highlight_file(__FILE__);
?>
cs

해당 문제는 9번 행을 보자마자 Error Based SQL Injection 문제라는 것을 단번에 알 수 있다.

쿼리문에서 SQL 문법 에러가 발생하면 에러 메시지를 보여준다.

 

따라서 if문으로 조건을 줘서 참일 경우엔 1을 반환하고, 거짓일 경우엔 에러 메시지를 반환하도록 쿼리를 작성하면 된다.

pw=1' or if(ascii(mid(pw,1,1))=48, 1, 9e307*2) #

 

해당 쿼리에서 pw의 첫 번째 글자의 아스키 코드값이 48일 경우 1을 반환하고, 거짓일 경우 9e307*2를 반환하게 되는데 이는 최대값을 초과하여 에러 메시지가 출력된다.

 

방법을 알았으니 자동화 스크립트를 이용해 pw를 쉽게 알아낼 수 있다.

 

[문제 풀이 구문]

https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?pw=06b5a6c16e8830475f983cc3a825ee9a