通过HackerOne漏洞报告学习PostMessage漏洞实战场景中的利用与绕过

转载https://www.anquanke.com/post/id/219088

 

0x00 前言

这是一篇关于postMessage漏洞分析的文章,主要通过hackerone平台披露的Bug Bounty报告,学习和分析postMessage漏洞如何在真实的场景中得到利用的。

 

0x01 什么是PostMessage

根据Mozilla开发文档描述:

The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.

也就是说,window.postMessage()方法可以安全地实现Window对象之间的跨域通信。例如,一个页面和它所产生的弹出窗口之间,或者一个页面和嵌入其中的iframe之间进行。

这里,我们看一个例子:

假设我们有一个主网站1.html与另一个网站2.html进行通信。在第二个网站中,有一个后退按钮,当第一个网站的导航改变时,这个按钮就会改变。例如,在网站1中,我们导航到 changed.html,那么网站2中的后退按钮就会指向 changed.html。为此,使用postMessage方法将网站1的值发送到网站2。

1.html中的代码如下:

<!DOCTYPE html>
<html>
<head><title>Website 1</title><meta charset="utf-8" />
<script>
var child;
function openChild() {child = window.open('2.html', 'popup', 'height=300px, width=500px');
}
function sendMessage(){let msg={url : "changed.html"};// In production, DO NOT use '*', use toe target domainchild.postMessage(msg,'*')// child is the targetWindowchild.focus();
}</script>
</head>
<body><form><fieldset><input type='button' id='btnopen' value='Open child' onclick='openChild();' /><input type='button' id='btnSendMsg' value='Send Message' onclick='sendMessage();' /></fieldset></form>
</body>
</html>

网站1中有两个按钮:

  • 1 . 第一个是通过openChild()函数打开一个包含2.html的弹出窗口。
  • 2 . 第二个是通过sendMessage()函数发送消息。要做到这一点,需要设置一个消息,定义msg变量,然后调用postMessage(msg,'*')

2.html中的代码如下:

<!DOCTYPE html>
<html>
<head><title>Website 2</title><meta charset="utf-8" /><script>// Allow window to listen for a postMessagewindow.addEventListener("message", (event)=>{// Normally you would check event.origin// To verify the targetOrigin matches// this window's domaindocument.getElementById("redirection").href=`${event.data.url}`;// event.data contains the message sent});function closeMe() {try {window.close();} catch (e) { console.log(e) }try {self.close();} catch (e) { console.log(e) }}</script>
</head>
<body><form><h1>Recipient of postMessage</h1><fieldset><a type='text' id='redirection' href=''>Go back</a><input type='button' id='btnCloseMe' value='Close me' onclick='closeMe();' /></fieldset></form>
</body>
</html>

