1. 程式人生 > >iOS逆向+越獄

iOS逆向+越獄

targe signature 有符號 .cn 模塊 issues appstore 安裝步驟 private

感覺本文涉及內容有點多的,但是自己不願意寫太多,就簡單的謝謝關於ios上手的東西吧

初級入手不免要用到,pp助手,i4 tools等

iOS逆向-ipa包重簽名及非越獄手機安裝多個應用

1.常識

我們平時開發的App,程序運行主要就是加載一個Mach-o可執行文件。當我們將程序打包成ipa文件,上傳到App Store的時候,期間就是進行了一些加殼操作,比如:數字證書簽名等。重簽名的目的就是將別人的程序重新簽上我們的證書信息。也可以簡單理解為將別人的加密文件解密,加上我們自己的加密算法。 2.查看應用是否加殼

將下載好的ipa包解壓縮之後,拿到裏面的Mach-o文件,cd

到所在目錄,執行如下命令:

otool -l 可執行文件路徑 | grep crypt

其中cryptid代表是否加殼,1代表加殼,0代表已脫殼。其實代表著該可執行文件支持兩種架構armv7arm64.
3.查看應用支持架構
lipo -info 文件路徑
4.應用脫殼
  • 一、直接從一些第三方應用商店裏面下載你想脫殼的應用,例如:PP助手iTools
  • 二、自己脫殼,利用GitHub上開源的一些工具,常用的有Clutch、dumdecrypted。具體如何使用,請自行Google
  • 步驟
  • 一臺iPhone,越不越獄都行
  • 開發者證書或者企業證書(個人賬號也行,但是應用安裝上之後,有效期只有7天)
  • 電腦安裝 iOS App Signer
5.利用iOS app Signer 給app重寫簽名

其實重簽名的方式有很多,比如:可以利用sigh resign命令,在終端下操作,還可以借助一些逆向相關的重簽名工具

  • 第一項:對應的.ipa或者.app路徑 ---已經脫殼好的app 可以從皮皮助手下載
  • 第二項:我們自己的簽名證書
    • 註意:個人證書不能重簽Extension文件,所以要刪除ipa包中包含的相應文件,包括Watch裏面的Extension,為了方便一般直接將Watch文件刪除:
    • 將對用的ipa文件解壓,修改一些東西

  • 第三項:證書對應的Profile文件,默認項Re-Sign Only是無效的,選擇證書下存在的Profile文件)
  • 第四項:重簽名之後的Bundle identifier(選擇了Profile文件,一般會自動填寫)
  • 下面的幾項隨便寫
  • 簽名完畢之後對應的文件夾下會生成重簽名之後的ipa包 ---註意:利用iOS App Signer重簽名,在刪除掉相應的Extension,選擇路徑的時候,一定要選擇Payload文件夾下對應的.app文件,否則會報找不到Payload文件夾的錯誤:

6.安裝重簽名之後的微信

可以用PP助手安裝,也可以用Xcode

備註:多個證書可以多次重新簽名,安裝多個相同的應用

版本越獄

幾乎ipad,iPhone等對應不同版本偶不同的越獄技巧

簡單的說通過組件漏洞來進行文件控制,達到控制內核,進而提升用戶權限。

下面我簡單說幾個關鍵名詞 一下轉自http://blog.sina.com.cn/s/blog_655dac9e01017wv3.html

越獄的內部工作原理是完全不知道的。許多人把越獄當黑匣子看待;當他們在越獄工具選項裏點擊jailbreak按鈕,認為工作起來像魔術一樣。這是由於對於他們所進行的越獄操作並不需要知道越獄的內部工作原理,如用戶層漏洞。

越獄的保持(Jailbreak Persistence)

依賴越獄使用的漏洞,越獄的效果可能長期的,也可能在設備關機再開啟後消失。為了描述兩種不同的越獄,越獄社區把這兩種方式叫做 完美越獄(tethered jailbreak)和非完美越獄(untethered jailbreak)。

  非完美越獄

  完美越獄(Untethered Jailbreaks)

