pyjail wiki

LACTF 2026 - pyjail

Challenge

Python 3.14 環境で、サブインタープリタ内で audit hook が設定された pyjail。

import concurrent.interpreters
import sys
def audit_hook(event, args):
# 3回のauditイベントのみ許可
global audit_count
audit_count += 1
if audit_count > 3:
raise RuntimeError("Too many audit events")
sys.addaudithook(audit_hook)
interp = concurrent.interpreters.Interpreter()
inp = input()[:67]
# 制限: 長さ67文字以下、printable ASCII のみ
# 禁止文字: space, _, ., \, ", ', {}, #, =
for c in inp:
if c not in string.printable or c in ' _.\\"\'{#}=':
exit()
interp.exec(f'print(eval("{inp}"))')

Solution

concurrent.interpreters の悪用

Python 3.14 の concurrent.interpreters.Interpreter.call() はインタープリタ間でオブジェクトを pickle/unpickle する。audit hook はサブインタープリタ内にのみ存在するため、メインインタープリタでは監視されない。

__reduce_ex__ の上書き

exit オブジェクトの __reduce_ex__ を上書きしてシェルを実行:

# dir(0)[41] で '__' を取得
# exit オブジェクトを操作

ペイロード

禁止文字を避けながらペイロードを構築:

# dir(0)[41] は '__' を返す
# これを使って dunder 属性にアクセス

Technical Details

Python 3.14 の新機能

  • concurrent.interpreters - サブインタープリタ間での通信
  • PEP 734 - Interpreter isolation
  • pickle によるオブジェクト転送

audit hook の境界

# メインインタープリタ
sys.addaudithook(hook)
# サブインタープリタには継承されない
interp = concurrent.interpreters.Interpreter()
interp.exec("...") # 別の audit 空間

文字制限のバイパス

禁止代替手段
_dir(0)[41]
.getattr()
=walrus :=
スペース改行やタブ

Flag

lactf{...}

References

  • LACTF 2026 Official
  • Python 3.14 concurrent.interpreters documentation