Blog: OmniSpace, d'une 0day automatisée à une RCE
Author: Florent
Published on
Si vous lisez cet article, nous supposons que vous comprenez l'automatisation réalisée par Patrowl. Cependant, l'exemple ci-dessous démontre efficacement comment la combinaison de Patrowl avec du Pentest-as-a-Service nous permet de traiter la vaste étendue de la surface d'attaque exposée de nos clients. Cette approche nous aide à identifier les actifs spécifiques qui nécessitent une attention particulière.
Nous tenons à remercier les administrateurs du projet OmniSpace / Agora, un projet open source, qui ont très rapidement pris en compte les vulnérabilités envoyées par Patrowl et développé le correctif.
The detection
Patrowl effectue des tests d'intrusion en continu sur les actifs exposés sur Internet et a pour principal but de devancer les attaquants potentiels, être plus rapide que les attaquants ! Patrowl identifie et centralise des millions de 'findings' uniques automatiquement analysées, contextualisées et hiérarchisées. Lorsque des actions avancées sont nécessaires, les analystes offensifs prennent l'initiative de se concentrer uniquement sur les parties intéréssantes, ayant une valeur stratégique du point de vue de l'attaquant. Lorsque l'actif est nouveau, émergeant de la découverte (cartographie) de Patrowl, il déclenche rapidement une alerte prioritaire au sein de notre système Patrowl Arsenal. Cette alerte s'accompagne d'un degré élevé de qualification et donc d'un haut degré de confiance quant à l'importance de l'actif pour un attaquant.
The Power of XSS (CVE-2023-40228)
L'un des 'finding' trouvés par l'automatisation de Patrowl implique une vulnérabilité XSS provenant d'un paramètre accessible sans authentification. D'ailleurs, de nombreuses autres vulnérabilités XSS avaient déjà été divulguées en 2017 : https://www.cvedetails.com/vulnerability-list/vendor_id-16180/product_id-36153/year-2017/opxss-1/Agora-project-Agora-project.html
Oh, ça c'est intéréssant. Pourquoi?
Tout d'abord, les CVE publiées affectaient 4 paramètres : targetObjIdChild, action, ditObjId, msgNotif[]. Étonnamment, ces paramètres ne sont pas automatiquement collectés et examinés par les outils de sécurité (scanner...) disponibles sur le marché, mais cela changera après la lecture de cet article 😉.
La présence de quatre paramètres vulnérables en 2017 constitue une indication forte qu’il pourrait y en avoir d'autres, attendant d'être découvertes. Naturellement, vous ne liriez pas cet article si ce n’était pas le cas. Bien que le produit soit dans une version à jour et que les vulnérabilités XSS précédemment révélées soient inexploitables, l'analyse doit s'étendre à tous les paramètres nouvellement introduits.
Une fois de plus, l'automatisation de Patrowl collecte systématiquement tous les paramètres accessibles grâce à une exploration continue des applications Web. En outre, Patrowl examine toutes les variables qui sont susceptibles d'être exploitables.
Et voilà : notre variable sensible notify[] récemment identifiée a été signalée comme sensible à une vulnérabilité XSS (nécessitant juste un peu d'encodage pour l'exploiter) et voici l'exploit :
https://x.x.x.x/index.php?disconnect=1¬ify[]=%3ci%3eiii%3c%2fi%3e68617%22)%3balert(1)%2f%2f869
Avec une automatisation et une validation complètes en place, que se passe-t-il ensuite ? Les découvertes de Patrowl nous ont encouragés à creuser plus profondément et, comme toujours, cela s'est avéré payant.
Under the cookie (CVE-2023-40227)
Une XSS non authentifié est intéréssante, en particulier sur une page d'authentification. Une telle vulnérabilité pourrait potentiellement faciliter le piratage de compte ou aider des attaques de phishing.
Une autre découverte signalée par l'automatisation a attirer notre attention : un cookie intitulé AGORAP_PASS qui semble n'être qu'un simple condensat SHA1. Étant donné qu'OmniSpace source, approfondissons nos recherches en explorant une version de laboratoire vis à vis de cet étrange condensat.
L'obtention de la version la plus récente accessible lors de la phase de test (23.5.0) a révélé qu'il est déconseillé d'utilisation AGORAP_PASS, avec l'utilisation d'un mécanisme d'authentification moderne. De plus, toutes les sessions datant de plus d'un an sont automatiquement purgées à chaque fois qu'un utilisateur se connecte ou se déconnecte de la plateforme.
if(!empty($_COOKIE["AGORAP_PASS"])) {setcookie("AGORAP_LOG",null,-1); setcookie("AGORAP_PASS",null,-1);}
Db::query("DELETE FROM ap_userAuthToken WHERE UNIX_TIMESTAMP(dateCrea) < ".(time()-31536000));
However, the version installed for our client (23.2.3) create the cookie with the SHA1:
//Enregistre login & password pour une connexion auto (10ans)
if(Req::isParam("rememberMe")){
setcookie("AGORAP_LOG", $login, (time()+315360000));
setcookie("AGORAP_PASS", $passwordSha1, (time()+315360000));
}
Dans la version précédente (< 23.4.1), cela rend la vulnérabilité XSS assez dangereuse. Désormais, un attaquant ayant la possibilité de détourner le cookie d'un utilisateur pourra :
- Exécuter une attaque Pass The Hash sur l'application, en l'utilisant pendant une durée supérieure à 10 ans
- Récupérez le mot de passe d'un utilisateur en retrouvant le mot de passe depuis le condensat SHA1 de l'utilisateur et en le réutilisant sur d'autres applications, un autre accès...
Le cookie est supprimé et n'est plus créé dans la version > 23.4.1. Cependant, il pourrait être utilisé et exploité par un attaquant pour toute authentification inférieure à une année.
Stone cold CSRF (CVE-2023-40230)
Une fois la connexion réussie, un examen rapide de l'interface utilisateur révèle une vulnérabilité dans la capacité de l'administrateur à modifier le mot de passe d'un utilisateur. Cette action est sensible au Cross-Site Request Forgery (CSRF) et n’a pas été correctement mise en oeuvre :
- Le processus de modification du mot de passe d'un utilisateur ne nécessite pas que l'utilisateur saisisse son ancien mot de passe. Cette surveillance permet à un attaquant de créer facilement des liens malveillants. Tout ce que l’attaquant a besoin de connaître, c’est l’identifiant des utilisateurs ciblés, qui peut être facilement obtenu s’ils appartiennent au même espace :
- L'application accepte également les paramètres POST comme paramètres GET, simplifiant ainsi le processus de création de liens malveillants pour un attaquant
- Aucune protection CSRF n'est implémentée
Ensuite, un attaquant pourrait simplement construire un lien qui changerait le mot de passe de l’utilisateur en un clic, plus amusant encore, il pourrait envoyer le lien malveillant via la messagerie interne : Exemple de lien, avec juste l'ID utilisateur à modifier :
http://127.0.0.1:8000/index.php?personImgFile=&personImgAction=change&login=admin_2@patrowl.io&password=toto&passwordVerif=toto&civility=&name= &firstName= &mail= admin_2@patrowl.io&telmobile=&telephone=&adress=&postalCode=&city=&country=&function=&companyOrganization=&comment=&connectionSpace=1&lang=francais&ctrl=user&action=userEdit&formValidate=1&typeId=user-1
La vulnérabilité ne sera pas corrigée pour le moment, le développeur a indiqué que changer le mot de passe sans l'ancien est une fonction spécifique nécessaire aux administrateurs.
Breaking the File upload (CVE-2023-40229)
Avec la possibilité de voler sans effort un compte sur la plateforme et de partager des documents depuis celle-ci, la prochaine étape est évidente : téléverser un fichier PHP malveillant et tenter l'exécution de code à distance.
La fonctionnalité de téléversement est assez classique :
- Une fois les fichiers téléversés, une vérification rapide est effectuée côté client pour restreindre certains fichiers spécifiques
- Un premier appel à ?ctrl=file&action=UploadTmpFile&tmpFolderName= tmpUploadFolder5333858564d63b8dd3e32 est effectué, cela créera le fichier dans le répertoire web DATAS/tmp/tmpUploadFolder5333858564d63b8dd3e32, où tmpUploadFolder53338585 64d63b8dd3e32 pourrait être défini arbitrairement
- Ensuite, un appel direct à la requête POST index.php et à l'action AddEditFiles qui stocke le fichier dans la base de données et le supprime du dossier /tmp.
Eviter le stockage direct des fichiers téléchargés sur le serveur Web est une bonne pratique de sécurité. Cependant, un attaquant, ayant la possibilité d'accéder directement à la fonction UploadTmpFile, peut contourner l'appel à AddEditFiles. Par conséquent, il est possible de contourner le processus de suppression de fichiers du dossier temporaire.
Armés de nos étonnantes trouvailles et d'un soupçon de finesse, essayons d'exécuter du code. Notre but ? Pour modifier le type de contenu par magie et conserver fièrement notre extension PHP bien-aimée :
Bingo! Le fichier est stocké dans DATAS/tmp/azerty/hack.php:
Ok, essayons maintenant de l'atteindre, avec un peu de chance, pourrait-il être atteint directement ?
curl http://localhost:8000/DATAS/tmp/azerty/hack.php -I
HTTP/1.1 403 Forbidden
Date: Fri, 11 Aug 2023 14:24:37 GMT
Server: Apache/2.4.38 (Debian)
Content-Type: text/html; charset=iso-8859-1
Non, vérifions le fichier .htaccess par défaut :
$cat DATAS/.htaccess
order allow,deny
<Files ~ '\.(?i:png|jpeg|jpg|gif|mp3|mp4|webm|flv)$'>
allow from all
</Files>%
Nous devons trouver un autre moyen.
La vulnérabilité a été corrigée dans la version 23.7.1.
One Hot Arbitrary File inclusion (CVE-2023-40226)
Maintenant que nous avons mis la main sur un fichier PHP niché au sein du serveur, notre prochaine mission est d'y accéder. Comment? Eh bien, partons en quête pour trouver un moyen permettant aux utilisateurs de contrôler quels fichiers sont inclus. Avec un peu de chance, nous pourrions tomber sur une opportunité d'inclure n'importe quel fichier PHP, ce qui pourrait nous amener à réaliser l'exécution de code à distance (RCE).
Après peu de recherche, nous trouvons le paramètre : curTrad, le code source est assez intéressant :
//Charge les trads si besoin (et garde en session) if(empty(self::$trad)) {
//Sélectionne la traduction if(Req::isParam("curTrad"))
{$_SESSION["curTrad"]=Req::param("curTrad");} ... //Charge les trads
(classe & methode) require_once "app/trad/".$_SESSION["curTrad"].".php";
Trad::loadTradsLang(); } }
Pas besoin de chercher plus, curTrad est directement extrait du paramètre curTrad des utilisateurs, puis envoyé gentiment dans un appel require_once(). Nous savons maintenant comment inclure notre fichier PHP malveillant :
Bingo! RCE.
Pour en ajouter à l'intrigue, le curTrad est accessible sans authentification et le processus d'inclusion fonctionne de manière transparente. Si nous revenions en 2010, nous utiliserions l'astuce de l'extension Null Byte pour exploiter cette vulnérabilité et accéder à des fichiers cruciaux qui n'ont pas été téléversés et qui n'étaient pas des scripts PHP – comme peut-être trouver des joyaux cachés tels que des sauvegardes de bases de données. Mais pour l'instant, supposons que nous soyons tous d'accord sur le fait que les versions PHP antérieures à 5.3 appartiennent au passé (https://svn.php.net/viewvc?view=revision&revision=305507).
Conclusion
Il va de soi que la série de vulnérabilités enchaînées pourrait avoir des conséquences importantes pour les entreprises qui déploient de tels logiciels sur leur surface d'attaque externe. Pour résumer cette kill chain :
- Vol de compte via XSS (CVE-2023-40228), Contournement de l'authentification via les cookies (CVE-2023-40227) et CSRF (CVE-2023-40230)
- Téléversement arbitraire de fichiers sans restriction (CVE-2023-40229)
- Inclusion arbitraire de fichiers PHP (CVE-2023-40226)
Tout cela mène à une exécution de code à distance.
Heureusement, les équipes du Projet Agora ont fait preuve de rapidité et de rigueur. Les vulnérabilités les plus critiques ont été rapidement corrigées. Vous comprenez à présent l'importance la la gestion continue de son exposition externe par de l'EASM combinée à l'approche PTaaS. Cela reflète précisément la méthodologie qu’un attaquant emploierait, bien qu’à un rythme plus lent dans son cas.
Chronologie:
- Découverte de failles : 17/06/2023
- Editeur prévenu : 20/06/2023
- Réponse de l'éditeur : 24/06/2023
- Première version du correctif 23.7.1 : 17/07/2023
- Demande CVE/MITRE : 08/08/2023
- CVE-2023-40226, CVE-2023-40227, CVE-2023-40228, CVE-2023-40229, CVE-2023-40230 réservés : 11/08/2023