錦州市廣廈電腦維修|上門維修電腦|上門做系統|0416-3905144熱誠服務,錦州廣廈維修電腦,公司IT外包服務
topFlag1 設為首頁
topFlag3 收藏本站
 
maojin003 首 頁 公司介紹 服務項目 服務報價 維修流程 IT外包服務 服務器維護 技術文章 常見故障
錦州市廣廈電腦維修|上門維修電腦|上門做系統|0416-3905144熱誠服務技術文章
影響Android多個高權限服務的嚴重漏洞詳情披露(CVE-2018-9411)

作者: 佚名  日期:2018-11-12 16:54:38   來源: 本站整理

 媒體框架是安卓系統組件中經常被發現安全漏洞的組件,所以每次谷歌發布月度例行更新時經常會有它的身影。Google最近發現的媒體框架的漏洞是遠程代碼執行漏洞,攻擊者可以制作特定的文件利用特權進程執行任意代碼。目前Google已將其命名為CVE-2018-9411,危險等級定位危急,并在7月安全更新(2018-07-01補丁)中對其進行了修補,包括9月安全更新(2018-09-01補丁)中的一些附加補丁。
我還為此漏洞編寫了一個概念驗證利用,演示了如何使用它來從常規非特權應用程序的上下文中提升權限。
本文,我將介紹該漏洞和利用此漏洞的技術細節。首先我將介紹與漏洞相關的一些背景信息,然后再詳細介紹漏洞本身。在介紹如何利用此漏洞的過程中,我將選擇一個特定服務作為攻擊目標,而不是受漏洞影響的其他服務。另外,我還將分析與漏洞相關的一些服務。最后,我將介紹我編寫的概念驗證漏洞利用的詳細信息。
Project Treble
什么是Project Treble?簡單的說就是谷歌為了整理安卓的碎片化,為了讓手機廠商適配安卓版本更輕松,推出的新架構。
Project Treble對Android內部運作方式進行了大量更改,其中的一個巨大的變化是許多系統服務的分離。以前,Android服務包含AOSP(Android開源項目)和供應商代碼。在Project Treble出現之后,這些服務會被分為一個AOSP服務和一個或多個供應商服務,稱為HAL服務。更多背景信息,請點此。
HIDL
Project Treble的服務的分離增加了IPC(進程間通信)的量,以前在AOSP和供應商代碼之間的同一進程中傳遞的數據,現在必須通過AOSP和HAL服務之間通過IPC。由于Android中的大多數IPC都要經過Binder,谷歌決定新的IPC也應該這樣做。
但僅僅使用現有的Binder代碼是滿足不了新的IPC的,Google決定對其進行一些修改。首先,Google引入了多個Binder域,以便將這種新型IPC與其他域分開。更重要的是,他們引入了HIDL,這是一種通過Binder IPC傳遞的數據的全新格式。這種新格式由一組新的庫支持,專用于AOSP和HAL服務之間的IPC新Binder域,其他Binder域仍使用舊格式。
與舊的HIDL格式相比,新HIDL格式的操作有點像層,新舊兩種情況下的底層都是Binder內核驅動程序,但頂層是不同的。對于HAL和AOSP服務之間的通信,使用新的庫;對于其他類型的通信,使用舊的庫。這兩種庫包含的代碼都非常相似,以至于新的HIDL庫中某些原始代碼會直接從舊庫中復制到。雖然每個庫的用法并不完全相同(你不能簡單地用一個替換另一個),但它們仍然非常相似。
這兩組庫都以c++對象的形式表示Binder事務中傳輸的數據,從相對簡單的對象(比如表示字符串的對象)到更復雜的實現(比如文件描述符或對其他服務的引用),這意味著HIDL為許多類型的對象引入了新的實現方式。
共享內存
Binder IPC的一個重要功能就是可以共享內存,為了保持簡單性和良好性能,Binder將每個事務限制為最大1MB。對于進程希望通過Binder在彼此之間共享大量數據的情況,使用共享內存。
為了通過Binder共享內存,進程利用Binder的共享文件描述符的功能。使用mmap可以將文件描述符映射到內存,這允許多個進程通過共享一個文件描述符來共享同一個內存區域,常規Linux(非Android)的一個問題是,文件描述符通常由文件支持,如果進程想要共享匿名內存區域怎么辦?出于這個原因,Android采用了Ashmem匿名共享內存機制,它允許進程在沒有涉及實際文件的情況下分配內存,來備份文件描述符。
是否是通過Binder共享內存處理對象,是HIDL和舊庫之間的一個區別。在這兩種情況下,最終操作都是相同的,一個進程將ashmem文件描述符映射到其內存空間,通過Binder將該文件描述符傳輸到另一個進程,而另一個進程將其映射到自己的內存空間。不過,在處理對象的實現方式上是不同的。
在HIDL的情況下,共享內存的一個重要對象是hidl_memory,如源代碼中所述:“hidl_memory是一種結構,可以用于在進程之間傳輸共享內存”。
漏洞介紹
讓我們來看看hidl_memory的組成內容:

