APP安全测试学习笔记

​ 通过辉哥发的 “APP安全检测指南–作者:panda” 跟进学习app渗透测试。

image-20200710153320829

1.客户端程序安全

1.1安装包签名

​ 用JDK的jarsigner.exe检查安全包的签名,命令:

1
jarsigner.exe -verify APK文件路径 -verbose -certs

​ 以某个算命app为例,结果如下:

image-20200627224441281

​ 如上图,测试结果为安全。只有使用直接客户的证书签名时才认定为安全,Debug 证书、第三方(如开发方)证书等均认为风险。

1.2反编译保护

​ 把apk当做zip解压,得到classes.dex文件(可能不止一个 .dex 文件),解压后如下:

image-20200628101834819

​ 使用dex2.jar执行如下命令:

1
dex2jar.bat classes.dex 文件路径

image-20200628102833253

​ 得到classes.dex.jar文件

image-20200628102833254

​ 使用jd-gui打开jar文件,可得到JAVA代码

image-20200628104345358

​ 如上图,逆向后发现代码未做混淆,是不安全的。

​ 下图为混淆后的代码,函数和变量名用无意义的字符来代替:

image-20200628104622176

​ 通过博客得知混淆的原理:android平台的混淆原理是用“不能直接猜出含义 的通用变量名和函数名a b c等”替换编译后程序包中“ 具有明显语义信息 的变量名和函数名”,这样,通过逆向工程得到的只是 难以理解 的代码。代码混淆并不能从根本上阻止反编译等。因为代码混淆仅仅提高了阅读难度,但并不能真正阻止反编译。

1.3应用完整性校验

​ 用apktool将目标apk文件解包,命令如下:

1
java -jar apktool.jar d -f apk文件路径 -o 解包目标文件夹

image-20200628105738136

​ 文件结构如下:

image-20200628105847820

​ 通过修改解包目录中的文件,可以找到logo之类的图进行修改(比较好辨认结果),我修改了咨询处的图片,如下:

image-20200628113532130

​ 用apktool,把解包目录重新打包成未签名的apk文件,命令如下:

1
java -jar apktool.jar b -f 待打包的文件夹 -o 输出apk目录

​ 重新打包的时候出现很多问题,具体百度加玄学解决了

image-20200628184932619

​ 成功输出apk文件

image-20200628185217847

​ 用SignApk,对未签名的APK文件进行签名,命令如下:

1
java -jar signapk.jar testkey.x509.pem testkey.pk8 待签名apk文件路径 签名后输出apk路径

image-20200629105838083

​ 输出签名后的apk

image-20200629105858875

​ 将签了名的APK安装、运行、确认是否存在自校验;需要注意的是,如果之前安装的APK和修改后的APK签名不同,就不能直接覆盖安装,一般来说,先卸载之前安装的APP即可。

​ 将客户端程序文件反编译,修改源码或资源文件后重新打包安装运行,结果如下图:

image-20200629110321139

​ 之前为咨询图片的位置,我换成了另一张图片。经测试,此某算命app是可以被重新打包运行的。

​ 如果是经过自校验后的情况,修改源码资源后是无法正常启动的。

1.4组件安全

方案一:

​ 使用apktool解包,打开解包目录中的AndroidManifest.xml,对其中声明的各个组件,根据以下规则判断是否可导出:

1
2
3
4
5
6
7
1.显式声明了android:exported="true",则可导出;
2.显示声明了android:exported="false",则不可导出;
3.未显示声明android:exported:
​ a) 若组件不是Content Provider:
​ i. 若组件包含<intent-filter>则可导出,反之不可;
​ b) 若组件是Content Provider:
​ i. 若SDK版本<17则可导出,反之不可。

​ 从测试的角度上,只能判断组件是否导出,但能否构成危害需要详细分析源代码后才能得出结论。一般来说,在测试时尽管写清所有的导出组件,由客户开发侧确认相关组件是否确实需要导出即可。

image-20200629144318194

​ 启动Activity和Content Provider大多是导出组件,一般无须理会。

方案二:

​ 检查 AndroidManifest.xml 文件中各组件定义标签的安全属性是否设置恰当。如果组件无须跨进程交互,则不应设置 exported 属性为 true。例如,如下图所示,当 com.umeng.message.XiaomiIntentService 的 exported属性为 true 时,将可以被其他应用调用。(当有设置权限(permissions)时,需要再考察权限属性。如 android:protectionLevel 为 signature 或 signatureOrSystem 时,只有相同签名的 apk才能获取权限。详情见附录参考资料API Guides 系统权限简介 )

image-20200629150016127

​ 当发现有可利用的组件导出时,(当然,并不是说所有导出的组件都是不安全的,如果要确定,必须看代码,对代码逻辑进行分析)可利用drozer测试工具进行测试。

1
2
drozer安装:https://www.jianshu.com/p/4ef5b26dd3fb
drozer使用:https://www.jianshu.com/p/dfa92bab3a55

2.敏感信息安全

2.1数据文件

​ 首先查看相关文件的权限配置,正常的文件权限最后三位应为空(类似”rw-rw—-“),即除应用自己以外任何人无法读写;目录则允许多一个执行位(类似“rwxrwx—x”)。如下图:

image-20200629160646287

​ 权限检测完整后,再检查客户端程序存储在手机中的 SharedPreferences 配置文件,通常是对本目录下的文件内容(一般是xml)进行检查,看是否包含敏感信息。最后在检测SQLite 数据库文件,在私有目录及其子目录下查找以.db 结尾的数据库文件。对于使用了 webView 缓存的应用,会在 databases 子目录中保存 webview.db 和 webviewCache.db。其中有可能会记录 cookies 和提交表单等信息。使用数据库查看工具即可查看这些文件中是否有敏感信息。

​ 还有些时候,客户端程序 apk 包中也是是保存有敏感信息的,比如检查 apk 包中各类文件是否包含硬编码的的敏感信息等。

2.2Logcat日志

​ 通过adb 工具连接设备:

1
2
3
adb devices  //查看安卓设备列表
adb -s 设备名称 其它命令 //当连接了多个设备时,选择操作的目标设备,否则会出错
adb pull 手机目录名 PC目录名 //从安卓设备中复制文件到电脑中

然后使用 WinHex 打开,查看内存遗留信息。

也可以直接用adb查询locat日志:

在adb shell中,有下列命令可用:

1
2
3
logcat  //持续输出日志,直到Ctrl+C
logcat -d //一次性输出日志缓存,不会阻塞
logcat -c //清空日志缓存

3.密码安全

3.1键盘劫持

​ 通常来说,只有使用系统输入法的编辑框才能够进行键盘码记录。如果是自制的软键盘,则可以尝试进行触摸屏记录。像下图这样,不使用系统输入法,且按键随机分布的软键盘是安全的。

image-20200629173937788

3.2随机布局软件盘

​ 当客户端软键盘未进行随机化处理时为低风险;当客户端软键盘只在某一个页面载入时初始化一次而不是在点击输入框时重新进行随机化也为低风险。

3.3屏幕录像

​ 使用ADB进行测试:

1
adb shell /system/bin/screencap -p 输出png路径(安卓设备中)

image-20200709161454548

​ 运行截图命令后,可以在 /mnt/sdcard/ 目录中查看到存在1.png

image-20200709162105260

​ 打开查看:

Screenshot_20200709_162157_com.android.gallery3d

成功截图。

​ 攻击者可以在用户进入登录页面,在输入密码的同时,进行连续截图,即可记录用户输入的密码。如果没有防截屏,那么即使是随机分布的、没有视觉反馈的软键盘也会被记录:
​ 还有一种验证方式是从代码方面进行验证:首先检测需较高安全性的窗口(如密码输入框),看代码中在窗口加载时是否有类似下图的代码。按照 android SDK 的要求,开启 FLAG_SECURE 选项的窗口不能被截屏。

image-20200709162413334

目前 FLAG_SECURE 测试结果:

1
2
3
N-PASS,可截图,
ZTE 880E, 可截图
ASUS TF300T,可阻止工具及 ddms 截图。

