1.1 应用结构
攻击面的梳理,需要以Android的结构出发,最重要的肯定是各模块的基础结构,也就是APK的结构,然后是整个系统的结构。
应用侧AndroidManifext.xml文件是最容易梳理的攻击面,也是渗透的首要审计目标。然后是应用的Java代码存放在dex文件中,native代码存放在lib目录中的so库。
除了应用侧,Android系统中还有系统服务、运行时环境、内核、驱动等,都是可以作为渗透目标的。
1.2 攻击面
我们的攻击面一方面可以从应用侧出发,包括:
-
四大组件的权限控制;
-
动静态注册的广播接收器;
-
服务的启动模式;
-
内容提供器的数据控制;
-
系统服务的核心逻辑和权限控制。
从系统侧出发,可以看到有:
-
系统属性、设置等:是否可以通过注入特异的数据接口破坏系统安全性;
-
adb等:提供了手机就意味着我们的攻击面并不局限于模块,通过adb产生的攻击也是一种方式;
-
内核、SELinux等:包括内核漏洞、BROM的安全启动流程、SELinux的安全策略等;
-
NFC、相机、蓝牙等:一方面可以考虑特权进程的劫持注入;另一方面可以考虑其背后应用层的数据解析。
我们总结这两年工作所看到的一些问题类型,选取了几个常见的问题类型做介绍,希望能给大家提供一些参考。
2.1 PendingIntent劫持
PendingIntent本质上是对于Intent的延迟发现,创建PendingIntent对象时,会将Intent数据存放到系统服务中,并在调用PendingIntent发送时以创建者身份发送调用请求。
PendingIntent的劫持容易发生在Notification、SliceProvider、MediaBrowserService、AppWidget等功能处,劫持后可通过篡改其Intent数据实现越权访问组件、读写文件、篡改业务逻辑等问题。
该类型的审计,一般可注意以下几个点:
-
PendingIntent.get...接口:PendingIntent对象的创建,基本都是使用该类型接口,对应的Intent一般也在附近,因此可以确认劫持后,能够实现什么样的利用。
-
权限控制:对于SliceProvider等场景,需要注意相关接口是否做好了权限控制,否则直接对三方泄露了PendingIntent对象,就会直接导致对应对象被劫持。
-
场景触发:对于通知等类型的劫持,我们除了要发现问题,还要找到触发问题的点,才能构造一个完成的利用。
-
目标组件:又是我们不一定要篡改调用的目标组件,也可以分析目标组件本身是否有逻辑问题,通过篡改extras等数据实现业务逻辑篡改。
另外,PendingIntent对象绝不仅仅被用于以上几种场景,开发者也会在一些特殊的场景中直接使用,对于这些类型,要注意对象的数据流向,寻找劫持的机会。
2.2 容易忽略的AIDL
很多开发者误以为AIDL文件是私有的,三方应用在没有获取私有文件的情况下无法跨进程调用对应接口,这是一个错误的认识。Android中系统服务和Bind模式的服务都是使用AIDL文件的,这两个地方也最有可能因为错误的认识导致校验缺失。
以控制黑夜模式的系统服务接口为例,AIDL本质上是按照特定结构生成的快进程调用接口。无论是否拥有AIDL文件,我们都可以主动构造调用结构,实现跨进程调用,Bind模式的服务也是一样的。
所以建议审计时多关注这些服务和接口,如果其中存在特权功能,且没有有效的安全校验,往往会带来一些提权操作。
2.3 信息泄露
信息泄露是Android中常见的漏洞类型,主要见于内容提供器对于数据访问的权限控制;WebView对于Cookie的管控;应用对外暴露端口;数据文件自身的权限控制等等。
审计时可以重点关注以下几点:
-
SQL注入:对于数据查询是否有做到参数化查询;
-
接口权限不统一:如暴露写权限,不暴露读权限,仍然可以通过数据写转数据读,实现数据读取;
-
权限控制:组件是否直接返回敏感数据,操作数据的权限是否有权限控制;
-
数据库结构:安全性不同的数据库表放到同一数据库中,可能导致安全性降级。
信息泄露产生的危害是非常直观的,如泄露了token、验证码可能导致账号窃取,进而被攻击者转移数据或金融资产;甚至以劫持账户为跳板攻击其他账户体系;或者利用信息执行特权功能等。
2.4 文件读写
文件读写主要是介绍FileProvider相关的问题,FileProvider往往通过URI控制权限,所以如果我们能够控制目标应用的以下三个接口调用的参数,就可能实现任意文件读写:
-
grantUriPermission接口的参数;
-
startService和startActivity等相关接口的Intent;
-
目标应用setResult中的Intent参数。
以上是授权的利用点,该类型问题还需要FileProvider本身配置存在问题。如PPT中呈现的,对于关键目录配置过于宽泛,如使用/、.和空字符串进行路径配置,就会将最大目录范围暴露出去,从而产生风险。
攻击者可以通过前面介绍的几个利用点获取对应FileProvider中的URI权限,从而实现任意文件的读写,进而实现任意代码执行、白名单绕过、诱导钓鱼等场景。
2.5 LaunchAnyWhere
LaunchAnyWhere是很常见的利用跳板,通过跳板我们往往可以实现一些安装类的漏洞组装、敏感信息的窃取、密码绕过等高危场景。
审计是可以重点关注以下几点:
-
Deeplink、Webview等需要开发生态的便捷技术;
-
数据解析类的应用,比如短信、NFC等是否能够实现远程劫持特权进程;
-
或者一些接口没有做好校验,直接将跳板暴露给了三方应用。
前面介绍了一些常见的问题类型,我们往往是从问题本身的原理出发,寻找其审计的关键点;这里我们从一些特殊现象出发,出现异常的地方往往代表者开发者的一些想法。
3.1 异常配置
异常配置主要是权限配置相关的,如果我们看到开发者在应用者有一些做权限配置的意图,但是配置是无效的,我们就可以重点关注一下。这往往意味着对应组件是有特权操作的,比如上图所示,开发者想要给组件增加高权限的权限控制,却将权限等级错误的配置到了组件上;还有一些将组件导出和URI授权同时设为true的,这就让URI授权的配置没有了效果。
还有一些是对于权限机制了解不到位的,比如对于内容提供器call函数来说,如果读写权限只配置了一个,就相当于没有配置权限,尤其是前面提到过的SliceProvider等场景,往往会泄露一些敏感数据和特权接口给到三方应用。
3.2 不严谨的校验
不严谨的校验方面,我们可以看到很多开发者会将UID Name当作包名去校验,只要攻击者将sharedUserId指定为校验目标的包名,往往就可以轻松绕过校验。
还有对于Activity的校验,如果开发者是通过包名做校验,往往也是很容易绕过的。
再比如,有的开发者想要校验签名或者密码等数据,却直接使用外部传入的参数和自己硬编码的数据进行比对,这都是无法有效达成校验目的的。
我们通过Android应用和系统结构帮助大家梳理了攻击面,它不仅仅是应用的四大组件,还有系统服务、运行时环境、系统功能、网络协议等等。
然后我们选取了几个常见的问题类型做了讨论,介绍了一些审计这些问题类型的关键审计点,以及发现问题后我们可以进一步利用的方向。
最后我们介绍了几个异常现象,不仅可以根据问题类型正向的排查问题,也可以寻找一些异常点,分析开发者心理找到一些利用方向。
原文始发于微信公众号(vivo千镜):Android移动应用攻防之道
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论