當前位置:
首頁 > 新聞 > iOS越獄主要步驟揭秘

iOS越獄主要步驟揭秘

對普通用戶以及很多技術人員來說,越獄過程一直都是一個神秘過程,對他們來說,所知道的就是在運行越獄程序幾秒鐘後iOS系統突然脫離蘋果的操作環境。而至於越獄程序在此期間發生了什麼事,一般人是不知道的。所以在這篇文章中,我將嘗試揭秘越獄的主要步驟,本文內容並不包含各種iOS版本中所使用的各種越獄工具的不同的補丁和技術,但讀完後,你將大有收穫。

為什麼要越獄?

該過程的命名可能來自Apple的「Jailed」方法,在越獄前,應用程序和用戶只能使用Apple提供的功能,這其實這只是Apple設備功能中的一小部分。因此為了打破原有設備的功能限制,就必須越獄。

不過在此要強調一下,裝了Cydia並不算越獄。它只是iPhone、iPod touch、iPad等設備上的一種破解軟體,類似蘋果在線軟體商店iTunes Store的軟體平台的客戶端,在越獄的過程中被裝入到系統中的,其中多數為iPhone、iPod Touch、ipad的第三方軟體和補丁,主要都是彌補系統不足用。

Cydia本質是一個GUI(圖形用戶界面)應用程序,它在後台使用dpkg和apt等來安裝.deb(Debian)軟體包。這些軟體包遵循非常嚴格的格式,具體的我將在稍後討論。但其實,你不需要Cydia就能安裝軟體包。由於Cydia依賴於apt和dpkg等,因此你可以通過SSH或通過設備上的移動終端應用程序簡單的使用這些二進位文件。

2017年的聖誕節,開發者Jonathan Levin為我們帶來了一款名為LiberiOS的越獄工具,支持運行iOS11.0~11.1.2系統的64位設備進行越獄,以此獲得讀取與修改iOS11的最高許可權。這可能是迄今為止最穩定的iOS 11越獄工具,主要是針對研究人員和高級用戶,而不是普通民眾。

越獄程序是如何運行的?

在打開Cydia,Installer 5,Icy Project或SSH之前,必須運行越獄程序。越獄在不同階段的運行內容取決於iOS版本和設備,過去,它對設備類型的依賴程度較低,但隨著iOS 9.0上的KPP(內核補丁保護程序)和iOS 10上的KTRR(據稱是內核文本只讀區域)的出現,對設備類型的依賴程度越來越高。例如,iPhone 7之前的設備使用KPP,這是在EL3(ARM Exception LEVEL 3)中運行的軟體保護,但iPhone 7及其以上版本使用的是基於硬體的KTRR。在這種情況下,包含KPP繞過(如Yalu)的越獄在iPhone 7及其以上版本中是不起作用的,因為KPP本身不在iPhone 7上。對於這些設備,需要進行各種KTRR繞過,因此,越獄工具必須非常了解它所處理的設備類型。

想知道越獄的歷史嗎?讓我以iOS 7.x.x的Pangu為例進行說明

Pangu越獄是中國越獄團隊「盤古」開發的一款iOS完美越獄工具,適配機型涵蓋全系列運行iOS7.1.1的蘋果設備, 採用一鍵式越獄,具有中英文界面,同時針對中文進行主頁面優化,更加貼合中國用戶的需求和使用習慣。

在設備運行之前,越獄工具就必須以某種方式將越獄有效載荷部署到設備上。這可能聽起來沒有什麼,因為任何人都可以通過訪問免費的Apple Developer帳戶來簽署IPA文件,然後用Cydia Impactor或類似的工具將其安裝到設備上,但它以前並沒有這麼簡單。因為這個自簽名配置文件是由從iOS 9.0才有的,而iOS 9.0在越獄歷史上所佔的地位卻很小。

早在出現專門的越獄工具之前,codesign就已經被那些高度熟練的越獄團隊以非常有趣的方式繞過了。如果你還用的是iPhone 4,你可能會因為使用的是iOS 7.1 - 7.1.2而被Pangu越獄。不過,現在這種技術已經不適用了。所以我談論的是iOS 7.1.x,請注意,免費提供配置文件的自簽名和部署簽名的IPA不是一回事。因為針對 iOS 7.1- 7.1.2的Pangu有自己的Windows和macOS程序,可以為用戶自動部署,用的是當時存在的企業證書籤署的。

