Web中的点击拦截研究

Web中的点击拦截研究

原文作者:Mingxue Zhang, Wei Meng, Sangho Lee, Byoungyoung Lee ,Xinyu Xing

原文标题:All Your Clicks Belong to Me: Investigating Click Interception on the Web

原文会议:Proceedings of the 28th USENIX Security Symposium (USENIX Security), Santa Clara, US, August 2019.

原文链接https://www.usenix.org/system/files/sec19fall_zhang_prepub.pdf

用户与Web应用交互主要通过点击事件,那么web中广告投放也不会放过拦截用户点击行为以获取利益。文章系统地研究了Web中的点击拦截实例,开发了一个基于浏览器的分析框架OBSERVER,用于收集和分析与点击相关的行为。文章作者使用OBSERVER,确定了三种不同的技术来拦截Alexa前250K网站上的用户点击,并检测到613个网站上437个截取用户点击的第三方脚本,这些网站平均每天可收到4300万次访问。通过拦截用户点击行为不仅是投放广告获利的手段之一,拦截用户点击行为还会让用户接触到诸如诈骗软件等恶意内容。

作者的工作:

作者基于开源Web浏览器Chromium,开发了一个框架OBSERVER,该框架可以识别出web应用中点击劫持行为,用户在使用web应用时对此类恶意行为的重视。整篇文章作者对研究背景进行描述总结,详细阐述了关键技术方法、实现与评估,同时还有局限性思考和未来相关工作的总结。

一、引言

点击HTML元素是用户与Web应用程序交互的主要方式。已知的用户劫持点击行为包括UI redressing attacks,还有利用bots to automatically and massively send fake click traffic,用来点击广告获取利益,当这些行为已不再有效时,攻击者就盯上了重定向用户的点击。例如,“浏览者重定向病毒” 将用户的默认搜索引擎修改为恶意搜索引擎,当用户点击搜索结果时将用户重定向到广告页面。恶意第三方iframe可以自动将用户重定向到广告页面,当脚本在点击时打开新tab时,用户的当tab可以自动重定向到非预期目标页。谷歌最近发布了新版Chrome浏览器,以阻止某些特定类型的自动重定向。尽管如此,Chrome仍然无法检测并阻止其他可能的方法来拦截用户点击,包括但不限于由第三方脚本修改的链接,伪装成第一方内容的第三方内容以及透明覆盖等恶意行为。

1.1 措施

作者认为有必要对点击拦截进行系统研究,以深入了解这一新出现的网络用户威胁。因此开发一个系统,以自动检测Web上的此类实例,并研究哪些技术是被用来劫持用户点击以及发起这种行为的人。

文章结构安排:首先设计和开发一个系统来检测JavaScript用来拦截用户点击的各种技术。然后,作者使用这个系统进行大规模测量,目的是找出那些劫持链接并欺骗用户点击的从业者。最后,作者分析测量结果,并探索隐藏在点击拦截实践背后的意图和后果。

1.2 挑战

由于Web应用程序的动态和事件驱动特性,执行上述系统研究具有挑战性。

1,可以动态加载JS代码。只对HTML源代码静态分析是无法涵盖拦截用户点击的所有脚本。

2,超链接可以由任何脚本动态创建和修改。为了确定一个脚本是否真正可以用于拦截,需要重新设计浏览器以区分不同脚本运行时的操作。

3,JS可以通过事件侦听器(handlers)动态地将URL绑定到任意HTML元素。

4,网页可能包含大量响应用户点击的事件处理程序。

1.3 应对

通过四个步骤对一个网站的所有可能涉及到劫持点击行为的地方的相关属性进行记录。

首先,在浏览器的渲染器中调解网页中JavaScript对超链接的所有访问。
通过这种方式可以识别与每个超链接关联的URL的发起者。

其次,监视JavaScript对象的创建和执行,以便我们可以追踪动态内联JS代码。

第三,监视所有在每个HTML元素上注册的事件处理程序以及与导航相关的JS API。

最后,导出导航网址。

1.4 贡献

•作者设计和开发OBSERVER,一个研究点击拦截实践的框架。这有助于我们自动检测各种网站上的各种点击拦截案例。

•作者进行了大规模测量研究,以探索和了解攻击者如何在实际环境中操纵网页拦截用户点击。

•作者描述了Alexa 前250K网站上点击拦截的活动,并发现了点击截取行为背后隐藏的意图和后果。

二、框架概要

在本节中,我们首先概述了OBSERVER框架,旨在全面记录JS代码执行的所有潜在点击拦截相关事件。关注三类JS会使用的基本操作劫持用户点击行为:

1)修改页面中的现有超链接;