3.4手势密码

​ 手势密码的复杂度:

1
2
3
1.进入客户端设置手势密码的页面进行手势密码设置。
2.进行手势密码设置,观察客户端手势密码设置逻辑是否存在最少点位的判断。
3.反编译 APK 为 jar 包,通过 jd-gui 观察对应代码逻辑是否有相应的判断和限制条件。(一般设置手势密码若输入点数过少时会有相应的文字提示,通过此文字提示可以快速定位到代码位置)

​ 手势密码的修改和取消:

1
2
3
4
5
1.进入客户端设置手势密码的位置,一般在个人设置或安全中心等地方。
2.进行手势密码修改或取消操作,观察进行此类操作时是否需要输入之前的手势密码或普通密码。
3.观察在忘记手势密码等其他客户端业务逻辑中是否存在无需原始手势或普通密码即可修改或取消手势密码的情况。
4.多次尝试客户端各类业务,观察是否存在客户端逻辑缺陷使得客户端可以跳转回之前业务流程所对应页面。若存在此类逻辑(例如手势密码设置),观察能否修改或取消手势密码。
5.反编译 APK 为 jar 包,通过 jd-gui 观察对应代码逻辑,寻找客户端对于手势密码的修改和删除是否存在相应的安全策略。

​ 手势密码的本地信息保存:

1
2
3
4
1.首先通过正常的操作流程设置一个手势密码并完整一次完整的登陆过程。
2.寻找/data/data 的私有目录下是否存在手势密码对应敏感文件,若进行了相关的信息保存,基本在此目录下。(关键词为 gesture,key 等)
3.若找到对应的文件,观察其存储方式,为明文还是二进制形式存储,若为二进制形式,观察其具体位数是否对应进行 MD5(二进制 128 位,十六进制 32 位或 16 位)、SHA-1(二进制 160 位,十六进制 40 位)等散列后的位数。如果位数对应,即可在反编译的jar包中搜索对应的关键字以迅速对应代码。
4.通过代码定位确认其是否进行了除单项哈希散列之外的加密算法,若客户端未将手势密码进行加密或变形直接进行散列处理可认为其不安全,一是因为现阶段 MD5、SHA-1 等常用的哈希算法已被发现碰撞漏洞,二是网络中存在 www.somd5.com 等散列值查询网站可以通过大数据查询的方式获取散列前的明文手势密码。

​ 手势密码的锁定策略:

1
2
3
4
1.首先通过正常的操作流程设置一个手势密码。
2.输入不同于步骤 1 中的手势密码,观察客户端的登陆状态及相应提示。若连续输入多次手势密码错误,观察当用户处于登陆状态时是否退出当前的登陆状态并关闭客户端;当
客户未处于登录状态时是否关闭客户端并进行一定时间的输入锁定。
3.反编译 APK 为 jar 包,通过 jd-gui 观察对应代码逻辑,寻找客户端是否针对输入次数及锁定时间有相应的逻辑处理。

​ 手势密码的抗攻击测试:

1
2
3
1.下载并安装 Xposed 框架及 SwipeBack 插件。
2.启动客户端并进入手势密码输入页。
3.启动 SwipeBack 插件,观察是否可以通过滑动关闭手势密码输入页的方式进入登陆后的页面。

4.安全策略

4.1密码复杂度检测:

​ 测试客户端程序是否检查用输入的密码强度,禁止设置弱口令。

4.2账号登录限制:

​ 测试一个帐号是否可以同时在多设备上成功登录客户端,进行操作。

4.3账户锁定策略

​ 测试客户端是否限制登录尝次数。 防止木马使用穷举法暴力破解用户密码。

4.4问题验证

​ 测试对账号某些信息(如单次支付限额)的修改是否有私密问题验证。私密问题验证是否将问题和答案一一对应。私密问题是否足够机密。

4.5会话安全

​ 测试客户端在超过20分钟无操作后,是否会使会话超时并要求重新登录。超时时间是否合理。

4.6界面切换保护

