[Nahamcon CTF 2022] Personnel

web

Diberikan website dan soal dengan deskripsi berikut ini

Soal

Diberikan juga sebuah source code dari website tersebut pada soal

#!/usr/bin/env python

from flask import Flask, Response, abort, request, render_template
import random
from string import *
import re

app = Flask(__name__)

flag = open("flag.txt").read()
users = open("users.txt").read()

users += flag


@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("lookup.html")
    if request.method == "POST":
        name = request.form["name"]
        setting = int(request.form["setting"])
        if name:
            if name[0].isupper():
                name = name[1:]

        results = re.findall(r"[A-Z][a-z]*?" + name + r"[a-z]*?\n", users, setting)
        results = [x.strip() for x in results if x or len(x) > 1]

        return render_template("lookup.html", passed_results=True, results=results)


if __name__ == "__main__":
    app.run()

Jika kita berinteraksi dengan websitenya langsung, kita hanya dapat melakukan 1 aktifitas saja, yaitu kita dapat mencari nama Personel yang ada di dalam website dan website akan menampilkannya.

Web

Kembali lagi ke source code, dapat dilihat website menggunakan python dan Flask sebagai frameworknya. Personel yang ada pada website diambil dari sebuah file yaitu users.txt. Flag ada pada flag.txt yang diappend dengan list user / Personel. 2 file tersebut juga dibuka menggunakan .read() yang menghasilkan suatu string panjang gabungan bukan berbentuk list.

Lalu pada website menerima 2 tipe HTTP Method yaitu GET dan POST. Pada method POST ini, pemrosesan dari pencarian Personel berlangsung. Kita perlu memperhatikan pada code berikut

results = re.findall(r"[A-Z][a-z]*?" + name + r"[a-z]*?\n", users, setting)
results = [x.strip() for x in results if x or len(x) > 1]

Lalu dengan info diatas, apa yang dapat dilakukan?
Kita tau tadi flag ditambahkan setelah list dari user.txt, dan user.txt ini adalah sebuah multiline text file. Kita juga tau bahwa flag menggunakan format flag{}, tetapi kita tidak bisa langsung mencari dengan format flag karena pattern dari regex tidak match.

Dengan itu kita dapat menginputkan pattern regex berikut

\n.*

Dan pattern akan menjadi

results = re.findall(r"[A-Z][a-z]*?\n.*[a-z]*?\n", users, setting)

Pattern di atas akan match dengan format flag, dan flag akan tampil

Flag

flag{f0e659b45b507d8633065bbd2832c627}