
[DreamHack] [Web] blind sql injection advanced 의 풀이를 진행하겠다.
우선, 웹에 들어가면 다음과 같은 화면이 나온다.

문구만 봐도 SQL Injection 취약점 관련 문제라는 것을 유추할 수 있다.
적당히 아무 값이나 넣어보면,

위 처럼 uid에 내가 입력했던 값이 입력된다는 것을 확인할 수 있고, 링크 형식을 보면 GET 방식이라고 유추 가능하다.
당장 웹사이트 내에서 뭔가 진행 할만큼 정보가 모이지 않았기 때문에, 첨부 파일인 app.py 먼저 확인해보겠다.
import os
from flask import Flask, request, render_template_string
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', 'user_db')
mysql = MySQL(app)
template ='''
<pre style="font-size:200%">SELECT * FROM users WHERE uid='{{uid}}';</pre><hr/>
<form>
<input tyupe='text' name='uid' placeholder='uid'>
<input type='submit' value='submit'>
</form>
{% if nrows == 1%}
<pre style="font-size:150%">user "{{uid}}" exists.</pre>
{% endif %}
'''
@app.route('/', methods=['GET'])
def index():
uid = request.args.get('uid', '')
nrows = 0
if uid:
cur = mysql.connection.cursor()
nrows = cur.execute(f"SELECT * FROM users WHERE uid='{uid}';")
return render_template_string(template, uid=uid, nrows=nrows)
if __name__ == '__main__':
app.run(host='0.0.0.0')
제일 위쪽인 import Flask 부분을 보면 Flask 기반 웹사이트임을 알 수 있고,
MySQL을 활용한 DB를 사용한다는 것을 알 수 있다.
if uid:
cur = mysql.connection.cursor()
nrows = cur.execute(f"SELECT * FROM users WHERE uid='{uid}';")
'''
{% if nrows == 1%}
<pre style="font-size:150%">user "{{uid}}" exists.</pre>
{% endif %}
'''
GET /?uid=에 전달한 입력이 uid에 바로 들어가며, SQL 쿼리로 삽입된다.f-string)으로 직접 삽입되어 있어, SQL 인젝션 취약점이 있다는 것을 알 수 있다.user "xxx" exists. 메시지가 출력되며, 존재하지 않으면 출력이 없다.이 부분에 대해서 조금 더 예시를 들어 살펴보면, 아래와 같다.