然而,由於企業證書已經不再使用。計算機上的盤古程序會要求用戶將設備的日期和時間設置回2014年6月2日。

由於這個虛擬應用程序是由盤古程序部署的,它的主要目的是刪除這個簽名證書。IPA本身實際上是盤古Windows/macOS二進位本身的一部分。通過使用任何反彙編程序(我使用的是Jtool和IDA)可以很容易的發現這一點,由Jonathan Levin開發的Jtool可以生成HTML輸出。

以下是macOS上的Pangu二進位文件的樣式,你看到多餘的部分了嗎?

LC 00: LC_SEGMENT_64 Mem: 0x000000000-0x100000000 __PAGEZERO

LC 01: LC_SEGMENT_64 Mem: 0x100000000-0x101e71000 __TEXT

Mem: 0x100002370-0x1000292cf __TEXT.__text (Normal)

Mem: 0x1000292d0-0x10002982e __TEXT.__stubs (Symbol Stubs)

Mem: 0x100029830-0x10002a132 __TEXT.__stub_helper (Normal)

Mem: 0x10002a140-0x10002a690 __TEXT.__const

Mem: 0x10002a690-0x10002b914 __TEXT.__objc_methname (C-String Literals)

Mem: 0x10002b914-0x10002b9d5 __TEXT.__objc_classname (C-String Literals)

Mem: 0x10002b9d5-0x10002beb6 __TEXT.__objc_methtype (C-String Literals)

Mem: 0x10002bec0-0x10002e8d5 __TEXT.__cstring (C-String Literals)

Mem: 0x10002e8d6-0x10002e92e __TEXT.__ustring

Mem: 0x10002e92e-0x10003dc04 __TEXT.__objc_cons1

Mem: 0x10003dc04-0x10029ed87 __TEXT.__objc_cons2 ; Yeee, see this!

Mem: 0x10029ed87-0x1002b71a9 __TEXT.__objc_cons3

Mem: 0x1002b71a9-0x100f11a36 __TEXT.__objc_cons4

Mem: 0x100f11a36-0x10160e0ca __TEXT.__objc_cons5

Mem: 0x10160e0ca-0x101dd6e3f __TEXT.__objc_cons6

Mem: 0x101dd6e3f-0x101dd7152 __TEXT.__objc_cons7

Mem: 0x101dd7152-0x101dd7a17 __TEXT.__objc_cons8

Mem: 0x101dd7a17-0x101e45a6e __TEXT.__objc_cons9

Mem: 0x101e45a6e-0x101e57e74 __TEXT.__objc_cons10

Mem: 0x101e57e74-0x101e69288 __TEXT.__objc_cons11

Mem: 0x101e69288-0x101e699e0 __TEXT.__unwind_info

Mem: 0x101e699e0-0x101e71000 __TEXT.__eh_frame

LC 02: LC_SEGMENT_64 Mem: 0x101e71000-0x101e75000 __DATA

Mem: 0x101e71000-0x101e71028 __DATA.__program_vars

Mem: 0x101e71028-0x101e710b8 __DATA.__got (Non-Lazy Symbol Ptrs)

Mem: 0x101e710b8-0x101e710c8 __DATA.__nl_symbol_ptr (Non-Lazy Symbol Ptrs)

Mem: 0x101e710c8-0x101e717f0 __DATA.__la_symbol_ptr (Lazy Symbol Ptrs)

Mem: 0x101e717f0-0x101e717f8 __DATA.__mod_init_func (Module Init Function Ptrs)

Mem: 0x101e717f8-0x101e71800 __DATA.__mod_term_func (Module Termination Function Ptrs)

Mem: 0x101e71800-0x101e71b40 __DATA.__const

Mem: 0x101e71b40-0x101e71b60 __DATA.__objc_classlist (Normal)

Mem: 0x101e71b60-0x101e71b68 __DATA.__objc_nlclslist (Normal)

Mem: 0x101e71b68-0x101e71b78 __DATA.__objc_catlist (Normal)

Mem: 0x101e71b78-0x101e71ba0 __DATA.__objc_protolist

Mem: 0x101e71ba0-0x101e71ba8 __DATA.__objc_imageinfo

Mem: 0x101e71ba8-0x101e72f90 __DATA.__objc_const