​ 检查客户端程序在切换到其他应用时,已经填写的账号密码等敏感信息是否会清空,防止用户敏感信息泄露。如果切换前处于已登录状态,切换后一定时间内是否会自动退出当前会话。

4.7UI信息泄露

​ 检查客户端的各种功能,看是否存在敏感信息泄露问题。使用错误的登录名或密码,看客户端提示是否不同。在显示卡号等敏感信息时是否进行部分遮挡。

4.8验证码安全

​ 测试客户端在登录和交易时是否使用图形验证码。验证码是否符合如下要求:由数字和字母等字符混合组成;采取图片底纹干扰、颜色变换、设置非连续性及旋转图片字体、异字体显示样式等有效方式,防范恶意代码自动识别图片上的信息;具有使用时间限制并仅能使用一次;验证码由服务器生成,客户端文件中不包含图形验证码文本内容。(观察验证码组成,若简单,可以尝试使用PKAVHttpFuzzer的验证码识别工具进行识别)

4.9安全退出

​ 检查客户端在退出时,是否向服务端发送终止会话请求。客户端退出后,还能否使用退出前的会话id访问登录后才能访问的页面。

4.10密码修改验证

​ 测试客户端在修改密码时是否验证旧密码正确性。

4.11Activity界面劫持

​ 安装Hi jackActivity.apk,使用activity 界面劫持工具,在工具中指定要劫持的应用进程名称。如图所示,从列表中选择被测试的应用,点击0K。打开应用,测试工具会尝试用自己的窗口覆盖被测的应用。

5.进程保护

5.1内存访问和修改

需要root权限,可以使用MemSpector查看、搜索和修改客户端内存数据,如图所示。用户名密码等数据通常会在/dev/ashmem/dalvik-heap内存段。(目前大多数工具都是通过ptrace接口修改客户端内存,可以使用ptrace机制本身防护。)

image-20200710114020175

5.2动态注入

​ 通过注入动态链接库,hook 客户端某些关键函数,从而获取敏感信息或者改变程序执行。检测 LD_PRELOAD 环境变量。使用 LD_PRELOAD 环境变量,可以让进程预先加载任意 so ,劫持函数。

6.通信安全

6.1通信加密

​ 如果客户端与服务器之间的通信加密协议实现不当,攻击者将有机会对当前网络环境中其他合法用户的通信内容进行窃听甚至篡改。

6.2证书有效性

​ 主要测试SSL协议安全性、SSL证书验证等。

6.3关键数据加密和校验

​ 测试客户端程序提交数据给服务端时,密码、收款人信息等关键字段是否进行了加密,防止恶意用户嗅探到用户数据包中的密码等敏感信息。

6.4访问控制

​ 测试客户端访问的URL是否仅能由手机客户端访问。是否可以绕过登录限制直接访问登录后才能访问的页面,对需要二次验证的页面(如私密问题验证),能否绕过验证。

6.5客户端更新安全性

​ 使用代理抓取检测更新的数据包,尝试将服务器返回的更新url替换为恶意链接。看客户端是否会直接打开此链接并下载应用。在应用下载完毕后,测试能否替换下载的apk 文件,测试客户端是否会安装替换后的应用。

6.6短信重放攻击

​ 检测应用中是否存在数据包重放攻击的安全问题。是否会对客户端用户造成短信轰炸的困扰。

7.业务安全

7.1越权操作

​ 服务器端对客户提出的数据操作请求过分信任,忽略了对该用户操作权限的判定,导致攻击账号拥有了其他账户的增删改查功能。

7.2交易篡改

​ 本项测试主要是修改金额信息(如:转帐金额为负值),订单信息(如:订单的数量)等

7.3重放攻击

​ 主要就是进行抓包重放(如:重放产品购买、订单创造等)测试。

7.4用户枚举

​ 此类漏洞情境一般是:登录界面无验证码、有明显的返回信息(如:该账号不存在、密码错误等)

7.5暴力破解

​ 主要是测试业务中查询、登录等功能,尝试使用暴力枚举的方式进行破解。

7.6注入/XSS/CSRF

​ 和WEB测试类似,主要测试站点存在的常见的web漏洞。

0%