2)在页面中创建新的超链接;

3)向HTML元素注册事件处理程序以挂钩用户点击。

每当OBSERVER识别出任何此类操作时,它都会使用启动操作的脚本的唯一标识来标记相应的元素。 此外,OBSERVER记录在故意点击与页面中的事件处理程序相关联的超链接或元素之后的反应,以便知道点击拦截后引导用户去向哪个URL。

2.1 威胁模型

作者只考虑第三方JS脚本为恶意的,因为第一方对页面有完全的控制权。

2.2 记录对网页中所有超链接的任何访问

在HTML中,使用锚元素(即,<a> 标签)来定义超链接,并且其href属性值为目标URL。因此,通过监视和记录哪个脚本修改了 <a> 标签的href属性,OBSERVER能够识别脚本的潜在点击拦截。不论是直接使用原生JS修改href属性值还是利用JQ等第三方库修改,OBSERVER都可以识别到,因为这些方式仍然需要调用DOM标准中定义的上述API,这是由所有浏览器实现的,以确保跨浏览器的兼容性。具体方式是OBSERVER hook所有这些DOM API,以监视DOM中 <a> 标签的href属性的修改。它拦截对这些API的任何调用。截获后,它会检查当前的JS调用堆栈,再在调用堆栈中找到底部JS框架,以找到发起API调用的JS函数。

2.2.1 脚本识别

在上个步骤找到了发起API调用的JS函数后,要将该API调用归于特定脚本,需要获取访问JS代码的标识。 OBSERVER为每个脚本对象分配一个scriptID,以便在JS运行时唯一地标识它。

在HTML中,JS代码常以三种方式引入:

  • 作为内联脚本包含在 <script></script> 标记之间。
  • 存储在外部JavaScript文件夹中,并作为外部脚本加载 <script> 标记。
  • JavaScript代码可以作为事件监听器写入HTML元素。

每个 <script> 标签都编译为JavaScript引擎中的单个JavaScript对象。还有其他类型的内联JavaScript代码。例如,JavaScript代码可以作为事件监听器写入HTML元素的贡献。未包含在
<script> 标签内的内联脚本也会编译为单独的JavaScript对象,这些对象由唯一的scriptID标识。

OBSERVER将脚本的scriptID与其sourceURL相关联,sourceURL是浏览器用于加载远程JavaScript代码的URL。但内联脚本的sourceURL为空,那么就使用浏览器用于将HTML文档加载到嵌入框架中的URL作为静态内联脚本的sourceURL。对于通过JavaScript创建内联脚本的情况将在之后讨论。除了scriptID之外,我们还在与元素关联的shadow数据存储中记录函数的行号,列号和名称。值得注意的是,JavaScript代码无法修改shadow数据存储,因为它是一个在JavaScript端不可写的C++数据结构。

2.3 追踪动态元素创建

在网页中动态创建新的超链接是拦截用户点击的另一种方法。OBSERVER考虑了脚本可以实现此目标的直接和间接方法:1)创建超链接,2)创建 创建超链接的脚本。

2.3.1 直接方式–HTML锚元素

JavaScript代码可以在网页中动态创建任何HTML元素,包括锚元素。

具体来说,JavaScript可以通过多种API将新的 <a> 标签插入到网页的DOM树中。利用这些技术可以拦截用户点击。

OBSERVER需要跟踪浏览器中 <a> 标签的动态创建。 OBSERVER将shadow initiator属性附加到DOM树中的每个锚元素,以表示对象的创建者。 initiator属性值是创建相应元素的脚本的scriptID。OBSERVER为浏览器解析器构建的所有静态元素分配一个特殊的initiator值O,它表示文档的所有者。静态 <a> 标签是第一方超链接。 OBSERVER拦截Web浏览器中的所有元素创建API,以便找到调用堆栈中的JavaScript框架。发起创建行为的脚本的scriptID用作动态创建的元素(超链接)的启动器。OBSERVER还会记录动态创建的锚元素的任何对href的访问。

2.3.2 间接方式–JS脚本

JavaScript代码也可以在Web应用程序中动态生成,就像HTML元素一样。 <script> 作为一个HTML元素类,可以由JavaScript动态创建。OBSERVER旨在为所有这些动态创建的脚本分配唯一标识。如果将外部脚本文件从远程主机加载到动态插入的 <script> 元素中,则获取其标识与获取一个静态 <script> 元素的sourceURL没有区别。

