<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/4907

            0x00 科普


            一個Service是沒有界面且能長時間運行于后臺的應用組件.其它應用的組件可以啟動一個服務運行于后臺,即使用戶切換到另一個應用也會繼續運行.另外,一個組件可以綁定到一個service來進行交互,即使這個交互是進程間通訊也沒問題.例如,一個service可能處理網絡事物,播放音樂,執行文件I/O,或與一個內容提供者交互,所有這些都在后臺進行.

            0x01 知識要點


            生命周期

            左圖是startService()創建service,右圖是bindService()創建service。 startService與bindService都可以啟動Service,那么它們之間有什么區別呢?它們兩者的區別就是使Service的周期改變。由startService啟動的Service必須要有stopService來結束Service,不調用stopService則會造成Activity結束了而Service還運行著。bindService啟動的Service可以由unbindService來結束,也可以在Activity結束之后(onDestroy)自動結束。

            關鍵方法

            extends

            1. Service

              這是所有service的基類.當你派生這個類時,在service中創建一個新的線程來做所有的工作是十分重要的.因為這個service會默認使用你的應用的主線程(UI線程),這將拉低你的應用中所有運行的activity的性能

            2. IntentService

              這是一個Service的子類,使用一個工作線程來處理所有的啟動請求,一次處理一個.這是你不需你的service同時處理多個請求時的最好選擇.你所有要做的就是實現onHandleIntent(),這個方法接收每次啟動請求發來的intent,于是你可以做后臺的工作.

            表現形式

            1. Started

              一個service在某個應用組件(比如一個activity)調用startService()時就處于"started"狀態(注意,可能已經啟動了).一旦運行后,service可以在后臺無限期地運行,即使啟動它的組件銷毀了.通常地,一個startedservice執行一個單一的操作并且不會返回給調用者結果.例如,它可能通過網絡下載或上傳一個文件.當操作完成后,service自己就停止了

            2. Bound

              一個service在某個應用組件調用bindService()時就處于"bound"狀態.一個boundservice提供一個client-server接口以使組件可以與service交互,發送請求,獲取結果,甚至通過進程間通訊進行交叉進行這些交互.一個boundservice僅在有其它應用的組件綁定它時運行.多個應用組件可以同時綁定到一個service,但是當所有的自由競爭組件不再綁定時,service就銷毀了.

            Bound Service

            當創建一個提供綁定的service時,你必須提供一個客戶端用來與service交互的IBinder.有三種方式你可以定義這個接口:

            1. 從類Binder派生

              如果你的service是你自己應用的私有物,并且與客戶端運行于同一個進程中(一般都這樣),你應該通過從類Binder派生來創建你的接口并且從onBind()返回一它的實例.客戶端接收這個Binder然后使用它來直接操作所實現的Binder甚至Service的公共接口.

              當你的service僅僅是一個后臺工作并且僅服務于自己的應用時,這是最好的選擇.唯一使你不能以這種方式創建你的接口的理由就是你的service被其它應用使使用或者是跨進程的.

            2. 使用一個Messenger

              如果你需要你的接口跨進程工作,你可以為service創建一個帶有Messager的接口.在此方式下,service定義一個Handler來負責不同類型的Message對象.這個Handler是Messenger可以與客戶端共享一個IBinder的基礎,它允許客戶端使用Message對象發送命令給servic.客戶端可以定義一個自己的Messenger以使service可以回發消息.

              這是執行IPC的最簡單的方法,因為Messenger把所有的請求都放在隊列中依次送入一個線程中,所以你不必把你的service設計為線程安全的

            3. 使用AIDL

              AIDL(Android接口定義語言)執行把對象分解為操作系統能夠理解并能跨進程封送的基本體以執行IPC的所有的工作.上面所講的使用一個Messenger,實際上就是基于AIDL的.就像上面提到的,Messenger在一個線程中創建一個容納所有客戶端請求的隊列,使用service一個時刻只接收一個請求.然而,如果你想要你的service同時處理多個請求,那么你可以直接使用AIDL.在此情況下,你的service必須是多線程安全的.

              要直接使用AIDL,你必須創建一個.aidl文件,它定義了程序的接口.AndroidSDK工具使用這個文件來生成一個實現接口和處理IPC的抽象類,之后你在你的service內派生它.

              注:大多數應用不應使用AIDL來處理一個綁定的service,因為它可能要求有多線程能力并且導致實現變得更加復雜.同樣的,AIDL也不適合于大多數應用并且本文檔不會討論如何在你的service中使用它.如果你確定你需要直接使用AIDL,請看AIDL的文檔.

            注意

            如果你打算只在本應用內使用自己的service,那么你不需指定任何intent過濾器.不使用intent過濾器,你必須使用一個明確指定service的類名的intent來啟動你的service.

            另外,你也可以通過包含android:exported屬性,并指定其值為“false”來保證你的service是私有的.即使你的service使用了intent過濾器,也會起作用.

            當一個service被啟動后,它的生命期就不再依賴于啟動它的組件并且可以獨立運行于后臺,即使啟動它的組件死翹翹了.所以,service應該工作完成后調用stopSelf()自己停止掉,或者其它組件也可以調用stopService()停止service. 如果service沒有提供綁定功能,傳給startService()的intent是應用組件與service之間唯一的通訊方式.然而,如果你希望service回發一個結果,那么啟動這個service的客戶端可以創建一個用于廣播(使用getBroadcast())的PendingIntent然后放在intent中傳給service,service然后就可以使用廣播來回送結果.

            0x02 安全建議


            service分類

            私有service:不能被其他應用調用,相對安全
            公開service:可以被任意應用調用
            合作service:只能被信任合作公司的應用調用
            內部service:只能被內部應用調用
            

            intent-filter與exported組合建議

            總結:

            exported屬性明確定義
            私有service不定義intent-filter并且設置exported為false
            公開的service設置exported為true,intent-filter可以定義或者不定義
            內部/合作service設置exported為true,intent-filter不定義
            

            rule book

            1. 只被應用本身使用的service應設置為私有

            2. service接收到的數據需需謹慎處理

            3. 內部service需使用簽名級別的protectionLevel來判斷是否未內部應用調用

            4. 不應在service創建(onCreate方法被調用)的時候決定是否提供服務,應在onStartCommand/onBind/onHandleIntent等方法被調用的時候做判斷.

            5. 當service又返回數據的時候,因判斷數據接收app是否又信息泄露的風險

            6. 有明確的服務需調用時使用顯示意圖

            7. 盡量不發送敏感信息

            8. 合作service需對合作公司的app簽名做效驗

            0x03 測試方法


            1. service不像broadcast receicer只能靜態注冊,通過反編譯查看配置文件Androidmanifest.xml即可確定service,若有導出的service則進行下一步

            2. 方法查看service類,重點關注onCreate/onStarCommand/onHandleIntent方法

            3. 檢索所有類中startService/bindService方法及其傳遞的數據

            4. 根據業務情況編寫測試poc或者直接使用adb命令測試

            0x04 案例


            案例1:權限提升

            案例2:services劫持

            攻擊原理:隱式啟動services,當存在同名services,先安裝應用的services優先級高

            攻擊模型

            案例3:拒絕服務

            現在除了空指針異常crash外還多出了一類crash:intent傳入對象的時候,轉化出現異常.

            Serializable:

            Intent i = getIntent();                             if(i.getAction().equals("serializable_action"))
                {  
                    i.getSerializableExtra("serializable_key");//未做異常判斷
                }
            

            Parcelable:

            this.b =(RouterConfig)  this.getIntent().getParcelableExtra("filed_router_config");//引發轉型異常崩潰
            

            POC內傳入畸形數據即可引發crash,修復很簡單捕獲異常即可.

            案例4:消息偽造

            0x05 參考


            http://blog.csdn.net/niu_gao/article/details/7307462

            http://developer.android.com/reference/android/app/Service.html

            http://developer.android.com/guide/components/services.html

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线