Diberikan sebuah website untuk membuat sebuah image dari text yang diinput oleh user, juga diberikan source code dengan python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from flask import Flask, request, redirect, url_for import os import random import string import time # lemonthink clean = time.time() app = Flask(__name__) chars = list(string.ascii_letters + string.digits) @app.route('/') def main(): return open("index.html").read() @app.route('/generate', methods=['POST']) def upload(): global clean if time.time() - clean > 60: os.system("rm static/images/*") clean = time.time() text = request.form.getlist('text')[0] text = text.replace("\"", "") filename = "".join(random.choices(chars,k=8)) + ".png" os.system(f"python3 generate.py {filename} \"{text}\"") return redirect(url_for('static', filename='images/' + filename), code=301) if __name__ == "__main__": app.run("0.0.0.0",1002) |
Pada kodingan ini jika kita lihat maka akan berjalan seperti ini. Jika /generate diakses dengan method post maka text dari user akan digenerate kedalam sebuah image dengan vulnerability yang berada di os.system (command injection).
Berikut testing dari command injection.


Ternyata command injection berhasil berjalan. Untuk flagnya ternyata pada DockerFile dicopy pada /flag.txt. Tetapi untuk melihat flag terdapat validasi pada generate.py yaitu ini :
1 2 3 4 5 |
.... if "rarctf" in text: # Don't try and exfiltrate flags from here :lemonthink: img = Image.open("static/generator/noleek.png") img.save(f"static/images/{outfile}") .... |
Lalu jika hasil dari command injection terlalu panjang maka akan tertutup oleh image

Nah untuk itu kita bisa mengakalinya dengan cara menggunakan command “cut” untuk mengambil flag per karakter. Karena “rarctf” di validasi maka kita bisa mulai dari index ke 7 sampai terakhir. Jadi dienumerasi manual dengan merubah index sampai 73


Flag : rarctf{b451c-c0mm4nd_1nj3ct10n_f0r-y0u_4nd_y0ur-l3m0nth1nk3rs_d8d21128bf}