其中mHandle是一個句柄,它是一個HIDL對象,它包含文件描述符(在本文所舉的樣本中只有一個文件描述符)。mSize 表示要共享的內存大小,mName應該代表內存的類型,但是只有ashmem類型與此相關。
當通過HIDL中的Binder傳輸這樣的結構時,復雜對象(比如hidl_handle或hidl_string)有自己的用于寫入和讀取數據的自定義代碼,而簡單類型(比如整數)則沒有自定義代碼。這意味著代碼大小會被轉換為64位整數,而在舊的庫中,則使用32位整數。
這看起來很奇怪,為什么內存的大小應該是64位?為什么不像舊的庫那樣,用32位進程處理這個問題呢?讓我們看一下映射hidl_memory對象(用于ashmem類型)的代碼:

其中,沒有任何關于32位進程的內容,甚至沒有提到64位進程。
那其中到底發生了什么?mmap簽名中的length字段的類型是size_t,這意味著它的位數與進程的位數相匹配。在64位進程中沒有問題,一切都只是64位。另一方面,在32位進程中,大小被截斷為32位,因此僅使用較低的32位。
這意味著,如果32位進程接收到大小大于UINT32_MAX(0xFFFFFFFF)的hidl_memory,則實際的映射內存區域將不夠用。例如,對于大小為0x100001000的hidl_memory,內存區域的大小將僅為0x1000。在這種情況下,如果32位進程是基于hidl_memory大小執行邊界檢查,它們將會失敗,因為它們將錯誤地表明內存區域跨越的范圍超過整個內存空間,這就是漏洞。
尋找攻擊目標
現在我們試著找到一個攻擊目標,尋找符合以下標準的HAL服務:
1.編譯為32位;
2.把對共享內存的接收作為輸入;
3.在共享內存上執行邊界檢查時,不會截斷大小。例如,以下代碼不容易受到攻擊,因為它對截斷的size_t執行邊界檢查:
以上都是此漏洞的基本要求,但我認為還有一些更重要的要求:
4.在AOSP中有默認實現,雖然供應商最終會負責所有HAL服務,但AOSP確實包含某些供應商可以使用的默認實現。我發現在許多情況下,當存在這樣的實現時,供應商不愿意修改它,只是按原樣使用它。這使得這樣的目標更有趣,因為它可能與多個供應商相關,而不是特定于某個供應商的服務。
你應該注意的一件事是,盡管HAL服務應該只能由其他系統服務訪問,但事實并非如此。有一些精選的HAL服務實際上可以由常規的非特權應用程序訪問。因此,最后一個要求是:
5.可以從無特權的應用程序直接訪問,否則漏洞利用將實現不了,下面我們將討論的一個漏洞,只有在你已經破壞了另一個服務的情況下才能訪問它。
幸運的是,我找到了一個滿足所有這些要求的HAL服務:android.hardware.cas,又稱為MediaCasService。
CAS
CAS代表條件訪問系統,簡單來說它與DRM類似。簡單地說,它的功能與DRM相同,有需要解密的加密數據。
MediaCasService
首先,MediaCasService確實允許應用程序解密加密數據。如果你閱讀我以前的文章,就會知道我是如何利用名為MediaDrmServer的服務中的漏洞。你可能會奇怪,我為什么要與DRM進行比較?因為MediaCasService與MediaDrmServer(負責解密DRM媒體的服務)從其API到內部運行方式都非常相似。
需要注意的是,MediaDrmServer這個API被稱為descramble,而不是decrypt(盡管它們最終也會在內部對其進行解密)。
讓我們看看descramble是如何運作的:

