千家信息网

如何利用postMessage窃取编辑用户的Cookie信息

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,如何利用postMessage窃取编辑用户的Cookie信息,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。当我在做某个项目的漏洞测试时,
千家信息网最后更新 2024年09月22日如何利用postMessage窃取编辑用户的Cookie信息

如何利用postMessage窃取编辑用户的Cookie信息,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

当我在做某个项目的漏洞测试时,在登录的一些HTTP请求记录中,我发现了一种利用postMessage方式窃取和编辑用户Cookie的方法。由于该测试是邀请测试,出于保密,我只能在下文中和大家分享一些方法思路。

postMessage介绍

相信大家都听过不同窗口之间的通信、当前窗口与内部iframe框架的通信以及一些跨域技巧,window.postMessage功能就是允许在两个客户端的窗口/frames间发送数据信息,跨域地实现通信的方法。

在HTML5中,Window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

Window.postMessage有三个参数,message、targetOrigin和可选的[transfer]),其中message代表将要发送到其他窗口的数据,targetOrigin表示接收数据消息的目标窗口,transfer代表消息的所有权。另外还有一个window.addEventListener("message", receiveMessage, false),用以监听消息数据的反馈,其中的message就存在data、origin和source三个属性,origin属性表示消息数据发送方的身份,只有和原来指定发送方的协议、域名或端口一致,才能建立通信。具体请参考 postMessage的详细介绍。

举个例子,比如我们这有一个包含js代码的页面,用来监听记录传入的消息,其中的js代码如下:

在上述child.html的子页面中,存在一个向主页面的消息发送,它就调用了postMessage方法,如下:

window.parent.postMessage("Hello parent", "target");

接下来,会发生什么呢?

首先,你访问那个会加载child.html子页面的主页面,之后,子页面会向主页面发送消息,然后,主页面接收该消息并通过控制台进行记录。这里会存在什么安全隐患吗?

如果攻击者能控制消息发送的目标窗口target参数值会怎样?

当然,如果子页面存在点击劫持又会怎样?

我们要思考的是,按照postMessage规范来说,如果消息发送的目标窗口target参数是星号*,表示无限制,也即可以发送到任何引用了子页面的域名中去。这样的话,就会导致一些不安全的问题出现。

具体测试

回到之前的漏洞测试过程中,为了更好地展示思路,接下来开始,假设我们的测试目标为域名onga.com。我通过爬虫找到了其中一个包含了HTML内容的一个HTML页面 sync.html,然后,我的工具也显示该页面中包含了一些不安全的Javascript代码。

这个文件没有其它过多的元素,只包含了一个script标记,所以这个页面看起来是起到一个中转作用。仔细分析其中的 sync.html 文件,其中包含了一个postMessage方法,它向变量名为wOrigin的目标发送了消息,如下:

window.parent.postMessage(JSON.stringify(msg), wOrigin);

这样,我们现在就看到了两个变量,分别为msg和wOrigin。于是,我认真查找了类似变量的初始化位置,以确定是否可以对它们进行控制。很惊讶的是,msg是Cookie值,其它相关的都是用户的输入。

在分析wOrigin变量的过程中, 它在三个地方存在,第一个地方就是:

var fdata = JSON.parse(decodeURIComponent_(window.location.hash.substr(1)));var ns = fdata.ns;var worigin = fdata.worigin;

代码很简单,首先,它获取到了当前窗口的URL哈希值,然后执行编码操作(Decode);之后,解析为json对象,接着,创建两个变量,ns代表命名空间,wOrigin代表消息的发送目标窗口。

看到_window.location.hash方法,我们就会自然地想到它可以用dom-based XSS加以利用,但这个问题在此不作讨论。

所以,接下来,我继续检查其中的代码,查看 ns 和 wOrigin 在传递给postMessage方法前的一些过滤机制,啊,竟然没有!那这样的话,我们就可以想办法来构造exploit看看了。

构造Exploit

现在,我们需要逆向来思考这个过程:

首先,要创建ns 和 wOrigin 两个变量;

假设 ns=anyblah ,wOrigin=*;

创建json对象格式 {"ns":"anyblah","wOrigin":"*"};

构造存在漏洞的URL:

http://vulnerable-onga.com/sync.html#{"ns":"anyblah","wOrigin":"*"}

当上述URL页面被加载之后,postMessage方法会向主页面发送一个消息,但由于采用了*星号,该过程中不会限制发送目标域,消息可以发送到任何采取监听措施的域名中去。

现在,我们在主页面中来设置一个监听以接收消息:

创建一个iframe框架来加载存在漏洞的页面,并把它设置为子页面,所以最终的PoC代码可以如下: