CSAW CTF Finals 2023 - Python Garbageman
Challenge
AST ベースのフィルタで数値リテラルが禁止されている。
import ast
code = input()tree = ast.parse(code, mode='eval')
for node in ast.walk(tree): if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)): print("Numbers not allowed!") exit()
result = eval(code)print(result)Solution
len() で数値を生成
len('') # 0len('a') # 1len('aa') # 2len('aaa') # 3chr() との組み合わせ
# 'a' = chr(97) = chr(len('a'*97))chr(len('a'*97))乗算による効率化
# 111 = 'o'chr(len('a')*111) # NG: 111 は数値リテラル
# True を使用chr(len('a')*(len('a')+len('a'))*(len('a')+len('a'))*(len('a')+len('a'))*(len('a')+len('a'))*(len('a')+len('a'))*(len('a')+len('a'))+(len('a')+len('a'))+(len('a')+len('a'))+(len('a')+len('a')))# 複雑だが数値リテラルなしTrue/False の活用
# True = 1, False = 0 (数値コンテキストで)True + True # 2True + True + True # 3Technical Details
AST での数値検出
import ast
code = "123"tree = ast.parse(code, mode='eval')# Constant(value=123)
code = "len('aaa')"tree = ast.parse(code, mode='eval')# Call(func=Name(id='len'), args=[Constant(value='aaa')])# 数値リテラルではない!使用可能な数値生成方法
| 方法 | 例 |
|---|---|
len() | len('aaa') → 3 |
True/False | True + True → 2 |
ord() | ord('a') → 97 |
bool() | bool([]) → False (0) |
Alternative Solutions
別解1: list の操作
len([[]] * ord('a'))別解2: 文字列の長さ
len(__name__) # 環境依存Flag
flag{...}
References
- CSAW CTF Finals 2023 Official