在本文中我们将证明,在现今许多手机模型上都有的 hover ( floating touch ,悬浮触控)技术可以被恶意软件滥用,用来记录系统范围内的所有触屏输入。通过这种攻击,运行在 Android 系统上的恶意软件可以获取用户的敏感信息诸如密码、 PIN, 记录用户的社交,掌握用户的行为。为评估此类攻击,我们实现了一款 POC ( proof-of-concept ,概念验证)恶意软件 Hoover ,让它在后台运行并记录下前台应用程序的输入。为评估 Hoover ,我们让 20 名志愿者在两台不同的 Android 设备用两种不同的输入方式,触控笔和手指,进行测试。用手指输入, Hoover 能在 100 像素的误差内找到用户的输入点,键盘输入的正确率为 79% 。触控笔的正确率会更高些,误差为 2 像素,键盘输入正确率为 98% 。与现在广为人知的边信道攻击( side channel attack )不同,本文是第一篇证明了 hover 技术的安全隐患以及它盗取用户输入的潜在可能性。我们也讨论了减轻此类攻击的方法,并发现不能通过简单的限制权限或者提高用户意识来实现,因为这将大大缩减 hover 技术的使用率。
分类
l 安全与隐私→手机平台安全;
关键词
Android , hover 技术,用户输入,攻击
近年来输入推理攻击( input inference attack )迅速发展,此类攻击是指盗取用户部分或全部输入。这并不足为奇,因为此类攻击可以让人对用户有大概的了解并且 / 或者获取用户的敏感信息诸如登录信息,信用卡卡号,私人信件等等。现有的攻击主要是应用程序层面的,通过 phishing (钓鱼)或界面伪装( UI redressing ) ( 例如 [24] 的 clickjacking) 诱使用户输入敏感信息 [7,27,28,35] 。其他攻击利用手机上的传感器作为边信道,通过读取不同传感器,例如,加速器、回转仪和麦克风,推断用户输入。在 Android 上,读取这些传感器(麦克风除外)的信息并不需要特殊的权限。
本文我们介绍一种新的基于 Android 设备的输入推理攻击,比起前人的工作,我们这个攻击准确率更高,更通用。我们的攻击同时影响设备上运行的所有应用程序(它是系统范围内的),而且它并不是专门为哪一款应用程序定制。它可以持续以高准确率收集用户输入,而且对环境条件不敏感。之前的方法要么针对特定的输入类型(比如,数字键)是应用程序级别的,是粗粒度的,要么是只在特定条件下有效(有限的手机移动,明确的手机位置,有限的环境噪声)。我们的攻击不是基于软件漏洞或者系统错误配置,而是基于新的未预料到的对新兴的 hover 技术的使用。
自从 Samsung ,手机市场的一大巨头,将 hover 技术应用到 Galaxy S4,S5 和 Note 系列以后, hover 技术方才流行起来。因此本文所提到的攻击会影响到数以万计的用户 [5,6,11,15] 。 Hover 技术,如图 1 所示,会引发一种特别的事件( hover event , hover 事件),此类事件可以让用户在没有物理接触屏幕的情况下与设备进行交互。我们将展示如何利用此类 hover event 进行强有力的,系统范围内的输入推理攻击。
图 1 : Hover 技术。输入设备在没有接触到设备屏幕的情况下引发特殊的事件( hover event )。最右图展示了用户在输入设备没有接触到屏幕的情况下与手机进行交互。
为获取足够的 post-tap (点击后) hover event 以便正确推断精确点击坐标,在用户对前台 app 进行每一次点击后,我们的攻击方式是立刻谨慎地创建( create )和销毁( destroy )覆盖窗口( overlay windows )。先前的 phishing 、 clickjacking 和 UI redressing 技术也创建覆盖窗口,但是都得用到 SYSTEM_ALERT_WINDOW 权限。我们的攻击方式并不依赖于该权限:我们的攻击不需要任何权限。而且,我们利用覆盖窗口的方式也不一样。我们的攻击是持续的,对用户完全透明,不会影响用户与前台 app 的交互,也不会将用户重定向到其他的恶意 view 上,更不会以任何方式欺骗用户——此前的攻击都做不到这点。
为评估此类攻击,我们实现了一款 POC ( proof-of-concept ,概念验证)恶意软件 Hoover ,让它在后台持续运行并记录下前台应用程序的 hover 输入。但是,要实现我们的攻击我们还得克服一些技术挑战。我们最初的实验表明 hover 技术,很令人意外,并不直接获取用户点击的位置。相对的, hover 事件散落在更广阔的区域。因此,为成功预测输入事件坐标,我们首先要知道用户是如何与手机进行交互的。为达到此目的,我们进行了一个用户实验,让 20 个志愿者用安装了 hoover 的设备进行两项操作:随便在屏幕上点、输入英文。 Hoover 收集到的 hover event 将用来训练回归模型以预测点击位置和用来生成一个推断输入键位的分类器。
事实证明,我们的攻击对触控笔和手指输入均有效。而且手指点击的误差为 100px ,触控笔误差只有 2px 。而在键盘输入事件中,触控笔和手指的键盘键位推断的正确率分别为 98% 和 79% 。
我们的这种攻击最直观的应用就是获取用户的输入信息,并且是系统范围内的。比如说, Hoover 可以记录敏感输入,例如 pin ,密码还有社交信息(信息类 app ,邮件)。当然还有其它更微妙的应用。比如, Hoover 可以刻画用户与设备的交互方式,也就是形成用户的生物计量学简介。这份简介又可以用来,比如说,仅对设备主人的限制访问,或者帮助敌手绕过现有的基于生物认证技术的按键 [20] 。
针对我们的攻击,我们讨论了应对策略,发现要么不能对抗此类攻击,要么将影响系统或 hover 技术的使用。
最后,本文有如下贡献:
l 我们介绍了一种全新的、系统范围内的基于 hover 技术的 Android 用户输入推断攻击。
l 我们实现了 Hoover ,一款 POC 恶意 app 。
l 我们实现了用户测试,证明了 Hoove 的正确性。
l 我们讨论了可能的应对策略,发现此类攻击很难抵御。
本文后面的组织如下:第二部分我们介绍有关 hover 技术的相关概念和 Android 系统的 view 的 UI 组件。第三部分,描述本文要考虑的问题以及我们的攻击。接下来,第四部分是 Hoover 的实现和评估。攻击实现是在第五部分,在第六部分我们讨论可能的抵御策略。第七部分回顾在本领域的相关工作,第八部分总结并展望未来。
在这部分,我们介绍一些关于 hover 技术和 Alert Window 的背景知识。 Alert Window 是 Android 手机 app 中比较常用的 UI 元素。
Hover (或者 floating touch ,悬浮触屏)技术可以让用户在不物理接触屏幕的情况下与移动设备进行交互。我们在图 1 已经展示过这个概念了。该技术于 2012 年由 Sony Xperia Device[32] 引入,基于结合互电容和自电容感知。被 Sony 引入后,在 2013 年 11 月下旬, hover 技术被 Asus 用到它的 Fonepad Note 6 中。最终兴起是在 Samsung ,手机市场一大巨头,将它用到 Galaxy S4,S5 和 Galaxy Note 系列。单单是 Samsung 就出售了超过 1 亿台支持 hover 技术的设备 [5,6,11,15] ——它们都是本文所提到的攻击的潜在目标。
Hover 是这么处理的:当用户与屏幕交互时,系统可以在未触摸到它的时候就检测到输入设备的位置。尤其是,当输入设备徘徊在屏幕周围 20mm 的时候(见图 1 ),操作系统会在规定区域触发一类特殊的用户输入事件—— hover event 。 App 以 x,y 坐标的形式获取输入设备的精确位置。只要获取了输入设备的位置,位置将被发送到 View —— Android 用户接口内置模块——以监听事件。更具体点,就是当用户徘徊在屏幕上方并点击屏幕后,操作系统产生的事件流是这样的:当输入设备接近屏幕(小于 20mm ) , 系统就针对( x,y )坐标发起一系列 hover event 。当触摸到屏幕的时候, hover 退出事件( hover exit event )就紧随着按下事件( touch down event )触发。 Touch up 事件意味着触摸完成。之后,当用户将输入设备带离触摸点的时候其他一系列的 hover event 会再次触发。最后,当输入设备离开悬浮区域,也就是说,距离屏幕的悬浮高度大于 20mm ,就产生 hover exit event 。
Android 通过 WindowManager 处理系统可视化和屏幕上的 app UI 控件。它的工作主要是管理和生成 window 、 view 、 button 、 image 和在屏幕上出现的其他对象。基于攻击的目的,可以产生不同的 view (主动 view ,例如 button ;或被动 view ,例如 image )以获取 hover event 和触摸事件。 View 的模式是可以改变的,通过设置或不设置特定的标志,可以化被动为主动。这些标志可以通过 WindowManager 接口的 updateViewLayout() API 实现。比如说,要将某个 view 变为被动,需设置 FLAG_NOT_FOCUSABLE 和 FLAG_NOT_TOUCHABLE 。第一个 flag 避免 view 获得键位输入焦点,第二个 flag 让其无法拦截触摸事件或者 hover event 。通过设置这两个标志,静态 view 就不会影响设备的正常使用,即使是它在其他 window 的上面。另外,通过设置某个 view 的 FLAG_WATCH_OUTSIDE_TOUCH ,当屏幕上某处,并且在该 view 的外面发生点击事件,无需知道点击的位置,也能精确获取该 view 。
在本文中,我们将会用到在其他对象,包括前台 app 的 view 顶层的 view 。这些 view 要么是 Alert Window 要么是 Toast Window 。 Alert Window 不仅用在像短信和电话这种内置 app 中也用在其他 app 中——根据 IzzyOnDroid 对应用商店的爬虫发现,有着上亿次下载的超过 600 款 app 都用到了 Alert Window 。要产生 Alert Window , WindowManager 接口需有 SYSTEM_ALERT_WINDOW 权限,这部分由产生该 view 的 service 完成。但是,用 Toast 类的话,实现我们的攻击所需要的功能不用任何权限。但是因为 Toast Window 的技术更难处理,此类实现比较复杂。因此,我们先用 Alert Window 实现我们的攻击,稍后在 4.6 节再解释如何不需要特殊权限实现攻击。
我们攻击的目标是以高精确率(比如,低误差)和高粒度(比如,在按键键位级别)追踪用户的每一次点击。只要用户与之交互的设备支持 hover ,那么不管输入设备是手指还是触控笔,攻击都有效。而且,攻击不应该被用户察觉,也就是说,攻击不会以任何形式影响用户与设备的交互。
在描述攻击之前,我们先声明假设和敌手模式。
我们假设用户运行的手机支持 hover 技术。用户用触控笔或手指与设备交互都没有关系。
我们假设的情节是,攻击者控制着在用户设备上运行的一款恶意软件。目标就是,在不被用户发现的前提下获取用户输入信息。在我们第一个攻击,更容易实现的攻击中,该恶意软件只需要两个权限: SYSTEM_ALERT_WINDOW ,就如前文所说的,这个权限在很多 app 中都有,和 INETERNET ——这个就更常用了,以至于 Android 将它的保护级别设置位 PROTECTION_NORMAL 。也就意味着这是无害的,而且所有 app 都有这两个权限,不需要询问用户。然后我们再讨论不需要 SYSTEM_ALERT_WINDOW 权限的攻击,这个攻击更复杂些。
为追踪输入设备的点击,我们探索 Android 操作系统发送 hover 事件到 app 的方式。当用户点击屏幕的时候,会以坐标和时间戳的形式形成一系列事件: hover (输入设备悬浮); hover exit 和 touch down (点击时); touch up (点击结束); hover (输入设备再次悬浮)。
为观察这些事件,如果该恶意软件有 SYSTEM_ALERT_WINDOW 权限的话,它可以生成一个透明的 Alert Window 覆盖在上面,不然它也可以如 4.6 节描述的那样用 Toast 类覆盖实现攻击。注意到在 Android 系统中, Alert Window 是在其他 view 的上面的(见第二部分)。一旦创建,该覆盖窗口可以获取点击所触发的一系列 hover event ,如此便可追踪输入设备。以秘密方式做到这些不惊扰用户与 app 的交互并非微不足道。因为, Android 只把 hover event 发送给收到 touch event 的 view 。而且,系统先知 touch stream (触摸流)的消耗,所有事件,包括 touch down 和 touch up 仅针对一个 view 。所以,用来追踪输入设备的恶意软件要么可以截取 hover event 和触摸事件,那这样就影响对实际 app 的触摸,要么就是截取不到,那这样就无法推断用户输入。
由敌手控制的恶意软件不能直接并隐秘的观察点击事件。但是我们可以证明通过观察用户点击之前和之后的 hover 事件可以隐秘地推断点击。要正确达到此目的,敌手需在不影响用户交互的情况下推断用户输入。
更具体一些,我们的攻击是这么实现的:恶意软件生成一个完全透明的 Alert Window 覆盖在整个屏幕上。该覆盖窗口位于其他窗口之上,包括用户正在用的 app 。因此,恶意软件可以追踪 hover event 。但是恶意 view 要及时以一种“聪明的方式”化主动(抓取所有事件)为被动(让它们顺利到达下层 app )。恶意软件通过 WindowManager API ,可以在影响用户交互的情况下适时的创建和移除覆盖窗口。
敌手(恶意软件)是一直运行在受害者设备上的后台服务。之前说过,它的难点在于如何知道将覆盖窗口由主动(将它放到屏幕上)变为被动(将它移除)然后再次变成主动的确切时间。须注意,为保证隐密性,我们只抓取 hover event ,并不抓取用户与之交互的 app 的触摸事件。因此,预测用户何时停止悬浮输入设备进行点击并不简单。我们通过如下方法进行处理:通过 WindowManager ,恶意软件其实是利用了 2 个 view 。一个是之前提到的完全透明的 Alert Window 。第二个,我们称之为监听器,其大小为 0px ,既不抓取悬浮坐标也不抓取点击事件。它存在的意义仅仅是告诉恶意软件何时发生了点击事件。然后恶意软件 Hoover 将利用这条信息移除 / 重建透明覆盖窗口。
图 2: Hoover用透明覆盖窗口抓取 post-click hover event。
3.4.1 推断点击时间。 所有用户点击都发生在监听器外面——它的大小是 0px 。另外,这个 view 设置了 FLAG_WATCH_OUTSIDE_TOUCH ,所以当由点击事件引起的 touch down event 发生是它会收到通知。结果就是,恶意软件可以推断点击的时间戳,虽然它不知道点击位置(见图 2 步骤 1 )。
3.4.2 抓取 post-click hover event 。 为了推断点击位置,攻击者在 touch down event 触发后马上激活透明覆盖窗口,点击事件将顺利传送给真正的 app 。(见图 2 步骤 2 )。这就保证了攻击不会影响到正常的设备使用。而覆盖窗口,从此刻起,拦截输入设备从点击位置到下一次点击位置所引起 hover event (见图 2 步骤 3 )。
与监听器的那个 view 不一样,监听器不会拦截用户的交互,因为它只有 0px ,覆盖窗口不能一直是活动的(出现在屏幕上)。不然它会干扰用户的下一次输入。同时,覆盖窗口又必须活跃足够长的时间,以保证能抓取足够多的 hover event 来推断点击位置。我们的实验表明,用本文所说的设备,系统平均每 19ms 产生一次 hover event 。我们还发现, 70ms 的活跃事件足够获取足够多的 hover event 去推断点击而不影响用户交互。这 70ms 包括了 app 的使用时间,不是点击时间,是像在键盘上输入时提示输入键位的那部分时间。当活跃时间用完,覆盖窗口将再次被移除(见图 2 步骤 4 )。
图 3 : Hoover 收集 hover event 。用触控笔输入时, hover event ( h,h, …… ,h ) 紧紧跟随触控笔的路径,用手指的话它们就散落在更宽一点的区域。
在这一部分,恶意软件已经收集了用户点击所引起的一系列 post-click hover event 。利用收集到的信息,攻击者的目标是推断用户点击的具体位置。一个方案是只用第一次点击所引起的 hover event 确定点击位置。但是这个方案虽然对触控笔效果很好,对手指的结果却不太好。原因就是,触控笔的接触面比较下,形成的 hover event 都仅仅跟随用户的移动(见图 3 )。所以,第一个 post-click hover event (相对的是,点击之前的最后一个 hover event )跟事实的点击位置很接近。相反的,手指的接触面比较大,所以 hover event ,包括那个点击后的,也不如触控笔那样紧密的贴近用户移动轨迹。这在我们最初的实验中就已经证实。该实验结果表明,第一个 post-click hover event 所抓取的位置很少在点击位置的上方。
出于此,为提高推断点击位置的正确率,我们决定应用机器学习工具,它不单考虑第一个 post-click hover event ,而是考虑了 70ms 内所抓取的全部事件。尤其是,为了一般化输入推断攻击我们应用了回归模型。对于有关键盘的攻击(键位推断)我们利用分类器。在高层次上,给定一系列 post-click hover event ( h,h, …… ,h ),回归模型要回答以下问题:“用户点击的位置在哪里?”同样的,分类器输出最可能是用户输入的那个键位。为评估攻击,我们用了数个回归模型和分类器,这些模型和分类器用的是 scikit-learn[25] 框架。我们在下一部分的结果中进行描述。
在我们最初的实验中,我们注意到不同的用户有不同的 hover event 模式。有些用户移动输入设备的速度比较快。就手指而言,手指的形状和大小所产生的 hover 模式是不一样的。为保证点击预测的正确率和鲁棒性,我们需要用不同的用户所产生的数据训练回归模型和分类器。出于此,我们进行了两类用户实验,将在下一部分进行描述。
表一:实验所用的设备
为评估本文所说的攻击,我们针对 Android 系统设计了一款恶意软件原型,叫 Hoover 。这个原型按逻辑分为两步:首先收集 hover event (如第三部分说的)然后分析它们以预测用户的点击坐标。我们用两个不同的组件来实现这两步。这两个组件可以在用户设备上同时运行。但是因为功能不同,为了方便分析,我们将它们分开了。 Hover event 收集组件是在用户设备上运行的 Android 恶意 app 。分析器用 python 实现,运行在远程服务器。它们之间的通信通过恶意软件的 INETERNET 权限来实现, INETRNET 权限是普通权限,所有 Android app 均默认配置,不会惊扰用户。
上传收集到的 hover event 到远程服务器并不需要多大的带宽。举个例子,一台设备运行四个小时,恶意软件收集到近 3800 次用户点击所引起的 hover event 。加密后每次点击的 hover event 是 40 Byte ,总的就 150KB 。这样的数据还是大量使用的结果,我们是为了得到一个上界才进行的。所以,我们相信,在实际生活中,一般用户点击产生的数据量会非常小。
最后,为进行实验,我们招募了 20 名志愿者,他们的数据在在下一节中。评估 Hoover 分两个场景:一个场景是用户在屏幕上乱点,另一个是明确的点击键盘输入文字。我们用两种不同的输入设备和表一所展示两种不同的设备进行了大量的实验。但是, Hoover 所表现的想法是通用的,不依赖于某个设备。因此,我们相信,此类攻击对于其他支持 hover 技术的 Android 设备一样有效。
在这一节我们描述用例的具体细节,同时报告为评估攻击所做的志愿者招募。
用例Ⅰ(常规点击) 这个用例的目的是收集用户随意在屏幕点击的信息。因此,我们让志愿者玩一个定制游戏:时不时的点击随机出现在屏幕上的小球。这个用例持续 2 分钟。
用例Ⅱ(文本输入) 这第二个用例主要是键盘输入。志愿者被要求输入乔治 奥威尔的《 1984 》的一段文章。每一段,平均有 250 个英文字母,包括标点符号。
每个用例由志愿者进行 3 次。第一次用拇指作为输入设备,第二次用食指,第三次用触控笔。我们记录下实验中所有用户点击位置和 hover event 。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课