Mem: 0x101e72f90-0x101e73590 __DATA.__objc_selrefs (Literal Pointers)

Mem: 0x101e73590-0x101e735a0 __DATA.__objc_protorefs

Mem: 0x101e735a0-0x101e736f8 __DATA.__objc_classrefs (Normal)

Mem: 0x101e736f8-0x101e73718 __DATA.__objc_superrefs (Normal)

Mem: 0x101e73718-0x101e738a8 __DATA.__objc_data

Mem: 0x101e738a8-0x101e73930 __DATA.__objc_ivar

Mem: 0x101e73930-0x101e74390 __DATA.__cfstring

Mem: 0x101e74390-0x101e746b8 __DATA.__data

Mem: 0x101e746c0-0x101e74b60 __DATA.__bss (Zero Fill)

Mem: 0x101e74b60-0x101e74b90 __DATA.__common (Zero Fill)LC 03: LC_SEGMENT_64 Mem: 0x101e75000-0x101eba000 __ui0

LC 04: LC_SEGMENT_64 Mem: 0x101eba000-0x101ebf000 __LINKEDIT

LC 05: LC_DYLD_INFO

LC 06: LC_SYMTAB

Symbol table is at offset 0x1ebbc48 (32226376), 293 entries

String table is at offset 0x1ebd610 (32232976), 4776 bytes

....

你看到__TEXT .__ objc_cons2部分了嗎?

如果你執行0x10029ed87 - 0x10003dc04 = 2494851位元組(十進位)=> 2.494851兆位元組,那工作量將會很大,因為它是嵌入式IPA文件。objc_cons1,objc_cons2和objc_cons3都是越獄載荷(untether,plists,libraries等)的嵌入部分。

Jtool是一個非常強大的工具,它能夠從二進位文件中提取整個部分。該命令是jtool -e(extract)/ path。如果我們對Pangu二進位文件執行此操作,那將獲得一個名為「pangu .__ TEXT .__ objc_cons2」的新文件,這恰好被文件(1)識別為「來自Unix的「gzip壓縮數據」,因此tar tvf應該能夠很好的列出內容。

Saigon:~ geosn0w$ /Users/geosn0w/Desktop/ToolChain/jtool/jtool -e __TEXT.__objc_cons2 /Users/geosn0w/Desktop/pangu.app/Contents/MacOS/pangu

Requested section found at Offset 252932

Extracting __TEXT.__objc_cons2 at 252932, 2494851 (261183) bytes into pangu.__TEXT.__objc_cons2

Saigon:~ geosn0w$ file /Users/geosn0w/pangu.__TEXT.__objc_cons2

/Users/geosn0w/pangu.__TEXT.__objc_cons2: gzip compressed data, from Unix

Saigon:~ geosn0w$ tar tvf /Users/geosn0w/pangu.__TEXT.__objc_cons2

drwxrwxrwx 0 0 0 0 Jun 27 2014 Payload/

drwxrwxrwx 0 0 0 0 Jun 27 2014 Payload/ipa1.app/

drwxrwxrwx 0 0 0 0 Jun 27 2014 Payload/ipa1.app/_CodeSignature/-rwxrwxrwx 0 0 0 3638 Jun 27 2014 Payload/ipa1.app/_CodeSignature/CodeResources-rwxrwxrwx 0 0 0 15112 Jun 27 2014 Payload/ipa1.app/AppIcon60x60@2x.png-rwxrwxrwx 0 0 0 20753 Jun 27 2014 Payload/ipa1.app/AppIcon76x76@2x~ipad.png-rwxrwxrwx 0 0 0 8017 Jun 27 2014 Payload/ipa1.app/AppIcon76x76~ipad.png-rwxrwxrwx 0 0 0 75320 Jun 27 2014 Payload/ipa1.app/Assets.car-rwxrwxrwx 0 0 0 7399 Jun 27 2014 Payload/ipa1.app/embedded.mobileprovision

