
PrestaShop (1.6.x <= 1.6.1.23 ou 1.7.x <= 1.7.4.4) Exécution de code à distance dans le Back Office (CVE-2018-19126)
Ceci est la preuve de concept (PoC) pour CVE-2018-19126, enchaînant plusieurs vulnérabilités dans le Back Office de PrestaShop pour déclencher une désérialisation via phar et ainsi obtenir une exécution de code à distance.
Prérequis :

Note de version de PrestaShop : http://build.prestashop.com/news/prestashop-1-7-4-4-1-6-1-23-maintenance-releases/
Lien du package vulnérable : https://assets.prestashop2.com/en/system/files/ps_releases/prestashop_1.7.4.3.zip
À DES FINS ÉDUCATIVES UNIQUEMENT. N'UTILISEZ PAS CE SCRIPT POUR DES ACTIVITÉS ILLÉGALES. L'AUTEUR N'EST PAS RESPONSABLE DE TOUTE MAUVAISE UTILISATION OU DE TOUT DOMMAGE.
Vous avez besoin de php avec l'extension curl et de définir phar.readonly = Off dans pour exécuter l'exploit.
php.ini# Téléchargement du dépôt
wget https://github.com/farisv/PrestaShop-CVE-2018-19126/archive/master.zip -O PrestaShop-CVE-2018-19126.zip
unzip PrestaShop-CVE-2018-19126.zip
cd PrestaShop-CVE-2018-19126-master
# Exécution de l'exploit
# Usage: php exploit.php back-office-url email password func param
php exploit.php http://127.0.0.1/admin-dev/ [email protected] 54l35m4n123 system 'cat /etc/passwd'
Notez que le répertoire de téléchargement sera renommé et que vous ne pouvez pas télécharger à nouveau le fichier phar malveillant si le nom du dossier n'est pas rétabli. Vous pouvez exécuter un reverse shell pour obtenir une persistance RCE ou inclure la commande pour renommer à nouveau le dossier dans votre charge utile (vous devez connaître le chemin du répertoire de téléchargement).
Nous pouvons réaliser une désérialisation implicite avec le wrapper phar via la fonction getimagesize() dans [back-office-path]/filemanager/ajax_calls.php.
case 'image_size':
if (realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) != realpath(_PS_ROOT_DIR_.$upload_dir)) {
die();
}
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false) {
$info = getimagesize(substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir)));
echo json_encode($info);
}
Nous devons trouver un moyen pour que getimagesize() soit appelée avec une URL de wrapper phar comme paramètre en contournant certaines vérifications.
La première vérification avec realpath() est assez stricte.
if (realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) != realpath(_PS_ROOT_DIR_.$upload_dir)) {
die();
}
La variable $upload_dir provient de config.php, qui est définie avec $upload_dir = Context::getContext()->shop->getBaseURI().'img/cms/'; par défaut. Nous ne pouvons pas utiliser phar://[string] dans $_POST['path'] car realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) retournera false car elle n'existe pas.
Il existe une autre vulnérabilité (CVE-2018-19125) qui permet à l'utilisateur de supprimer ou renommer $upload_dir. Si le répertoire $upload_dir n'existe pas, realpath(_PS_ROOT_DIR_.$upload_dir) retournera false et nous pouvons contourner cette vérification car realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) est aussi false. Cette vulnérabilité a été découverte lors d'une revue de code en essayant de trouver un moyen de contourner :) .
En bref, CVE-2018-19125 permet au paramètre path dans l'appel aux actions delete_folder ou rename_folder dans execute.php d'être vide, de sorte que l'application supprime/renomme le $upload_dir à la place.
La deuxième vérification est simple, $_POST['path'] doit contenir $upload_dir.
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false) {
Nous pouvons simplement ajouter /img/cms/ dans l'URL phar après le chemin du fichier vers le fichier phar car si le répertoire n'existe pas dans l'archive phar, la désérialisation se produit quand même. Le substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir)) remplacera uniquement /img/cms/ par le chemin absolu ($current_path) de ce dossier (par exemple /var/www/html/img/cms/ si l'application est installée dans /var/www/html/).
Étant donné que nous pouvons contrôler la fonction getimagesize() pour traiter une URL de wrapper phar, nous devons télécharger le fichier phar malveillant sur le serveur. Par défaut, FileManager dans PrestaShop n'autorise que les extensions 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'svg', 'pdf', 'mov', 'mpeg', 'mp4', 'avi', 'mpg', 'wma', 'flv' et 'webm'. Nous pouvons simplement fabriquer la charge utile et l'enregistrer avec une extension valide. Nous pouvons utiliser les chaînes de gadgets Monolog de PHPGGC (https://github.com/ambionics/phpggc/blob/master/gadgetchains/Monolog/RCE/1/) car il est utilisé par PrestaShop.
Étapes finales de l'exploitation :
image_size avec phar://../../img/renamed/phar.pdf/img/cms/ comme paramètre path.Le script exploit.php effectuera automatiquement toutes les étapes.
Rappelez-vous que le répertoire de téléchargement est renommé à l'étape 3 et que vous ne pouvez pas télécharger à nouveau le fichier phar malveillant si le nom du dossier n'est pas rétabli. Vous pouvez utiliser un reverse shell comme charge utile ou inclure la commande pour renommer à nouveau le dossier dans la charge utile (vous devez connaître le chemin du répertoire de téléchargement).