通过辉哥发的 “APP安全检测指南–作者:panda” 跟进学习app渗透测试。
1.客户端程序安全
1.1安装包签名
用JDK的jarsigner.exe检查安全包的签名,命令:
1 | jarsigner.exe -verify APK文件路径 -verbose -certs |
以某个算命app为例,结果如下:
如上图,测试结果为安全。只有使用直接客户的证书签名时才认定为安全,Debug 证书、第三方(如开发方)证书等均认为风险。
1.2反编译保护
把apk当做zip解压,得到classes.dex文件(可能不止一个 .dex 文件),解压后如下:
使用dex2.jar执行如下命令:
1 | dex2jar.bat classes.dex 文件路径 |
得到classes.dex.jar文件
使用jd-gui打开jar文件,可得到JAVA代码
如上图,逆向后发现代码未做混淆,是不安全的。
下图为混淆后的代码,函数和变量名用无意义的字符来代替:
通过博客得知混淆的原理:android平台的混淆原理是用“不能直接猜出含义 的通用变量名和函数名a b c等”替换编译后程序包中“ 具有明显语义信息 的变量名和函数名”,这样,通过逆向工程得到的只是 难以理解 的代码。代码混淆并不能从根本上阻止反编译等。因为代码混淆仅仅提高了阅读难度,但并不能真正阻止反编译。
1.3应用完整性校验
用apktool将目标apk文件解包,命令如下:
1 | java -jar apktool.jar d -f apk文件路径 -o 解包目标文件夹 |
文件结构如下:
通过修改解包目录中的文件,可以找到logo之类的图进行修改(比较好辨认结果),我修改了咨询处的图片,如下:
用apktool,把解包目录重新打包成未签名的apk文件,命令如下:
1 | java -jar apktool.jar b -f 待打包的文件夹 -o 输出apk目录 |
重新打包的时候出现很多问题,具体百度加玄学解决了
成功输出apk文件
用SignApk,对未签名的APK文件进行签名,命令如下:
1 | java -jar signapk.jar testkey.x509.pem testkey.pk8 待签名apk文件路径 签名后输出apk路径 |
输出签名后的apk
将签了名的APK安装、运行、确认是否存在自校验;需要注意的是,如果之前安装的APK和修改后的APK签名不同,就不能直接覆盖安装,一般来说,先卸载之前安装的APP即可。
将客户端程序文件反编译,修改源码或资源文件后重新打包安装运行,结果如下图:
之前为咨询图片的位置,我换成了另一张图片。经测试,此某算命app是可以被重新打包运行的。
如果是经过自校验后的情况,修改源码资源后是无法正常启动的。
1.4组件安全
方案一:
使用apktool解包,打开解包目录中的AndroidManifest.xml,对其中声明的各个组件,根据以下规则判断是否可导出:
1 | 1.显式声明了android:exported="true",则可导出; |
从测试的角度上,只能判断组件是否导出,但能否构成危害需要详细分析源代码后才能得出结论。一般来说,在测试时尽管写清所有的导出组件,由客户开发侧确认相关组件是否确实需要导出即可。
启动Activity和Content Provider大多是导出组件,一般无须理会。
方案二:
检查 AndroidManifest.xml 文件中各组件定义标签的安全属性是否设置恰当。如果组件无须跨进程交互,则不应设置 exported 属性为 true。例如,如下图所示,当 com.umeng.message.XiaomiIntentService 的 exported属性为 true 时,将可以被其他应用调用。(当有设置权限(permissions)时,需要再考察权限属性。如 android:protectionLevel 为 signature 或 signatureOrSystem 时,只有相同签名的 apk才能获取权限。详情见附录参考资料API Guides 系统权限简介 )
当发现有可利用的组件导出时,(当然,并不是说所有导出的组件都是不安全的,如果要确定,必须看代码,对代码逻辑进行分析)可利用drozer测试工具进行测试。
1 | drozer安装:https://www.jianshu.com/p/4ef5b26dd3fb |
2.敏感信息安全
2.1数据文件
首先查看相关文件的权限配置,正常的文件权限最后三位应为空(类似”rw-rw—-“),即除应用自己以外任何人无法读写;目录则允许多一个执行位(类似“rwxrwx—x”)。如下图:
权限检测完整后,再检查客户端程序存储在手机中的 SharedPreferences 配置文件,通常是对本目录下的文件内容(一般是xml)进行检查,看是否包含敏感信息。最后在检测SQLite 数据库文件,在私有目录及其子目录下查找以.db 结尾的数据库文件。对于使用了 webView 缓存的应用,会在 databases 子目录中保存 webview.db 和 webviewCache.db。其中有可能会记录 cookies 和提交表单等信息。使用数据库查看工具即可查看这些文件中是否有敏感信息。
还有些时候,客户端程序 apk 包中也是是保存有敏感信息的,比如检查 apk 包中各类文件是否包含硬编码的的敏感信息等。
2.2Logcat日志
通过adb 工具连接设备:
1 | adb devices //查看安卓设备列表 |
然后使用 WinHex 打开,查看内存遗留信息。
也可以直接用adb查询locat日志:
在adb shell中,有下列命令可用:
1 | logcat //持续输出日志,直到Ctrl+C |
3.密码安全
3.1键盘劫持
通常来说,只有使用系统输入法的编辑框才能够进行键盘码记录。如果是自制的软键盘,则可以尝试进行触摸屏记录。像下图这样,不使用系统输入法,且按键随机分布的软键盘是安全的。
3.2随机布局软件盘
当客户端软键盘未进行随机化处理时为低风险;当客户端软键盘只在某一个页面载入时初始化一次而不是在点击输入框时重新进行随机化也为低风险。
3.3屏幕录像
使用ADB进行测试:
1 | adb shell /system/bin/screencap -p 输出png路径(安卓设备中) |
运行截图命令后,可以在 /mnt/sdcard/ 目录中查看到存在1.png
打开查看:
成功截图。
攻击者可以在用户进入登录页面,在输入密码的同时,进行连续截图,即可记录用户输入的密码。如果没有防截屏,那么即使是随机分布的、没有视觉反馈的软键盘也会被记录:
还有一种验证方式是从代码方面进行验证:首先检测需较高安全性的窗口(如密码输入框),看代码中在窗口加载时是否有类似下图的代码。按照 android SDK 的要求,开启 FLAG_SECURE 选项的窗口不能被截屏。
目前 FLAG_SECURE 测试结果:
1 | N-PASS,可截图, |
3.4手势密码
手势密码的复杂度:
1 | 1.进入客户端设置手势密码的页面进行手势密码设置。 |
手势密码的修改和取消:
1 | 1.进入客户端设置手势密码的位置,一般在个人设置或安全中心等地方。 |
手势密码的本地信息保存:
1 | 1.首先通过正常的操作流程设置一个手势密码并完整一次完整的登陆过程。 |
手势密码的锁定策略:
1 | 1.首先通过正常的操作流程设置一个手势密码。 |
手势密码的抗攻击测试:
1 | 1.下载并安装 Xposed 框架及 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机制本身防护。)
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漏洞。