不出所料,數據通過共享內存共享,有一個緩沖區指示共享內存的相關部分(稱為srcBuffer,但是對于源和目標都是相關的)。在此緩沖區上,服務從其中讀取源數據以及將目標數據寫入的位置都存在偏移量。此時,源數據不是加密的,在這種情況下,服務只需將數據從源復制到目標,而無需修改它。
這看起來很脆弱,至少,如果服務僅使用hidl_memory大小來驗證它是否完全適合共享內存,而不是其他參數,則會如此。在這種情況下,通過讓服務相信我們的小內存區域跨越了它的整個內存空間,我們就可以繞過邊界檢查,并將源和目標偏移量放在我們喜歡的任何地方。這將使我們能夠對服務內存進行完整的讀寫訪問,因為我們可以從任何地方讀取到共享內存,從共享內存寫入任何地方。注意,負偏移量也應利用此漏洞,因為即使是0xFFFFFFFF(-1)也會小于hidl_memory大小。
讓我們通過查看descramble的代碼來驗證這一點,請注意,函數validateRangeForSize只檢查“first_param + second_param 

可以看到,代碼根據hidl_memory大小檢查srcBuffer是否位于共享內存中。在此之后,不再使用hidl_memory,其余的檢查將針對srcBuffer本身執行。至此,為了實現完整的讀寫訪問,我們需要做的就是使用這個漏洞,然后將srcBuffer的大小設置為大于0xFFFFFFFF。這樣,源和目標偏移量的任何值都是有效的。

使用漏洞進行越界讀取

使用漏洞進行越界寫入
TEE設備
在使用這個原語編寫漏洞之前,讓我們先想好這個漏洞要實現的目標。查看此服務的SELinux規則,就可以看到它實際上受到嚴格限制,并且沒有很多權限。不過,它還有一個普通的非特權應用程序沒有的有趣權限,就是對TEE(可信執行環境)設備的訪問。
此權限非常有趣,因為它允許攻擊者訪問各種各樣的內容,比如不同供應商的不同設備驅動程序、不同的信任區域操作系統和大量信任。在我之前的文章中,我已經討論過這個權限有多危險了。
雖然訪問TEE設備確實可以驗證很多事情,但我只想證明我可以獲得此訪問權限。因此,我的目標是執行一個需要訪問TEE設備的簡單操作。在Qualcomm TEE設備驅動程序中,有一個相當簡單的ioctl,用于查詢設備上運行的QSEOS版本。因此,構建MediaCasService漏洞時的目標是運行此ioctl并獲取其結果。
漏洞利用
到目前為止,我們對目標進程內存進行了完全讀取和寫入。雖然這是一個很好的開始,但有兩個問題需要解決:
1.ASLR:雖然我們有完全的讀訪問權限,但它只與共享內存映射的位置相關。我們并不知道它與內存中的哪些數據進行比較。理想情況下,我們希望找到共享內存的地址以及其他有趣數據的地址。
2.漏洞在每次執行時,共享內存都會被映射,然后在操作后取消映射。不能保證每次都將共享內存映射到同一個位置,在執行期間完全有可能會有另一個內存區域取代原來的映射位置。
讓我們看一下這個特定構建的服務內存空間中鏈接器的一些內存映射:

如上說示,鏈接器恰好在linker_alloc_small_objects和linker_alloc之間創建了2個內存頁(0x2000)的小差距。這些存儲器映射的地址相對較高,此進程加載的所有庫都映射到較低的地址。這意味著這個差距是內存中最高的差距。由于mmap的行為是嘗試將低地址映射到高地址,因此任何映射2頁或更少內存區域的嘗試都應映射到此差距中。幸運的是,該服務通常不會映射這么小的內容,這意味著這個差距應該留在那里。這就解決了我們的第二個問題,因為這是內存中的確定性位置,我們的共享內存將始終映射在這個位置。讓我們直接查看差距之后的linker_alloc中的數據:

這里的鏈接器數據恰好對我們有用,它包含的地址可以很容易的指示linker_alloc內存區域的地址。由于漏洞提供了相對讀取,并且我們已經得出結論,共享內存將在linker_alloc之前被直接映射,因此我們可以使用它來確定共享內存的地址。如果我們取偏移量為0x40的地址并將其減少0x10,就將得到linker_alloc地址,減少共享內存本身的大小將導致共享內存地址。
到目前為止,我們解決了第二個問題,但第一個問題只是部分解決了。雖然我們確實有共享內存的地址,但沒有其他有趣數據的地址,我們感興趣的其他數據還有哪些呢?
劫持一個線程
MediaCasService API的一部分功能是客戶端為事件提供監測的能力,如果客戶端提供偵聽器,則會在發生不同CAS事件時通知它。客戶端也可以自己觸發事件,然后將其發送回偵聽器。Binder和HIDL的工作方式是,當服務向偵聽器發送事件時,它將等待偵聽器完成對事件的處理,等待偵聽器的線程將被阻塞。

