文章总结: 文档详细描述了作者通过代码审计在XiboCMS中发现存储型XSS漏洞,并利用postMessage缺失来源验证和jQuery的DOM注入漏洞实现沙盒逃逸,最终通过metarefresh标签绕过CSP完成管理员页面劫持的攻击链。关键发现包括四个漏洞的组合利用(CWE-79/346/116及CSP绕过),并提供了修复方案(使用.text()和DOMPurify)。建议防御者验证postMessage来源、清理DOM输出,猎人应深入挖掘漏洞组合可能性。 综合评分: 92 文章分类: 漏洞分析,WEB安全,实战经验,安全开发,红队
我是如何找到攻击链并获得 CVE-2026-42558 的?
haidragon haidragon
安全狗的自我修养
2026年5月25日 12:06 湖南
在小说阅读器读本章
去阅读
官网:http://securitytech.cc
#
经过数天的代码审查,终于发现了一个跨站脚本攻击漏洞(XSS)。之后又花了更多时间,将其扩展成一个完整的沙盒逃逸和攻击链。
按回车键或点击查看完整尺寸的图片
Xibo CMS——开源数字标牌平台。服务于超过38,000家企业、77,000多个显示屏,覆盖186个国家。为医院、大学、机场、肯德基菜单板、索尼BRAVIA电视网络等场所的屏幕提供支持。
我选择它的原因是:它基于 PHP 代码库,支持 Docker,而且安全团队响应迅速。我克隆了代码库,启动了一个本地实例,然后开始阅读。
第 1-3 天:了解应用程序
头几天我都在读代码。没有模糊测试,也没有用 Burp Suite。我只是理解应用程序的工作原理——输入如何流经控制器,如何存储在实体中,以及如何通过 Twig 模板渲染。我需要理解整个系统,才能找到问题所在。
我走了不少弯路。SQL 查询使用了预处理语句。输入数据经过了适当的清理。文件验证也正确无误。安全措施做得很好——但这对于一个猎手来说却令人沮丧。
在查看模板文件时,我注意到了一些问题。一些输出变量使用了 Twig 的{{ | raw }}过滤器,该过滤器会禁用 HTML 转义。大多数变量都是安全的——JSON 数据,预先清理过的变量。但有一个变量却很特别:
< script type = " text /javascript" nonce = "{{ cspNonce }}" > {
{ script|raw }}
</script>
一个名为 <variable\_name> 的变量script,直接显示在 script 标签内。任何用户都可以访问此页面。我开始反向追踪代码库——跟踪每一个函数调用,以了解这个变量的来源,以及是否有任何代码对其进行了清理。
经过数小时对控制器层和实体层的调用进行追踪,我绘制出了完整的管道图:
输入—
getParam()返回用户原始输入。不进行任何过滤。存储方式——
file_put_contents($path, $script)直接写入磁盘,不进行验证。输出——
{{ script|raw }}在浏览器中渲染。不进行转义。
三个文件。全程未进行任何清理。典型的存储型跨站脚本攻击。
我已验证跨用户利用漏洞——内容管理器保存有效载荷,管理员打开页面:
127.0.0.1 - "GET /?proof=XSS HTTP/1.1" 200
但该页面被隔离在一个沙盒化的 iframe 中。没有会话 cookie,也没有身份验证上下文。我可以窃取localStorage(用户名、设备配置),但无法触及管理员的会话。
中等严重程度。我本来可以就此止步。
我想要的是连击!
第 4-6 天:寻找沙盒逃生
难点就在这里。我的代码是在一个沙盒化的iframe中执行的。问题是:我能突破这个限制吗?
iframe 中的sandbox="allow-scripts"JavaScript 代码可以运行,但无法访问父页面。parent.document没有 cookie。脚本被限制运行。
但是数据连接器需要将结果发送回父页面。它使用了postMessage一种实现方式。我花了几天时间研究父页面如何处理这些消息,追踪每种消息类型,并追踪每条数据最终在 DOM 中的位置。
在反复阅读同一段代码大概二十遍之后,我终于明白了:
// 父窗口接受任何消息——不检查来源
。window.addEventListener( 'message' , function( event ) {
receiveData( event.data.type , event.data );
});
// 对于“criteria”消息,dataKey 直接进入 HTML
$ .each (criteria, function ( key, value ) {
$tableBody.append ( ' <tr><td>' + key + '</td>...' );
});
该数据key来自 iframe 的 postMessage 方法。它通过 jQuery 注入到父页面的 HTML 中.append()。未经任何清理。
我可以从沙盒内部向已认证的父页面注入 HTML 代码。沙盒逃逸机制隐藏在 jQuery 字符串拼接中。
第7天:遭遇CSP瓶颈
找到注入点就成功了一半。父页面已设置内容安全策略:
script-src 'nonce-xxx' 'strict-dynamic'
我花了一整天的时间试图绕过它:
有效载荷结果
<script>alert(1)</script>❌已阻止
<img onerror=fetch(...)>❌ 已屏蔽
<svg onload=...>❌ 已屏蔽
<iframe srcdoc="<script>...">❌ 已屏蔽
所有 JavaScript 向量都失效了。我多次离开键盘。阅读了 CSP 绕过方面的研究资料。回来后,仍然失败。
然后我恍然大悟:CSP 控制的是 JavaScript,而不是 HTML 指令。
window.onload = function ( ) {
window.parent.postMessage ({ type : 'criteria' , dataKey : '<meta http-equiv="refresh" content="0;url=http://127.0.0.1:9999/?pwned=true">' , data : { metric : ' x ' , value : 'x' , ttl : 1 } }, '*' ); }
<meta http-equiv="refresh">指示浏览器进行重定向。这是 HTML,不是 JavaScript,CSP 无法影响它。
已将有效载荷保存为内容管理器。以管理员身份登录。打开页面。
127.0.0.1 - "GET /?pwned=true HTTP/1.1" 200
管理员的整个页面都重定向到我的服务器了。已确认两次。
沙盒逃脱成功
四个漏洞导致了这种情况:
**1. 存储型跨站脚本攻击 (CWE-79) — 脚本未经过滤保存到服务器
- 缺少来源验证 (CWE-346) — 接受来自任何来源的 postMessage 请求
- 未经过滤的 DOM 注入 (CWE-116) — jQuery 的 .append() 函数未进行编码
- CSP 绕过 — meta refresh 属性是 HTML 代码,而非 JavaScript 代码。CSP 无法阻止此类攻击**
单独来看,它们都无害。但结合起来,就能实现:沙盒逃逸→管理员页面劫持。
攻击链
1.输入:file_put_contents() 函数存储脚本时未进行验证
↓
2.沙盒:允许从沙盒 iframe发送 postMessage 消息
↓
3.源:父级接受消息时未检查来源
↓
4. CSP:<meta refresh>是HTML 代码——CSP 未阻止它
↓
管理员已认证的页面重定向到攻击者的服务器
实际操作中:
内容管理器保存有效载荷 → 等待
管理员打开数据连接器页面(日常操作)→ iframe加载 → 脚本运行 → postMessage 触发 → 父级注入 meta refresh → 浏览器重定向 → 伪造登录页面 → 管理员输入密码 → 被盗
没有可疑链接。管理员打开了一个他们已经访问过上百次的页面。
按回车键或点击查看完整尺寸的图片
为什么单独一个漏洞都无关紧要
单独使用 XSS:在独立页面中运行,不涉及会话。 “这是供应商所说的‘预期功能’。”
仅注入 PostMessage: iframe 中没有脚本 = 不会发送恶意消息。
攻击链: XSS 存储武器 → 沙箱逃逸触发武器 → 管理员页面被劫持。
破坏其中任何一个环节,链条都会断裂。但这两个环节都存在。
修复方案
Xibo在数小时内做出回应,并寄出了PR #3428:
.text()对于dataKey——HTML 变成无害文本- DOMPurify用于列值——去除危险标签
- 日志条目也已清理。
沙盒逃逸机制已被破解。
要点总结
防御者:验证postMessage来源。清理.append()输出。记住,这<meta refresh>会绕过内容安全策略 (CSP)。
猎人们:不要止步于中等难度。
请阅读 iframe 的两侧。
狩猎前请先了解应用的全部功能。CSP并非无敌!
-
-
公众号:安全狗的自我修养
-
vx:2207344074
-
http://gitee.com/haidragon
-
http://github.com/haidragon
-
bilibili:haidragonx
-
#
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全狗的自我修养 haidragon haidragon《我是如何找到攻击链并获得 CVE-2026-42558 的?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论