但是,识别动态生成的内联脚本的标识并不简单,因为它的sourceURL是空白的。为了克服这种困难,OBSERVER hook用于生成动态脚本的API。它将调用脚本生成API的JavaScript代码的sourceURL保存为新生成的内联脚本的sourceURL。OBSERVER记录父脚本的scriptID作为子脚本的parentScriptID属性。最初由文档所有者静态嵌入的所有脚本的parentScriptID设置为O。OBSERVER还记录对任何DOM对象的任何内联事件处理程序的所有访问,它遍历所有脚本,将内联事件处理程序设置为其父脚本,并从中得到sourceURL。

如果找不到这样的条目,OBSERVER会将创建接收者对象的脚本设置为其父脚本。

2.4 监控JavaScript事件监听器

不需要修改或创建一个超链接,直接监听现有的HTML元素上的事件侦听器也能达到一样的效果。事件侦听器的作用是当用户点击已绑定侦听器的元素时,会触发该事件,事件处理程序则异步执行一些操作。也许是任意打开一个URL或者悄悄地发起某些请求。于是OBSERVE旨在监控这些事件侦听器看看是否会导航用户到不同的URL去。

2.5 视觉欺骗

作者确定了两种可能的视觉欺骗:模仿和透明叠加。
都是字面意思,模仿就是弄一个和真实网站中部分内容类似的,使用户不仔细看以为是正常的就去点击;透明叠加是将恶意内容覆盖到原本正常内容之上,修改透明度使用户不易察觉。

例如左边黄色线框内,小字是sponsored,与上下红色框做得很像,诱使用户点击。
右边青色线框标记的全是第三方内容,由于覆盖在第一方内容之上,用户无论点哪都会触发第三方脚本预先设定好的点击事件。

2.6 部署

Chromium browser (version 64.0.3282.186)

三、方法

3.1 数据集

Alexa前250K网站。有效网站为228,614个。

两个步骤获取数据:1)在页面渲染后立即收集原始数据; 2)通过与渲染页面交互来收集反应数据。 首先OBSERVER等待最多45秒,是为了让浏览器完全呈现页面。

之后,在页面中插入一个脚本以预先遍历DOM树,以收集OBSERVER已记录的每个元素的所有数据,还记录每个元素的几个显示属性(宽度,高度,位置,不透明度等),以研究可用于拦截用户点击的其他技巧(例如,某些第三方内容与之重叠或出现 类似于第一方内容)。

然后,将当前DOM树的快照保存到外部HTML文件夹中。通过Selenium自动点击DOM树中的所有元素,触发click事件侦听器和超链接导航以收集导航日志。

3.2 第三方脚本检测

由于作者认定第一方脚本具有高度完全的权力去操控任意元素,所以其行为不被认定为攻击,识别出第三方脚本就至关重要。主要通过判定该网站所属域以及加载的各个脚本所属域是否是同一组织或个人。该判断并不是100%准确的。

3.3 拦截检测

对三种方式(超链接、事件侦听器、视觉欺骗)进行拦截点击的方法第二节描述过。

3.4 逃避检测

一些第三方脚本有选择地拦截用户点击。通过限制拦截点击的速度,避免用户的怀疑。还有些脚本仅在用户第一次访问页面时才会在其事件处理程序中激活相关的代码。这可以通过在用户的浏览器中删除cookie来实现。

3.5 实验结果

3.5.1 第三方脚本识别

三大类技术,分别是超链接、事件处理器、视觉欺骗。

3.5.2 第三方代码加载方式

从下表可以看出,由第一方脚本静态引入第三方脚本是最常用的方法。

3.6 点击拦截缘由与影响

  1. 盈利,主要是广告与欺骗用户点击广告。
  2. 传播恶意内容,自动下载恶意软件等。

四、讨论与将来工作

作者从第三方脚本识别、检测范围(网站数量)、区分真实点击与自动化测试软件的模拟点击、生成安全警告与使浏览器自动执行一些策略来防止点击被拦截五个方面来讨论。

第三方脚本识别问题作者是使用了域名作为判断依据,如何判断不同脚本来自同一个域比较复杂,感兴趣的可以看看原文。

检测范围是Alexa前250K个网站的主页面,子页面没有检测。

作者使用了selenium去驱动OBSERVE与网站进行交互,但是区分真实点击与这种自动化工具生成的模拟点击也是一个研究方向。

已知存在这种安全威胁后,作者提出两点进行防御,一是生成安全警告让用户决定是否继续访问,二是安全策略确保链接与点击为整体,不会被任何第三方脚本修改。

五、思考

从最后作者提出的几个待解决的问题来说,到目前为止没有很好的方法去解决,我们可以沿着这些思路继续研究下去。作者的工作量很大,涵盖的点击事件可能性全面,只是有些点击行为较为主观不好定义为是正常的还是恶意的。