原文出处:
PostMessage跨域漏洞 - 知乎 (zhihu.com)
背景
价值: $3000
漏洞原因:postMessage跨域漏洞导致,利用websocket接收用户认证token
Hacking Slack using postMessage and WebSocket-reconnect to steal your precious token
- 基础知识
在了解这个漏洞的时候我们需要了解以下基础的知识:PostMessage
PostMessage
PostMessage API是一个很简单的实现跨域的方法,最基本的使用方法是:
B站的data数据,发送数据端
parent.postMessage('I am B data!!','*');
获取数据代码:
window.addEventListener('message',function(e){
alert(e.data);
})
PostMessage产生的漏洞
伪造获取数据端
若是发送数据端的第二个参数使用的是”*” 那么表示的是这个数据可以被任何域获取到,这时候只要构造window.addEventListener来接受数据就可以了
伪造发送数据端
来看一段代码:
window.addEventListener("message", function(message){
if(/^http://www.examplesender.com$/.test(message.origin)){
console.log(message.data);
}
});
可以看到对接收的message.origin进行了判断,但是使用的正则并不标准
直接利用“wwwaexamplesender.com“, “wwwbexamplesender.com” etc.进行绕过,用postMessage发送数据给他接收
使用的poc可以参考:
<iframe src=https://targetpage/using_addthis"></iframe>
<script>
document.getElementById("frame").contentWindow.postMessage('hello', '*');
</script>
测试代码:window.postMessage("hello", "*")
利用xss进行攻击
先看代码:
//Listener on http://www.examplereceiver.com/
window.addEventListener("message", function(message){
if(/^http://www\.examplesender\.com$/.test(message.origin)){
document.getElementById("message").innerHTML = message.data;
}
});
这个对来源进行了严格的限制,可以通过查找http://www.examplesender.com/上面的xss进行攻击
查看是否使用PostMessage
这个可以使用chrome下的开发者工具,在source ——> Global Listeners 下面可以看到
案例
上面slack的漏洞是一个案例,总体的思路就是站点监听着一个message,并且没有判断message的来源,导致可以给他发message,message中有websocket的url的话,站点会和发送message的站点建立websocket链接,兵器会把认证后的token传递给发送者站点
该作者还有个PostMessage的漏洞,会影响到百万网站,是AddThis这个插件导致的,不难理解
- qq邮箱
再国内的站点了翻了一个下午也没有能找到一个可以利用的漏洞,不过在qq邮箱还是可以找到可以练习的地方
首先打开http://mail.qq.com 使用开发者工具打开查看listeners
我们构造测试代码:
window.postMessage("hello", "*")
这时候对代下断点进行调试,可以最终得到:
window.postMessage('{"action":"resize","width":"222","height":400}', "*")
方法有两个一个是close,一个是resize。
直接执行的话就可以看到登入框的大小属性产生了变化,构造poc:
<iframe id="frame" src="登录QQ邮箱" height="1000" width="1000" onload=xss()></iframe>
<script>
function xss(){
document.getElementById("frame").contentWindow.postMessage('{"action":"resize","width":"10","height":400}', "*");
}
</script>
构造html页面,访问这个页面,就能看到登入框的大小产生了变化,
这个只是个案例,要是邮箱中接收的信息做了其他处理,那么就有可能产生其他的问题
- 微博
qq邮箱是伪造发送者,那微博这个就是伪造接收者。同样打开微博查看信息
可以看到一行代码:
b[c] && b[c].contentWindow && b[c].contentWindow.postMessage ? b[c].contentWindow.postMessage(g, "*")
这个很明显的使用了*的配置
构造poc:
<iframe src=Sina Visitor System></iframe>
<script>
window.addEventListener('message',function(e){
alert(e.data);
})
</script>
访问html页面触发:
这个里面没有任何可以利用的东西,但是一旦有用户的敏感信息,那么就可以跨域获取这些信息