Android App安全渗透测试(二)
一、 安卓应用攻击概览
1. 安卓应用简介
根据开发方式的不同,安卓应用大致分为三种。Web应用、原生应用、混合应用
Web应用
Web应用是通过使用JavaScript、HTML5等Web技术来实现交互、导航以及个性化功能的。Web应用可以在移动设备的Web浏览器中运行,并通过向后台服务器请求Web页面来进 行渲染。一个应用可以有浏览器渲染的版本,也可以有作为独立应用的版本,这种现象很常见, 因为这样可以避免重复开发。
原生应用
不同于Web应用,原生应用具有优良的性能和高度的可靠性。原生应用不需要从服务器获取 支持,而且还能利用安卓系统提供的高速本地支持,所以原生应用的响应速度很快。另外,用户 不连接网络也能使用某些应用。但是,使用原生技术开发的应用不能够跨平台,只能使用某一特 定平台进行开发。所以,一些企业开始寻求能够避免重复工作的跨平台移动应用开发解决方案。
混合应用
混合应用尝试综合利用原生应用和Web应用的优点,使用Web技术(HTML5、CSS和 JavaScript)编写,像原生应用一样在设备上运行。混合应用在原生容器中运行,利用设备的浏览 器引擎(不是浏览器)在本地渲染HTML,并处理JavaScript。混合应用能够通过一个从Web应用 到原生应用的抽象层访问设备上的接口,如加速器、摄像头以及本地存储等,而Web应用则不能 访问这些接口。混合应用通常使用PhoneGap、React Native等框架进行开发。
2. 理解应用攻击面
移动应用架构
社交类、银行类、娱乐类等移动应用具有很多需要使用网络通信的功能,所以,如今的大部 分移动应用都采用常见的客户端——服务器架构。想要了解这类应用的攻击面,需要 充分考虑应用的各个方面,包括客户端、后端API、服务器漏洞以及数据库等。这些地方的任何 一个入口都有可能对整个应用或应用数据造成威胁。
在开发软件时,建议遵循安全软件开发生命周期(SDLC)流程。很多企业都采用安全软 件开发生命周期,从而保证软件开发生命周期中每一个阶段的安全性。
客户端存在的威胁
静态应用数据
随着移动应用的出现,在客户端存储数据的概念被广泛采用。很多移动 应用在设备上存储未经加密的敏感数据,这是移动应用存在的主要问题之一。这些数据 可能是敏感的、机密的或者私人的。有多种方法可以利用设备上的数据,拥有设备物理 访问权限的攻击者几乎可以轻而易举地窃取这些数据。如果设备已经ROOT过了或者越狱 了,那么恶意应用就可能窃取这些数据。所以,我们必须要确保应用不在设备上存储用 户名、密码、认证标记、信用卡号码等敏感数据。如果不得不存储这些数据,就必须将 其加密,谨防被攻击者窃取。
传输中的应用数据
需要与后台进行通信的移动应用极易受到攻击,攻击者想要窃取传 输中的数据。终端用户经常连接咖啡店和机场的公用网络,而此时攻击者就可能使用burp 代理、 MITM代理、SSL MitM代理等工具窃取数据。
代码漏洞
不具有安全措施的移动应用在遭受各种攻击时会变得脆弱不堪。应用中的编 码错误会导致严重的漏洞,进而影响用户数据和应用数据安全。包括导出的内容提供程序、导出的activity、客户端注入,等等。攻击场景包括拥有设备物理访问权限的攻击者可能窃取另一个用户的会话,设备中的恶意应用可以读取其他应用中由于编码错误而暴露的数据,能访问应用二进制数据的攻击者可能会对应用进行反编译,从而查看源代码中硬编码的证书。
应用数据泄漏
几乎所有平台的移动应用都存在这一个问题。应用可能会无意间将敏感数据泄漏给攻击者,开发者需要格外注意这一点。开发人员需要移除在开发阶段中用于打印日志的代码,还必须保证没有容易泄漏的数据。这是因为应用沙盒不适用于这一类型中的某些攻击。譬如,用户从应用中复制了像安全问题答案之类的敏感数据,这些数据就会被存放在设备的剪贴板上,而剪贴板并不在沙盒中。设备上的其他应用不需要知道之前的应用,就可以读取这些数据。
平台问题
为移动应用设计威胁模型时,考虑针对该应用运行平台的威胁很重要。以安卓平台为例,面向安卓平台开发的原生应用很容易被反编译,而且很容易查看Java源代码。 这样,攻击者就能查看应用的源代码以及代码中被硬编码的敏感数据。此外,攻击者还能修改应用代码,然后重新编译,并把应用发布到第三方应用市场上。如果应用是敏感应用或者付费应用,那么就必须对应用进行完整性检查。虽然上述问题对iOS这样的系统影响相对较小,但如果设备越狱了,那么也会存在系统方面的问题。
后端存在的威胁
身份验证与授权
在后端API开发中,开发人员经常创建自定义身份验证。在身份验证与授权中可能存在与之相关的漏洞。
会话管理
移动平台通常使用身份验证令牌来管理会话。用户首次登录后,会得到一个身份验证令牌,这个令牌在接下来的会话中都会用到。如果身份验证令牌在销毁前没有得到妥善保护,这就有可能导致一次攻击。只在客户端结束会话,而服务器没有结束回话,这是移动应用另一个常见的问题。
输入验证
输入验证是应用中已知的常见问题。如果不进行输入验证,可能会存在SQL 注入、命令注入以及跨站脚本攻击等风险。
错误处理不当
应用错误对攻击者很有吸引力。如果错误处理不当,而API针对特定的请求抛出数据库异常或服务器异常,那么攻击者就可能利用这些错误进行巧妙的攻击。
脆弱的加密方法
加密是开发者在开发过程中另一个经常犯错的地方。虽然各个平台都支持通过加密的方法来保证数据安全,但密钥管理是客户端存在的主要问题。同样,也需要安全地存储后台数据。
数据库攻击
攻击者有可能在未经授权的情况下直接访问数据库。例如,如果没有强认证保护,攻击者有可能在未经授权情况下访问phpMyAdmin等工具数据库控制台, 另一个例子就是访问未授权的MongoDB控制台,因为MongoDB默认不需要任何认证就能访问它的控制台。
3. 移动应用测试与安全指南
OWASP移动应用十大风险
服务端弱控制
第一个 OWASP 漏洞是服务端弱控制,顾名思义,服务端不以安全的方式将数据从移动应用程序发送到服务端,或者在发送数据时暴露一些敏感的 API,常见的攻击向量包括找出暴露的API入口,查找各种漏洞,利用配置错误的服务器等。 例如,考虑一个 Android 应用程序发送登录凭据到服务器进行身份验证,而不验证输入。攻击者可以以这样的方式修改凭证,以便访问服务器的敏感或未授权区域。此漏洞可视为移动应用程序和 Web 应用程序中的一个漏洞。
不安全的数据存储
这仅仅意味着,应用相关信息以用户可访问的方式在设备上存储。 许多 Android 应用程序在共享首选项,SQLite(纯文本格式)或外部存储器中,存储与用户相关的私密信息或应用程序信息。 开发人员应该始终记住,即使应用程序在数据文件夹(/data/data/package-name
)中存储敏感信息,只要手机已 root,恶意应用程序/攻击者就可以访问它。
传输层保护不足
许多 Android 开发人员依赖于通过不安全模式的网络来发送数据,例如 HTTP 或没有正确实现 SSL 的形式。 这使得应用程序易受到网络上发生的所有不同类型的攻击,例如流量拦截,从应用程序向服务器发送数据时操纵参数,以及修改响应来访问应用程序的锁定区域。
意外的数据泄漏
当应用程序将数据存储在本身易受攻击的位置时,会出现此漏洞。 这些可能包括剪贴板,URL 缓存,浏览器 Cookie,HTML5DataStorage
,统计数据等。 一个例子是用户登录到他们的银行应用程序,他们的密码已经复制到剪贴板。 现在,即使是恶意应用程序也可以访问用户剪贴板中的数据。
缺少授权和认证
如果 Android 应用程序或一般的移动应用程序在没有适当安全措施的情况下,尝试基于客户端检查来验证或授权用户,则这些应用程序最容易受到攻击。 应该注意的是,一旦手机已 root,大多数客户端保护可以被攻击者绕过。 因此,建议应用程序开发人员使用服务器端身份验证和授权进行适当的检查,一旦验证成功,请使用随机生成的令牌,以便在移动设备上验证用户。
无效的加密
这仅仅表示使用不安全的密码函数来加密数据部分。 这可能包括一些已知存在漏洞的算法,如 MD5,SHA1,RC2,甚至是没有适当的安全措施的定制算法。
客户端注入
这在Android应用程序中是可行的,主要成因是使用 SQLite 进行数据存储。客户端注入的结果是,可以通过应用在移动设备上执行恶意代码。通常,恶意代码通过不同的方式借助威胁代理输入到移动应用中。
下面是安卓应用中客户端注入攻击的一些例子:
WebView注入;
通过原始SQL语句对SQLite数据库进行传统的SQL注入;
内容提供程序SQL注入;
内容提供程序路径遍历。
通过不可信输入的安全决策
开发者应该假设未授权的用户可以通过不正确的输入过度使用应用的敏感功能。特别是安卓 平台,攻击者可以拦截调用(进程间通信或Web服务调用),并篡改其中的敏感参数。不能实现 这类功能就会导致应用产生错误,甚至让攻击者获得更高的权限。使用不正确的Intent调用敏感 的activity 就是例子之一。
不正确的会话处理
移动应用使用诸如SOAP或REST一类的协议来连接服务器。它们都是无状态协议,当移动客 户端应用使用这些协议时,客户端会在身份验证完成后从服务器获得一个令牌。用户在会话期间将会使用这个令牌,OWASP的“会话处理不当”就是指攻击和保护这些会话。这个令牌在客户端失效后,却没有服务器上失效,这是移动应用的一个常见问题。通常,应用收到的这个令牌会通 过共享首选项或SQLite数据库存放在客户端的文件系统中。一旦恶意用户获得了这个令牌,而服务器没有及时让这个令牌失效,那么他就可以随时使用这个令牌。其他可能出现的情况包括会话 超时、弱令牌创建以及过期令牌等
缺乏二进制保护
这意味着不能正确地防止应用程序被逆向或反编译。 诸如 Apktool 和 dex2jar 之类的工具可用于逆向 Android 应用程序,如果没有遵循正确的开发实践,它会暴露应用程序的各种安全风险。 为了防止通过逆向攻击来分析应用程序,开发人员可以使用 ProGuard 和 DashO 等工具。
自动化工具
Drozer 和Quark是两款可能会在安卓应用评估中使用到的工具。
Drozer工具
Drozer是一个由MWR实验室开发的安卓安全评估框架。,Drozer是用于安卓安 全评估的最佳工具。根据Drozer的官方文档介绍,“Drozer可以把你当作一款安卓应用,通过安卓 的进程间通信机制和操作系统与其他应用进行交互。
Drozer是交互式的。用户使用Drozer进 行安全评估时,需要在工作站控制台运行命令,然后Drozer把这些命令发送给设备的代理,进而执行相关任务。
Drozer相关命令
模块 作用
auxiliary.webcontentresolver 开启web服务来获取content providers
exploit.jdwp.check 针对@jdwp-control漏洞
exploit.pilfer.general.apnprovider 获取APN信息
exploit.pilfer.general.settingsprovider 查看系统设置
information.datetime 查看设备时间
information.deviceinfo 获取设备详细信息
information.permissions 列出所有手机应用使用过的权限信息
scanner.activity.browsable 获取可以从浏览器查看的activity
scanner.misc.native 列出包含native的包
scanner.misc.readablefiles 查找可被其应用读取的文件
scanner.misc.secretcodes 查找手机暗码
scanner.misc.writablefiles 查找能被其他应用写数据权限的文件
scanner.provider.finduris 查找content providers URI链接
scanner.provider.injection 查找content providers SQL注入
scanner.provider.sqltables 通过SQL注入查找表名
scanner.provider.traversal 查找目录遍历漏洞
shell.exec 执行单条shell命令
shell.send 发送ASH shell到远程监听器
shell.start 进入shell模式
tools.file.download 下载手机上的文件
tools.file.md5sum 获取文件的md5
tools.file.size 获取文件大小
tools.file.upload 从PC上传文件到设备
tools.setup.busybox 安装Busybox
tools.setup.minimalsu 安装minimal-su
4. 识别攻击界面
Sieve是测试APP。
如上图所示,sieve应用有三个导出的activity。现在,我们需要找出这三个activity的名字, 并确认它们是否属于敏感的activity。我们可以使用现有的Drozer模块来进行进一步查找它。这个应用是可以调试的,这意味着我们可以把这个进程连接到调试器上,逐一地调试每一条指令,甚至可以在这个进程上运行任意的代码。
使用 Drozer识别并利用安卓应用漏洞
为了识别当前软件包中activity的名称,我们可以使用下面的命令。
dz> run app.activity.info -a [包名]
在前面的图中,我们可以查看目标应用中的activity列表。
使用Drozer来尝试启动它。
dz> run app.activity.start --component [包名] [组件名]
在模拟器可以看到sieve主界面。
很明显,我们绕过了用于登录应用的身份验证。
二、 数据存储与安全
1. 什么是数据存储
安卓使用了类似Unix中的文件系统来进行本地数据存储,用到的文件系统有十几种,如 FAT32、EXT等。
事实上,安卓系统中的一切都是文件。因此,我们可以使用下面的命令从/proc/filesystems文件中查看文件系统详情。
C:\> adb shell cat /proc/filesystems
典型的文件系统根目录如下图:
安卓在filesystems这个文件中存储了许多详细信息,比如内置应用、通过谷歌Play商店安装 的应用等。任何拥有物理访问权限的人都能轻易从中获得许多敏感信息,如照片、密码、GPS位 置信息、浏览历史或者公司数据等。
重要目录
/data:存储应用数据。/data/data目录用于存储与应用相关的私人数据,如共享首选项、缓 存、第三方库等
/proc:存储与进程、文件系统、设备等相关的数据。
/sdcard:SD卡用于增加存储容量。在三星设备上,/sdcard通常对应内置SD卡,而/extsdcard 则对应外置SD卡。SD卡可以存储视频等大文件。
安卓本地数据存储技术
安卓为开发人员提供了下列几种存储应用数据的方法。
共享首选项、SQLite数据库、内部存储、外部存储
除了外部存储方式,其他存储方式都将数据存放在/data/data目录下的文件夹中,其中包含缓存、数据库、文件以及共享首选项这四个文件夹。每个文件夹分别用于存放与应用相关的特定类 型的数据:
shared_prefs:使用XML格式存放应用的偏好设置;
lib:存放应用需要的或导入的库文件;
databases:包含SQLite数据库文件;
files:用于存放与应用相关的文件;
cache:用于存放缓存文件
共享首选项
共享首选项是一些XML文件,它们以键值对的形式存储应用的非敏感设置信息。所存储的 数据类型通常是boolean、float、int、long和string等
SQLite数据库
SQLite数据库是基于文件的轻量级数据库,通常用于移动环境。安卓系统同样支持SQLite框 架,因此你经常会发现许多使用SQLite数据库存储数据的应用。由于安卓系统在安全性方面的限 制,应用存储在SQLite数据库中的数据默认不能被其他应用访问。
内部存储
内部存储也被称为设备的内部存储,可以将文件存储到内部存储空间。由于能被直接访问,
因此它能快速响应内存访问请求,与应用相关的全部数据几乎都在这里被使用。从逻辑上来说, 它是手机的硬盘。在安装过程中,每个应用都在/data/data/<应用包名>/下创建了各自的文件目录, 这些目录对每个应用都是私有的,其他应用没有访问权限。当用户卸载应用后,这些目录中的文件将会被删除。
内部存储空间的有限意味着应物尽其用,用来保存比较重要的数据,例如用户信息资料,口令密码等不需要与其他应用程序共享的数据。
外部存储
外部存储是安卓系统中一种用于存储文件的全局可读写的存储机制。任何应用都能访问外部 存储区域并读写文件,由于这一特性,敏感文件不应该存储在这里。开发人员需要在 AndroidManifest.xml中声明合适的权限才能进行这些操作。
2. 用户字典缓存
用户字典是大多数移动设备所具有的一个非常方便的功能,能够让键盘记住用户经常输入的 词组。当我们使用键盘输入特定的词组时,它能自动提供一些补全建议。安卓系统同样具有这一功能,它将常用词组存放在一个名为user_dict.db的文件中。因此,应用开发人员需要小心。如果允许缓存输入安卓应用的敏感信息,那么任何人都可以通过浏览user_dict.db文件或使用其内容提 供程序的URI访问这些数据。
由于任何应用都可以通过用户字典的内容提供程序访问其内容,因此攻击者可以轻易读取和 搜集其中的有用信息
3. 不安全的数据存储—NoSQL数据库
目前,NoSQL数据库使用广泛。企业普遍使用了诸如MongoDB、CouchDB等NoSQL数据库。这些数据库同样适用于移动应用。与其他本地存储技术类似,如果NoSQL数据库通过不安全的方式存储数据,就可能会被利用。
4. 备份技术
使用备份功能在未ROOT的设备上查看应用的内部存储。利用特定应用或设 备的备份文件,可以检查其安全问题。
按照下面的步骤使用安卓系统备份技术来查找安全问题。
(1) 使用adb backup命令备份应用的数据;
(2) 使用Android Backup Extractor将.ab格式转换为.tar格式;
(3) 使用pax或star工具解压TAR文件;
(4) 分析上一步解压后的内容,查找存在的安全问题。
5. 确保数据安全
敏感信息不应该以明文存储,想要安全地存储数据需要花费很大的精力。
尽量不要将敏感信息存储到设备上,而应该将它放到服务器上。如果必须选择前者,就应该 在存储数据的时候使用加密算法。有很多工具库可以帮助你对保存到设备上的数据进行加密。
Secure Preferences就是一个这样的库,它能帮你对保存到共享首选项的数据进行加密。可以 通过https://github.com/ scottyab/secure-preferences找到它。
如果想要对SQLite数据库进行加密,可以选择SQLCipher。它的下载地址是:https://www. zetetic.net/sqlcipher/sqlcipher-forandroid/。
注意,当使用类似AES等对称加密算法时,密钥管理是一个问题。在这种情况下,可以使用 基于密码加密(PBE)的方法。这样,密钥就会基于用户输入的密码生成。
如果你考虑使用散列来加密,那就选择一个强的散列算法并对其加盐。