网站2中有一个链接和一个按钮:

  • 1 . 链接处理重定向,href字段根据window.addEventListener("message", (event)接收到的数据而变化。接收到消息后,从event.data中读取事件中的数据并将url并传递给href
  • 2 . 按钮调用函数closeMe()关闭窗口。

 

0x02 一个基础漏洞的简例

XSS漏洞的实现

PostMessages如果执行不当,可能导致信息泄露或跨站脚本漏洞(XSS)。
在这种情况下,2.html在没有验证源的情况下就准备接收一个消息,因此我们可以将网页3.html作为iframe加载2.html,并调用postMessage()函数来操作href值。

<!DOCTYPE html>
<html>
<head><title>XSS PoC</title><meta charset="utf-8" />
</head>
<body><iframe id="frame" src="2.html" ></iframe><script>let msg={url : "javascript:prompt(1)"};var iFrame = document.getElementById("frame")iFrame.contentWindow.postMessage(msg, '*');
</script>
</body>
</html>

在这里例子中,恶意的msg变量包含数据{url: "javascript:prompt(1)"};,该数据将被发送到2.html2.html处理后,将<a href中的值更改为msg.url的值。iframe用于在网站中加载攻击。当用户单击返回链接时,将实现一个XSS。

缓解措施

根据Mozilla文档中的说法。

如果不希望收到来自其他网站的消息,不要为任何消息添加事件监听器的。这可以完全避免此类安全问题。

如果希望从其他站点接收消息,需要对源和可能的源验证发送方的身份,因为任何窗口都可以向任何其他窗口发送消息,并且不能保证未知的发送者不会发送恶意消息。但是,在验证了身份之后仍然应该验证接收到的消息的语法,否则,也可能出现跨站点脚本攻击。

当使用postMessage向其他窗口发送数据时,一定要指定一个准确的目标,而不是*。恶意网站可以在不知情的情况下改变窗口的位置,安全的设置可以拦截使用postMessage发送的数据。

根据文档的方案,应当将1.html中的:

child.postMessage(msg,'*')

修改为:

child.postMessage(msg,'2.html')

2.html中的:

window.addEventListener("message", (event)=>{    
...
}

修改为:

window.addEventListener("message", (event)=>{if (event.origin !== "http://safe.com")return;...
}

漏洞检测

检测postMessage漏洞的方法是读取JavaScript代码。因为当定义了一个监听器后,需要按照事件数据流来分析代码是否以容易被攻击的函数结束。这里推荐两种方法来检测函数调用:

  • 1 . J2EEScan,从git仓库(https://github.com/ilmila/J2EEScan)可以获得更新版本,而不是从 Burp AppStore
  • 2 . BurpBounty (https://github.com/wagiro/BurpBounty),定义一组用于搜索关键字的被动响应字符串,如 postMessageaddEventListener("message.on("message"

 

0x03 hackerone 漏洞报告分析

如果你在hackerone平台搜索PostMessage漏洞报告关键字,将看到一些报告,有一些漏洞被发现的时间距离现在并不遥远,并且获得了丰厚的奖励。这里重点分析3篇Hackerone披露的报告,并提供一些利用/绕过postMessage漏洞的技巧。

DOM Based XSS in www.hackerone.com via PostMessage and Bypass (#398054)

在hackeronep披露的 #398054报告中,通过Marketo中的不安全消息事件侦听器,Dom XSS在Hackerone中被成功利用。代码流程如下图所示:

通过分析报告可以看出,如果响应的设置没有错误,它就会创建一个名为u的变量,并将其设置为findCorrectFollowUpUrl方法的返回值。这将对一个名为followUpUrl的响应对象的属性进行处理,该属性是在表单提交完成后重定向的URL。

但是HackerOne窗体并没有用到这个,攻击者通过将其设置为绝对URL,就可以控制u变量的值。后来这个变量被用来改变窗口的location.href。当向Hackerone窗口发送下图所示的mktoResponse消息时,窗口被重定向到JavaScript URL,并执行代码alert(document.domain)

这部分代码由三部分组成:

  • 1 . mktoResponsePostMessage的第一个JSON元素,以调用函数:
else if (d.mktoResponse){onResponse(d.mktoResponse)
}
  • 2 . 为了能执行这个函数,需要一个JSON结构数据,其元素有forerrordata。如果errorfalse,则repuest.success执行:
var requestId = mktoResponse["for"];var request = inflight[requestId];if(request){if(mktoResponse.error){request.error(mktoResponse.data);}else{request.success(mktoResponse.data);
  • 3 . 在这个函数中,followUpUrl值将关联到u,并传递给location.href。因此,有效payloadjavascript:alert(document.domain)触发XSS执行:
  var u = findCorrectFollowUpUrl(data);location.href = u;

这个漏洞提交之后,Hackerone团队修改了OnMessage函数,添加了一个对源的验证:

if (a.originalEvent && a.originalEvent.data && 0 === i.indexOf(a.originalEvent.origin)) {var b;try {b = j.parseJSON(a.originalEvent.data)} catch (c) {return}b.mktoReady ? f() : b.mktoResponse && e(b.mktoResponse)
}

Bypass #398054 (#499030)

@honoki在报告#499030找到了上述#398054漏洞修复后的绕过办法。

在上述的修复代码中,变量i解析为https://app-sj17.marketo.com/indexOf检查字符串中是否包含源。因此注册一个marcarian域名.ma,验证将被绕过:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")

如果之前的漏洞攻击代码托管在注册域名https://app-sj17.ma下,XSS依旧会被成功执行。

CVE-2020-8127: XSS by calling arbitrary method via postMessage in reveal.js (#691977)

在报告#691977中,@s_p_q_r提交了一个通过PostMessage成功利用的DOM XSS。代码流程如下图所示:

首先,使用addKeyBinding方法调用setupPostMessage来定义带有恶意负载的JSON元素。然后,调用函数showHelp()在浏览器中展示出registeredKeyBindings[binding].description中定义的malicios有效payload。要利用此漏洞,使用以下代码:

这个代码片段中有三个部分:

  • 1 . 将第一个JSON元素作为"method":"addKeyBinding",用于调用方法并应用到args:
if( data.method && typeof Reveal[data.method] === 'function' ) {Reveal[data.method].apply( Reveal, data.args );
  • 2 . 为了到达函数addKeyBinding与参数args,构造一个JSON对象,包含callbackkeydescription
function addKeyBinding( binding, callback ) {if( typeof binding === 'object' && binding.keyCode ) {registeredKeyBindings[binding.keyCode] = {callback: callback,key: binding.key,description: binding.description};}
  • 3 . 调用toggleHelp()函数,在没有验证的情况下展现了包含payload的JSON数据,触发JavaScript执行:
function showHelp() {...for( var binding in registeredKeyBindings ) {if( registeredKeyBindings[binding].key && registeredKeyBindings[binding].description ) {html += '<tr><td>' + registeredKeyBindings[binding].key + '</td><td>' + registeredKeyBindings[binding].description + '</td></tr>';}}...
}

 

0x04 绕过PostMessage漏洞的技巧

1 . 如果indexOf()被用来检查PostMessage的源,如果源包含在字符串中,有可能被绕过,如Bypass #398054 (#499030)中分析的那样。

2 . 如果使用search()来验证源,也有可能是不安全的。根据String.prototype.search()的文档,该方法接收一个常规的压缩对象而不是字符串,如果传递了正则表达式以外的任何东西,也将被隐式转换为正则表达的内容。例如:

"https://www.safedomain.com".search(t.origin)

在正则表达式中,点(.)被视为通配符。换句话说,源的任何字符都可以用一个点来代替。攻击者可以利用这一特点,使用一个特殊的域而不是官方的域来绕过验证,比如www.s.afedomain.com就可以绕过上述语法的验证。

3 . 如果使用了escapeHtml函数,该函数不会创建一个新的已转义的对象,而是重写现有对象的属性。这意味着,如果我们能够创建具有不响应hasOwnProperty的受控属性的对象,则该对象将不会被转义。例如,File对象非常适合这种场景的利用,因为它有只读的name属性,使用这个属性,可以绕过escapeHtml函数:

// Expected to fail:
result = u({message: "'\"<b>\\"
});
result.message // "'&quot;&lt;b&gt;\"
// Bypassed:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

 

0x05 hackerone上PostMessage漏洞报告推荐

Hackerone report #168116
(Twitter: Insufficient validation on Digits bridge)

Hackerone report #231053
(Shopify: XSS on any Shopify shop via abuse of the HTML5 structured clone algorithm in postMessage listener on “/:id/digital_wallets/dialog”)

Hackerone report #381356
(HackerOne: Client-Side Race Condition using Marketo, allows sending user to data-protocol in Safari when form without onSuccess is submitted on www.hackerone.com)

Hackerone report #207042
(HackerOne: Stealing contact form data on www.hackerone.com using Marketo Forms XSS with postMessage frame-jumping and jQuery-JSONP)

Hackerone report #603764
(Upserve: DOM Based XSS via postMessage at https://inventory.upserve.com/login/)

Hackerone report #217745
(Shopify: XSS in $shop$.myshopify.com/admin/ via “Button Objects” in malicious app)

参考文献

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

https://medium.com/javascript-in-plain-english/javascript-and-window-postmessage-a60c8f6adea9

https://hackerone.com/hacktivity?querystring=postmessage

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31653.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的一些实战的漏洞挖掘过程(一)

最近挖到的漏洞&#xff0c;在这里分享一下&#xff0c;有些信息比较敏感就打码处理&#xff0c;目标网站都换为target.com 反射xss漏洞挖掘 跨站脚本攻击&#xff08;Cross-site Scripting&#xff0c;XSS&#xff09;是一种常见的Web安全漏洞&#xff0c;攻击者通过在Web应…

漏洞挖掘之信息收集

简介 对单一指定目标网站进行黑盒测试&#xff0c;最重要的就是信息收集&#xff0c;因为网站管理员肯定会在用户经常访问的主网站进行经常维护&#xff0c;而那些子域名&#xff0c;没有什么人访问的&#xff0c;可能就会忘记维护&#xff0c;挖洞的突破点大都在于子域名上&am…

我的HackerOne漏洞赏金平台漏洞挖掘流程

简介 高强度在hackerone平台挖了一周的漏洞&#xff0c;在这里分享一下经验 选定目标 hackerone有两种src&#xff0c;一种是给钱的&#xff0c;一种是免费的&#xff0c;我一般都是选的有钱的去挖 假如我选择了这个作为今天的挖洞目标 首先需要往下滑&#xff0c;看他不收…

麦肯锡教我的思考武器-读书心得

《麦肯锡教我的思考武器》从逻辑思考到真正解决问题&#xff0c;思考&#xff0c;不要使用蛮力&#xff0c;工作&#xff0c;不只靠体力&#xff01;从议题出发&#xff0c;创造有价值的工作。面对任务繁多的工作&#xff0c;你该如何应付&#xff1f;对于专业工作者而言&#…

麦肯锡三部曲_麦肯锡三部曲推荐

人生&#xff0c;唯有读书与运动不可辜负。 今日推荐&#xff1a; 艾森拉塞尔和保罗弗里嘉所著的麦肯锡三部曲&#xff1a;《麦肯锡方法》、《麦肯锡意识》和《麦肯锡工具》。 作者简介&#xff1a; 艾森拉塞尔(Ethan M. Rasiel)是麦肯锡纽约公司的一名顾问。他的客户包括在金融…

《麦肯锡意识》前言 解决问题的战略模型-思维导图

《麦肯锡意识》前言 解决问题的战略模型-思维导图 文章目录 解决问题的理论模型解决问题的战略模型客户需求分析汇报管理实施领导力 本书侧重探讨此模型的分析、汇报和管理部分 本书的基础是麦肯锡所实践的解决问题流程 关于解决问题流程 解决问题的理论模型 战略模型图&…

《麦肯锡方法》读书笔记22

《爱数圈-每日悦享读书会》打卡&#xff1a;第二十一章 关于麦肯锡的回忆&#xff1a;

《麦肯锡方法》第12章 管理公司的内部沟通-思维导图

文章目录 麦肯锡的内部沟通让信息流动起来蘑菇种植法保持信息的通畅内部沟通 有效信息的三个关键因素简洁全面系统 慎言慎行 麦肯锡的内部沟通 以团队为基础的运营&#xff0c;其成功与否有赖于沟通 自上而下的沟通自下而上的沟通 沟通方式 电子邮件备忘录会议… 让信息流动…

《麦肯锡方法》第1章建立解决方案-思维导图

《麦肯锡方法》第1章建立解决方案-思维导图 文章目录 第1章 建立解决方案 与事实为友 优先收集和分析事实 事实为何如此重要&#xff1f; 事实弥补了直觉的缺陷事实可提高可信度 对MECE原则应用自如 分解问题 把大的复杂的问题&#xff0c;拆分成小的容易解决的子问题子问题…

《麦肯锡方法》第13章 与客户合作-思维导图

《麦肯锡方法》第13章 与客户合作-思维导图 文章目录 与客户团队合作让客户团队站到你这边如何与客户团队中的”讨债鬼“打交道让客户参与工作获得整个公司的支持实施要严谨 与客户团队合作 最大限度地发挥客户团队的积极性 怎样让客户在项目中发挥积极影响并限制消极影响 对…

用讯飞星火大模型1分钟写一个精美的PPT

文章目录 前言SparkDesk讯飞星火认知大模型简介利用讯飞星火写一个转正述职ppt1.告诉讯飞星火我想写一篇转正述职ppt2.利用MindShow一键生成ppt 申请体验写在最后 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个…

ChatGpt AI智能绘画java开源系统快速搭建

要快速搭建AI智能绘画的Java开源系统&#xff0c;您可以按照以下步骤进行操作&#xff1a; 确定系统需求&#xff1a;明确您希望系统具备哪些功能和特性&#xff0c;例如图像处理、机器学习、深度学习等方面。 寻找相关开源库和框架&#xff1a;Java生态系统中存在许多强大的开…

ChatGPT 编写:高性能 2000 怪同屏碰撞检测|征稿活动 V6

本文来自 Cocos 中文社区第 6 期征稿活动 Cocos AIGC Creators Award&#xff0c;征稿持续进行中&#xff0c;丰富奖品等你来拿&#xff5e; 前言 大家好我是 98k, 好久没更新作品了&#xff0c;是时候为大家作贡献了。 新作品体验链接: https://store.cocos.com/app/detail/48…

和chatgpt学架构04-路由开发

目录 1 什么是路由2 如何设置路由2.1 安装依赖2.2 创建路由文件2.3 创建首页2.4 编写HomePage2.5 更新路由配置2.6 让路由生效 3 测试总结 要想使用vue实现页面的灵活跳转&#xff0c;其中路由配置是必不可少的&#xff0c;我们在做开发的时候&#xff0c;先需要了解知识点&…

和chatgpt学架构05-首页开发

目录 首页提示词使用container布局正确的显示菜单的层级图标显示不正常解决纵向滚动条的问题 我们上一篇只是简单写了一个首页&#xff0c;作为一个系统的管理后台&#xff0c;首页相对复杂&#xff0c;既包含菜单导航&#xff0c;又需要根据菜单显示具体的页面。我们本篇就让c…

李彦宏:文心大模型 3.5 版本推理速度提升 17 倍;ChatGPT 访问量增速大降;Linux 6.4 发布|极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&#…

程序员该如何定位?看这四大方向

宽泛的意义上讲&#xff0c;程序员是这样一群人&#xff1a;他们用某种语言或技术&#xff0c;开发某种软件产品&#xff08;系统&#xff09;&#xff0c;解决特定现实领域的问题。 有了这个定义&#xff0c;我们就可以来讨论程序员的几种常见定位&#xff1a; 解决某类问题的…

活动回顾丨那些闪闪发光的女开发者们

在刚刚度过的三八妇女节 我们看到了令人振奋的女性力量 在各个行业领域闪闪发亮 给予无数女性力量与鼓舞 在开发领域当然也不例外 亚马逊云科技深度支持并联合 Jina AI 与优秀的女开发者们展开线上对谈 和我们一起来领略她们的 智性魅力与思维碰撞吧 精彩回顾 多模态 AI 技术 T…

Let‘s Learn .NET|通过 Semantic Kernel .NET SDK 管理你的 OpenAI 项目

编辑&#xff1a;Alan Wang 排版&#xff1a;Rani Sun Lets Learn .NET 系列 “Lets Learn .NET” 是面向全球的 .NET 初学者学习系列&#xff0c;旨在通过不同语言&#xff0c;帮助不同地区的开发者掌握最新的 .NET 开发知识与技能。 在 ChatGPT 与 OpenAI 火热的当下&#x…

LangChain 查询使用指「北」

一只鹦鹉加上一根链条&#xff0c;组成了时下最流行的 AI 话题热门榜选手——LangChain。 LangChain 是一种 AI 代理工具&#xff0c;可以为以 ChatGPT 为代表的额大语言模型&#xff08;LLM&#xff09;增添更多功能。此外&#xff0c;LangChain 还具备 token 和上下文管理功能…