:
- 错误地实施 isValidFragment:
检查存在漏洞的类是否包含或沿用了实施 isValidFragment 的方式(即在所有代码路径中返回 True)。如果确实是这样,请更新该类,以检查是否存在允许的 Fragment 类列表。例如:如果 PreferenceActivity 应该允许使用 MyFragment 类而不得使用其他 Fragment,请按照如下方式实施检查:
public boolean isValidFragment(String fragmentName) {
return MyFragment.class.getName().equals(fragmentName);
}
- targetSdkVersion 小于 19 并且未实施 isValidFragment:
如果应用目前在清单中将其 targetSdkVersion 设为小于 19 的值,并且存在漏洞的类不包含 isValidFragment 的任何实施方式,那么漏洞便来自于 PreferenceActivity。
注:由于Fragment可以加载APP内的任意未导出组件,因此Fragment注入漏洞可攻击面比较广
0x02 经典Setting Fragment Inject漏洞之绕过旧密码验证修改密码
首先我们来看一个经典的老洞,虽然现在没有了,但漏洞产生的原理,还是值得思考,而且修复的方式并不一定代表再新的版本中就不存在,这取决于开发人员的安全能力
Android 4.4之前版本的Fragment绕过PIN码攻击原理:
- 导出的PreferenceActivity的子类中,没有加入isValidFragment方法,进行fragment名的合法性校验,攻击者可能会通过设置Intent的extra,实现动态修改PreferenceActivity的初次显示的Fragment,来绕过限制,访问未授权的界面
攻击条件:
- Android 4.3及之前版本
- 有Activity继承PreferenceActivity类并且被声明成export=true
攻击面:
- 在Java中,当一个对象被构建的时候,这个类的静态构建函数和对象的构建函数都被执行,如果这两个函数包含特定的代码, 则可以触发攻击,由于构建出来的对象需要转换成Fragment对象,所以当产生的对象不是Fragment类型则会出异常
- 但是,如果这个对象刚好是一个Fragment类型时,PreferenceActivity能展现对应的界面,可以绕过某些验证而直接呼出对应的界面
手工检测:
- 反编译APK,检索到继承PreferenceActivity的子类,查看子类是否重写了isValidFragment方法,Activity是否对外暴露(exported)
相关知识:
- PreferenceActivity两个重要的Intent Extra
这两个参数可以决定当前的PreferenceActivity首次显示的Fragment