
Mautic < 5.2.3 RCE authentifiée
Une mauvaise assainissement du contenu, du type et de l'extension des fichiers téléversés dans la fonctionnalité d'édition des Assets permet à un attaquant authentifié d'écrire du code PHP arbitraire dans le répertoire web et de localiser où ce fichier est écrit. Cela aboutit à une exécution de code à distance.
Un chemin traversant permet également d'exploiter cette fonctionnalité pour supprimer récursivement n'importe quel répertoire du système de fichiers que l'utilisateur web a la permission de modifier.

Lors de la modification d'un Asset via la route /assets/view/{assetID}, il est possible de modifier le fichier de l'Asset.
Le téléversement d'un nouveau fichier appelle finalement la fonction suivante dans app/Bundles/AssetBundle/Controller/AssetController.php :
public function editAction(Request $request, UploaderHelper $uploaderHelper, AssetModel $model, $objectId, $ignorePost = false)
La logique de téléversement se trouve ici :
if (!$ignorePost && 'POST' == $method) {
$valid = false;
if (!$cancelled = $this->isFormCancelled($form)) {
if ($valid = $this->isFormValid($form)) {
$entity->setUploadDir($this->coreParametersHelper->get('upload_dir'));
$entity->preUpload();
$entity->upload();
Plus particulièrement, nous nous intéressons aux méthodes preUpload() et upload(), car elles gèrent l'écriture réelle du fichier sur le disque.
Le premier défaut réside dans preUpload() dans app/Bundles/AssetBundle/Entity/Asset.php, car l'implémentation nous permet de spécifier une extension de fichier arbitraire (contournant ainsi la protection normalement fournie par le tableau allowed_extensions) :
$filename = sha1(uniqid(mt_rand(), true));
$extension = $this->getFile()->guessExtension();
if (empty($extension)) {
// get it from the original name
$extension = pathinfo($this->originalFileName, PATHINFO_EXTENSION);
}
$this->path = $filename.'.'.$extension;
La ligne $extension = $this->getFile()->guessExtension(); retournera NULL si nous fournissons un nom de fichier se terminant par .php et un contenu commençant par la balise <?php.
La vérification empty($extension) sera donc évaluée à vrai, et l'extension du fichier sera ensuite extraite via l'appel pathinfo(), nous permettant ainsi de téléverser des fichiers temporaires avec un contenu et une extension arbitraires. Nous ne pouvons pas contrôler le nom réel du fichier car il est généré avec sha1().
Ensuite, dans la méthode upload() qui suit, le fichier sera réellement écrit sur le disque dans le répertoire web via l'appel suivant :
$this->getFile()->move($this->getUploadDir(), $this->path);
Il utilise notre extension arbitraire (contenue dans la variable $this->path).
Le nom du fichier peut ensuite être récupéré en actualisant la page des détails de l'Asset (/assets/view/{assetId}), sous l'entrée du tableau Nom de fichier local.
NB : Cela fonctionne également en modifiant les requêtes envoyées lors de la création d'un nouvel Asset. Cela appellera la fonction newAction(), mais la logique est identique, et les défauts résident toujours dans les méthodes preUpload() et upload().
Le PoC ne sera pas publié avant environ un mois.
Ceci afin de laisser le temps aux organisations qui dépendent de ce logiciel de le corriger sans craindre que des script kiddies détruisent leurs installations.
Après cela, ce dépôt sera mis à jour avec le script d'exploitation complet et les preuves. Il y a déjà suffisamment d'informations sur cette page de toute façon.
Lors de la validation d'un téléversement temporaire (via /s/assets/new ou /s/assets/edit/{assetId}), le répertoire stockant le fichier temporaire est supprimé récursivement à la fin de la requête. Le paramètre chargé de contenir le nom du répertoire temporaire est susceptible à des attaques de type chemin traversant, permettant à un attaquant authentifié de supprimer n'importe quel répertoire du système, à condition que l'utilisateur web en ait la permission. Cela peut entraîner une perte de données, voire la destruction de l'ensemble du système de fichiers si le serveur est exécuté par l'utilisateur root.
Spécifiez n'importe quel fichier existant sur le système via le point de terminaison utilisé ci-dessous. Si le fichier existe, le serveur tentera de supprimer le répertoire dans lequel il est stocké.

Prise de contrôle du serveur Déni de service Perte de données