iOS逆向之a(chǎn)pp脫殼

什么是脫殼

iOS端App在上線之前會有蘋果商店進行FairPlayDRM數(shù)字版權(quán)加密保護,我們稱之為“加殼”。要對App Store分發(fā)的iOS App進行分析,我們需要先對App進行解密,我們稱之為“脫殼”,有些人也稱為“砸殼”。脫殼之后的二進制文件就是原始的、未加密的二進制文件。

注意,對于macOS上的App,蘋果官方是不會對其進行加殼的。所以分析macOS App不需要執(zhí)行脫殼操作。

判斷是否加殼

網(wǎng)上有很多文章介紹如何判斷iOS App是否被加殼。這里進行簡單的介紹。
大家通常使用的判斷加殼的方式是是使用machOView可視化工具或otool命令行工具。
這兩個工具本質(zhì)上都是看LC_ENCRYPTION_INFO(LC代表load command)中的Crypt ID字段。

使用otool檢測

otool是Xcode自帶的命令行工具,安裝了Xcode的macOS系統(tǒng)不需要額外安裝otool。
使用otool的如下命令可以檢測App是否被加殼。如下:

otool -l mach-O文件 | grep crypt 

例如:


image.png

如上:TEST是筆者App的已經(jīng)脫殼的可執(zhí)行文件。cryptid為0說明未加殼或已脫殼,cryptid為1說明App已加殼。

使用MachOView檢測

不想使用otool命令行還可以使用MachOView,MachOView是一款開源的Mach-O可視化工具。通過MachOView可以清晰的查看Mach-O問價的內(nèi)部結(jié)構(gòu)。這里是MachOView的地址
)。將代碼下載到本地使用Xcode編譯成功后打開APP即可。使用MachOView打開目標Mach-O文件。展開“Load Commands”節(jié)點,選擇“LC_ENCRYPTION_INFO_64”節(jié)點,右邊的crypt ID即代表了是否加密。為0則代表未加密(沒有殼或已脫殼),為1則代表已加密(已加殼)。

image.png

脫殼

按照脫殼的時機來區(qū)分,給App脫殼的方式分為兩種:靜態(tài)脫殼、動態(tài)脫殼。
靜態(tài)脫殼:破解App的加殼原理,通過反向操作給App去殼。
動態(tài)脫殼:將App加載進內(nèi)存,直接dump加載進內(nèi)存的App的即可。
從操作難度上來看動態(tài)脫殼相對簡單一些,因筆者也沒有實踐過靜態(tài)脫殼,本文只介紹動態(tài)脫殼。
筆者了解到的冬天脫殼方式主要有三種:Clutch、dumpdecrypted、Frida。
關(guān)于Clutch和dumpdecrypted的使用方式網(wǎng)上教材眾多,本文只是簡單的羅列步驟,重點講解Frida的使用。

Clutch

1.下載Clutch:https://github.com/KJCracks/Clutch/releases并重命名為Clutch

image.png

2.將Clutch文件拷貝到越獄iPhone的/usr/bin目錄下


image.png

3.以root管理員身份登錄iPhone,給Clutch賦予執(zhí)行權(quán)限 chmod +x /usr/bin/Clutch

image.png

4.Clutch -i查看已經(jīng)安裝的App

image.png

5.Clutch -d app bundleId執(zhí)行脫殼操作。比如給上圖的微信脫殼,命令如下:

// 通過bundleId來指定脫殼的App
# Clutch -d com.tencent.xin
// 或者 通過App的序號來指定脫殼的App
# Clutch -d 5

注意:因為是動態(tài)脫殼,使用Clutch脫殼前需要先啟動目標App。

  1. 脫殼的文件路徑,脫殼成功后,命令行會列出脫殼后的文件在:/private/var/mobile/Documents/Dumped/ 目錄下
    如果脫殼中遇到錯誤,但仍有部分文件脫殼成功,那么此時文件路徑是:/var/tmp/clutch
  2. 將脫殼的文件從iPhone導(dǎo)出到電腦。有多重方式,可以用iOS逆向之必要軟件安裝 - 簡書 (jianshu.com)中介紹的可視化工具。也可以用scp命令。該命令在iPhone上執(zhí)行,命令格式如下(scp的詳細使用見Linux scp命令 | 菜鳥教程):
iPhone:/ root# scp iPhone本地源文件 電腦userName@電腦ip地址:電腦目標路徑

執(zhí)行Clutch 命令報錯:killed 9

執(zhí)行Clutch -i報錯:killed 9,如下圖:

iPhone:/usr/bin root# Clutch -i
Killed: 9
iPhone:/usr/bin root# Clutch -i
Killed: 9

