UIUCTF 2024 - ASTea
Challenge
AST ベースのフィルタで特定のノードタイプが禁止された pyjail。
import ast
FORBIDDEN = { ast.Import, ast.ImportFrom, ast.Call, ast.Attribute, ast.Subscript}
code = input()tree = ast.parse(code)
for node in ast.walk(tree): if type(node) in FORBIDDEN: print("Forbidden!") exit()
exec(code)Solution
license() の利用
license() は対話的なページャーを起動する。ページャー (less など) からシェルコマンドを実行可能:
# less 内で!shただし Call が禁止されているため、直接呼び出せない。
AnnAssign (アノテーション付き代入)
# 変数アノテーションx: int = 1
# AST では ast.AnnAssign# annotation は通常の式として評価されないデコレータの悪用
デコレータは関数呼び出しを生成するが、クラス定義と組み合わせて使用:
@decoratorclass X: pass実際のペイロード
Call を使わずにコードを実行:
# match 文を使用 (Python 3.10+)match __builtins__: case x: # x から属性にアクセスTechnical Details
AST ノードタイプ
| ノード | 例 |
|---|---|
ast.Call | f() |
ast.Attribute | x.y |
ast.Subscript | x[0] |
ast.AnnAssign | x: int = 1 |
ast.Match | match x: |
禁止されていないノード
ast.Name- 名前参照ast.BinOp- 二項演算ast.Compare- 比較演算ast.Match- パターンマッチ
Alternative Solutions
別解1: walrus 演算子
# := は NamedExpr[x := something for _ in [1]]別解2: f-string
# f-string は JoinedStrf"{...}"Flag
uiuctf{...}
References
- UIUCTF 2024 Official
- Python AST documentation