0x01 可信執(zhí)行環(huán)境(TEE)
可信執(zhí)行環(huán)境是為了在 執(zhí)行對(duì)敏感任務(wù) (例如:付款、用戶身份驗(yàn)證、用戶數(shù)據(jù)保護(hù))時(shí)提供安全的環(huán)境。 安全環(huán)境與名為富執(zhí)行環(huán)境(REE,Rich Execution Environment)的非安全或不受信任的環(huán)境相互隔離。在我們所分析的案例中,也就是Android OS,在后續(xù)文章中REE可以等價(jià)為Android。
TEE操作系統(tǒng)通常由具有較高特權(quán)的內(nèi)核和具有較低特權(quán)的多個(gè)應(yīng)用程序(稱為可信應(yīng)用程序,TA,Trusted Applications)組成。
TA之間彼此隔離,且與TEE內(nèi)核隔離 。
這樣一來(lái),如果有應(yīng)用程序被攻陷,它就無(wú)法危害到其他應(yīng)用程序或TEE內(nèi)核。
簡(jiǎn)而言之,一個(gè)強(qiáng)大的TEE機(jī)制可以實(shí)現(xiàn)下述三類隔離:
- 1、TEE與REE之間的隔離;
- 2、TA和TEE內(nèi)核之間的隔離;
- 3、TA之間的隔離。 為了達(dá)到這些安全需求,TEE需要硬件原語(yǔ)的支持,以強(qiáng)制進(jìn)行隔離。硬件和軟件之間的配合是至關(guān)重要的,并且需要持續(xù)配合。
廣義上來(lái)說(shuō),TEE由多個(gè)組件組成,具體包括:
- 1、TEE感知硬件;
- 2、強(qiáng)大的安全啟動(dòng)(Secure Boot)鏈,用于初始化TEE軟件;
- 3、TEE OS內(nèi)核,用于管理安全區(qū)域和可信應(yīng)用程序;
- 4、可信應(yīng)用程序,用于向TEE提供功能。
在我們的系列文章中,將聚焦在1、3和4上面, 并且我們假設(shè)平臺(tái)已經(jīng)正確實(shí)施了安全啟動(dòng) 。我們假設(shè) 攻擊者已經(jīng)控制REE ,從而可以與TEE進(jìn)行通信,其攻擊目標(biāo)是完整攻陷TEE。
TEE內(nèi)核通常僅向Android OS暴露非常有限的接口,大多數(shù)功能都是由TA實(shí)現(xiàn)的。
所以我們的計(jì)劃是首先在TA中找到可以利用的漏洞,然后提升權(quán)限到內(nèi)核。但是,在進(jìn)入到反匯編程序之前,我們首先要看一下用于實(shí)現(xiàn)TEE的ARM擴(kuò)展——TrustZone。
0x02 ARM的TrustZone
rustZone技術(shù)是ARM開(kāi)發(fā)的一種硬件體系結(jié)構(gòu),它允許軟件在安全與非安全的兩個(gè)域中執(zhí)行。
這是使用“NS”位來(lái)進(jìn)行標(biāo)識(shí)的,這一位可以指示master是在安全模式下還是非安全模式下運(yùn)行。這里所說(shuō)的master可以是CPU內(nèi)核,也可以是硬件外設(shè)(例如DMA或加密引擎)。
master是否安全,可以在設(shè)計(jì)中通過(guò)硬連線來(lái)定義,也可以通過(guò)配置定義。例如,可以通過(guò)調(diào)用SMC指令(稍后詳細(xì)介紹)或切換SCR寄存器中的NS位來(lái)切換CPU內(nèi)核的安全狀態(tài)。
為了定義slave(例如外圍設(shè)備或內(nèi)存)的訪問(wèn)限制,TrustZone通常包括兩個(gè)組件,分別是TrustZone地址空間控制器(TZASC)和TrustZone保護(hù)控制器(TZPC)。
TZASC可以用于定義DRAM中的安全范圍。ARM提供了兩種不同的實(shí)現(xiàn)方式,最新的是TZC-400。下圖概述了其通常情況下在SoC中的實(shí)現(xiàn)方式,引自官方技術(shù)文檔。
TZASC概述:
可以看出,任何對(duì)DRAM存儲(chǔ)器的訪問(wèn)都會(huì)首先通過(guò)TZASC,然后轉(zhuǎn)發(fā)給內(nèi)存控制器。TZASC可以基于一組內(nèi)部規(guī)則來(lái)判斷是否允許訪問(wèn)內(nèi)存。
TZASC包 含一個(gè)始終啟用的基礎(chǔ)區(qū)域(區(qū)域0),能夠跨越整個(gè)DRAM內(nèi)存范圍 。此外,還定義了許多其他安全區(qū)域,可以限制對(duì)其的訪問(wèn)。詳細(xì)來(lái)說(shuō),在其他區(qū)域可以設(shè)置以下內(nèi)容:
- 1、起始地址和結(jié)束地址。
- 2、安全讀取和寫(xiě)入的權(quán)限。這些權(quán)限將應(yīng)用在嘗試訪問(wèn)內(nèi)存范圍的任何安全master上。請(qǐng)注意,TZASC沒(méi)有委派給MMU的執(zhí)行許可和強(qiáng)制執(zhí)行的概念。
- 3、非安全I(xiàn)D過(guò)濾??梢詫^(qū)域配置為允許訪問(wèn)非安全的master。對(duì)于TZC-400來(lái)說(shuō),可以為讀取和寫(xiě)入權(quán)限來(lái)設(shè)置位掩碼,以便對(duì)允許哪些非安全master訪問(wèn)內(nèi)存范圍進(jìn)行精細(xì)化控制。
TZPC實(shí)現(xiàn)了類似的概念,但適用于內(nèi)部外圍設(shè)備和SRAM,不適用于外部DRAM 。其中包含一個(gè)寄存器(R0size),以4KB為單位指定安全分片上SPAM的大小。 與TZASC相比,它不太靈活,因?yàn)樗辉试S定義一個(gè)安全區(qū)域和一個(gè)非安全區(qū)域,安全區(qū)域是從0開(kāi)始直到指定的大小,剩余的SRAM直接被視為非安全區(qū)域。 然后,還有很多其他的寄存器,用于為每個(gè)外圍設(shè)備指定其安全性(只能由安全的master訪問(wèn))。TZPC寄存器中的不同位對(duì)應(yīng)哪些外設(shè)并沒(méi)有定義,并且它是完全針對(duì)不同的SoC。
通常,TZASC和TZPC的大多數(shù)設(shè)置都是在初始化期間配置的,并且永遠(yuǎn)不會(huì)更改 。但是,其中有一些需要在運(yùn)行時(shí)動(dòng)態(tài)修改。
這里的一個(gè)示例是用于執(zhí)行安全付款的可信用戶界面(TUI)。以S10手機(jī)的三星支付為例,當(dāng)用戶需要輸入PIN來(lái)授權(quán)付款時(shí),TEE將會(huì)接管,并直接控制顯示屏和觸摸傳感器。這里的底層邏輯是,由于PIN是一個(gè)敏感數(shù)據(jù),因此交由TEE來(lái)處理整個(gè)過(guò)程,而不再使用不受信任的Android OS。 因此,必須使用TZPC將顯示器和觸摸控制器重新配置為“安全”,這樣一來(lái),即使是在Android中運(yùn)行內(nèi)核級(jí)代碼的攻擊者也無(wú)法獲取到PIN。要在屏幕中顯示圖像,需要在DRAM中存儲(chǔ)一個(gè)安全的幀緩沖區(qū),因此TEE還會(huì)使用TZASC將DRAM中的一部分重新配置為“安全”,并將其作為幀緩沖區(qū)。
在用戶輸入完P(guān)IN后,TZASC和TZPC將其恢復(fù)為之前的值,然后Android再次接管。
安全和非安全模式之間的轉(zhuǎn)換由名為“安全監(jiān)視器”(Secure Monitor)的組件來(lái)管理。這個(gè)監(jiān)視器是TEE和REE之間的主要接口,并且是唯一可以修改內(nèi)核安全狀態(tài)的組件。
與在REE中一樣,TEE在內(nèi)核和TA之間保持用戶模式與內(nèi)核模式之間的隔離 。TEE OS還負(fù)責(zé)加載TA,并在REE和TA之間傳遞參數(shù)。
TA在安全區(qū)域的用戶空間中運(yùn)行,并為REE提供服務(wù)。
ARMv8-A CPU在每個(gè)區(qū)域中支持四個(gè)特權(quán)級(jí)別,也將其稱為異常級(jí)別,分別是:
- (S-)EL0 – 用戶模式/APP
- (S-)EL1 – 內(nèi)核
- EL2 – 管理程序(Hypervisor)
- EL3 – 安全監(jiān)視器(Secure Monitor)
在REE中,我們的Android應(yīng)用程序在EL0上運(yùn)行,而Linux內(nèi)核則在EL1上運(yùn)行。
EL2僅以非安全模式存在(在ARMv8.4-A版本之前),稱之為管理程序(Hypervisor)。它最初被設(shè)計(jì)為一種處理以較低特權(quán)級(jí)別并行運(yùn)行的多個(gè)虛擬環(huán)境的方法, 但是在Android環(huán)境中,通常將其用作內(nèi)核加固機(jī)制。 在三星手機(jī)中也是如此, 管理程序組件被稱為實(shí)時(shí)內(nèi)核保護(hù)(RKP,Real-time Kernel Protection),除了這些用途之外 ,它還限制了內(nèi)核可以訪問(wèn)的內(nèi)存,并將某些內(nèi)核結(jié)構(gòu)設(shè)置為只讀,從而增加了內(nèi)核漏洞利用的難度。在系列文章的第三篇中,我們將詳細(xì)分析RKP。
最后,我們來(lái)分析安全組件,我們研究的目標(biāo)是EL3(始終以安全模式運(yùn)行)、S-EL0和S-EL1。關(guān)于TEE的實(shí)現(xiàn)方式,有多種方式,但是目前最常見(jiàn)的示例是:在EL3上運(yùn)行一個(gè)非常小的組件,負(fù)責(zé)在兩個(gè)區(qū)域之間進(jìn)行切換;在EL1上運(yùn)行一個(gè)成熟的內(nèi)核;在EL0上運(yùn)行多個(gè)TA。三星的TEE OS TEEGRIS也采用了這樣的設(shè)計(jì)方式。
盡管完全隔離的環(huán)境非常安全,但在使用的過(guò)程中,它還是需要與Android中運(yùn)行的其他不受信任的組件進(jìn)行通信。REE和TEE之間的通信使用名為“安全監(jiān)視器調(diào)用”(SMC)的專用指令觸發(fā)。兩個(gè)指令都可以在EL > 0時(shí)調(diào)用該指令,這意味著Android應(yīng)用程序無(wú)法直接啟動(dòng)與TEE的通信。
通常的情況是Linux內(nèi)核充當(dāng)代理并公開(kāi)驅(qū)動(dòng)程序,應(yīng)用程序可以使用該驅(qū)動(dòng)程序與TEE進(jìn)行交互。
這種設(shè)計(jì)的優(yōu)勢(shì)在于,可以將訪問(wèn)限制策略(例如使用SELinux)應(yīng)用于訪問(wèn)驅(qū)動(dòng)程序的場(chǎng)景中,以確保只有部分應(yīng)用程序可以與TEE通信 ,從而收斂了攻擊面。對(duì)于S10手機(jī)來(lái)說(shuō),情況也是如此,僅允許有限的應(yīng)用程序和服務(wù)與TEE通信。
請(qǐng)注意, 在我們的后續(xù)研究中,我們假設(shè)攻擊者具有與TEE進(jìn)行通信的能力。在使用Magisk這樣的工具對(duì)手機(jī)進(jìn)行root時(shí)就是這種情況 ,或者,也可以獲取Linux內(nèi)核的運(yùn)行時(shí)控制,還可以獲取允許與TEE通信的Android應(yīng)用/服務(wù)的運(yùn)行時(shí)控制。
一旦執(zhí)行了SMC指令,就會(huì)在EL3中運(yùn)行的安全監(jiān)視器中生成一個(gè)中斷。SMC處理機(jī)制會(huì)將SMC路由到相應(yīng)組件。如果監(jiān)視器可以直接處理SMC,那么就進(jìn)行處理并立即返回。否則,會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到TEE內(nèi)核(在S-EL1運(yùn)行),然后在其內(nèi)部進(jìn)行處理,或者繼續(xù)將其轉(zhuǎn)發(fā)到在S-EL0運(yùn)行的TA。
現(xiàn)在,我們已經(jīng)了解TrustZone的工作原理,接下來(lái)來(lái)分析一下三星的實(shí)現(xiàn)方式。
0x03 TEEGRIS
TEEGRIS是一個(gè)相對(duì)較新的TEE操作系統(tǒng),由三星在Galaxy S10機(jī)型上首次推出。從2019年開(kāi)始,大多數(shù)使用Exynos芯片的三星新款手機(jī)也開(kāi)始在TEE中運(yùn)行TEEGRIS。
在2019年3月推出S10之前,Exynos芯片使用的是另一個(gè)由Trustonic開(kāi)發(fā)的、名為Kinibi的TEE OS,此前的一些研究文章對(duì)這個(gè)操作系統(tǒng)進(jìn)行了充分分析。不過(guò),由于TEEGRIS是一個(gè)相對(duì)較新的操作系統(tǒng),因此網(wǎng)上沒(méi)有太多的公開(kāi)信息。
實(shí)際上,我們只能從一篇網(wǎng)上的文章中找到一些可用信息,這篇文章對(duì)TEEGRIS及其內(nèi)核進(jìn)行了很好地介紹,主要說(shuō)明了如何設(shè)置QEMU以進(jìn)行fuzzing。盡管我們主要聚焦在逆向工程的方向,但這篇文章仍然為我們提供了一些有用的信息,例如引導(dǎo)映像布局(存儲(chǔ)TEEGRIS的位置),以及如何識(shí)別內(nèi)核中處理的系統(tǒng)調(diào)用等。
基于這些信息,我們來(lái)分析一下TEEGRIS的主要組件:內(nèi)核、TA、驅(qū)動(dòng)程序。
如前所述,監(jiān)視器代碼在TrustZone中扮演著非常重要的角色,但是在三星的實(shí)現(xiàn)中,監(jiān)視器以加密的方式存儲(chǔ)在內(nèi)存中。
因此,我們沒(méi)有對(duì)它進(jìn)行分析,而是專注于其他組件,這些組件都是以明文存儲(chǔ)的。
0x04 TEEGRIS內(nèi)核
TEEGRIS內(nèi)核是一個(gè)在安全EL1中運(yùn)行的小型組件。即使小,但它從嚴(yán)格意義上說(shuō)并不是微內(nèi)核。舉例來(lái)說(shuō),其中集成了很多可以由TA使用的驅(qū)動(dòng)程序。它以64位模式運(yùn)行,并支持在用戶空間中運(yùn)行的64位和32位TA和驅(qū)動(dòng)程序。由于內(nèi)核以明文存儲(chǔ)在引導(dǎo)分區(qū)中,因此我們可以輕松提取它并進(jìn)行反匯編。
內(nèi)核實(shí)現(xiàn)了許多POSIX兼容的系統(tǒng)調(diào)用,還添加了一些TEEGRIS特定的系統(tǒng)調(diào)用。在Alexander Tarasikov的文章中我們注意到,有兩個(gè)共享庫(kù)中實(shí)現(xiàn)的系統(tǒng)調(diào)用包裝器(請(qǐng)參考下面的TA章節(jié),詳細(xì)介紹了如何處理共享庫(kù)),分別是libtzsl.so和libteesl.so。這讓我們可以快速地識(shí)別內(nèi)核中的兩個(gè)表,分別適用于64位和32位TA的系統(tǒng)調(diào)用處理程序。
64位和32位系統(tǒng)調(diào)用表:
通過(guò)對(duì)系統(tǒng)調(diào)用進(jìn)行分析,我們發(fā)現(xiàn)三星充分利用了兩個(gè)在Linux中比較熟悉的例程——copy_to和from_user。使用這些例程來(lái)訪問(wèn)來(lái)自用戶區(qū)域的數(shù)據(jù),以確保TA不能引用內(nèi)部?jī)?nèi)核結(jié)構(gòu)。
copy_from_user反編譯的代碼:
上圖中的代碼首先驗(yàn)證標(biāo)志位,以判斷是否忽略其他任何檢查。當(dāng)內(nèi)核使用已知的安全參數(shù)直接調(diào)用系統(tǒng)調(diào)用處理程序時(shí),就會(huì)啟用這個(gè)標(biāo)志位。如果設(shè)置了標(biāo)志位,這個(gè)函數(shù)就變成了memcpy的包裝。而在其它情況下,代碼將調(diào)用check_address,如下圖所示。
地址檢查例程:
上圖中的代碼片段為我們提供了一些重要的信息,一定不能映射TA的第一頁(yè)(第10行,可能是為了防止NULL指針解引用),有效的TA地址應(yīng)該小于0x40000000(第12行)。任何比它大的值都將被視為無(wú)效,并且會(huì)被丟棄。
此外需要注意的一點(diǎn)是,復(fù)制是使用LDTR指令執(zhí)行的。LDTR的行為與常規(guī)LDR * 指令相同,但會(huì)導(dǎo)致使用EL0特權(quán)執(zhí)行內(nèi)存訪問(wèn)。
這是因?yàn)镻AN被啟用,即使check_address函數(shù)漏掉了某些邊界情況,對(duì)內(nèi)核內(nèi)存的非特權(quán)訪問(wèn)也會(huì)導(dǎo)致訪問(wèn)沖突。
TA地址空間的上限0x40000000可能意味著ASLR的隨機(jī)性相對(duì)較小,特別是考慮到支持64位TA的情況。
為了確認(rèn)這個(gè)假設(shè)是否成立,我們分析了如何加載TA映像的過(guò)程。
請(qǐng)注意,在TEEGRIS中,TA是經(jīng)過(guò)略微修改后的ELF文件,因此我們可以在代碼中查找用于解析標(biāo)準(zhǔn)ELF格式的函數(shù)。
最終,我們找到了map_elf32_image函數(shù),在64位TA中也存在等價(jià)的函數(shù)。
代碼和數(shù)據(jù)段的隨機(jī)化:
需要注意的是,該代碼強(qiáng)制只能加載PIE可執(zhí)行文件(第120行)。隨后,它生成2個(gè)字節(jié)的隨機(jī)數(shù)(第132行),用0x7FFF作為掩碼(第134行),并將其作為要添加到入口點(diǎn)的頁(yè)面偏移量(和基址,稍后會(huì)在同一函數(shù)中完成)。這意味著ASLR偏移最多只能有32768個(gè)值,并且它應(yīng)用于ELF中指定的所有段。
動(dòng)態(tài)內(nèi)存(例如:用于堆和REE共享的映射內(nèi)存)在“派生”系統(tǒng)調(diào)用時(shí)會(huì)使用不同的值,但還是采用類似的方法進(jìn)行隨機(jī)化。
動(dòng)態(tài)內(nèi)存隨機(jī)化:
請(qǐng)注意,ASLR不僅適用于TA,并且也會(huì)在內(nèi)核中使用(通常稱為KASLR)。在這里我們不會(huì)過(guò)多介紹細(xì)節(jié),但是,如果我們最終想要實(shí)現(xiàn)內(nèi)核利用,則需牢記這一點(diǎn)。在入口函數(shù)中,內(nèi)核生成另一個(gè)隨機(jī)值,并相應(yīng)地修改頁(yè)和重定位表。
KASLR,全稱Kernel Address Space Layout Randomization,是一種計(jì)算機(jī)安全技術(shù)。它是一種隨機(jī)化內(nèi)核地址空間布局的方法,旨在防止攻擊者通過(guò)猜測(cè)內(nèi)核的地址空間布局來(lái)攻擊系統(tǒng)。KASLR技術(shù)通過(guò)在內(nèi)核啟動(dòng)階段獲取一個(gè)隨機(jī)值,并使用該隨機(jī)值對(duì)內(nèi)核加載地址進(jìn)行相應(yīng)的隨機(jī)偏移,以實(shí)現(xiàn)內(nèi)核地址空間的隨機(jī)化。這樣,每次啟動(dòng)系統(tǒng)時(shí),內(nèi)核的地址空間布局都會(huì)有所不同,使得攻擊者難以猜測(cè)正確的內(nèi)核地址空間布局。在完成內(nèi)核數(shù)據(jù)隨機(jī)映射之后,還需要對(duì)符號(hào)地址進(jìn)行重定位,校正內(nèi)核代碼的符號(hào)尋址,以確保內(nèi)核代碼的正常執(zhí)行。總之,KASLR是一種提高系統(tǒng)安全性的技術(shù),通過(guò)隨機(jī)化內(nèi)核地址空間布局,防止攻擊者猜測(cè)內(nèi)核的地址空間布局并攻擊系統(tǒng)。
如前所述,在內(nèi)核中內(nèi)置了許多驅(qū)動(dòng)程序。驅(qū)動(dòng)程序主要用于和外圍設(shè)備(例如SPI和I2C)進(jìn)行通信或執(zhí)行加密操作。
內(nèi)核中實(shí)現(xiàn)的驅(qū)動(dòng)程序的部分列表:
考慮到三星是遵循POSIX規(guī)范來(lái)實(shí)現(xiàn)TEEGRIS的,那么這種與驅(qū)動(dòng)程序進(jìn)行交互的方式就不足為奇了。
驅(qū)動(dòng)程序的名稱通常以“dev://”開(kāi)頭,可以從TA打開(kāi)相應(yīng)的文件進(jìn)行訪問(wèn)。
隨后,TA就可以使用許多系統(tǒng)調(diào)用(例如:read、write、ioctl、mmap)與驅(qū)動(dòng)程序進(jìn)行交互。在內(nèi)核內(nèi)部,使用一種結(jié)構(gòu)來(lái)存儲(chǔ)每個(gè)驅(qū)動(dòng)程序的系統(tǒng)調(diào)用實(shí)現(xiàn)。
在這里,并不是一直向每個(gè)TA授予堆驅(qū)動(dòng)程序和系統(tǒng)調(diào)用的訪問(wèn)權(quán)限。實(shí)際上,根據(jù)TA所屬不同的組,每個(gè)組都有不同的權(quán)限級(jí)別。
內(nèi)核會(huì)跟蹤向每個(gè)TA授予了哪些權(quán)限,并執(zhí)行檢查,以確保只有允許的TA才能訪問(wèn)受限制的功能。下面的兩張圖就展示了授予兩個(gè)不同組的權(quán)限,分別是samsung_ta和samsung_drv。
samsung_ta組的訪問(wèn)權(quán)限:
samsung_drv組的訪問(wèn)權(quán)限:
如圖所示,每個(gè)TA有19個(gè)權(quán)限。其中值為0就表示未授予權(quán)限,其他值表示授予了部分或完整權(quán)限。
其中大多數(shù)只是標(biāo)記已授予和未授予,但有幾個(gè)(MMAP)還包含一個(gè)特定的掩碼用以確定是否可以使用讀/寫(xiě)/執(zhí)行特權(quán)來(lái)映射內(nèi)存。
在上面的兩個(gè)示例中,samsung_ta受到了較多限制,只能訪問(wèn)幾個(gè)權(quán)限,但samsung_drv組就具有更大的權(quán)限。除此之外,其他組也具有不同的權(quán)限,但到目前為止,我們發(fā)現(xiàn)上述兩個(gè)是最為常見(jiàn)的。
0x05 TA和用戶區(qū)域驅(qū)動(dòng)程序
至此,我們對(duì)內(nèi)核工作原理以及與內(nèi)核的交互方式進(jìn)行了分析,接下來(lái)看看TA。通常,在TEE中使用TA的方式有兩種。
- 一種是與TEE OS綁定的不可變的blob,始終在初始化時(shí)加載;
- 另一種是可以在運(yùn)行時(shí)由Android加載。
三星的TEEGRIS采用了混合的方式,同時(shí)支持這兩種選擇。 引導(dǎo)分區(qū)中包含一個(gè)特殊的壓縮包(startup.tzar),其中包含TA所需的所有共享庫(kù)以及在Android完全引導(dǎo)之前早期系統(tǒng)所需的一些特殊TA和驅(qū)動(dòng)程序,包括TSS(用于管理共享內(nèi)存)、ACSD(用于支持TA身份驗(yàn)證的驅(qū)動(dòng)程序)和root_task(用于加載TA,與ACSD共同對(duì)其進(jìn)行驗(yàn)證)。
tzar壓縮包中的二進(jìn)制文件是標(biāo)準(zhǔn)的ELF文件,可以直接加載到反匯編程序中進(jìn)行分析。
由于壓縮包是啟用映像的一部分,因此在啟動(dòng)時(shí)會(huì)驗(yàn)證它的簽名。
TA也可以在運(yùn)行時(shí)從Android加載??杉虞d的TA存儲(chǔ)在/vendor/tee和/system/tee分區(qū)中。
在S10系列中,大約有30種不同的TA可供加載,其格式如下:
- 1、標(biāo)頭長(zhǎng)度為8個(gè)字節(jié),包含4個(gè)字節(jié)的版本信息(SEC2、SEC3或SEC4)和4個(gè)字節(jié)的內(nèi)容。
- 2、內(nèi)容部分是包含實(shí)際TA內(nèi)容的常規(guī)ELF文件。如果TA的類型為SEC4,則內(nèi)容是加密的,否則內(nèi)容以明文形式存在。
- 3、元數(shù)據(jù)部分包含TA組。從SEC3版本開(kāi)始,還有一個(gè)包含版本號(hào)的附加字段。root_task和ACSD會(huì)利用這個(gè)版本號(hào)來(lái)管理TA,防止其回滾。當(dāng)加載SEC3或SEC4版本的TA時(shí),都會(huì)提取版本號(hào),并將其與RPMB存儲(chǔ)中存儲(chǔ)的版本號(hào)進(jìn)行比較。如果低于存儲(chǔ)的版本號(hào),則不能加載TA并報(bào)錯(cuò)。如果高于存儲(chǔ)的版本號(hào),則增加RPMB中的版本號(hào)以匹配TA版本,從而不再加載同一TA的較舊副本。這也意味著,從現(xiàn)在開(kāi)始,SEC2版本的TA將無(wú)法使用。這個(gè)功能對(duì)于防護(hù)包含已知漏洞的舊版本TA至關(guān)重要,我們將在第二篇文章中對(duì)此進(jìn)行詳細(xì)介紹。
- 4、簽名部分包含其余映像的RSA簽名。它遵循X.509格式,并由ACSD進(jìn)行解析。
從這個(gè)簡(jiǎn)短的描述中,我們可以看出,如果刪除初始標(biāo)頭并將其作為ELF文件加載到反匯編程序中,我們就可以輕松地對(duì)TA進(jìn)行反匯編。唯一比較麻煩的就是SEC4格式,因?yàn)槠渲械腅LF已加密,但是實(shí)際上,我們發(fā)現(xiàn)Galaxy S10和S20中僅使用SEC2和SEC3。然后,TA可以從tzar壓縮包中導(dǎo)入庫(kù)。庫(kù)也是常規(guī)的ELF文件,實(shí)現(xiàn)C庫(kù)函數(shù)和Global Platform(GP)API和TEEGRIS特定功能。
EEGRIS中的TA實(shí)現(xiàn)了GP API, 在這個(gè)API中指定了TA需要實(shí)現(xiàn)以與REE交互的5個(gè)接口:
- 1、TA_CreateEntryPoint,在加載TA時(shí)調(diào)用。
- 2、TA_OpenSessionEntryPoint,在REE中運(yùn)行的客戶端應(yīng)用程序(CA,在我們的場(chǎng)景中為Android應(yīng)用程序)首次建立與TA的連接時(shí)調(diào)用。
- 3、TA_InvokeCommandEntryPoint,其中包含將被CA發(fā)送的每個(gè)命令調(diào)用的主命令處理程序。這是大多數(shù)TA功能實(shí)現(xiàn)的位置。
- 4、TA_CloseSessionEntryPoint,在CA結(jié)束與TA的會(huì)話時(shí)調(diào)用。
- 5、TA_DestroyEntryPoint,在從內(nèi)存中卸載TA時(shí)執(zhí)行。
即使TA是可執(zhí)行文件,由于實(shí)際的main()函數(shù)位于libteesl.so庫(kù)內(nèi)部,因此它的執(zhí)行也比較復(fù)雜。啟動(dòng)TA時(shí),實(shí)際上會(huì)發(fā)生以下情況:
- 1、執(zhí)行TA內(nèi)部的start()函數(shù)。這個(gè)函數(shù)通常情況下只是main()的包裝。
start()函數(shù)的示例:
- 2、主要函數(shù)實(shí)際上不在TA內(nèi)部,而是在libteesl.so庫(kù)中。這里是配置TEEGRIS內(nèi)核與REE通信的大多數(shù)邏輯的地方。 建立了一個(gè)基于POSIX epoll的標(biāo)準(zhǔn)機(jī)制,用于與根TA進(jìn)行通信。在下面的代碼段中,主函數(shù)首先調(diào)用TA_CreateEntryPoint(),然后跳轉(zhuǎn)到start_event_loop()。
libteesl主要函數(shù)的代碼片段:
- 3、在start_event_loop()中,該庫(kù)隨后將接收事件,例如來(lái)自CA的請(qǐng)求。隨后將時(shí)間轉(zhuǎn)發(fā)到對(duì)應(yīng)的GP API入口點(diǎn)。
這一章的標(biāo)題是“TA和用戶區(qū)域驅(qū)動(dòng)程序”,但到目前為止我們說(shuō)得都是TA。那么,驅(qū)動(dòng)程序在哪里呢?
實(shí)際上,驅(qū)動(dòng)程序與TA相同。它們具有相同的格式,實(shí)現(xiàn)相同的GP API,但調(diào)用的是TEEGRIS特定的API,名為TEES_InitDriver。
該函數(shù)允許驅(qū)動(dòng)程序指定驅(qū)動(dòng)程序名稱和結(jié)構(gòu),可用于與用戶區(qū)域驅(qū)動(dòng)程序進(jìn)行交互,方式類似于與內(nèi)核區(qū)域驅(qū)動(dòng)程序進(jìn)行交互的方式。默認(rèn)情況下,用戶區(qū)域驅(qū)動(dòng)程序不具有任何特殊權(quán)限,但它們通常屬于特權(quán)較高的組。
0x06 漏洞利用緩解措施
總結(jié)一下我們對(duì)內(nèi)核和TA的分析,就可以明確在內(nèi)核和TA中實(shí)現(xiàn)的漏洞利用緩解措施。其中的一些已經(jīng)在前面的內(nèi)核分析中介紹過(guò)了。在這里,我們匯總措施如下:
- 1、內(nèi)核和TA中都使用了XN(eXecute Never)。這意味著數(shù)據(jù)內(nèi)存永遠(yuǎn)不可執(zhí)行,代碼永遠(yuǎn)不可寫(xiě)。
- 2、內(nèi)核和TA中使用了棧金絲雀保護(hù)(Stack Canaries),以防止棧緩沖區(qū)溢出。
- 3、ASLR和KASLR用于隨機(jī)化TA和內(nèi)核的地址空間。
- 4、使用PAN和PXN可以防止內(nèi)核訪問(wèn)或執(zhí)行用戶模式內(nèi)存。
從歷史上看,與其他流行的OS相比,此前TEE OS中的漏洞利用緩解措施還是比較少的。之前針對(duì)三星TEE的攻擊主要針對(duì)僅使用XN來(lái)防護(hù)的舊款機(jī)型,所以緩解措施比較少。
S10無(wú)疑是朝著正確方向邁出了一步,如果攻擊者再想要完整攻陷TEE,可能需要結(jié)合利用多個(gè)漏洞。
0x07 與TA通信
現(xiàn)在,我們對(duì)TA已經(jīng)有更多的了解,我們需要了解如何從Android環(huán)境中與TA進(jìn)行通信。幸運(yùn)的是,GP標(biāo)準(zhǔn)不僅為TA定義了一組API,而且還為希望與TA進(jìn)行通信的CA定義了一組API。每一個(gè)入口點(diǎn)都有一個(gè)可供CA使用的對(duì)應(yīng)調(diào)用,例如TEEC_OpenSession可以用于打開(kāi)會(huì)話,TEEC_InvokeCommand可以用于發(fā)送命令等等。
對(duì)于TEEGRIS來(lái)說(shuō),libteecl.so庫(kù)實(shí)現(xiàn)了GP API,因此與TA進(jìn)行通信就像使用dlopen/dlsym來(lái)解析GP API所需的符號(hào)一樣簡(jiǎn)單。要打開(kāi)會(huì)話,需要指定目標(biāo)TA的UUID。然后,庫(kù)會(huì)在/vendor/tee或/system/tee中查找具有該UUID的TA(UUID是文件名),并將整個(gè)TA映像都傳遞給TEE,然后TEE將對(duì)其進(jìn)行身份驗(yàn)證后加載。所有操作都是對(duì)CA透明進(jìn)行的,因此CA并不知道實(shí)際通信是如何發(fā)生的。
前面我們也提到過(guò),并非每個(gè)Android應(yīng)用都被允許與TEE進(jìn)行通信。這里存在限制,完整的漏洞利用鏈需要攻擊者首先獲得對(duì)可以與TEE通信的應(yīng)用程序的運(yùn)行時(shí)控制。
-
寄存器
+關(guān)注
關(guān)注
31文章
5295瀏覽量
119824 -
SCR
+關(guān)注
關(guān)注
2文章
149瀏覽量
44105 -
ARM處理器
+關(guān)注
關(guān)注
6文章
360瀏覽量
41632 -
SoC系統(tǒng)
+關(guān)注
關(guān)注
0文章
52瀏覽量
10655 -
DRAM控制器
+關(guān)注
關(guān)注
0文章
11瀏覽量
7762
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論