Eigenständiges Docker-Labor, das CVE-2007-4559 (TarSlip) Directory-Traversal über das Python-tarfile-Modul demonstriert. Enthält anfällige und gepatchte APIs, Payload-Generierung und ein interaktives Demo-Skript für die Sicherheitsschulung.
Nur für Bildungszwecke. Diese Laborumgebung nutzt absichtlich Dateisystem-Schwachstellen in isolierten Docker-Containern aus. Nicht auf Systemen mit sensiblen Daten oder in Produktionsumgebungen ausführen.
Ein in sich geschlossenes Docker-Labor, das CVE-2007-4559 demonstriert – die berüchtigte „TarSlip“-Schwachstelle im Python tarfile-Modul – anhand einer konkreten, durchgängigen Angriffskette:
extractall() schreibt blind einen Tar-Eintrag mit dem Namen ../../../etc/passwd außerhalb des Extraktionsverzeichnisses und überschreibt dabei die echte Systemdatei./admin-Endpunkt.Python's tarfile.extractall() reproduziert getreu jeden Eintrag in einem Tar-Archiv, einschließlich Einträge, deren Namen ../-Pfad-Traversal-Sequenzen enthalten. Es wurde nie als Sicherheitsgrenze konzipiert.
Tar-Eintragsname : ../../../etc/passwd
Extraktionsverz. : /shared/uploads/a1b2c3d4/
aufgelöster Pfad : /shared/uploads/a1b2c3d4/../../../etc/passwd
= /etc/passwd ← Systemdatei überschrieben
| Zeitachse | |
|---|---|
| 2007 | Fehler an das Python-Sicherheitsteam gemeldet |
| 2007 – 2022 | Als „kein Sicherheitsproblem“ markiert – tarfile funktioniert „wie vorgesehen“ |
| 2022 | Trellix-Forscher durchsuchen GitHub und finden 350.000+ Repos, die extractall() auf nicht vertrauenswürdige Eingaben aufrufen |
| 2022 | Öffentliche Offenlegung. CVE-2007-4559 taucht wieder auf. Branchenweite Hektik. |
| 2023 | PEP 706 liefert filter='data' in Python 3.12 – der Fix ist ein einziges Argument |
Die Demo läuft in drei Abschnitten, die jeweils einen Tastendruck zum Fortfahren erfordern.
GET /admin → 401. Der Admin-Endpunkt existiert und ist geschützt. Der Angreifer kennt das Passwort nicht.innocent.tar.gz → Dateien landen im Sandbox-Verzeichnis. Alles sieht normal aus.Angreifer erstellt tarslip_passwd.tar.gz
└─ Eintrag: "../../../etc/passwd"
Inhalt: admin:hacked:1001:... ← platziertes Passwort
│
▼
POST /upload (Multipart-Datei-Upload)
│
▼
extractall("/shared/uploads/{uuid}/")
löst "../../../etc/passwd" auf → /etc/passwd ← CVE-2007-4559
│
▼
GET /admin Authorization: Basic admin:hacked
│
▼
HTTP 200 — "Welcome, admin! You have full admin access."
Flag: CVE-2007-4559{tarslip_passwd_overwrite_to_admin_rce}
Ein HTTP-POST. Keine Shell. Kein RCE-Payload. Nur eine Tar-Datei.
Das gleiche Tarball wird in die behobene API hochgeladen, die filter='data' an extractall() übergibt. Python wirft tarfile.OutsideDestinationError – der Traversal wird blockiert, /etc/passwd bleibt unberührt und /admin bleibt gesperrt.
# Verwundbar – Standard vor Python 3.14
tar.extractall(extraction_dir)
# Gefixt – PEP 706 (Python 3.12+)
tar.extractall(extraction_dir, filter='data')
Ein Argument. Fünfzehn Jahre bis zur Auslieferung.
Vier Dienste in einem isolierten Docker-Bridge-Netzwerk (tarslip-net). Kein Zugriff auf das Internet.
┌─────────────────────────────────────────────────────────┐
│ tarslip-net (bridge) │
│ │
│ ┌─────────────────┐ ┌──────────────────────────┐ │
│ │ vulnerable-api │ │ file-server │ │
│ │ python:3.11.3 │ │ nginx:alpine │ │
│ │ port 8000 │ │ port 8080 (host) │ │
│ │ │ │ │ │
│ │ POST /upload │ │ Serves /shared over │ │
│ │ GET /admin │ │ HTTP — browse extracts │ │
│ │ GET /health │ │ visually │ │
│ └────────┬────────┘ └────────────┬─────────────┘ │
│ │ shared-storage volume │ │
│ └────────────────────────────┘ │
│ │
│ ┌─────────────────┐ │
│ │ attacker │ │
│ │ python:3.12 │ (no host port — internal only) │
│ │ │ │
│ │ craft_malicious.py — generates tarballs │
│ │ demo.py — drives the demo │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
| Dienst | Image | Rolle | Host-Port |
|---|---|---|---|
vulnerable-api | python:3.11.3-slim | Flask-Upload-API + /admin geschützt durch /etc/passwd-Auth | 8000 |
fixed-api | python:3.12-slim | Gleicher Code + USE_SAFE_EXTRACTION=true | 8000 |
file-server | nginx:alpine | Verzeichnislisting extrahierter Dateien | 8080 |
attacker | python:3.12-slim | Payload-Generator + Demo-Treiber | — |
Die verwundbare und die behobene API verwenden identischen Quellcode. Der einzige Unterschied ist die Umgebungsvariable USE_SAFE_EXTRACTION=true auf dem behobenen Container, die das einzelne filter='data'-Argument umschaltet.
CVE-2007-4559-lab/
├── run_demo.sh ← start here
├── docker-compose.vulnerable.yml
├── docker-compose.fixed.yml
├── vulnerable-api/
│ ├── app.py # Flask-API: /upload + /admin + /health
│ ├── Dockerfile # seedet admin:s3cr3t_Adm1nPass in /etc/passwd
│ └── requirements.txt
├── file-server/
│ ├── Dockerfile
│ └── nginx.conf
└── attacker/
├── craft_malicious.py # erzeugt innocent.tar.gz + tarslip_passwd.tar.gz
├── demo.py # CLI-Treiber mit vier Modi (craft/baseline/exploit/verify)
├── Dockerfile
└── requirements.txt
docker compose version)bashgit clone https://github.com/your-username/CVE-2007-4559-lab.git
cd CVE-2007-4559-lab
bash run_demo.sh
Das Skript ist vollständig interaktiv. Es zeigt vor jedem Schritt eine Erläuterung an und wartet auf Eingabetaste, um fortzufahren. Für das Mitverfolgen sind keine Docker-Kenntnisse erforderlich.
| Halt | Angezeigte Erläuterung | Aktion bei Eingabetaste |
|---|---|---|
| 1 | CVE-Zeitachse, Beschreibung der drei Abschnitte | Verwundbaren Stack bauen |
| 2 | Rollen der Container, eingesetztes Admin-Passwort | Payloads generieren |
| 3 | Inhalt jedes Tarballs | Abschnitt 1 – Basislinie |
| 4 | Warum /admin 401 ist, wie normale Extraktion aussieht | Abschnitt 2 – Exploit |
| 5 | Die genaue Traversal-Berechnung, was überschrieben wird | Zum behobenen Stack wechseln |
| 6 | Was filter='data' bewirkt und warum es funktioniert | Abschnitt 3 – Verifikation |
| 7 | Wichtige Erkenntnisse + allgemeines ZipSlip-Muster | Aufräumen |
Für manuelles Durchgehen:
# Verwundbarer Stack
docker compose -f docker-compose.vulnerable.yml up --build -d
docker compose -f docker-compose.vulnerable.yml exec attacker python craft_malicious.py
docker compose -f docker-compose.vulnerable.yml exec attacker python demo.py baseline
docker compose -f docker-compose.vulnerable.yml exec attacker python demo.py exploit