漏洞類型(Exploit Type)

漏洞的存在位置影響你對設備的存取級別。一些允許低級別的硬件存取。另一些受限於沙盒內的許可權限。 由高到低
  Bootrom級別 =硬件版本

  iBoot級別 <=硬件版本

  Userland級別 =軟件版本

理解越獄過程(Understanding the Jailbreaking Process)

,把你的iPhone設置為設備固件升級(DFU)狀態

當你點擊Jailbreak越獄按鈕後,紅雪指導設置你的iPhone為DFU模式,根據你連接上的設備,提供你可選擇的不同的越獄特性。你簡單選擇你的選項(如多任務手勢),點擊Next繼續按鈕,等待紅雪完成它的工作。

從用戶角度看這是非常簡單的過程,但是這這些操作後面發生了很多事情,並且除了越獄社區的少數人,沒人真的知道發生了什麽。當你讀完下面章節後,你將成為了解紅雪內部工作的少數人之一。

經作者的允許,下面章節的所有信息都來自一個反編譯版本的紅雪越獄。由於A5處理器的iPad2或iPhone 4S設備沒有一個公開知曉的bootrom漏洞,這些設備的所有越獄必須是用戶層面級別的。 這表示bootrom破解和啟動ramdisk的頭兩個步驟必須由MobileSafari漏洞和一個內核漏洞替代,其余的越獄過程工作是一樣的。

  破解Bootrom(Exploiting the Bootrom)

