Share
## https://sploitus.com/exploit?id=9F947F43-03EA-5E83-B3B9-710D394C95E2
# CVE-2026-20660 PoC Bundle

This folder packages a standalone proof-of-concept for:

- CVE-2026-20660
- CFNetwork `NSGZipDecoder` path traversal via gzip FNAME
- Impact on vulnerable macOS Safari with auto-open enabled

## 1. Directory Layout

- `server.py`: Main PoC server with configurable traversal depth and target name
- `server_overwrite.py`: Focused variant writing `../../pwn.sh`
- `README.md`: Reproduction notes and operation log

## 2. Preconditions

1. Target is vulnerable macOS Safari (before 26.3 patch line).
2. Safari setting enabled:
   - Preferences -> General -> Open safe files after downloading
3. You can access this host from the target browser.

## 3. Root Cause Summary

Patch diff shows `-[NSGZipDecoder filenameWithOriginalFilename:]` changed behavior:

- Old behavior: return gzip FNAME-derived name directly.
- New behavior: apply `lastPathComponent` before returning.

This blocks directory components such as `../` and absolute paths in FNAME.

## 4. Why Content-Disposition Is Not the Vector

The HTTP filename can be clean and still exploit succeeds.

- HTTP `Content-Disposition` filename: clean (example: `report.gz`)
- gzip header FNAME: malicious (example: `../../proof.txt`)

Safari-side sanitization primarily applies to HTTP-layer names, not the embedded gzip FNAME consumed by `NSGZipDecoder` in the vulnerable flow.

## 5. Quick Start

From repo root:

```bash
python3 exploit/cve-2026-20660/server.py --port 8888 --depth 2
```

Open in vulnerable Safari:

```text
http://:8888/
```

Click `Trigger depth=2`.

## 6. Validation

After triggering, verify write result on target machine:

```bash
ls -la ~/cve-2026-20660-proof.txt
cat ~/cve-2026-20660-proof.txt
```

For overwrite variant:

```bash
python3 exploit/cve-2026-20660/server_overwrite.py --port 9999
```

Then open:

```text
http://:9999/
```

Check:

```bash
ls -la ~/pwn.sh
cat ~/pwn.sh
```

## 7. Parameter Notes (`server.py`)

- `--bind`, `-b`: bind address (default `0.0.0.0`)
- `--port`, `-p`: listening port (default `8888`)
- `--depth`, `-d`: traversal depth (`../` repeat count, default `2`)
- `--name`, `-n`: target output file name

Examples:

```bash
# write to ~/proof.txt when depth matches runtime directory nesting
python3 exploit/cve-2026-20660/server.py -p 8888 -d 2 -n proof.txt

# explicit absolute path test (if resolver permits)
python3 exploit/cve-2026-20660/server.py -p 8888
# then use: /download?depth=0&fname=/tmp/proof.txt
```

## 8. Observed Behavior (Current Notes)

1. Decompression may occur in a temp directory under `~/Downloads`, so depth often needs to be >= 2 to escape into `~/`.
2. Existing target files may not be overwritten; download stack can auto-rename to avoid collisions.
3. Script payloads may appear with executable bits in observed runs; validate per build/config.

## 9. Troubleshooting

1. No write observed:
   - Confirm Safari auto-open setting is enabled.
   - Increase depth (`2`, `3`, `4`) and re-test.
2. File stays in Downloads:
   - Depth too shallow for current decompression directory nesting.
3. Connection fails:
   - Confirm host firewall and LAN reachability.
4. Target path unchanged:
   - Existing filename conflict may cause renamed output.

## 10. Safety and Scope

Use only in authorized testing environments.

- Do not target systems without explicit permission.
- Keep payloads non-destructive for reproducibility.
- Store screenshots/logs for assessment evidence.

## 11. Suggested Evidence Collection

1. Safari version and OS build screenshot.
2. PoC server console logs (request + FNAME).
3. Filesystem verification commands and output.
4. Before/after directory listing for target path.

## 12. Related Documents in Repo

- `blog.cve-2026-20660.md`: full analysis and root cause narrative
- `log.md`: ongoing research timeline and checkpoints