ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 1 Fragment注入漏洞CVE-2013-6271检测 # 12001 系统版本小于Android 4.4(API level 19)存在该漏洞。 在API level < 19(即Android 4.4)的app,所有继承了PreferenceActivity类的activity并将该类置为exported的应用都受到Fragment注入漏洞的威胁。因为PreferenceActivity.isValidFragment函数的默认返回值为*true*,开发者不对该方法进行重写时不会报错。 Google在 Android 4.4 KitKat 里面修正了该问题,PreferenceActivity.isValidFragment函数的默认返回值为*false*,且要求用户重写该函数验证Fragment来源正确性,若不重写则会报错。 风险等级:`中危` 检测方式:`静态检测` 问题示例: 检测API Level小于19的app是否有导出activity继承自PreferenceActivity,如果存在则有注入漏洞。 我们查看一下`isValidFragment`的方法体,我们可以看到在Android 4.4版本前该方法的返回值是*true* ![isValidFragment](https://wiki-1252789527.picsh.myqcloud.com/scan_model/image085.jpg?imageMogr2/thumbnail/500x) 反编译成Smali代码 ![isValidFragment反编译代码](https://wiki-1252789527.picsh.myqcloud.com/scan_model/image087.jpg?imageMogr2/thumbnail/500x) 即 ![不知道啥的代码](https://wiki-1252789527.picsh.myqcloud.com/scan_model/image089.jpg) 建议: * 当Android api >=19时,要重写每一个PreferenceActivity类下的isValidFragment方法以避免异常抛出; * 当Android api < 19时,如果在PreferenceActivity内没有引用任何fragment,建议覆盖isValidFragment并返回false 查阅更多: * http://developer.android.google.cn/reference/android/os/Build.VERSION_CODES.html#KITKAT * http://developer.android.google.cn/reference/android/preference/PreferenceActivity.html#isValidFragment(java.lang.String) ## 2 SQLite数据库日志泄露漏洞(CVE-2011-3901)检测 # 12002 Android2.3.7版本存在该漏洞,其他版本可能也受到影响,4.0.1不受影响。 Android SQLite数据库journal文件可被所有应用程序读取,所有目录对应程序数据库目录拥有执行权限,意味着应用程序数据目录全局访问,`/data/data/<app package>/databases`目录以`[rwxrwx--x]`权限创建,可导致全局读写。数据库目录下创建的journal文件以`[-rw-r--r--]`权限创建,可被所有app读取。 风险等级:`低危` 检测方式:`静态检测` 通过检测app的AndroidManifest.xml文件中声明的min SDK版本进行判断。如果min sdk小于4.0.1(Android API Level 14),则判定有风险,否则安全。 建议: 升级到Android4.0.1以上版本或者使用SQLCipher或其他库加密数据库和日志信息。 ## 3 随机数生成漏洞 # 12003 SecureRandom的使用不当会导致生成的随机数可被预测,该漏洞存在于Android系统随机生成数字串安全密钥的环节中。该漏洞的生成原因是对SecureRandom类的不正确使用方式导致生成的随机数不随机。 **该漏洞存在于Android 4.2之前(即API < 17)**,在Android API 17以后SecureRandom的默认实现方式从Cipher.RSA换到了OpenSSL。SecureRandom新的实现方式不能将自己的seed替换掉系统的seed。 风险等级:`高危` 检测方式:`静态检测` 问题示例: 检测是否调用了SecureRandom(byte[]seed)或者setSeed(long seed)和setSeed(byte[]seed)方法。 ``` Ljava/security/SecureRandom;-><init>([B)V Ljava/security/SecureRandom;->setSeed([B)V Ljava/security/SecureRandom;->setSeed(J)V ``` 例如: ``` SecureRandom secureRandom = new SecureRandom(); byte[] b = new byte[] { (byte) 1 }; secureRandom.setSeed(b); // 对于Android 4.2版本Test1和Test2会返回相同的值 Log.v("wgc","-------------------------------"); Log.v("wgc","Test1:" + secureRandom.nextInt()); SecureRandom secureRandom2 = new SecureRandom(new byte[] { (byte) 1 }); Log.v("wgc","Test2:" + secureRandom2.nextInt()); SecureRandom secureRandom3 = new SecureRandom(); secureRandom3.setSeed(10L); Log.v("wgc","Test3:" + secureRandom3.nextInt()); SecureRandom secureRandom4 = new SecureRandom(); secureRandom4.nextBytes(b); secureRandom4.setSeed(10L); Log.v("wgc","Test4:" + secureRandom4.nextInt()); SecureRandom secureRandom5 = new SecureRandom(); Log.v("wgc","Test5:" + secureRandom5.nextInt()); ``` 打印的日志信息见下图: ![随机数漏洞-代码示例运行的结果](https://wiki-1252789527.picsh.myqcloud.com/scan_model/image092.jpg?imageMogr2/thumbnail/400x) 可见,Test1和Test2使用了相同的自定义种子,替换掉了系统默认的种子,导致随机数的产生结果相同,而Test3使用了自定义、固定的种子,则会产生固定的结果。只有方法4和方法5才真正做到了随机值,Test4在调用setSeed()方法前先调用了一次nextBytes()方法,而Test5则使用默认的参数进行随机数的生成。 建议: * 不要使用自定义随机源代替系统默认随机源(推荐)除非有特殊需求,在使用SecureRandom类时,不要调用以下函数:SecureRandom类下SecureRandom(byte[]seed)、setSeed(long seed)和setSeed(byte[]seed)方法。 * 在调用setSeed方法前先调用任意nextXXX方法。具体做法是调用setSeed方法前先调用一次SecureRandom的nextBytes(byte[]bytes)方法,可以避免默认随机源被替代,详细见参考资料。 查阅更多: * https://developer.android.google.cn/reference/java/security/SecureRandom.html