Android系統是基於Linux核心開發的,因此,Android系統不僅保留和繼承了Linux作業系統的安全機制,而且其系統架構的各個層次都有獨特的安全特性[2] 。
1. Linux核心層安全機制
Android的Linux核心包含了強制存取控制機制和自主存取控制機制。強制存取控制機制由Linux安全模組來實現,但Google出於某種原因,並沒有將LSM編譯進Android核心。自主存取控制機制通常由檔案存取控制來實現,Linux檔案系統的許可權控制是由user、group、other與讀(r) 、寫(w) 、執行(x)的不同組合來實現的。這樣,每個檔案都有三個基本許可權集,它們的組合可以容許、限制、拒絕使用者、使用者組和其他使用者的訪問。通常,只有uid是“system”或“root”使用者才擁有Android系統檔案的存取權限,而應用程式只有通過申請Android許可權才能實現對相應檔案的訪問,也正因為此,Android使用核心層Linux的自主存取控制機制和運行時的Dalvik虛擬機器來實現Android的“沙箱”機制。
2. Android的“沙箱”機制
Android“沙箱”的本質是為了實現不同應用程式和進程之間的互相隔離,即在預設情況下,應用程式沒有許可權訪問系統資源或其它應用程式的資源。每個APP和系統進程都被分配唯一併且固定的User Id,這個uid與核心層進程的uid對應。每個APP在各自獨立的Dalvik虛擬機器中運行,擁有獨立的地址空間和資源。運行於Dalvik虛擬機器中的進程必須依託核心層Linux進程而存在,因此Android使用Dalvik虛擬機器和Linux的檔案存取控制來實現沙箱機制,任何應用程式如果想要訪問系統資源或者其它應用程式的資源必須在自己的manifest[23]檔案中進行聲明許可權或者共用uid。
3. Android的許可權檢查機制
Android是一個“許可權分離”的系統,任何一個應用程式在使用Android受限資源(網路、電話、簡訊、藍芽、通訊錄、SdCard等)之前都必須以XML檔案的形式事先向Android系統提出申請,等待Android系統批准後應用程式方可使用相應的資源,許可權與Java的API是多對多的映射關係。
當Android應用程式獲得相應許可權後,它就能通過調用API來完成相應的功能。一個API調用可被分為三個步驟[3]:第一,應用程式擷取相應許可權後會調用公用庫中的API;第二,公用API會調用一個叫API代理的介面(RPC stub);第三,RPCstub把請求以IPC綁定的形式傳遞給系統服務,由系統服務進程完成具體的功能,許可權檢查恰恰發生在對系統服務和系統進程中。許可權檢查不僅包括安裝時的靜態檢查,還包括APP運行時的動態檢查。動態檢查是指APP在運行期間調用的系統服務或系統組件需要經過授權檢查。動態檢查並不發生在APP本身,而是發生在系統服務或系統組件的進程中。在Android4.0版本之前,Android的許可權檢查機制是可以被繞過的,這是因為許可權檢查機制存在漏洞,即調用者不需要具有被調用者的相關許可權,Android4.0版本不僅使用函數“checkUidPermission”來決定許可權是否應授予相應的進程而且使用了函數“checkCallingPermission”來檢查調用者是否有相應的許可權。因此,Android許可權機制一般不能被繞過,但Android許可權機制有些不容忽視的缺陷,具體表現在如下幾個方面:
第一,許可權一經授予應用程式,那麼此許可權在該應用程式生命期間都將有效,使用者無法剝奪許可權;
第二,許可權機制缺乏靈活性,要麼全都批准應用程式所要求的所有許可權,要麼拒絕應用程式的安裝;
第三,許可權機制安全性不夠,不能阻止惡意軟體通過JNI技術直接調用C庫,從而擷取系統服務。
4. Android的數位簽章機制
所有安裝到Android系統中的應用程式都必須擁有一個數位憑證[4],此數位憑證用於標識應用程式的作者和應用程式之間的信任關係。Android系統不會安裝一個沒有數位憑證的應用程式,如果一個許可權的保護層級為signature,只有當應用程式所用數位簽章與聲明此許可權的應用程式所用數位簽章相同時,Android系統才會授權。如果一個許可權的保護層級為signatureOrSystem,Android系統會將該許可權授予具有相同數位簽章的應用程式或Android包類。