drwxrwxrwx 0 0 0 0 Jun 27 2014 Payload/ipa1.app/en.lproj/-rwxrwxrwx 0 0 0 74 Jun 27 2014 Payload/ipa1.app/en.lproj/InfoPlist.strings-rwxrwxrwx 0 0 0 1955 Jun 27 2014 Payload/ipa1.app/Info.plist-rwxrwxrwx 0 0 0 312208 Jun 27 2014 Payload/ipa1.app/ipa1-rwxrwxrwx 0 0 0 968 Jun 27 2014 Payload/ipa1.app/ipa1-Info.plist-rwxrwxrwx 0 0 0 235794 Jun 27 2014 Payload/ipa1.app/LaunchImage-700-568h@2x.png-rwxrwxrwx 0 0 0 785321 Jun 27 2014 Payload/ipa1.app/LaunchImage-700-Landscape@2x~ipad.png-rwxrwxrwx 0 0 0 261481 Jun 27 2014 Payload/ipa1.app/LaunchImage-700-Landscape~ipad.png-rwxrwxrwx 0 0 0 660541 Jun 27 2014 Payload/ipa1.app/LaunchImage-700-Portrait@2x~ipad.png-rwxrwxrwx 0 0 0 244644 Jun 27 2014 Payload/ipa1.app/LaunchImage-700-Portrait~ipad.png-rwxrwxrwx 0 0 0 216627 Jun 27 2014 Payload/ipa1.app/LaunchImage-700@2x.png-rwxrwxrwx 0 0 0 8 Jun 27 2014 Payload/ipa1.app/PkgInfo-rwxrwxrwx 0 0 0 150 Jun 27 2014 Payload/ipa1.app/ResourceRules.plist

drwxrwxrwx 0 0 0 0 Jun 27 2014 Payload/ipa1.app/zh-Hans.lproj/-rwxrwxrwx 0 0 0 73 Jun 27 2014 Payload/ipa1.app/zh-Hans.lproj/InfoPlist.strings

Saigon:~ geosn0w$

執行tar xvf會將內容提取到「Payload」文件夾。因此,在手機上部署的IPA文件實際上是ipa1。如上所示,有一個名為embedded.mobileprovision的文件,其中包含企業證書。如果我們右鍵單擊它並選擇「獲取信息」,Finder可以向我們顯示有關嵌入式證書的一些信息。如下所示,它屬於「Hefei Bo Fang」。

正如你所看到的,像許多其他越獄方式一樣,Pangu也依賴於開發人員證書來繞過CodeSign,但是將IPA部署到設備並不像你想像的那麼容易。如今,我們可以迅速啟動Cydia Impactor,拖入IPA,然後登錄就可以了。但在iOS 9.0之前,情況並非如此。

在iTunes 12.x之前,iTunes可以輕鬆地與蘋果設備通信,iTunes也能夠處理iOS應用程序。不過,現在iTunes的這些功能都沒有,這意味著,一個或多個框架(或Windows民用的DLL)必須能夠創建與設備的連接並執行與應用程序相關的任務。當然,這是以談論AppleMobileDevice(framework/dll)來進行說明的。在iTunes及其驅動程序包中,這個框架以前主要用于越獄,現在仍然被Windows上所有「備份iOS/照片/聯繫人/其他」程序用於與設備進行可靠的通信。當然,這些API是都是用戶越獄後私自安裝的,也在libimobiledevice項目中重新被創建。

這樣,Pangu就可以與設備通信,並在適當的時候刪除有效載荷。接下來,我將在下面討論一組近乎公式化的規範補丁。

之所以以最新的Pangu為例,是因為與redsn0w等相比,它適用以下大部分下載的補丁,也因為它是我在iPhone 4上經常使用的越獄之一。

我主要以它為例進行說明,以便你可以看到當時繞過CodeSign與現在繞過CodeSign之間的區別。

規範補丁

我創建了下面的越獄流程圖表,理論上它應該顯示大多數越獄的流程。當然,現實的實現過程還是根據iOS版本的不同而有差異的,並且一些越獄流程可能以完全不同的順序來執行。

如上圖所示,最重要的一步是讓越獄程序載入到設備中。Pangu的這個載入過程可與如今看到的越獄過程不同。如今,大多數越獄程序,包括我開發的Osiris,Coolstar&Co開發的Electra,Jonathan開發的LiberiOS,都會通過臨時證書籤署的IPA應用程序,並使用Xcode或Cydia Impactor(或簽名服務)部署到設備上。之後,用戶才能對越獄程序進行操作並觸發漏洞,

