Authenticated Arbitrary File Upload che porta a Remote Code Execution. Analisi tecnica e riproduzione controllata di CVE-2026-38526 in Webkul Krayin CRM 2.2.x.
Caricamento arbitrario di file autenticato che porta a esecuzione di codice in remoto — Analisi tecnica e riproduzione controllata di CVE-2026-38526 in Webkul Krayin CRM 2.2.x.
CVE-2026-38526 è una vulnerabilità di caricamento arbitrario di file autenticato che interessa Webkul Krayin CRM 2.2.x.
La funzionalità vulnerabile è esposta tramite l'endpoint di caricamento di TinyMCE dell'applicazione:
POST /admin/tinymce/upload
L'applicazione non limita in modo sufficiente il tipo di file che può essere caricato. Un utente autenticato può inviare un file con un'estensione eseguibile lato server, come .php. L'applicazione memorizza il file caricato e restituisce il relativo URL accessibile.
Quando il deployment consente l'esecuzione di PHP dalla posizione di caricamento, il file caricato può successivamente essere richiesto tramite il server web, con conseguente esecuzione di codice in remoto nel contesto del processo dell'applicazione web.
Il record CVE pubblicato assegna alla vulnerabilità un punteggio CVSS 3.1: 9.9 (Critico).
Questo repository contiene la mia analisi tecnica e la riproduzione controllata della vulnerabilità.
La vulnerabilità era già stata divulgata pubblicamente con l'identificativo CVE-2026-38526. Questo lavoro non rivendica la scoperta della vulnerabilità. Lo scopo di questa ricerca era comprendere l'implementazione vulnerabile, riprodurre il percorso di sfruttamento in un ambiente controllato ed esaminare le condizioni che trasformano il problema di caricamento file in esecuzione di codice in remoto.
La vulnerabilità è stata inoltre utilizzata nella macchina Hack The Box GCSB 2026 Nexus, che ha fornito un ambiente pratico per studiare il problema.
Prodotto: Webkul Krayin CRM Versioni interessate: 2.2.x Vulnerabilità: Caricamento arbitrario di file Impatto risultante: Esecuzione di codice in remoto Autenticazione: Richiesta Vettore di attacco: Rete CWE: CWE-434 — Caricamento non limitato di file con tipo pericoloso CVSS: 9.9 Critico CVE: CVE-2026-38526
La funzionalità vulnerabile è gestita da:
/admin/tinymce/upload
L'endpoint accetta un file caricato tramite il parametro file. La logica applicativa rilevante deriva il nome del file memorizzato dal nome del file originale e ne preserva l'estensione originale.

Questo comportamento è importante perché l'applicazione non si limita ad accettare un oggetto caricato; conserva un'estensione eseguibile controllata dall'attaccante e rende l'oggetto risultante accessibile tramite il meccanismo di archiviazione dell'applicazione.
Il problema principale è la validazione insufficiente lato server dei file caricati.
L'applicazione utilizza l'estensione originale fornita dal client quando costruisce il nome del file memorizzato. Non esiste una allowlist sufficientemente restrittiva che impedisca ai tipi di file eseguibili di raggiungere il livello di archiviazione.
Il flusso rilevante è

L'uso di un nome file generato non risolve il problema alla base.
Ad esempio, trasformare shell.php in un nome file generato come .php non rende sicuro il file caricato se il server continua a interpretare i file .php come codice PHP eseguibile.
Un caricamento non limitato non significa automaticamente esecuzione di codice in remoto.
Il percorso di esecuzione dipende dalla gestione del file caricato da parte del server.
Nello scenario di deployment vulnerabile, la catena diventa

Se l'esecuzione di PHP è disabilitata per la directory di caricamento, il percorso diretto verso l'RCE può essere impedito anche se la debolezza sottostante di caricamento arbitrario di file rimane.
wget:
wget https://raw.githubusercontent.com/Ish3ng0m4/CVE-2026-38526-KrayinCRM/main/poc/upload.py
wget https://raw.githubusercontent.com/Ish3ng0m4/CVE-2026-38526-KrayinCRM/main/poc/marker.php
curl:
curl -LO https://raw.githubusercontent.com/Ish3ng0m4/CVE-2026-38526-KrayinCRM/main/poc/upload.py
curl -LO https://raw.githubusercontent.com/Ish3ng0m4/CVE-2026-38526-KrayinCRM/main/poc/marker.php
2. Posiziona i file in
poc/
├── upload.py
└── marker.php
3. Crea un ambiente Python e installa la dipendenza
python3 -m venv .venv
source .venv/bin/activate
pip install requests
4. Rendi eseguibile il PoC
chmod +x poc/upload.py
6. Eseguilo
python3 poc/upload.py \
--url http://[Lab_IP:PORT] \
--email [email protected] \
--password 'YOUR_PASSWORD'
Lo sfruttamento richiede un account autenticato in grado di raggiungere la funzionalità vulnerabile.
A livello generale:
Il contesto di esecuzione risultante è determinato dal deployment sottostante. In un tipico deployment Linux questo può essere l'account di servizio del server web, ad esempio:
www-data
Questo non fornisce automaticamente privilegi di root a livello di sistema operativo. L'impatto ulteriore dipende dai permessi e dalla configurazione dell'ambiente compromesso.
Il comportamento vulnerabile può essere ridotto a tre operazioni importanti.
Ottenere il file caricato
$file = request()->file('file');
L'applicazione riceve il file fornito dal client.
Preservare l'estensione controllata dal client
$filename = md5($file->getClientOriginalName().time())
.'.'.$file->getClientOriginalExtension();
Il nome del file stesso viene modificato, ma l'estensione originale viene mantenuta. Questa è una distinzione importante: la randomizzazione del nome del file non è una validazione del tipo di file.
Archiviare ed esporre il file
$path = $file->storeAs($this->storagePath, $filename);
return [
'file' => $path,
'file_name' => $file->getClientOriginalName(),
'file_url' => Storage::url($path),
];
L'applicazione archivia il file e fornisce il suo URL al client.
Uno sfruttamento riuscito può fornire a un attaccante l'esecuzione di codice con i privilegi dell'applicazione web.