"In the Android platform, the binder is used for nearly everything that happens across processes in the core platform." html
–Dianne Hackborn,Googlejava
lkml.org/lkml/2009/6…android
Android Binder是知名女程序員Dianne Hackborn基於本身開發的OpenBinder從新實現的Android IPC機制,是Android裏最核心的機制。不一樣於Linux下的管道、共享內存、消息隊列、socket等,它是一套傳輸效率高、可操做性好、安全性高的Client-Server通訊機制。Android Binder經過/dev/binder驅動實現底層的進程間通訊,經過共享內存實現高性能,它的安全經過Binder Token來保證。git
Binder裏用到了代理模式(Proxy Pattern)、中介者模式(Mediator Pattern)、橋接模式(Bridge Pattern)。熟悉這些設計模式有助於更好的理解Binder機制。須要瞭解如下概念:Binder、Binder Object、Binder Protocol、IBinder interface、Binder Token、AIDL(Android interface definition language)、ServiceManager等。下圖大體描述了Binder從kernel層、中間件層到應用層中涉及的重要函數,本文漏洞利用部分會用到。程序員
讀者若是想深刻了解Binder,推薦閱讀:Android Binder Android Interprocess Communication。github
drozer是MWR實驗室開發的一套針對Android安全審計和攻擊利用的框架,相似於Metasploit。drozer由三部分組成:Console、Agent、Server。下圖左邊的部分爲Agent界面,運行在手機端,右邊的部分爲Console界面,運行在PC端。shell
Agent是一個只申請了internet權限的非特權App,它會開啓一個ServerSocket服務,默認監聽31415端口。Console連上Server以後就能夠控制Agent與Dalvik虛擬機、第三方App的IPC節點(intent)以及底層操做系統進行交互。爲何一個無特權的Agent應用能夠無縫與Dalvik虛擬機進行交互呢?設計模式
drozer使用了反射和動態類加載的技術。下圖右邊的部分是官方提供的drozer模塊的demo,能夠看到這麼一行,直接能夠new一個Java類對象實例,這裏內部實現就用到了Java反射機制。左邊的部分是drozer源碼的一個目錄,能夠看到有許多.java源文件和對應的APK文件,drozer使用了動態類加載機制,在運行相應模塊時,會將這個APK文件上傳到手機上Agent應用的緩存目錄,使用動態類加載機制調用類裏的Java函數。這個功能很實用,在本文第三部分還會涉及到這部分知識。緩存
關鍵代碼:安全
drozer有兩種模式:直連模式和基礎設施模式。Android應用安全審計用到最多的就是直連模式,手機端裝上Agent應用,經過USB鏈接電腦,Console端經過端口轉發後便可發送命令給Agent端的Embedded Server,來實現對Agent端的控制。
基礎設施模式多用在遠程攻擊利用上:以下圖你能夠手動設置Server的host和port,以及是否須要開啓密碼保護和SSL。
也能夠經過源碼編譯一個無launcher的惡意Agent,只須要下圖中一條命令。
編譯時能夠指定Agent回連的server IP 、port,而且能夠經過設置密碼來作身份鑑權,只有經過認證的用戶才能夠與該Agent創建session,所以很適合作Android遠控。能夠在一臺服務器上開啓drozer Server,以下圖所示命令。
當用戶中招(能夠經過社工、釣魚等手段誘導用戶下載安裝),Agent連上來以後,你可在以任意一臺電腦上經過Console連上Server來控制Agent。你能夠遠程下載安裝相應的攻擊插件,好比打電話、發短信、讀取聯繫人、上傳下載Sdcard文件等。開源的drozer-modules比較好用的有curesec、metall0id。這些功能在Android 4.3如下很好用,在高系統版本因爲各類安全機制的限制,致使許多攻擊功能沒法完成。
下圖展現了用戶中招後,經過遠程下載安裝drozer利用模塊,實現讀取用戶聯繫人、打電話、停止來電的功能:
drozer是模塊化的,可擴展。上文也提到了許多開源的drozer攻擊模塊。那麼如何寫一個本身的插件呢?
有兩個要素:
1.圖中顯示的這些元數據是必須的,哪怕是空。
2.execute()函數是核心,在這裏執行本身的邏輯。
fuzzing是安全人員用來自動化挖掘漏洞的一種技術,經過編寫fuzzer工具向目標程序提供某種形式的輸入並觀察其響應來發現問題,這種輸入能夠是徹底隨機的或精心構造的,使用邊界值附近的值對目標進行測試。爲何選擇drozer來作fuzzing框架呢?可擴展、易用是最大的緣由。下面簡單介紹我如何使用drozer對Android Binder進行fuzzing測試。
介紹兩種:fuzzing intent、fuzzing系統服務調用。
第一種fuzzing intent。這裏我介紹一種通用的方式,不依賴數據類型。這裏用到了15年初做者發現的通用型拒絕服務漏洞,能夠參考發佈在360博客上的技術文章Android通用型拒絕服務漏洞分析報告。簡單介紹下這個漏洞的原理:經過嚮應用導出組件傳遞一個序列化對象,而這個序列化對象在應用上下文中是不存在的,若是應用沒有作異常處理將會致使應用拒絕服務crash。而對Android系統中的一些高權限組件實施這樣的攻擊,將會致使Android系統拒絕服務重啓。 這個漏洞很暴力,可讓不少第三方手機廠商的系統拒絕服務,固然也包括Google原生系統。
第二種是fuzzing系統服務調用。我儘可能用你們容易理解的方式來簡單介紹這塊。Android中有不少系統服務,能夠經過adb shell service list這條shell命令列出來。以下圖,個人Nexus 5X 7.12系統能夠列出126個這樣的系統服務。[ ]裏是該服務對應的類接口。
這些接口裏定義了系統服務用到的函數,下圖列出的是lock_settings服務對應的接口類。接口裏的每個函數對應一個整型int值,咱們能夠對這些函數進行fuzzing,fuzzing其參數。
以下圖,咱們能夠基於shell命令進行fuzzing。舉例:adb shell service call lock_settings CODE i32 -1 ,其中CODE部分對應接口類中每個函數對應的數字,i32是第一個參數的類型,表明32位的整型。
前面提到drozer利用動態加載技術能夠加載一個apk文件執行,咱們能夠利用Java反射機制來肯定系統服務中函數的參數個數和類型,而後傳入相應類型的隨機或畸形數據,這些數據能夠經過Ramada生成。
上文也講到了如何寫一個drozer模塊,咱們只要在execute()函數中執行fuzzing邏輯便可。這裏提一下,由於drozer的模塊每次修改都須要從新經過module install MODULE_NAME命令進行安裝,這裏能夠把核心功能寫在drozer的Python模塊裏或者寫在Java文件裏,而後經過外部的Python腳原本自動化這個過程,控制fuzzing的邏輯,經過輸出每一個fuzzing數據的參數值以及logcat來定位引起漏洞的參數。要注意的是:不是隻有Crash纔是漏洞,有的漏洞就是正常的調用,並無Crash異常。我接下來分享的lock_settings服務漏洞就屬於這種類型。至此,你就能夠寫個本身的fuzzer進行自動化漏洞挖掘了。
最後,咱們再介紹幾種漏洞利用方法。
在Android開發中,可使用Android SDK tools基於AIDL文件自動生成Java語言的接口文件。讀者可自行了解更多關於AIDL相關知識。能夠參考:對安卓Bound Services的攻擊。
關鍵代碼:
和第一種利用方式相似,只是不須要根據AIDL文件生成Java接口文件,直接經過反射利用。
關鍵代碼:
須要將利用代碼放在Android系統源碼目錄進行編譯。參考BinderDemo。
關鍵代碼:
關鍵代碼:
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(command);
複製代碼
shell腳本內容舉例:
service call lock_settings 10 i32 0
複製代碼
2017年加入美團點評金融服務平臺。從事Android端應用安全和系統漏洞挖掘將近4年,積累了大量真實漏洞案例。後續擬分享Android應用安全系列技術文章,主要從漏洞利用場景、漏洞產生原理、漏洞案例、修復方案來展開,但願能幫助公司開發者提高安全意識,共同構建更加安全,更加健壯的應用軟件。