紅雪的越獄開始時利用the limera1n 的DFU bootrom漏洞來使在高權限級別執行代碼成為可能。這個漏洞是一個前A5處理器設備的bootrom中USB DFU堆棧中的基於堆的緩沖區溢出漏洞。我們這裏不討論漏洞的細節。如果感興趣,你可以在諸如THEiPHONEWiKi(http://theiphonewiki.com/wiki/index.php?title=Limera1n_Exploit)的一些地方找到這個漏洞的說明和源代碼。

對越獄來說,你唯一需要知道的是這個漏洞用來給bootrom裏的簽名驗證代碼打補丁修改,允許你啟動專門的ramdisk,給Low-Level-Bootloader (LLB)、 iBoot和內核的版本打補丁。 Chronic Dev Team團隊已在GitHub(https://github.com/Chronic-Dev/syringe)上釋放了同樣執行效果的源代碼。由於紅雪沒有公開源代碼,如果你想重頭編寫自己的越獄工具,這些代碼是一個很好的起點。

  啟動Ramdisk(Booting the Ramdisk)

紅雪利用 limera1n 漏洞啟動一個打補丁修改過的內核和一個預先定制的ramdisk。內核被打了一些越獄補丁以便允許執行未簽名的代碼。然而,它並沒包括在已完美越獄的系統中發現所有內核補丁。依據用戶在越獄時設置的開關選項,ramdisk在每次運行時都在根目錄創建不同的文件,形成定制的ramdisk。這些文件的存在在晚些時候會被ramdisk上的越獄執行過程檢測到,以此決定紅雪的哪種特性被激活。例如noUntetherHacks文件的存在會使紅雪跳過完美越獄漏洞的安裝。

ramdisk啟動時,內核會運行 ramdisk的/sbin/launchd的二進制文件,它包括一個初始化越獄的小型stub程序。這個程序首先在系統裏裝載root根文件系統和數據分區,為修改需要,以上裝載好的文件系統和數據分區是可讀寫。最終,一個越獄的執行程序會接管並執行所有接下來的步驟。

  越獄文件系統(Jailbreaking the Filesystem)

iPhone的文件系統缺省分成2個分區,第一個分區是root根文件系統,存放iOS的操作系統文件和如MobileMail,MobileSafari的標準應用程序集。早期的iOS版本裏,root根文件系統的大小接近分區的容量大小,分區沒有多少剩余空間。雖然root文件系統是假設為不可修改的,分區也缺省裝載為只讀的,但如今root根文件系統接近1GB大小,分區有200MB左右空間剩余。設備的其余存儲空間分配給第二個分區,即數據分區,它裝載在/private/var目錄下,可以讀寫。在根目錄的 /etc/fstab文件裏有以下配置:

/dev/disk0s1 / hfs ro 0 1
/dev/disk0s2 /private/var hfs rw,nosuid,nodev 0 2

你可以看到,數據分區的裝載配置文件有 nodev 和nosuid標誌。為了防止文件系統層面的攻擊,nodev標誌是確保設備節點在可寫的數據分區裏的存在將會被忽略。nosuid標誌是告知內核在數據分區裏執行時忽略suid位。suid位表示執行時需要以超級用戶root身份執行,或與當前用戶不同的一個用戶來執行。這些標誌都是iOS內部用來防止權限提升漏洞的防禦措施。

不管是bootrom級別,還是用戶層面級別的漏洞,這個缺省的配置是所有越獄面臨的難題。因為他們通常需要對root根文件系統進行修改,使程序在設備重啟後還能存在,或能增加服務和守護進程。所以每次越獄獲得超級用戶root的權限後的第一個動作就是重新裝載root根文件系統,使之可讀可寫。為了使設備重啟後修改也生效,下一個步驟就是用下面類似的配置替換系統的/etc/fstab文件:

/dev/disk0s1 / hfs rw 0 1
/dev/disk0s2 /private/var hfs rw 0 2

這個新的文件系統的配置文件將裝載root根目錄文件為可讀可寫,並從第二個分區的裝載配置中移去nosuid和nodev標誌。

  安裝完美越獄破解(Installing the Untethering Exploit)

每次當一個新版本的iOS出現,原先的已知漏洞就被修復了。 所以在一個有限的時間窗口裏,紅雪在老設備上能越獄新的固件,但不能安裝完美越獄漏洞。

一旦得到了一個新的完美越獄漏洞,紅雪的作者就會修改程序來安裝新的漏洞。 由於每個漏洞都是不同的,所以都需要不同的安裝步驟。

雖然實際的完美越獄漏洞安裝是不同的,但都是在root根文件系統裏重命名和移動一些文件,並拷貝一些文件到它上面。當你反編譯當前的紅雪軟件版本,你會發現它從4.2.1到5.0.1的大部分iOS版本上都支持安裝完美越獄漏洞,發現每個完美越獄漏洞需要那些文件。

  安裝 AFC2服務(Installing the AFC2 Service)

蘋果文件連接 (AFC)是一個運行在每臺iPhone上的文件傳送服務,它允許你通過USB連線存取iPhone的/var/mobile/Media的目錄裏的文件。AFC服務由lockdownd守護進程提供,被命名為com.apple.afc 。但lockdownd守護進程只提供存取服務,實際由afcd守護進程實現。在MAC上通過MobileDevice.framework,在Windows PC上通過 iTunesMobileDevice.dll來使用。

afcd還提供lockdownd的第二個服務,它註冊為com.apple.crashreportcopymobile。它用來從設備向電腦復制CrashReporter報告,並只限制於/var/mobile/Library/Logs/CrashReporter目錄和子目錄的讀寫存取 。

由於這些服務運行於mobile用戶的許可權限下,被鎖定於特定目錄下,他們對於越獄的作用是受限的。所以紅雪和其他越獄工具向lockdownd註冊了一個額外的服務,叫做com.apple.afc2。這個服務利用afcd守護進程提供對整個文件系統的root超級用戶權限的讀寫存取,這是一個大部分用戶都不知道的相當危險的越獄特性。這意味著一臺沒有密碼保護或在未鎖定狀態的越獄過的iPhone,只要連接上一個USB充電站或其他人的電腦,就給了另一方在沒有用戶交互下的整個文件系統的讀取存取權限。他們可以竊取你的所有數據或安裝系統後門。

com.apple.afc2服務通過更改在/System/Library/Lockdown/Services.plist文件裏的lockdownd配置來安裝。這是一個正常的.plist 文件,可以通過 .plist文件的標準工具或API來修改。

  安裝基本程序庫(Installing Base Utilities)

  應用程序隱藏(Application Stashing)

當從蘋果的應用程序商店安裝應用時,它們被安裝在/var/mobile/Applications目錄裏,該目錄駐留在iPhone的大容量的數據分區裏。可以安裝的應用程序的數量依賴於數據分區的空閑空間。空閑空間通常有上GB 容量,所以對安裝應用程序數量來講不是真正的限制.

Cydia是越獄者制做的相當於蘋果AppStore的應用程序商店,通過Cydia下載的越獄應用的安裝地點是不同的。像Cydia自身和其他內置的二進制文件安裝在root根目錄的/Application目錄下。前面提到,root根文件系統的容量取決於固件的版本、容量和設備類型。通常在1GB和1.5GB之間,有大約200MB的空閑,這點容量對安裝應用程序來說是不多的。

另外,墻紙和鈴聲也存放在根目錄的 /Library/Wallpaper 和 /Library/Ringtones目錄下,所以從Cydia安裝的每個墻紙和鈴聲也也會占用掉有限的應用程序空間。

為解決這個問題,各種越獄都實現了應用程序隱藏技術。它是在iPhone的數據分區創建了/var/stash的新目錄,並把一些正常情況下位於root根文件系統下的應用程序移到/var/stash目錄下,原來的目錄替換為鏈接到新目錄的符號鏈接。

以下清單是通過程序隱藏轉移到/var/stash下的目錄:

然而,不是所有的越獄工具和所有版本的越獄工具都進行應用程序隱藏。因為這樣,Cydia創建時在第一次調用時會進行檢測,這是Cydia裏的重新組織文件系統(“Reorganizing Filesystem”)的耗時較長的步驟。

  安裝程序包 (Bundle Installation)

  安裝後過程(Post-Installation Process)

內核payload。

  執行內核Payloads並修改內核(Executing Kernel Payloads and Patches)

雖然每個內核漏洞和每個payload是不同的,但能把越獄所用的內核級的payload分為為4個部分:

(1)修復內核狀態Kernel State Reparation

(2)權限提升Privilege Escalation

(3)修改內核Kernel patching
(4)清理並返回Clean return
接下來的章節對他們進行詳細描述

  修復內核狀態(Kernel State Reparation)

  權限提升(Privilege Escalation)

由於iPhone上的所有應用程序的都以權限較少的用戶(如mobile,_wireless,_mdsnresponder,_securityd)角色運行,一個內核漏洞的payload執行後,通常要把應用程序的運行進程的權限提升到root超級用戶權限。 如果少了這一步驟,有些操作是不可能完成的的,像重新裝載root根文件系統到可寫狀態,或修改屬於root超級用戶的文件。所有這些在越獄的初始安裝時都時需要的。只用於完美越獄的重啟後執行的內核漏洞不需要這一步驟,因為通常已經已root超級用戶角色運行。

在內核內部,提升當前運行進程的權限是很容易的。只需要修改進程的proc_t結構的信用值。這個結構在XNU源代碼的/bsd/sys/proc_internal.h文件的proc結構裏定義。依據不同的內核漏洞payload開始運行方法的不同,取得當前進程的proc_t結構的指針的方法是不同的。在以前公開的許多iOS內核漏洞裏,用於覆蓋系統調用表裏的系統調用程序的地址的辦法是不同的。內核漏洞的payload由調用被覆蓋的系統調用來觸發。在這種情況下,它獲得的proc_t結構是微不足道的,因為它是系統調用程序的第一參數。

得到proc_t結構的地址的更通用的方法是調用current_proc()內核函數,它能取回這個結構的的地址。這個函數是一個內核輸出的符號,很容易找到。由於剛開始的內核漏洞能檢測使用的內核版本,並且內核裏沒有地址隨機化,所以它可以把函數的地址硬編碼到內核漏洞裏。

取到proc_t結構的地址的第三個方法是使用通過sysctl接口泄露的內核地址信息。這項技術是由noir在破解OpenBSD內核的過程中首先發表的(詳見www.phrack.org/issues.html?issue=60&id=06),並被nemo用於XNU內核(詳見www.phrack.org/issues.html?issue=64&id=11)。這個泄露的信息允許用戶態進程通過一個簡單的sysctl系統調用取到proc結構的內核地址。

在取到進程proc_t結構的地址後,結構裏的p_ucred成員用來修改連接的ucred結構。 這個元素可以通過proc_ucred()函數讀取,或直接讀取。下面的反匯編代碼表明在當前iOS版本裏結構裏p_ucred域的偏移量是0×84.

_proc_ucred:

LDR.W R0, [R0,#0x84]
BX LR

在/bsd/sys/ucred.h文件裏有ucred結構的定義。結構裏還包含擁有這個結構的進程的用戶ID和組ID。

struct ucred {
TAILQ_ENTRY(ucred) cr_link;
u_long cr_ref;
struct posix_cred {

uid_t cr_uid;
uid_t cr_ruid;
uid_t cr_svuid;
short cr_ngroups;
gid_t cr_groups[NGROUPS];
gid_t cr_rgid;
gid_t cr_svgid;
uid_t cr_gmuid;
int cr_flags;
} cr_posix;
struct label *cr_label;

struct au_session cr_audit;

};

為了提升擁有這個結構的進程的權限,結構偏移量0x0c處的cr_uid域被設置為0。如你預料的,偏移量是0x0c,而不是0×08,是因為一個TAILQ_ENTRY條目是8byte的。當然,其他元素也能被修改。然而一旦uid值等於0,用戶態的進程就能利用系統調用更改它的許可權限。

修改內核(Kernel Patching)

內核級payload最重要的部分是對內核代碼和數據進行內核級別的修改,使安全功能失效,

然而,接下來的章節向你介紹這些補丁和它們背後的原理,你可以用它們來開發你自己的內核修改補丁,運用於未來的iOS版本。

  security.mac.proc_enforce變量

security.mac.proc_enforce是個系統調用變量,它控制著是否在進程操作中使能MAC策略。變量禁止時,各種進程策略檢查和限制就被關掉了。例如,對fork(), setpriority(), kill() 和 wait() 系統調用的限制。 除此以外,這個變量還控制著代碼簽名blob的數字簽名是否合法。變量禁止時,代碼簽名blob的數字簽名是非法的二進制代碼也可以被執行。

  內核的cs_enforcement_disable變量

/osfmk/vm/vm_fault.c文件的頁錯誤處理程序的源代碼裏有一個cs_enforcement_disable變量,它控制著頁錯誤處理程序的代碼簽名是否起作用。

  AMFI模塊的cs_enforcement_disable變量

只有在一些我們知道的未公開的越獄裏proc_enforce標誌沒有更改,在這種情況下,補丁是有效的。

  PE_i_can_has_debugger函數

iOS內核有一個PE_i_can_has_debugger()函數,內核和一些內核擴展裏都用它來決定是否允許調試。在一些iOS內核擴展裏設置調試啟動參數會引起內核錯誤。所以當前的大部分越獄不再修改這個函數代碼,而是修改內核裏的debug_enable 變量。為了確定這個變量的地址,必須分析PE_i_can_has_debugger()函數的代碼。因為這個變量位於一個未初始化的數據段裏,修改只能在運行時進行。為了查找啟動時初始化這個變量的代碼,需要搜索debug-enabled字符串,可以直接找到把值復制到變量的代碼。

  vm_map_enter函數

當內存映射到進程的地址空間時,內核函數vm_map_enter()被用於分配一段虛擬地址映射。

  vm_map_protect函數

vm_map_protect() 是內核函數,它在映射內存的保護改變時被調用。

因為這個修改,越獄減弱了iOS設備的內存保護。我們建議當用戶想運行需要修改自身代碼的應用程序時才進行這個補丁修改。這些修改的問題是禁止了非執行內存的限制,以致對iPhone應用程序的遠程攻擊不需要實現百分百的ROP操作。相反,這些攻擊或惡意程序只需要一個利用 mprotect()函數來註入執行代碼的簡短的ROP stub。

  AMFI二進制信任緩沖區(AMFI Binary Trust Cache)

AMFI內核模塊負責檢查簽名代碼blob的數字簽名的合法性。它註冊了一些MAC的策略處理句柄,如vnode_check_signature鉤子,它在每次內核增加一個新的簽名代碼blob時都會被調用;AMFI處理程序對來自蘋果的證書驗證簽名。

  0號進程任務陷阱(Task_for_pid 0)

雖然這個補丁修改對大部分越獄者都是沒有必要的,我們把它記錄下來是因為它涉及一個mach陷阱,下面我們會向你介紹一種在iOS二進制內核裏尋找mach陷阱表(mach_trap_table)的策略。

task_for_pid()是一個mach陷阱,會返回另一個進程的任務端口,以它的進程ID命名。這局限於用戶ID相同的進程,除非請求任務端口的進程是特權的。

修改沙盒 (Sandbox Patches)

Comex的內核修改補丁的最後一步就是改變沙盒的行為。沒有這個修改補丁,越獄過的iPhone不能運行類似MobileSafari 和 MobileMail的應用程序。因為越獄後/Applications 目錄已經移到/var/stash/Applications目錄了,這違反了沙盒機制。 奇怪的是目前我們只知道這兩個應用程序受影響。即使沒有修改沙盒,其他所有的內置應用程序看起來都能完美運行。

這個修改補丁包括兩塊:第一塊是用鉤子(hook)覆蓋sb_evaluate()函數的開始部分;第二塊是在內核裏的未用區域寫入新代碼。這個函數的更多信息,可以回顧第5章。這個修改補丁改變了沙盒仿真的修為,去存取處理不同的特定的目錄。

在描述新的仿真功能前,由於沒有符號表可用,我們要找到在內核代碼裏定位sb_evaluate()函數的方法。一個可能性是在沙盒內核擴展裏搜索mac策略處理程序表。一些mac策略處理程序會用到sb_evaluate()函數。當前的iOS內核裏很容易搜索到錯誤操作碼的字符。因為只能在你的函數裏使用它,一旦找到它的數據引用,你要找到它所用的函數的開始的地方。

定位到sb_evaluate()函數的地址後,可以給它安裝一個鉤子函數,讓它跳轉到一個內核未使用的區域,在那裏你可以放置其余代碼。我們在第9章裏已經討論過如何找到未用的區域。在comex的GitHub程序庫裏可以找到datautils0程序的源代碼,它模擬了鉤子的功能,我們現在要仔細研究它。代碼的總體想法是對/private/var/mobile和private/var/mobile/Library/Preferences裏的文件避免進行沙盒檢查。代碼開始時檢查提供的vnode是否為0,如果為0,不調用鉤子函數,只是跳過檢查,執行原來的處理程序。

  清空緩存(Clearing the Caches)

  清理並返回(Clean Return)

提升權限,修改安全特性,脫離內核的掌控後,唯一要做的是讓內核空間保持在清潔的狀態,防止內核不穩定或立即崩潰。通常只需要把普遍意義上的CPU寄存器的值恢復到調用內核payload前的值,並返回保存的程序指針。萬一內核堆棧被溢出了,由於真實的堆棧的值被溢出的緩沖區覆蓋,導致不可能恢復。這種情況下,可以返回一個未被破壞的以前的堆棧幀。

另一個退出內核的辦法是調用內核的thread_exception_return()函數。由於這個函數在內核裏沒有符號表,需要通過模式匹配掃描和交叉引用掃描找到這個函數。當內核堆棧幀不可能回退時需要執行完當前內核線程的例外情況,需要調用這個函數來恢復內核。因此,可以用它來離開漏洞payload後的內核。但是,內核應該盡可能通過返回正確的堆棧幀的來離開,否者,離開後內核不能保證還在穩定狀態。

以上參考:作者:czj_warrior
鏈接:https://www.jianshu.com/p/25e1f44c90f7

http://blog.sina.com.cn/s/blog_655dac9e01017wv3.html

iOS逆向+越獄