其中比較常見的是觸發WebKit漏洞和郵件漏洞。TotallyNotSpyware就是一個適用於從iOS 10.x到10.3.3 64位越獄的很好的例子,如果我們談論的是Legacy啟動模式,則JailbreakMe系列越獄軟體可能就是最好的例子,JailbreakMe是一款用於iPhone、iPad、iPod Touch上的一款最簡便的iOS越獄軟體,是由著名的開發人員Comex所開發的。這些基於WebKit的越獄通常是通過在設備上訪問Safari中的網站來部署的,該網站經過精心設計,可以利用webkit漏洞(WebKit是Safari的內核),從而獲得任意代碼執行。

在接下來的文章中,我所講解的越獄前提假設都是基於IPA的越獄,如Osiris,LiberiOS或Electra。此外,這篇文章的討論還假設我們已經有了一個原始內核漏洞利用程序,它為我們提供了TFP0和KPPless方法。

應用程序成功安裝並運行後,至少在初始階段,繞過CodeSign不再是問題。不過我們仍然無法運行未簽名或偽造簽名的二進位文件,但至少我們可以自己運行(漏洞利用程序)而不會被移動文件完整性(AMFI)安全功能殺死。然而,問題是我們現在仍然受到沙箱的安全限制。因為沙箱使我們無法訪問容器外的任何內容,因此我們沒有R/W許可權。此時,我們只能看到自己的數據,僅此而已。為此,我們必須讓Shai Hulud變得更加強大。

沙箱是一個內核擴展(KEXT),它是確保你不會訪問超出你應該訪問的內容。默認情況下,/var/mobile/Containers中的所有內容都在沙箱中,因為Apple自己的默認應用程序也是被沙箱化了。當你通過Xcode,App Store或Cydia Impactor安裝應用程序時,你將自動將應用程序放在/var/mobile/Containers/Bundle/Application/中。由於沒有其他方法可以安裝應用程序,所以我們安裝的越獄應用程序將默認都在沙箱中進行。

那麼,越獄應用程序是如何獲得運行所需的服務的呢?比如:如何把Deezer(法國在線音樂網)如何連接我的藍牙耳機?YouTube如何解碼通信的幀?Twitter如何向我發送通知?很簡單,通過API即可完成。這些API允許你的容器化應用程序以受控方式與核心服務(bluetoothd,wifid,mediaserverd等)進行通信,這些服務也在沙箱中進行,並且通過IOKit與kexts /內核通信。所以你不能直接與內核通信。下圖即為整個流程:

當然,作為iOS上的應用程序,你不僅無法看到文件系統和用戶數據,而且你也很大程度上不了解任何其他應用程序的存在。如果其他應用程序被註冊為接受處理此類輸入的應用程序,那通過一些API,你可以將文件/數據傳遞給另一個應用程序,但即使這樣,你的應用程序也不知道其他應用程序的存在以及通過iOS提供的一系列API,不過你可以傳遞.PDF文件,例如,在任何應用程序中打開它。

不過有些應用程序還提供了URI方案,供你與它們進行通信。假設你在iOS上使用Chrome瀏覽器,並且你可以找到要服務公司的電話號碼。如果你按下這個號碼,系統會詢問你是否真的要聯繫客服,然後直接利用iOS撥打電話應用程序撥打。知道這個過程是如何實現的嗎?

這個過程非常簡單,由於電話應用程序已註冊了一個如下所示的URI方案:tel:// xxxxxxxxxxxxxxxxxx,如果你將tel://5552220001添加到HTML頁面並在Safari中單擊它,iOS就知道該打開誰來處理它。同樣,這個方案也適用於Facebook,Whatsapp,如果它們要使用應用程序中的URI方案,你只需調用正確的UIApplication方法即可。如下所示:

UIApplication.shared.open(url, options: [:], completionHandler: nil)

由於你能夠將數據傳遞到另一個應用程序並打開它,所以你認為現在你已經繞過沙箱了嗎?其實你離這個目標還差很遠,你以上所做的只是使用了一組控制良好的API,因為你不知道手機應用程序的存在,但iOS知道。以下是沙箱對應用程序的檢測。

避免沙箱檢測的方法可以通過多種方式完成:Osiris越獄使用QiLin的內置沙箱進行逃逸,稱為「ShaiHulud」。QiLin以及LiberiOS和Osiris越獄,都是通過偽造內核的憑證逃脫了沙箱。如果你擁有內核的憑證,就可以訪問任何我們想要的內容,包括像execve()、fork()和posix_spawn()這樣的系統調用,Jonathan Levin在這篇文章中,非常清楚地解釋了QiLin如何逃離沙箱。