觸發事件的流程
此時,我們可以在已知的預定線程中阻止服務中的線程發生阻塞。一旦我們有一個處于這種狀態的線程,就可以修改它的堆棧來劫持它,只有在我們完成后,才能通過完成處理事件來恢復線程。不過,我們如何在內存中找到線程堆棧?
由于我們的確定性共享內存地址很高,該地址與阻塞線程堆棧的可能位置之間的距離很大。由于ASLR的影響,試圖從確定性地址相對地查找線程堆棧太不可靠,所以我們使用了另一種方法,即嘗試使用更大的共享內存,并在阻塞的線程堆棧之前映射它,這樣我們就能夠通過漏洞訪問它。
此時,我們得到多個(5)線程,而不是只有一個線程處于阻塞狀態。這會導致創建更多線程,并分配更多線程堆棧。通過執行此操作,如果內存中存在少量線程堆棧大小的空白,則應填充它們,并且阻塞線程中的至少一個線程堆棧應映射到低地址,而不在其之前映射到任何庫。 mmap是在低地址之前映射高地址的區域,然后,理想情況下,如果我們使用大型共享內存,則應在此之前進行映射。

填充差距并映射共享內存后的MediaCasService內存映射
不過缺點是,有可能其他意想不到的內容(比如jemalloc heap)可能會被映射到其中,因此被阻塞的線程堆棧將不會是我們期望的。可能有多種方法可以解決這個問題。我決定簡單地利用服務崩潰(使用漏洞來寫入未映射的地址)再試一次,因為每次服務崩潰時它都會重新啟動。無論如何,這種情況通常不會發生,即使發生了,一次重試通常就足夠了。
一旦我們的共享內存在被阻塞的線程堆棧之前被映射,我們就可以使用該漏洞從線程堆棧中讀取兩種地址:
1.線程堆棧地址,使用pthread元數據,它位于堆棧本身之后的同一內存區域中。
2.libc映射到的地址,以便稍后使用libc中的gadget 框架和符號構建ROP鏈(libc具有足夠的gadget 框架)。我們通過讀取libc中特定位置的返回地址來實現這一點,libc位于線程堆棧中。

從線程堆棧讀取的數據
至此,我們就可以使用漏洞讀取和寫入線程堆棧。由于我們既有確定性共享內存位置的地址,也有線程堆棧的地址,因此通過使用地址之間的差異,我們可以從共享內存(具有確定性位置的小內存)到達線程堆棧。
ROP鏈
我們可以完全訪問我們可以恢復的被阻塞的線程堆棧,因此下一步是執行ROP鏈。由于我們要準確知道ROP鏈覆蓋堆棧的哪個部分,因此必須時刻關注線程被阻塞的確切狀態。覆蓋部分堆棧后,我們可以恢復線程,從而執行ROP鏈。
遺憾的是,SELinux對此過程的限制使我們無法將此ROP鏈完全轉換為任意代碼來執行。沒有execmem權限,因此無法將匿名內存映射為可執行文件,并且我們無法控制可以映射為可執行文件的文件類型。在本文的示例中,目標非常簡單(運行單個ioctl),所以我只是編寫了一個ROP鏈來執行此操作。從理論上講,如果你想要執行更復雜的操作,那仍然可以利用這個原語。例如,如果你想根據函數的結果執行復雜的邏輯,你可以執行多階段ROP:執行一個運行該函數的ROP鏈并將其結果寫入某處,讀取結果,執行復雜的邏輯,然后基于此運行另一個ROP鏈。
如上所述,由于目標是獲得QSEOS版本,下面是ROP鏈執行的代碼。