解決辦法:
iPhone 終端輸入以下4條命令(參考自:越獄設(shè)備運行Clutch報錯:Killed: 9_jinrui_w的博客-CSDN博客

iPhone:/usr/bin root# cd /private/var/mobile/Documents/
iPhone:/private/var/mobile/Documents root# ldid -e `which bash` > end.xml
iPhone:/private/var/mobile/Documents root# ldid -Send.xml `which Clutch`
iPhone:/private/var/mobile/Documents root# inject `which Clutch`

Clutch -d 命令報錯:Error: Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed!

如下圖:

Clutch -d 報錯

參考文章:Error: Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed! · Issue #144 · KJCracks/Clutch · GitHub

按照提問者的說法,在/var/tmp/clutch目錄下找到了dump出來的部分文件。

dumpdecrypted

dumpdecrpyted是開源的,需要先進行編譯,然后再將編譯好的dylib復(fù)制到越獄iPhone上。具體步驟如下:
1.通過git地址下載源碼。

2.目錄下執(zhí)行make命令執(zhí)行編譯操作。


image.png

3.編譯成功后目錄下會多出一個dylib動態(tài)庫文件。


image.png

4.將dylib復(fù)制到越獄設(shè)備的/var/root目錄下(以root用戶身份登錄)


image.png

5.root身份登錄iPhone并進入到dylib所在的iPhone目錄


image.png

6.使用環(huán)境變量DYLD_INSERT_LIBRARIES將動態(tài)庫dumpdecrpyted注入到需要脫殼的目標mach-O文件中。命令格式DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib 可執(zhí)行文件路徑
例如:

 DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/5B7E8BAE-3F8E-448A-829E-452912476BC8/TEST.app/TEST

7.執(zhí)行成功后目錄下會多出一個xxx.decrypted文件。該文件就是脫殼后的可執(zhí)行文件。

Frida

Frida-ios-dump基于Frida(一款跨平臺的輕量級的Hook框架)提供的強大的功能,通過注入JS實現(xiàn)內(nèi)存dump,然后利用Python腳本自動將內(nèi)存復(fù)制到macOS,從而生成最終的脫殼后的ipa文件。
Frida-ios-dump的原理和dumpdecrypted一樣,都是通過把內(nèi)存匯總已解密的數(shù)據(jù)dump出來再修復(fù)mach-O,dan dumpdecrypted僅能dump主程序,對于框架需要自行修改源代碼才能完成,操作比較麻煩。Frida-ios-dump提供的強大功能允許我們一鍵快速完成脫殼。
使用Frida脫殼要求越獄設(shè)備上安裝Frida插件。具體操作步驟如下:
1.首先Cydia中添加源Frida源:https://build.frida.re
2.搜索并安裝對應(yīng)版本的Frida。筆者的越獄iPhone是64位的,iOS 版本是10.13.5,所以下載并安裝了Frida for pre-A12 devices
3.Mac上在github上下載Frida-ios-dump:https://github.com/AloneMonkey/frida-ios-dump
4.進入本地的Frida-ios-dump目錄下執(zhí)行sudo pip install -r requirements.txt --upgrade 來安裝python依賴
注意:如果這一步安裝Python依賴失?。嚎梢試L試手動逐個安裝requirements.txt中的python依賴庫

5.mac終端執(zhí)行iproxy 2222 22。把Mac上的2222端口映射到iPhone的22。前提是要保證此時iPhone已經(jīng)和Mac通過usb進行了連接
注意:如果這一步出現(xiàn)command not found:iproxy。說明Mac本地還沒有iproxy。只需終端執(zhí)行brew install usbmuxd。在安裝usbmuxd的過程中iproxy會被自動安裝。安裝好后執(zhí)行iproxy 2222 22

6.電腦當前目錄下繼續(xù)執(zhí)行./dump.py -l命令。列出iPhone上當前的所有應(yīng)用

image.png

7.終端執(zhí)行./dump.py bundleId即可對app進行脫殼。
注意:這一步需要我們把app啟動

8.脫殼成功后,會在電腦的當前目錄新增一個ipa文件。該文件就是脫殼后的APP包。

分離架構(gòu)

我們最終脫殼出的二進制文件和使用的越獄設(shè)備有關(guān)。即arm64的越獄設(shè)備只能脫殼出arm64的可執(zhí)行文件。Mach-O通常是胖二進制格式,也就是一個Mach-O文件包含多種架構(gòu),比如:arm64、armv7、armv7s等。胖二進制的目的是為了支持更多架構(gòu)的iPhone。關(guān)于每款iPhone的架構(gòu)可以自行Google。
搞過靜態(tài)庫和動態(tài)庫的開發(fā)者對于分離架構(gòu)應(yīng)該并不陌生。在合并和分離二進制文件的時候,我們通常使用lipo命令。lipo是macOS自帶的工具,其功能非常強大。下面列舉了lipo命令常用的幾個命令:

# 查看可執(zhí)行文件的架構(gòu)信息
命令格式:lipo -info Mach-O文件
# lipo -info WeChat

# 分離出某種特定架構(gòu)
命令格式:lipo  mach-O文件  -thin  架構(gòu)類型  -output  分離的mach-O文件  
# lipo WeChat -thin arm64 -output WeChat_arm64

# 合并多種架構(gòu)
命令格式:lipo  mach-O文件1  mach-O文件2  -output  合成的mach-O文件
# lipo WeChat_arm64 WeChat_armv7 -output WeChat

補充:查看可執(zhí)行文件架構(gòu)還可以使用file命令:file Mach-O文件
例如:file WeChat

參考文章&鏈接

MachOView:https://github.com/gdbinit/MachOView
Clutch:https://github.com/KJCracks/Clutch/releases
dumpdecrypted:https://github.com/stefanesser/dumpdecrypted
frida-ios-dump:https://github.com/AloneMonkey/frida-ios-dump
《iOS應(yīng)用逆向與安全之道》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容