前言:
安全策略在实际测试中受限较多,因此建议的风险等级:安全策略类全部为低危
强行有图.jpg1.1 密码复杂度检测:
测试客户端程序是否检查用户输入的密码强度,禁止用户设置弱口令
测试流程:
手工测试,尝试将密码修改为弱口令,如:123456,888888 等,查看客户端是否拒绝弱口令。
也可以阅读逆向后的客户端 java 代码,寻找对用户输入口令的检查方法
安全建议:
当系统允许用户设置弱密钥时为低风险,如果存在系统存在一定的安全策略(密码使用数字和字母组成,至少为 8 位)时无风险。
1.2 账号登录限制:
测试一个帐号是否可以同时在多个设备上成功登录客户端,进行操作。
安全建议:
禁止同一个账号可以同时在多台移动终端设备上登陆。
1.3 账户锁定策略:
测试客户端是否限制登录尝试次数。防止木马使用穷举法暴力破解用户密码
安全建议:
设定账户锁定策略。
1.4 私密问题验证:
测试对账号某些信息(如单次支付限额)的修改是否有私密问题验证。
私密问题验证是否将问题和答案一一对应。
私密问题是否足够私密
威胁等级:
对于敏感功能操作时,要进行私密问题验证。比如当用户进行忘记密码操作时,在发送邮件给用户邮箱前是否进行私密问题的验证,若验证则无风险;若不验证则低风险
1.5 会话安全:
测试客户端在超过 20 分钟无操作后,是否会使会话超时并要求重新登录。超时时间设置是否合理
测试步骤:
一段时间无操作 ==> 检测应用是否要求用户重新登陆并退出应用 ==> 检测应用是否要求用户登陆。
1.6 界面切换保护:
检查客户端程序在切换到其他应用时,已经填写的账号密码等敏感信息是否会清空,防止用户敏感信息泄露。如果切换前处于已登录状态,切换后一定时间内是否会自动退出当前会话。
测试步骤:
在登录界面(或者转账界面等涉及密码的功能)填写登录名和密码,然后切出,再进入客户端,看输入的登录名和密码是否清除。登录后切出,5 分钟内自动退出为安全。
安全建议:
对于画面切换进行提示或者验证
1.7 UI 信息泄露:
检查客户端的各种功能,看是否存在敏感信息泄露问题。
测试步骤:
使用错误的登录名或密码登录,看客户端提示是否不同
查看 APP 各界面,检测是否对用户的真实姓名、身份证号、银行卡号、手机号等进行适当遮挡
1.8 验证码安全:
测试客户端在登录和交易时是否使用图形验证码
验证码是否符合如下要求:
由数字和字母等字符混合组成;
采取图片底纹干扰、颜色变换、设置非连续性及旋转图片字体、变异字体显示样式等有效方式,防范恶意代码自动识别图片上的信息;
具有使用时间限制并仅能使用一次;
验证码由服务器生成,客户端文件中不包含图形验证码文本内容
观察验证码组成,若发现验证码易识别,可以尝试使用 PKAVHttpFuzzer 的验证码识别工具进行识别,这款工具我已经比较熟悉了就不作演示了
这次我用下面这款验证码识别工具演示:
1、输入验证码地址后,添加滤镜,确保处理后的图像形如下图:
2、添加字模,自动分隔后要保证只能识别出验证码字模,其余的都排除掉:
3、不停地点击:下载图像
+ 添加字模
,并将每个字模对应的字符填上
4、保存退出后,进行验证码识别:
威胁等级:
当图形验证码由本地生成而不是从服务器获取时为中风险;当验证码安全性低或不存在验证码时为中风险;不存在以上两个问题时无风险。
安全建议:
加强验证码的识别难度,对于验证码的验证做到“一次一验”
1.9 安全退出:
测试客户端退出时是否正常终止会话
检查客户端在退出时,是否向服务端发送终止会话请求。
测试步骤:
在客户端登出账号之后,继续使用之前的会话 token 进行操作,检测用户登出后会话 token 是否在服务端被正确销毁
威胁等级:
若客户端退出登录时不会和服务器进行 Logout 的相关通信则为中风险,否则无风险。
安全建议:
客户端退出时要做到和服务器进行 Logout 的相关通信
1.10 密码修改验证:
尝试在修改密码时使用错误的旧密码,检测服务端是否验证旧密码的正确性
威胁等级:
当进行密码修改时是否要求输入原密码已验证其正确性,若需要输入则无风险;如不需输入原密码则中风险。
1.11 Activity 界面劫持:
检查是否存在 activity 劫持风险,确认客户端是否能够发现并提示用户存在劫持
这里先介绍一下activity劫持:
安卓应用的界面是一层一层的,后启动的应用会在栈顶,显示在最前面,而恶意apk可以不停枚举进程是否存在要劫持的目标进程。如果发现了目标进程,就将自己的欺骗页面启动。如果目标apk未对界面劫持进行反劫持检测,那么用户就会受到欺骗攻击;
假设存在这样一个情景:
一个恶意应用在用户启动银行app时,启动自身界面,模拟成银行的登录界面,那么在用户没有察觉的情况下,可以直接偷走用户输入的账号密码。
项目地址:https://github.com/aloswoya/android_app
测试流程:
直接使用一个测试的apk对目标应用进行界面覆盖,观察目标应用是否进行了报警
我们先随便打开一个app,进入到登录页面:
利用drozer打开恶意劫持apk:
run app.activity.start --component com.test.uihijack com.test.uihijack.MainActivity
emmmm,没有报警信息,好想提交SRC可多半不收。。。。
从源代码层面分析:
利用工具逆向、扫描源代码进行分析,查看代码在关键位置是否进行了一些报警,如toast
威胁等级:
若客户端无法抵抗 Activity 界面劫持攻击时为中风险;若可以抵抗攻击则无风险。
安全建议:
Activity 劫持通常依靠注册 Receiver 响应 android.intent.action.BOOT_COMPLETED事件。
1、客户端程序可以在启动前检查 Receiver 并报警;
2、判断当前应用程序是否位于栈顶 (是否显示在前面),如果在后台了,就进行一些如toast提示、震动、通知弹窗等等,告诉用于当前应用已经在后台运行了
3、在界面切换到后台时弹出警告信息
4、建议开发客户端时针对进程栈进行相应的保护,可禁止其他进程放置于客户端之上
1.12 弱加密算法审查:
反编译工具进行反编译后,查找代码中的敏感数据和敏感函数
使用 DES 弱加密算法,弱加密代码样例:
SecretKeySpec key = new SecretKeySpec(rawKeyData, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
审查代码中以下几点:
- 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);
- 没有安全的初始化向量:
初始化向量时,使用了硬编码到程序的常量.
风险代码样例:
byte[] iv = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
IvParameterSpec ips = new IvParameterSpec(iv)
- 使用了不安全的加密模式:
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
- 使用了不安全的密钥长度:
public static KeyPair getRSAKey() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512);
KeyPair key = keyGen.generateKeyPair();
return key;
}
1.13 应用权限测试:
检查申请应用权限是否大于业务需要权限,有即存在安全隐患
直接用MobSF静态检测即可,没啥好说的
参考如下:
安卓activity劫持测试工具开发
Android APP渗透测试方法大全.pdf
App安全检测指南-V1.0.pdf
网友评论