stack_addr是堆棧內存區域的地址,它只是一個我們知道的可寫的地址,不會被覆蓋(堆棧從底部開始,不靠近頂部),所以我們可以將結果寫入該地址然后使用此漏洞讀取它。在最后的休眠時,線程不會在運行ROP鏈后立即崩潰,所以我們可以讀取結果。
構建ROP鏈本身非常簡單, libc中有足夠的gadget來執行它,所有的符號也都在libc中,且我們已經擁有了libc的地址。
完成漏洞利用后,我們就完成了劫持一個線程來執行ROP鏈,因此進程處于一個不穩定的狀態。為了使所有內容都處于不被感染的狀態,我們只是使用漏洞(通過寫入未映射的地址)使服務崩潰,以便讓它重新啟動。
總結
正如我之前的文章所講的那樣,雖然谷歌宣稱Project Treble有利于Android的安全性,但我們在本文中所找到的這個漏洞,就可以說明Project Treble并不是無懈可擊的。這個漏洞本身就是Project Treble的一個組成部分,且它不存在于以前的源代碼庫中,僅僅出現在新庫中。由于這個漏洞會出現在一個常用的庫中,因此它影響了許多高權限服務。
GitHub上提供了完整的漏洞利用代碼,注意:本文所講的漏洞僅用于教育或防御目的,它不適用于任何惡意或攻擊性用途。
漏洞發現的時間脈絡
2018.5.3:發現漏洞;
2018.5.7:我們將漏洞詳情及 PoC反饋給Google;
2018.7.2:Google發布了一組補丁;
2018.7.13:谷歌要求我們推遲發布此文章;
2018.9.4:Google發布了一組額外的補丁;
 



熱門文章
  • 機械革命S1 PRO-02 開機不顯示 黑...
  • 聯想ThinkPad NM-C641上電掉電點不...
  • 三星一體激光打印機SCX-4521F維修...
  • 通過串口命令查看EMMC擦寫次數和判...
  • IIS 8 開啟 GZIP壓縮來減少網絡請求...
  • 索尼kd-49x7500e背光一半暗且閃爍 ...
  • 樓宇對講門禁讀卡異常維修,讀卡芯...
  • 新款海信電視機始終停留在開機界面...
  • 常見打印機清零步驟
  • 安裝驅動時提示不包含數字簽名的解...
  • 共享打印機需要密碼的解決方法
  • 圖解Windows 7系統快速共享打印機的...
  • 錦州廣廈電腦上門維修

    報修電話:13840665804  QQ:174984393 (聯系人:毛先生)   
    E-Mail:174984393@qq.com
    維修中心地址:錦州廣廈電腦城
    ICP備案/許可證號:遼ICP備2023002984號-1
    上門服務區域: 遼寧錦州市區
    主要業務: 修電腦,電腦修理,電腦維護,上門維修電腦,黑屏藍屏死機故障排除,無線上網設置,IT服務外包,局域網組建,ADSL共享上網,路由器設置,數據恢復,密碼破解,光盤刻錄制作等服務

    技術支持:微軟等
    主站蜘蛛池模板: 亚洲av福利无码无一区二区| 亚洲中文字幕无码亚洲成A人片 | 狠狠躁天天躁无码中文字幕图| 无码av专区丝袜专区| 国精品无码一区二区三区在线| 中文无码不卡的岛国片| 国产精品午夜福利在线无码| 久久久久久亚洲Av无码精品专口| AV无码小缝喷白浆在线观看 | 秋霞鲁丝片Av无码少妇| 影音先锋无码a∨男人资源站| 国产日韩精品中文字无码| 少妇人妻av无码专区| 无码人妻丰满熟妇区96| 中文字幕丰满伦子无码| 一本一道AV无码中文字幕| 精品无码成人网站久久久久久| 欧洲精品久久久av无码电影| 2014AV天堂无码一区| 国产免费AV片无码永久免费 | 人妻少妇看A偷人无码精品视频| 亚洲AV永久无码精品成人| 亚洲日产无码中文字幕| 国产在线无码视频一区| 亚洲成a∧人片在线观看无码| 无码一区二区波多野结衣播放搜索| 无码人妻丰满熟妇啪啪| 免费无码又爽又刺激高潮| 亚洲成AV人在线播放无码| 亚洲精品无码永久中文字幕| 日韩人妻无码一区二区三区 | 无码精品蜜桃一区二区三区WW| 亚洲另类无码专区丝袜| 无码H黄肉动漫在线观看网站| 色欲狠狠躁天天躁无码中文字幕| 麻豆国产精品无码视频| 久久精品无码中文字幕| 内射人妻无码色AV天堂| 色综合久久久无码中文字幕波多| 无码人妻丰满熟妇区五十路| 亚洲AV无码AV男人的天堂不卡|