作業系統安全機制(2)
Linux作業系統安全機制
先說明 Linux 更適合學習,Android也基於Linux.
程序和執行緒
- 程序: 可執行檔案的活動表現,如Android中Activity的生命週期.對於程序來講,他有很多獨立的空間,如堆和棧,所以程序是資源的最基本的分配單位.
- 執行緒: CPU(核的排程單位),他可以讓一個程序的任務在CPU下多管齊下,併發執行.所以執行緒是CPU的最小排程單位.
程序的地址空間邊界
一個虛擬的地址空間,只有當程式執行的時候才會分配具體的物理空間。由此我們可以得知,程式的虛擬地址相對來說是固定的,而實體地址則隨著每一次程式的執行而有所不同。
程序邊界的安全圍欄:Crash的不可延續性
Windiows: 也就是說當某一程序對OS的某塊記憶體進行written
,但是該記憶體快是only read
的,這時改程序就會發生crash,但是他的crash不會影響到其他應用的程序,如chrome,360等應用不受其影響.這就是Crash的不可延續性.
Android: 常見的crash是 Force close
塞班: 諾基亞時代的手機,那時候的系統是沒有程序邊界的安全圍欄的,在對實體記憶體地址空間這塊都是對映同一塊,也就是說只要當一個發生了crash,那麼整個機子就會重啟.那時對於那種crash是非常謹慎的,在測試這塊是做最多的.
程序邊界的安全圍欄:全域性資料和服務的不可訪問性
儲存在兩個不同的塊,提高了安全.
如A專案無法對B專案的私密資訊進行訪問,因為這兩個專案的儲存區是在兩塊不同的地址範圍.
多使用者和多使用者邊界
- 多使用者的需求背景:資源匱乏,中央的統一管理,現實中還是其他有很多方面的原因而要用到多使用者的作業系統。
- 多使用者的邊界:獨立的工作目錄,每個使用者都有自己的獨立空間,互不干擾;可操作或訪問的資源,每個使用者對某一種資源的許可權是不一樣的;可執行的操作,每個使用者對某一個資源擁有的許可權也是不一樣的;UID和GID,使用者名稱只是用來看的,Identifier才是系統層面的標識,而使用者的行為就是一系列程序的行為,所以多使用者的特性標識其實就是程序的UID和GID。
多使用者的特性標識: UID 和 GID
我們先來了解下UID 和 GID.
- GID為GroupId,即組ID,用來標識使用者組的唯一識別符號
- UID為UserId,即使用者ID,用來標識每個使用者的唯一標示符,每個程序都會有一個UID.
擴充套件:
使用者組:將同一類使用者設定為同一個組,如可將所有的系統管理員設定為admin組,便於分配許可權,將某些重要的檔案設定為所有admin組使用者可以讀寫,這樣可以進行許可權分配。
每個使用者和使用者組都有一個唯一的使用者id.
Name 和ID 的對映
瞭解完UID 和 GID那他們是如何將這些ID和Name關聯起來的呢.
Android中很多一些系統自帶的app都有自己的UID,如
Android_filesystem_config.h檔案的對映關係:
#define AID_ROOT 0
#define AID_SYSTEM 1000
#define AID_CAMERA 1006
#define AID_APP 10000
使用者安裝的app,如使用者開啟了很多app就會被分配到10001,10002…1000X下去
這些Name的String 都會被對映到一張表(android_id_info)裡去,最後交給C/C++去呼叫.
Chmod和Chown命令介紹
對UID,GID和Name,ID 的映射了解後,那他們到底有什麼用呢,跟安全有什麼關係呢? 像在Linux 中可以說一切皆檔案,一切皆資源,使用者/群組在操作這些檔案的時候,肯定也會涉及到檔案的許可權問題(r/w),我們是如何操作這些許可權的,下面繼續看 Chmod和Chown命令介紹.
Chmod用於修改檔案許可權
- 檔案的讀取都是R/W/X,系統內部採用了3Bit表示這些讀寫狀態,如R為最高位位元,置為0x04,W為中間位元,置位0X02,X為最低位位元,置位為0x01.
- Sheel中表示時,位置使用相應R/W/X表示,沒有置位使用
-
表示. - 操作檔案面向群體的操作許可權時,使用Chmod,可以直接使用數字,也可使用助記符:
a:all
u:owner user
g:group
+:add one permission
-:remove one permission
如我們要修改根目錄下的 test.txt檔案許可權:
ls-l
chmod 664 test.txt //對應 6-rw; 4-r
chmod u-w test.txt //對應 u-w表示使用者組移除了 w許可權
Chown用於修改檔案的UID和GID
- Sheel命令中通常採用Name方式修改,而不是ID修改,因為ID玩我們是看不到的.
- 一般格式: chown newUID:newGID FileName
如:根目錄下有一個test.txt
它的UID和GID都是ROOT,這時如果我們要修改他的UID/GID,只能通過他的名字來更改.
chown system:system text.txt //修改了UID/GID, root -> system
//但是他的r/w/x許可權是不變的
被ROOT了怎麼辦
- 惡意程式獲得了ROOT許可權怎麼辦?
如我們肯能只是想獲取到ROOT許可權,做A,B兩件事情,但是如果有些惡意的程式因為你獲取了ROOT後,他可以做一些A,B之外的事情,不是我們希望事情.
那我們應該怎麼辦呢?
>
惡意應用獲得了ROOT許可權 — 現在我們是無能為力的.
我們想要做到的: 即便一個程序的EUID==ROOT許可權,仍然不能為所欲為.
SELinux
- DAC()模式:主體(EUID==ROOT)對它所屬的物件和執行的程式擁有所有的控制權 – 可以做任何事
- MAC()模式:SELinux基於的安全策略。管理員管理訪問控制,管理員指定策略,使用者不能改變它,任何主體不能改變 – 只能做安全策略授權的,不能為所欲為
舉例,web伺服器案例:
- DAC模式下:web伺服器程序具有root許可權,當惡意病毒攻擊成功並注入web伺服器程序後,則可以利用web伺服器程序的root許可權,做任何事情.
- MAC模式下:web伺服器程序所能操作的物件和許可權均在安全策略中明確列出,比如,只允許訪問網路和訪問特定檔案等.即便web伺服器被而已病毒攻擊注入了,你仍然無法藉由web伺服器程序為所欲為,所有安全策略上沒有授權的行為仍然是不允許的.
SEAndroid
與SELinux的關係
SEAndroid (Security-Enhanced Android)將原本運用在LinuxOS上的SELinux,移植到Android平臺上.與SELinux的區別
除了移植SELinux以外,google釋出了那麼多個版本,還做了很多針對於Android的安全提高,比如把Binder IPC,Socket,Properties訪問控制加入到了SEAndroid的控制中.SEAndroid的核心理念
裡邊而已應用篡得了ROOT許可權.
但惡意應用仍然被有限的控制著而不能為所欲為.
JB MR2的一個漏洞彌補
JB(4.3) MR2的漏洞彌補
在JB MR2之前,APK內部可以通過Java的Runtime執行一個具有Root-setUID的可執行檔案而提升EffectiveUID 來進行一些特權操作,典型的就是Root包中的su就是這個原理JB(4.3) MR2修補了這個漏洞
每個apk程序在建立完後,都會執行如下這段程式碼,將CAPBSET全部清空.新程序的Effecttive(Capability Sets)為空,所以CAP_SETUID就沒了,那麼系統基於Root-setUID的可執行檔案來提升EUID到ROOT當然就不允許了。所以新程序的EUID=RUID == APK的RUID.