Midnight Monologues

日々勉強したことを書いてきます

b01lers CTF bootcamp - Writeup (web : Where's Tron?)

Web

Where's Tron?

We've lost Tron on the grid, find him using this uplink!

http://chal.ctf.b01lers.com:3004
server.pySize: 1.10 KB
MD5: 80b2f70baf1f8706a5eaf2cd86fe624b

添付ファイルのソースより、mysqlのDBにPOSTリクエストのクエリを投げて
該当するレコードがあれば表示する作りになっている。

◆ソースファイル
#!/usr/bin/env python3

from flask import Flask, render_template, request
import MySQLdb

app = Flask(__name__)


def query(query):
    db = MySQLdb.connect(host='localhost', user='selection_program', passwd='designation2-503', db='grid')
    cursor = db.cursor()
    try:
        cursor.execute(query + " LIMIT 20;")
        results = cursor.fetchall()
        cursor.close()
        db.close()
        return results
    except MySQLdb.ProgrammingError as e:
        print(e)
        return 1
    except MySQLdb.OperationalError as e:
        print(e)
        return 2


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        query_str = request.form['query']
        results = query(query_str)

        if results == 1:
            return render_template('index.html', error="Syntax error in query."), 500
        elif results == 2:
            return render_template('index.html', error="MySQLdb.OperationalError."), 500
    else:
        results = None

    return render_template('index.html', results=results)


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

POST処理で受け取ったqueryに対して何も対策をしていないのでSQLインジェクションを狙うことができる。

色々調べると以下の情報がわかる。

Database : grid
Table : program
Column : id/location/name/statusの4つ

登録されているデータが1万件以上あるので、正規表現を使って検索した。

(select name,id,location from programs where name regexp '^Tron')
→Tron-JA-307020 1980 flag{I_fight_for_the_users_and_yori}
flag{I_fight_for_the_users_and_yori}