詳解 SEAndroid 以及 Hack 其規則(sepolicy)
之前在搞Xposed的時候遇到一個問題是Xposed的解除安裝原本需要root許可權,但是Xposed的原理是hack了zygote這個程序(xposed原理以後有時間再寫),而zygote本身是有root許可權的,所以Xposed應該是可以利用zygote的root許可權來解除安裝自身。但是實際操作中發現並不可以。經過一番研究發現這是由於SEAndroid的緣故,zygote的一些操作會被SEAndroid限制,它的root許可權並不是為所欲為的。下面就要詳細的談一下SEAndroid這個東西,然後再談一談如何去更改這個規則。
本文章有三個目的:
1.理解SEAndorid的工作原理
2.能夠看懂SEAndroid的規則
3.能夠自己增添刪改其規則(這一條估計大多數人都用不到,所以前兩條是主要目的)
1. SEAndroid 概念
SEAndroid 是SELinux 在Android 上面的一個移植。SELinux 是Linux上系統保護機制,SELinux 全稱 Security Enhanced Linux (安全強化 Linux),是MAC (Mandatory Access Control,強制訪問控制系統)的一個實現。其目的在於明確的指明某個程序可以訪問哪些資源(檔案、網路埠等)。Android系統基於Linux實現。針對傳統Linux系統,NSA開發了一套安全機制SELinux,用來加強安全性。然而,由於Android系 統有著獨特的使用者空間執行時,因此SELinux不能完全適用於Android系統。為此,NSA同Google一起針對Android系統,在SELinux基礎上開發了 SEAndroid。
Android 4.4首次引入了這一機制,SEAndroid與SELinux最大的不同在於SEAndroid對Android系統中的Binder做來了適配。進入adb shell 之後可以通過getenforce命令來檢視其是否應用。root之後可以通過setenforce 0關閉SEAndroid。但是目前好像關閉了這一功能。

檢視SEAndroid是否開啟
理解SEAndorid的概念不得不提到DAC 和 MAC。
1.1 DAC (Discretionary Access Control,自主訪問控制)
DAC是傳統的Linux的訪問控制方式,DAC可以對檔案、資料夾、共享資源等進行訪問控制。 在DAC這種模型中,檔案客體的所有者(或者管理員)負責管理訪問控制。DAC使用了ACL(Access Control List,訪問控制列表)來給非管理者使用者提供不同的許可權,而root使用者對檔案系統有完全自由的控制權。
通俗的說就是,小明如果建立的某個檔案他就對這個檔案擁有絕對的控制權,他能夠自主的控制其他人對該檔案的許可權。一個檔案許可權有讀(r)寫(w)執行(x)三種。我們可以通過ls -l 這個命令看到各個檔案的許可權情況。然後通過 chmod 這個命令可以指定這個其他人對這個檔案的許可權。(chmod 777 1.txt 這個命令大家應該都明白就不細說了)

但是這個機制有個不好的地方就是root使用者可以控制任意檔案的許可權,可以為所欲為。而且控制粒度較粗,如果我只想讓另一個人讀我的檔案,而這個人跟我不是同一使用者組,我只能通過chmod XX4 XX 才能達到這一目的,但是這樣的話其他任何人都可以讀我的檔案。所以說它粒度比較粗。
1.2 MAC (Mandatory Access Control,強制訪問控制)
所以Linux就引入了MAC機制,即強制控制訪問。 MAC核心思想 : 即任何程序想在SELinux系統中幹任何事情,都必須先在安全策略配置檔案中賦予許可權。凡是沒有出現在安全策略配置檔案中的許可權,程序就沒有該許可權。這個機制相當於一個白名單,這個白名單上配置了所有程序的許可權,程序只能做白名單上許可權內的事情,一旦它想做一個不屬於它許可權的操作就會被拒絕。
MAC不再像DAC一樣簡單的把程序分為root others等,而是每個程序(Subject,主體)和檔案(Object,客體)都配置了一個型別(Type),當一個程序去操控(讀寫等)一個檔案時,系統會檢測該程序型別是否有對該檔案型別的操作許可權。
通過命令ps -Z 可以檢視程序的安全label,ls -Z 可以看到檔案的label(安全上下文)。