當然,QiLin保存了應用程序的憑證,並在退出之前恢復它們,這是為了防止由於內核cred被鎖定而造成的恐慌。

適用於iOS 11.2.x的Electra - > iOS 11.3.1也會使用相同的內核憑證方法繞過沙箱和其他許可權。

重新對文件系統執行mount命令

mount是Linux下的一個命令,它可以將分區掛接到Linux的一個文件夾下,從而將分區和該目錄聯繫起來,因此我們只要訪問這個文件夾,就相當於訪問該分區了。目前mount已經不僅僅局限於Linux了。在Windows系統下的應用也越來越廣了,多用在虛擬光碟機類軟體上,比如Clone CD,Daemon tool,WinMount等。

所以,我要利用的就是內核,並獲得內核內存的R/W許可權,為此我利用了其中一個漏洞,才獲得了內核憑證,才逃避了沙箱的檢測,現在我想要做的就是刪除我的有效載荷,這可以包含Cydia、二進位文件、配置文件以及用於檢查是否安裝了越獄的虛擬文件等。為了能夠做到這一點,就需要我獲取文件系統的R/W許可權。默認情況下,iOS ROOT FS僅以只讀方式執行mount命令,因此我們需要重新執行mount命令,為此我需要的修補程序的名稱為Root FS Remount,這個組件是在2018年7月iOS 11.3.1的Electra開發時丟失的。

那麼,我們該怎麼做?

在QiLin以及在LiberiOS和Osiris越獄上,重新在iOS 11.2.6上執行mount命令的方式是這樣的:正如我以上所說,默認情況下ROOT FS是以只讀方式執行mount命令。不僅如此,沙箱還有一個掛鉤,可以防止你重新執行mount命令而獲得R/W許可權。掛鉤是通過mount_begin_update()和mount_common()中的MACF調用強制執行的。所有掛鉤都會檢查mount命令中是否存在MNT_ROOTFS標誌。如果存在,則操作失敗。此時,QiLin會關閉MNT_ROOTFS標誌。

以下列表是QiLin Toolkit中的remountRootFS,由Jonathan Levin發布。

