[color=rgb(51, 51, 51) !important]硬件平臺:飛凌嵌入式 OKT507-C開發板 [color=rgb(51, 51, 51) !important]操作系統:Android10.0 [color=rgb(51, 51, 51) !important]飛凌嵌入式 T507 開發板 Android系統版本為Android10.0,默認開啟了SELinux。基于MAC訪問控制模型的SElinux,可以更好地保護我們的Android系統, 比如限制系統服務的訪問權限、控制應用對數據和系統日志的訪問等措施,這樣就降低了惡意軟件的影響,并且可以防止因代碼存在的缺陷而產生的對系統安全的影響。 [color=rgb(51, 51, 51) !important]從系統安全方面考慮,SELinux是保護神,但是從軟件開發方面,SELinux就是一道牽絆,這是一把雙刃劍。 [color=rgb(51, 51, 51) !important]比如我們開發應用或者增加系統服務的某些權限的時候,我們必須遵循SELinux的規則,給我們的應用設置對應的安全策略,否則我們的應用就不具備訪問數據或者設備的權限。下面我們MAC訪問控制模型開始,簡單的梳理一下飛凌嵌入式 T507 開發板 Android的安全策略,以及自定義飛凌嵌入式 T507 開發板Android安全策略的方法。 訪問控制模型DAC,MAC[color=rgb(51, 51, 51) !important]訪問控制是指控制對計算機或者網絡中某個資源的訪問。沒有它,所有人都可以訪問任何資源。有了訪問控制,用戶在獲取實際訪問資源或進行操作之前,必須通過識別、驗證、授權。 [color=rgb(51, 51, 51) !important]自主訪問控制(DAC: Discretionary Access Control)系統識別用戶,根據被操作對象的權限的設置,來決定該用戶對其擁有的操作權限,read、write、exec。擁有這個對象權限的用戶,又可以將該權限分配給其他用戶,此謂之“Discretionary”。缺陷就是對權限控制比較分散,不便于管理,比如無法簡單地將一組文件設置統一的權限開放給指定的一群用戶。 [color=rgb(51, 51, 51) !important]強制訪問控制(MAC: Mandatory Access Control)MAC是為了彌補DAC權限控制過于分散的問題而誕生的。在MAC這種模型里,管理員管理訪問控制。管理員制定策略,用戶不能改變它。策略定義了哪個主體能訪問哪個對象。這種訪問控制模型可以增加安全級別,因為它基于策略,任何沒有被顯式授權的操作都不能執行。MAC被開發和實現在最重視保密的系統中,如軍事系統。主體獲得清楚的標記,對象得到分類標記,或稱安全級別。 基于MAC的SElinux[color=rgb(51, 51, 51) !important]參考鏈接:https://source.android.google.cn/security/selinux [color=rgb(51, 51, 51) !important]軟件通常情況下必須以 Root 用戶帳號的身份運行,才能向原始塊設備寫入數據。在基于 DAC 的傳統 Linux 環境中,如果 Root 用戶遭到入侵,攻擊者便可以利用該用戶身份向每個原始塊設備寫入數據。從 Android 4.3 起,SELinux 開始為傳統的自主訪問控制 (DAC) 環境提供強制訪問控制 (MAC) 保護功能。作為 Android 安全模型的一部分,Android 使用安全增強型 Linux (SELinux) 對所有進程強制執行強制訪問控制 (MAC),甚至包括以 Root/超級用戶權限運行的進程(Linux 功能)。例如,可以使用 SELinux 為這些設備添加標簽,以便被分配了 Root 權限的進程只能向相關政策中指定的設備寫入數據。這樣一來,該進程便無法重寫特定原始塊設備之外的數據和系統設置。借助 SELinux,Android 可以更好地保護和限制系統服務、控制對應用數據和系統日志的訪問、降低惡意軟件的影響,并保護用戶免遭移動設備上的代碼可能存在的缺陷的影響。 [color=rgb(51, 51, 51) !important]飛凌嵌入式 T507 開發板Android系統版本為Android10,SELinux默認開啟,即使獲得了該系統的root權限,也只能向相關策略中指定的設備寫入數據,從而更好地保護和限制系統服務,保障系統和數據的安全。 標簽、規則和域[color=rgb(51, 51, 51) !important]SELinux 依靠標簽來匹配操作和策略。標簽用于決定允許的事項。套接字、文件和進程在 SELinux 中都有標簽。SELinux 在做決定時需參照兩點:一是為這些對象分配的標簽,二是定義這些對象如何交互的策略。 [color=rgb(51, 51, 51) !important]在 SELinux 中,標簽采用以下形式:user:role:type:mls_level,其中 type 是訪問決定的主要組成部分,可通過構成標簽的其他組成部分進行修改。對象會映射到類,對每個類的不同訪問類型由權限表示。 [color=rgb(51, 51, 51) !important]策略規則采用以下形式:allow domains types:classes permissions;,其中: [color=rgb(51, 51, 51) !important]Domain - 一個進程或一組進程的標簽。也稱為域類型,因為它只是指進程的類型。 [color=rgb(51, 51, 51) !important]Type - 一個對象(例如,文件、套接字)或一組對象的標簽。 [color=rgb(51, 51, 51) !important]Class - 要訪問的對象(例如,文件、套接字)的類型。Permission - 要執行的操作(例如,讀取、寫入)。 策略配置源文件[color=rgb(51, 51, 51) !important]1、external/sepolicy [color=rgb(51, 51, 51) !important]這是獨立于設備的配置,一般不能針對設備進行修改 2、device///sepolicy [color=rgb(51, 51, 51) !important]這是特定于設備的配置,基于 BOARD_SEPOLICY_* 變量來選擇對應平臺的策略配置。 [color=rgb(51, 51, 51) !important]以飛凌嵌入式 T507 開發板為例,T507策略文件的路徑如下: [color=rgb(51, 51, 51) !important]OKT507-android-source/android$ ls device/softwinner/common/sepolicy/private vendor Type Enforcement (TE) 配置文件[color=rgb(51, 51, 51) !important].te 文件中保存了對應對象的域和類型定義、規則。通常每個域一個 .te 文件,例如installd.te。在 device.te、file.te 中聲明了設備和文件類型。在某些文件(例如domain.te、app.te)中則存儲著共享規則。 [color=rgb(51, 51, 51) !important]以飛凌嵌入式 T507 開發板為例,T507 system_app的TE文件的路徑如下: [color=rgb(51, 51, 51) !important]device/softwinner/common/sepolicy/vendor/system_app.te 標簽配置文件[color=rgb(51, 51, 51) !important]1、file_contexts:文件安全上下文 [color=rgb(51, 51, 51) !important]2、property_contexts:屬性安全上下文 [color=rgb(51, 51, 51) !important]以飛凌嵌入式 T507 開發板為例,T507 安全上下文文件路徑如下: [color=rgb(51, 51, 51) !important]device/softwinner/common/sepolicy/vendor/property_contexts [color=rgb(51, 51, 51) !important]device/softwinner/common/sepolicy/vendor/file_contexts SEAndroid app分類[color=rgb(51, 51, 51) !important]SELinux(或SEAndroid)將app劃分為主要三種類型(根據user不同,也有其他的domain類型): [color=rgb(51, 51, 51) !important]1)untrusted_app 第三方app,沒有Android平臺簽名,沒有system權限 [color=rgb(51, 51, 51) !important]2)platform_app 有android平臺簽名,沒有system權限 [color=rgb(51, 51, 51) !important]3)system_app 有android平臺簽名和system權限 [color=rgb(51, 51, 51) !important]從上面劃分,權限等級,理論上:untrusted_app < platform_app < system_app APP的domain和type[color=rgb(51, 51, 51) !important]查看seapp_contexts文件,APP的domain和type由user和seinfo兩個參數決定 [color=rgb(51, 51, 51) !important]system/sepolicy/private/seapp_contexts [color=rgb(51, 51, 51) !important]isSystemServer=true domain=system_server_startup [color=rgb(51, 51, 51) !important]user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all [color=rgb(51, 51, 51) !important]user=system seinfo=platform domain=system_app type=system_app_data_file [color=rgb(51, 51, 51) !important]user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file [color=rgb(51, 51, 51) !important]user=network_stack seinfo=network_stack domain=network_stack levelFrom=all [color=rgb(51, 51, 51) !important]type=radio_data_file [color=rgb(51, 51, 51) !important]user=nfc seinfo=platform domain=nfc type=nfc_data_file [color=rgb(51, 51, 51) !important]user=secure_element seinfo=platform domain=secure_element levelFrom=all [color=rgb(51, 51, 51) !important]user=radio seinfo=platform domain=radio type=radio_data_file [color=rgb(51, 51, 51) !important]user=shared_relro domain=shared_relro [color=rgb(51, 51, 51) !important]user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file [color=rgb(51, 51, 51) !important]user=webview_zygote seinfo=webview_zygote domain=webview_zygote [color=rgb(51, 51, 51) !important]user=_isolated domain=isolated_app levelFrom=al [color=rgb(51, 51, 51) !important]luser=_app seinfo=app_zygote domain=app_zygote levelFrom=all [color=rgb(51, 51, 51) !important]user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file [color=rgb(51, 51, 51) !important]levelFrom=user [color=rgb(51, 51, 51) !important]user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user [color=rgb(51, 51, 51) !important]user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all [color=rgb(51, 51, 51) !important]user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user [color=rgb(51, 51, 51) !important]user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all [color=rgb(51, 51, 51) !important]user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all [color=rgb(51, 51, 51) !important]user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file [color=rgb(51, 51, 51) !important]levelFrom=user [color=rgb(51, 51, 51) !important]user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user [color=rgb(51, 51, 51) !important]user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all [color=rgb(51, 51, 51) !important]user=_app fromRunAs=true domain=runas_app levelFrom=user user[color=rgb(51, 51, 51) !important]參考鏈接:https://blog.csdn.net/huilin9960/article/details/81530568 [color=rgb(51, 51, 51) !important]user可以理解為UID。android的UID和linux的UID根本是兩回事,Linux的UID是用于針對多用戶操作系統中用于區分用戶的,而Android中的UID是用于系統進行權限管理的。參考鏈接中的文章對于uid的產生講的很清楚。 seinfo[color=rgb(51, 51, 51) !important]不同簽名會創建對應的selinux上下文。 [color=rgb(51, 51, 51) !important]Android.mk [color=rgb(51, 51, 51) !important]LOCAL_CERTIFICATE := platform [color=rgb(51, 51, 51) !important]有platform簽名,所以seinfo是platform。 LOCAL_CERTIFICATE作用[color=rgb(51, 51, 51) !important]參考文檔https://blog.csdn.net/hnlgzb/article/details/107823874 [color=rgb(51, 51, 51) !important]可以查看Android源碼build/target/product/security/ 目錄下提供的默認簽名文件,不同平臺可能會有差異:飛凌嵌入式 T507 開發板提供了media、networkstack、platform、shared、testkey、verity六種不同權限的簽名文件。 [color=rgb(51, 51, 51) !important]以飛凌嵌入式 T507 開發板為例,查看當前運行的應用信息: [color=rgb(51, 51, 51) !important]console:/ # ps -Z [color=rgb(51, 51, 51) !important]u:r:system_app:s0 system 15712 1861 1050628 110868 SyS_epoll_wait [color=rgb(51, 51, 51) !important]0 S forlinx.example.app [color=rgb(51, 51, 51) !important]u:r:untrusted_app_27:s0:c512,c768 u0_a62 30259 1861 1052120 114132 SyS_epoll_wait [color=rgb(51, 51, 51) !important]0 S com.forlinx.changelogo [color=rgb(51, 51, 51) !important]當前運行的兩個APP,forlinx.example.app的UID(user)是system,擁有platform簽名,它的domain和type就是system_app。 [color=rgb(51, 51, 51) !important]com.forlinx.changelogo沒有設置UID使用的默認設置,其UID為u0_a62,并且沒有設置簽名文件,它的domain和type就是untrusted_app。 T507自定義安全策略[color=rgb(51, 51, 51) !important]以上面兩個運行的app來說,我們為這兩個APP添加額外的權限,對應的TE配置文件分別就是system_app.te、untrusted_app.te,對應路徑為: [color=rgb(51, 51, 51) !important]device/softwinner/common/sepolicy/vendor/system_app.te [color=rgb(51, 51, 51) !important]device/softwinner/common/sepolicy/vendor/untrusted_app.te [color=rgb(51, 51, 51) !important]以forlinx.example.app為例,我們為其添加can設備的執行權限: [color=rgb(51, 51, 51) !important]OKT507-android-source/android$ vi device/softwinner/common/sepolicy/vendor/system_app.te [color=rgb(51, 51, 51) !important]... [color=rgb(51, 51, 51) !important]allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans }; [color=rgb(51, 51, 51) !important]allow system_app shell_exec:file { getattr open read execute execute_no_trans }; [color=rgb(51, 51, 51) !important]allow system_app shell:file { getattr open read execute execute_no_trans }; [color=rgb(51, 51, 51) !important]... [color=rgb(51, 51, 51) !important]以策略規則配置形式(allow domains types:classes permissions) [color=rgb(51, 51, 51) !important]分析:domains:system_app [color=rgb(51, 51, 51) !important]types:vendor_shell_exec [color=rgb(51, 51, 51) !important]classes:file [color=rgb(51, 51, 51) !important]permissions:getattr open read execute execute_no_trans neverallow failures[color=rgb(51, 51, 51) !important]有時我們增加的權限,系統默認的配置是不允許的,比如我們上面給forlinx.example.app增加的執行腳本的權限,報錯如下: [color=rgb(51, 51, 51) !important]libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te [color=rgb(51, 51, 51) !important](or line 41463 of policy.conf) violated by allow system_app shell:file { read open }; [color=rgb(51, 51, 51) !important]libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te [color=rgb(51, 51, 51) !important](or line 40025 of policy.conf) violated by allow system_app shell:file { read open }; [color=rgb(51, 51, 51) !important]libsepol.check_assertions: 2 neverallow failures occurred [color=rgb(51, 51, 51) !important]系統默認的安全策略的路徑為system/sepolicy/,根據報錯的提示,我們可以修改默認的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,從而完成權限的賦予。 [color=rgb(51, 51, 51) !important]以上就是Android 安全策略的脈絡,以及飛凌嵌入式 T507 開發板Android系統下自定義安全策略的方法了。 [color=rgb(51, 51, 51) !important]原文鏈接:https://www.forlinx.com/article_view_792.html |