程序

檔案
比如程序安全上下文中的init程序,他的type為init,下面的程序的type為kernel。( 其實程序的type也被稱為Domain )
檔案安全上下文中的 123.txt 的 type為 tootfs。
(程序和檔案安全上下文label格式為 user:role: type :security_level 中的其它幾列不用管。這個涉及到SELinux中其它幾種訪問控制模型,在SEAndroid中我們只用關心他的type就好,比如init程序的 u:r: init: s0,我們只用知道他的type為init。)
知道程序和檔案的安全上下文,那具體是怎麼通過他們的安全上下文來控制權限的呢?
在手機上有個檔案叫做sepolicy,這個檔案就是SEAndroid的安全策略配置檔案,裡面有所有程序的許可權配置,程序只能進行它的許可權規定內的操作。這個檔案就有root許可權也刪不掉。把這個檔案的內容dump出來後會發現裡面有好多條規則(我逆過魅族的4000條,三星的20000條)。看兩條例子。
allow untrusted_app system_app_data_file : file { read }
allow zygote sdcard_type : file { read write creat rename }
它的具體格式為: allow Domain Type : Class { Permission } (Domain 是指程序的type)
通過這個格式解讀上面的三條規則就是,
1. 允許 untrusted_app型別的程序對 system_app_data_file型別的檔案進行read。
2.允許zygote型別的程序對sdcard_type的file進行 read write creat rename。
所以MAC控制方式是這個樣子的:當一個程序去操作一個檔案的時候,系統會去檢測這個程序和檔案的上下文,看看這個程序的所屬的type有沒有對這個的檔案的type操作的許可權。比如:zygote如果要去讀sdcard上的一個檔案,這個檔案的type為sdcard,zygote的type(Domain)為zygote, 系統去檢測看看發現這條規則 allow zygote sdcard_type : file { read write creat rename }。那麼這個操作就會被允許執行。zygote要是想刪除一個sdcard上的檔案,系統發現對應的規則裡沒有delete,那麼就會被deny。(上面的兩條規則和這個例子是我自己編的,只是為了說明情況,真實情況下zygote是有許可權刪除sdcard上的檔案的。)
DAC和MAC是同時作用的,一個操作會先後根據DAC和MAC檢測完再去執行,不滿足任何一個機制的條件都會被拒絕。
2 Hack SEAndroid
上面一節解釋了SEAndroid的工作原理,這下知道為什麼zygote的root許可權並不能為所欲為了,但是如何去更改SEAndroid的規則,擴大zygote的許可權。直接更改sepolicy是不行的,因為sepolicy在boot.img裡面,每次開機都會重寫讀取sepolicy這個檔案,無法更改成功。
所以要直接解壓boot.img替換裡面的sepolicy然後重打包。Linux上有一套解壓打包工具,windows解壓工具為Android-Image-Tools-windows.zip 先找到手機廠商的官方ROM刷機包,找到boot.img解壓。裡面有個檔案是sepolicy。修改sepolicy然後替換它重新打包刷入手機。(好吧其實蠻複雜的,但是我覺得大多數人可能用不到就先這樣寫吧,以後有需要的話會詳細寫。本來打算上傳自己工具,不知道簡書怎麼上傳檔案。。。 我找不到我工具的連結了,可以去這裡找找))
https://github.com/xmikos/setools-android
1.sepolicy-inject:插入規則
2.sesearch:反編譯sepolicy
3.seinfo: 檢視sepolicy版本
修改sepolicy的命令:push到手機上 直接輸入./(相應檔案)即可檢視其使用方式 (下面是我插入的其中一條命令)
./sepolicy-inject -s zygote -t labeledfs -c filesystem -p remount,getattr,relabelto,transition,quotamod,unmount -P /sepolicy -o /sdcard/sepolicy1
https://forum.xda-developers.com/showthread.php?t=2073775
部落格是學習的起點而不是終點。。。 這篇文章只是入門SEAndroid,目的性較強,只講了主要部分,很多內容沒有涉及。深入瞭解SEAndroid的話可以去看看老羅的文章。
參考連結:
SEAndroid安全機制簡要介紹和學習計劃 強烈推薦老羅