hacktricks/src/pentesting-web/json-xml-yaml-hacking.md

4.5 KiB
Raw Blame History

JSON, XML & Yaml Hacking & Issues

{{#include ../banners/hacktricks-training.md}}

Go JSON デコーダ

Go JSON で以下の問題が検出されましたが、他の言語にも存在する可能性があります。これらの問題はこのブログ投稿で公開されました。

Go の JSON、XML、および YAML パーサーには、一貫性のない長い履歴と、認証をバイパス権限を昇格、または機密データを抽出するために悪用される可能性のある不安全なデフォルトがあります。

(Un)Marshaling 予期しないデータ

目的は、攻撃者が機密フィールド(例:IsAdminPassword)を読み書きできる構造体を悪用することです。

  • 例の構造体:
type User struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
IsAdmin  bool   `json:"-"`
}
  • 一般的な脆弱性
  1. タグの欠如 (タグなし = フィールドはデフォルトでまだ解析される):
type User struct {
Username string
}

ペイロード:

{"Username": "admin"}
  1. -の不適切な使用:
type User struct {
IsAdmin bool `json:"-,omitempty"` // ❌ wrong
}

ペイロード:

{"-": true}

✔️ フィールドを(アン)マーシャルされないようにブロックする正しい方法:

type User struct {
IsAdmin bool `json:"-"`
}

パーサーの差異

目的は、異なるパーサーが同じペイロードを異なって解釈する方法を利用して認証をバイパスすることです。例えば:

  • CVE-2017-12635: 重複キーによるApache CouchDBのバイパス
  • 2022: XMLパーサーの不整合によるZoomの0クリックRCE
  • GitLab 2025 SAMLのバイパスによるXMLの特異性

1. 重複フィールド: Goのencoding/json最後のフィールドを取ります。

json.Unmarshal([]byte(`{"action":"UserAction", "action":"AdminAction"}`), &req)
fmt.Println(req.Action) // AdminAction

他のパーサーJavaのJackson最初を取るかもしれません。

2. 大文字小文字の区別: Goは大文字小文字を区別しません

json.Unmarshal([]byte(`{"AcTiOn":"AdminAction"}`), &req)
// matches `Action` field

ユニコードトリックも機能します:

json.Unmarshal([]byte(`{"ationſ": "bypass"}`), &req)

3. クロスサービスの不一致: 想像してみてください:

  • Goで書かれたプロキシ
  • Pythonで書かれたAuthZサービス

攻撃者が送信します:

{
"action": "UserAction",
"AcTiOn": "AdminAction"
}
  • PythonはUserActionを認識し、それを許可します
  • GoはAdminActionを認識し、それを実行します

データフォーマットの混乱 (ポリグロット)

目的は、フォーマットJSON/XML/YAMLを混在させるシステムを悪用すること、またはパーサーエラーでオープンに失敗するシステムを悪用することです。例えば

  • CVE-2020-16250: HashiCorp Vaultは、STSがXMLの代わりにJSONを返した後、XMLパーサーでJSONを解析しました。

攻撃者が制御するもの:

  • Accept: application/json ヘッダー
  • JSONボディの部分的な制御

GoのXMLパーサーはそれをとにかく解析し、注入されたアイデンティティを信頼しました。

  • 作成されたペイロード:
{
"action": "Action_1",
"AcTiOn": "Action_2",
"ignored": "<?xml version=\"1.0\"?><Action>Action_3</Action>"
}

結果:

  • Go JSON パーサー: Action_2 (大文字小文字を区別しない + 最後が勝つ)
  • YAML パーサー: Action_1 (大文字小文字を区別する)
  • XML パーサー: 文字列内の "Action_3" を解析

🔐 緩和策

リスク 修正
不明なフィールド decoder.DisallowUnknownFields()
重複フィールド (JSON) stdlib に修正なし
大文字小文字を区別しない一致 stdlib に修正なし
XML ゴミデータ stdlib に修正なし
YAML: 不明なキー yaml.KnownFields(true)

{{#include ../banners/hacktricks-training.md}}