int remountRootFS (void){

...

uint64_t rootVnodeAddr = findKernelSymbol("_rootvnode");

uint64_t *actualVnodeAddr;

struct vnode *rootvnode = 0;

char *v_mount;

status("Attempting to remount rootFS...
");

readKernelMemory(rootVnodeAddr, sizeof(void *), &actualVnodeAddr);

readKernelMemory(*actualVnodeAddr, sizeof(struct vnode), &rootvnode);

readKernelMemory(rootvnode->v_mount, 0x100, &v_mount);

// Disable MNT_ROOTFS momentarily, remounts , and then flips the flag back uint32_t mountFlags = (*(uint32_t * )(v_mount + 0x70)) & ~(MNT_ROOTFS | MNT_RDONLY);

writeKernelMemory(((char *)rootvnode->v_mount) + 0x70 ,sizeof(mountFlags), &mountFlags);

char *opts = strdup("/dev/disk0s1s1");

// Not enough to just change the MNT_RDONLY flag - we have to call // mount(2) again, to refresh the kernel code paths for mounting.. int rc = mount("apfs", "/", MNT_UPDATE, (void *)&opts);

printf("RC: %d (flags: 0x%x) %s
", rc, mountFlags, strerror(errno));

mountFlags |= MNT_ROOTFS;

writeKernelMemory(((char *)rootvnode->v_mount) + 0x70 ,sizeof(mountFlags), &mountFlags);

// Quick test: int fd = open ("/test.txt", O_TRUNC| O_CREAT);

if (fd

else {

status("Mounted / as read write :-)
");

unlink("/test.txt"); // clean up }

return 0;

Jonathan Levin的代碼很簡單,逆向MNT_ROOTFS標誌,調用mount(2)刷新內核代碼路徑以執行mount命令、恢復標誌並進行測試。此時,你就具有了R/W許可權。

我以上所說的,都存在於較舊的越獄補丁LightweightVolumeManager :: _ mapForIO中。

對Electra越獄工具重新執行mount命令

iOS 11.3更進一步,加入了APFS快照。當蘋果開始使用快照的時候,APFS已經在iOS中使用了很長一段時間,但是這破壞了我對iOS 11.2.x甚至更早版本的越獄嘗試,我必須得重新執行mount命令。要解決這個問題,我就需要找到一個新的漏洞。但問題是iOS會恢復到以只具有隻讀方式mount命令的快照,這樣我以前安裝的所有關於微調、二進位等方面的內容都消失了。

此時,只能通過更改整個越獄過程並使用Rootless機制(可以將該機制理解為一個更高等級的系統的內核保護措施,系統默認將會鎖定 /system、/sbin、/usr 這三個目錄。),或者找到一個方法繞過快照。在此,感謝@ Pwn20wnd和@umanghere已經重新創建的mount命令,Umang發現了pwn20wnd在Electra中利用的一個漏洞。

Pwn20wnd繞過這個快照的方法非常簡單,用於iOS 11.3.1的Electra源代碼中的函數可能看起來很複雜。那是因為Pwn20wnd花了很多工作來實現這個繞過,但是一旦開始利用這個漏洞,就會出現錯誤。請注意,該錯誤非常簡單,如果有重啟,iOS將在每次重啟後恢復為APFS系統快照。此時如果沒有捕獲機制,iOS就會像在沒有快照的iOS 11.2.6上一樣,隨意的繼續啟動,而不是以被破壞的方式啟動或出錯。

至於補丁,可以查找快照並將其重命名為其他內容。至於越獄過程就有點複雜,如果你分析代碼,就可以看到所述快照的名稱是動態的或至少包含動態部分,因此無法進行硬編碼。動態部分恰好是boot-manifest-hash。在做任何事情之前,Pwn20wnd似乎能賦予自己內核憑證。

你可以通過運行以下命令找到它boot-manifest-hash:

ioreg -p IODeviceTree -l | grep boot-manifest-hash

在Electra中,查找boot-manifest-hash的所有邏輯都位於apfs_util.c中,如下所示:

char *copyBootHash(void) {

unsigned char buf[1024];

uint32_t length = 1024;

io_registry_entry_t chosen = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/chosen");

if (!MACH_PORT_VALID(chosen)) {

printf("Unable to get IODeviceTree:/chosen port
");

return NULL;

}

kern_return_t ret = IORegistryEntryGetProperty(chosen, "boot-manifest-hash", (void*)buf, &length);

IOObjectRelease(chosen);

if (ret != ERR_SUCCESS) {

printf("Unable to read boot-manifest-hash
");

return NULL;

}

// Make a hex string out of the hash char manifestHash[length*2+1];

bzero(manifestHash, sizeof(manifestHash));

int i;

for (i=0; i

sprintf(manifestHash+i*2, "%02X", buf[i]);

}

printf("Hash: %s
", manifestHash);

return strdup(manifestHash);}

這個函數從另一個名為find_system_snapshot的函數內部調用,該函數處理查找快照本身的邏輯。該函數將檢索到的manifestHash附加到硬編碼部分com.apple.os.update-,以得到當前快照的真實名稱,然後它將快照名稱返回給調用者。

const char *find_system_snapshot(const char *rootfsmnt) {

char *bootHash = copyBootHash();

char *system_snapshot = malloc(sizeof(char *) + (21 + strlen(bootHash)));

bzero(system_snapshot, sizeof(char *) + (21 + strlen(bootHash)));

if (!bootHash) {

return NULL;

}

sprintf(system_snapshot, "com.apple.os.update-%s", bootHash);

printf("System snapshot: %s
", system_snapshot);

return system_snapshot;}

有了內核的憑證,以及正確的快照名稱,Pwn20wnd就將返回rootfs_remount.c,以獲取重命名快照。將其重命名為「orig-fs」,然後Pwn20wnd將檢查重命名是否成功,此時Pwn20wnd會恢復自己的憑證並刪除內核憑證。 最後,Pwn20wnd重新啟動設備,這就是為什麼第一次在iOS 11.3-11.3.1中使用Electra時,無論你使用的是哪種漏洞,你的設備都會強制重新啟動。

重命名了快照後,iOS就沒有要執行mount命令的快照了。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嘶吼RoarTalk 的精彩文章:

如何使用Python腳本分析惡意軟體
攻擊者如何使用常見的MDM功能對iOS設備發起攻擊

TAG:嘶吼RoarTalk |