問題名:SSTI1
picoCTFのWeb問題にあるSSTI1を解きました。
起動するとユーザーの入力画面が出てきます。
問題文に”何でも好きなことを発信できる”と書いてある通り、XSSのスクリプトを打ち込むと実行することもできました!
制限がゆるゆるですね…(・・)
Burpsuiteでの確認
Burpsuiteを使って中身を確認してみました。
実行結果↓

<b>abcd</b>と入力してみると、<>などの特殊文字がURLエンコーディングされてますが、エスケープ処理されずにそのままHTMLの一部として入力されていることが分かります。
SSTIについて
ある程度サイトについて分かってきましたね。
次にpicoCTFのヒントを確認してみます。
ヒント:SSTI(Server Side Template Injection)
SSTIという言葉を今回初めて知りました。
調べてみると、Webアプリケーションのテンプレートエンジンに悪意のあるコードを注入し、サーバー上で任意のコマンドを実行する攻撃らしいです。
SSTIについて分かりやすくまとめられているサイトのURLを張っておきます。
URL:https://guardian.jpn.com/security/web-api/ssti/
SSTIの実行
実際に下のSSTIのスクリプトを入力して実行してみようと思います。
スクリプト:{{7*7}}
意味:7×7の掛け算をするという意味です。
実行画面に49と表示されたら成功です!
今回は{{7*7}}を使いましたが、テンプレートエンジンは様々な種類があり各種類よってスクリプトの書き方は変わってきます。
SSTI対応表
| テンプレートエンジン | スクリプト | 実行結果 |
|---|---|---|
| Jinja2/Flask | {{7*7}} | 49 |
| Twig(PHP) | {{7*7}} | 49 |
| Smarty(PHP) | {$smarty.version} | バージョン表示 |
| Django | {{7|add:7}} | 14 |
| Velocity(Java) | ${7*7} | 49 |
| Freemarker(Java) | ${7*7} | 49 |
| Go template | {{7}} | 7(演算不可) |
{{7*7}}が使えたということは、Jinja2かTwigのどちらかだということが分かります。
{{config}}がJinja2特有の挙動らしいので入力してみます。

※なぜかドアップになったブラウザの画面が表示されてしまい、すごく見えにくくてすみません(・・;)
画面が正常に変わり、設定が表示されましたね!
このことからJinja2が使われていることが判明しました。
いよいよFlagを探していこうと思います。
Flag探し
SSTIについてまとめられているサイト(上記のURL先)に載っている以下のスクリプトを打ち込むとOSコマンドを不正に実行できるそうなので使ってみます。
どのようなデータがあるのか確認したいのでpopenの後の()の中をlsコマンドに書き換えて入力します。
スクリプト:{{config.class.init.globals['os'].popen('ls').read()}}
↓実行結果

flagというデータが分かりました。
ではflagの中身をcatコマンドで見ていきましょう。
スクリプト:{{config.class.init.globals['os'].popen('cat flag').read()}}

フラグが出てきました!
※実際のブラウザ画面では何故かフラグが画面からはみ出してしまうため、ページのソース画像を張っています。
おまけ
今回の問題には関係ないのですが個人的に勉強になったと思う点を少し書きたいと思います。
SSTIの回避のために{{}}などの特殊文字をエスケープ処理すればいいのではないかと考えたのですが、絶対には防ぐことができないっぽいです。
理由:テンプレートの構文解析・実行がエスケープ処理よりも先に行われる場合があるから。
<流れ>
1.テンプレートを受け取る
2.受け取ったデータの構文解析
3.テンプレートの実行←ここでSSTIが実行される
4.実行結果をHTMLに埋め込む
5.最終HTMLをブラウザ(クライアント)に返す


