jailCTF 2025 - impossibler
Challenge
impossible の強化版。builtins が空。
import re
code = input()
# 許可: 小文字、コロン、アンダースコア、ドット、角括弧if not re.match(r'^[a-z_:\.\[\]]+$', code): exit()
eval(code, {'__builtins__': {}})Solution
__typing_subst__ dunder (Python 3.11+)
Python 3.11 以降、型パラメータ構文で __typing_subst__ が呼ばれる:
# T[arg] で T.__typing_subst__(T, arg) が呼ばれる# これを悪用して1引数の関数を呼び出しサブクラスからの脱出
# builtins が空でもサブクラスチェーンは使える().__class__.__bases__[0].__subclasses__()完全なペイロード
# __typing_subst__ を使った関数呼び出し# list comprehension で変数を設定[x for x in ... if (setattr(...))]Technical Details
__typing_subst__ の仕組み
Python 3.11 で導入された特殊メソッド:
from typing import TypeVar
T = TypeVar('T')
# T[int] は内部的にT.__typing_subst__(T, int)# を呼び出すimpossible との違い
| 項目 | impossible | impossibler |
|---|---|---|
| builtins | あり | なし |
| 難易度 | Medium | Hard |
| 必要テクニック | __getitem__ | __typing_subst__ + subclasses |
リスト内包表記での変数設定
# walrus 演算子は使えないが、for 文の変数は使える[x for x in [target] for y in [setattr(...)]]Alternative Solutions
別解1: generator の gi_frame
# フレームからbuiltinsにアクセス(x for x in []).gi_frame.f_builtins別解2: __class_getitem__
# 一部のクラスで使用可能list[some_value]Flag
jail{...}
References
- jailCTF 2025 Official
- Python 3.11 typing module changes