iOS 應用程序重打包和簽名詳盡指南Part 2
作為iOS應用程序重打包和簽名詳盡指南的第二部分,本文將介紹的是使用App Extensions(應用擴展)和高級應用程序功能的應用程序以及綁定WatchKit的應用程序的重打包和簽名。
3.使用App Extensions應用程序的重打包
一些iOS應用程序使用程序擴展來實現iOS提供的進程間通信(IPC)。其中一個例子是共享擴展(Share Extension),允許跨應用程序共享內容。這些擴展通常與IPA綁定作為單獨的可執行文件。下面的代碼片段展示了LinkedIn應用程序包中各種MachO二進位文件的布局:
Payload/
LinkedIn.app/
Frameworks/
lmdb.framework/
lmdb
...
libswiftAVFoundation.dylib
...
Plugins/
IntentsExtension.appex/
IntentsExtension
IntentsUIExtension.appex/
IntentsUIExtension
...
應用程序擴展位於Plugins/目錄下,如上面所示。每個應用程序都有綁定擴展名 .appex。
3.1解密MachO二進位文件
在處理綁定應用程序擴展名的應用程序時,除了解密應用程序二進位和框架之外,還必須解密應用程序擴展的二進位圖像。為了解密應用程序擴展,首先設置debugserver來攔截並附加到啟動的應用程序擴展。在下面的代碼片段中,debugserver設置為附加到IntentsExtension:
amarekano-ipod:~/amarekano root# ./debugserver *:6666 -waitfor IntentsExtension &
設置好debugserver後,啟動應用程序擴展。這一步可以手動執行,如下所示:
amarekano-ipod:~/amarekano root# /var/containers/Bundle/Application/AC8C5212-67D0-41AB-A01A-EEAF985AB824/LinkedIn.app/PlugIns/IntentsExtension.appex/IntentsExtension
debugserver附加了之後,就使用lldb進行連接,並從內存中轉儲解密後的圖像。
(lldb) image list IntentsExtension
[ 0] 2F48A100-110F-33F9-A376-B0475C46037A 0x00000001000f0000 /var/containers/Bundle/Application/AC8C5212-67D0-41AB-A01A-EEAF985AB824/LinkedIn.app/PlugIns/IntentsExtension.appex/IntentsExtension (0x00000001000f0000)
(lldb) memory read --force --outfile ./decbins/intentsextension.bin --binary --count 114688 0x00000001000f0000+16384
114688 bytes written to "./decbins/intentsextension.bin"
(lldb) exit
一旦被解密,將被轉儲的二進位文件連接到原始的應用程序擴展二進位文件中,並使用同一方法將cryptid標誌設置為0,就像對其他MachO二進位文件進行解密一樣。
3.2給應用程序打補丁
修補應用程序二進位文件以載入FridaGadget的過程與前面示例演示的過程相同。
Amars-Mac:sandbox amarekano$ optool install -c load -p "@executable_path/FridaGadget.dylib" -t Payload/LinkedIn.app/LinkedIn
Found FAT Header
Found thin header...
Found thin header...
Inserting a LC_LOAD_DYLIB command for architecture: arm
Successfully inserted a LC_LOAD_DYLIB command for arm
Inserting a LC_LOAD_DYLIB command for architecture: arm64
Successfully inserted a LC_LOAD_DYLIB command for arm64
Writing executable to Payload/LinkedIn.app/LinkedIn...
3.3生成Provisioning Profile
一般來說,使用應用程序擴展名的應用程序幾乎總是需要高級的應用程序功能。這些功能通常允許應用程序開發人員使用一些蘋果技術,比如Siri、Apple Pay、iCloud等。示例中的LinkedIn應用程序使用了iCloud和Siri。這是通過審查應用程序的許可權而發現的:
Amars-Mac:sandbox amarekano$ codesign -d --entitlements :- "Payload/LinkedIn.app/"
Executable=/Users/amarekano/Desktop/sandbox/Payload/LinkedIn.app/LinkedIn
... ...
application-identifier
8AXPVS6C36.com.linkedin.LinkedIn
......
com.apple.developer.icloud-services
CloudDocuments
com.apple.developer.siri
... ,,,
高級的應用程序功能只對使用付費開發者帳戶的iOS開發人員可用。因此,為了在重新打包的應用程序中使用這些應用程序功能,必須使用付費開發者帳戶創建一個合適的provisioning profile。這一操作可以通過創建一個虛擬的Xcode項目來實現,並指定一個付費的開發人員簽署cert,如下面的截屏圖所示:
創建了一個項目之後,就可以在Capabilities選項卡下啟用應用程序所需的功能。下面的截屏圖顯示了在虛擬Xcode項目中啟用的所需功能。
構建這個虛擬的Xcode項目將生成一個有效的Provisioning profile,該Provisioning profile具有重新打包LinkedIn應用程序所需的許可權的權利。從生成的配置文件中提取這些許可權如下所示:
Amars-Mac:sandbox amarekano$ security cms -D -i embedded.mobileprovision > profile.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -x -c "Print :Entitlements" profile.plist > entitlements.plist
Amars-Mac:sandbox amarekano$ cat entitlements.plist
application-identifier
MS4K289Y4F.com.example.amarekano.advrepackdemo
......
com.apple.developer.icloud-services
*
com.apple.developer.siri
com.apple.developer.team-identifier
MS4K289Y4F
... ...
get-task-allow
keychain-access-groups
MS4K289Y4F.*
3.4更新應用程序元數據
在成功生成Provisioning profile的過程中,將文件添加到應用程序包中,並更新應用程序和應用程序擴展的各種Info.plist文件如下所示:
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo" Payload/LinkedIn.app/Info.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo.IntentsExtension" Payload/LinkedIn.app/PlugIns/IntentsExtension.appex/Info.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo.IntentsUIExtension" Payload/LinkedIn.app/PlugIns/IntentsUIExtension.appex/Info.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo.MessagingNotificationContentExtension" Payload/LinkedIn.app/PlugIns/MessagingNotificationContentExtension.appex/Info.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo.NewsModuleExtension" Payload/LinkedIn.app/PlugIns/NewsModuleExtension.appex/Info.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo.ShareExtension" Payload/LinkedIn.app/PlugIns/ShareExtension.appex/Info.plist
Amars-Mac:sandbox amarekano$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.amarekano.advrepackdemo.WVMPTodayExtension" Payload/LinkedIn.app/PlugIns/WVMPTodayExtension.appex/Info.plist
Amars-Mac:sandbox amarekano$
3.5MachO二進位文件重簽名
當重簽名應用程序二進位文件時,用多個可執行二進位文件重新打包應用程序時,重簽名二進位文件的順序非常重要。從重新簽名應用程序擴展開始,如下所示:
Amars-Mac:sandbox amarekano$ codesign --force --sign "iPhone Developer: m***************" Payload/LinkedIn.app/PlugIns/IntentsExtension.appex/IntentsExtension
Payload/LinkedIn.app/PlugIns/IntentsExtension.appex/IntentsExtension: replacing existing signature
Amars-Mac:sandbox amarekano$ codesign --force --sign "iPhone Developer: m***************" Payload/LinkedIn.app/PlugIns/IntentsUIExtension.appex/IntentsUIExtension
Payload/LinkedIn.app/PlugIns/IntentsUIExtension.appex/IntentsUIExtension: replacing existing signature
...
接下來是Framework和dylibs重簽名:
Amars-Mac:sandbox amarekano$ codesign --force --sign "iPhone Developer: m***************" Payload/LinkedIn.app/Frameworks/lmdb.framework/lmdb
Payload/LinkedIn.app/Frameworks/lmdb.framework/lmdb: replacing existing signature
...
Amars-Mac:sandbox amarekano$ codesign --force --sign "iPhone Developer: m***************" Payload/LinkedIn.app/Frameworks/libswiftAVFoundation.dylib
Payload/LinkedIn.app/Frameworks/libswiftAVFoundation.dylib: replacing existing signature
...
Amars-Mac:sandbox amarekano$ codesign --force --sign "iPhone Developer: m***************" Payload/LinkedIn.app/FridaGadget.dylib
Payload/LinkedIn.app/FridaGadget.dylib: replacing existing signature
最後,使用3.3節中生成的許可權對LinkedIn應用程序進行重簽名。
Amars-Mac:sandbox amarekano$ codesign --force --sign "iPhone Developer: m***************" --entitlements entitlements.plist Payload/LinkedIn.app/LinkedIn
Payload/LinkedIn.app/LinkedIn: replacing existing signature
3.6歸檔和安裝
應用程序被重簽名後,將Payload目錄歸檔到IPA中,並將重打包的 IPA安裝到目標設備上。
Amars-Mac:sandbox amarekano$ zip -qr LinkedIn_resigned.ipa Payload/
Amars-Mac:sandbox amarekano$ ideviceinstaller -i LinkedIn_resigned.ipa
WARNING: could not locate iTunesMetadata.plist in archive!
Copying "LinkedIn_resigned.ipa" to device... DONE.
Installing "com.example.amarekano.advrepackdemo"
Install: CreatingStagingDirectory (5%)
......
Install: GeneratingApplicationMap (90%)
Install: Complete
3.7運行重新打包的應用程序
重新打包的應用程序成功安裝到目標設備上後,使用idevicedebug啟動它,然後連接到生成的Frida伺服器。
Amars-Mac:sandbox amarekano$ idevicedebug -d run com.example.amarekano.advrepackdemo &
Amars-Mac:sandbox amarekano$ frida -H 192.168.1.91:8080 -n Gadget
____
/ _ | Frida 10.7.7 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about "object"
. . . . exit/quit -> Exit
. . . .
. . . . More info at http://www.frida.re/docs/home/
[Remote::Gadget]-> %resume
[Remote::Gadget]-> String(ObjC.classes.NSBundle.mainBundle().objectForInfoDictio
naryKey_("CFBundleName"))
"LinkedIn"
[Remote::Gadget]-> String(ObjC.classes.NSBundle.mainBundle().objectForInfoDictio
naryKey_("CFBundleIdentifier"))
"com.example.amarekano.advrepackdemo"
4.重打包與WatchOS軟體捆綁的應用程序
通常情況下,應用程序開發人員將在他們的移動應用程序中加一個配套的WatchOS應用程序。為了證明重新打包的iOS應用程序綁定了WatchOS應用程序,本指南使用Tube Map應用程序。IPA內的MachO二進位文件布局如下:
Payload/
TubeMap.app/
Frameworks/
AFNetworking.framework/
AFNetworking
.... ...
Watch/
TubeMap WatchKit App.app/
Frameworks/
libswiftCore.dylib
... ...
Plugins/
TubeMap WatchKit Extension.appex/
TubeMap WatchKit Extension
TubeMap WatchKit App
TubeMap
4.1解密MachO二進位文件
當遇到解密二進位文件時,綁定WatchOS應用程序的重打包應用程序面臨一個獨特的挑戰。到目前為止,示例應用程序中的所有可執行二進位文件都是為單個處理器體系結構編譯的。因此,可以在調試器中啟動這些加密的二進位文件,然後轉儲它們的解密部分。WatchOS二進位文件是為armv7k架構編譯的。不幸的是,截至撰寫本文,作者也沒有破解的iWatch來解密WatchOS二進位文件。下面討論一個解決這個挑戰的方法。
如果不打算評估WatchOS應用程序,就可以簡單地刪除Watch/文件夾並重新打包應用程序,就像前面的示例演示的那樣。然而,這種方法在運行應用程序時可能會導致穩定性問題,特別是在評估涉及WatchOS應用程序的功能時。
假設有一個破解的iWatch可用,那麼必須在破解的watch上設置debugserver,並在調試器中啟動WatchOS二進位文件。在調試器中運行應用程序之後,轉儲二進位文件解密部分的過程與前面示例中演示的轉儲常規iOS應用程序二進位文件相同。
4.2給應用程序打補丁
給解密應用程序打補丁同樣再次需要將FridaGadget dylib添加到解壓縮的IPA中,然後使用optool將載入命令插入應用程序二進位文件以載入Frida dylib。
4.3更新應用程序元數據
更新TubeMap應用程序的元數據包括更新應用程序的Info.plist文件以及應用程序擴展的Info.plist文件。需要將合適的provisioning profile添加到針對特定設備的解壓縮IPA中。
4.4重簽名MachO二進位文件
首先,將所有綁定的框架和dylib進行重簽名,然後對應用程序二進位文件進行重簽名。
Amars-Mac:Frameworks amarekano$ codesign --force --sign "iPhone Developer: m*******" AFNetworking.framework/AFNetworking
AFNetworking.framework/AFNetworking: replacing existing signature
...
Amars-Mac:Frameworks amarekano$ codesign --force --sign "iPhone Developer: m*******" libswiftCore.dylib
libswiftCore.dylib: replacing existing signature
...
Amars-Mac:TubeMap.app amarekano$ codesign --force --sign "iPhone Developer: m*******" --entitlements ../../entitlements.plist TubeMap
4.5歸檔和安裝
應用程序被重簽名後,將Payload目錄歸檔到IPA中,並將重打包的 IPA安裝到目標設備上。
Amars-Mac:sandbox amarekano$ zip -qr TubeMap_resigned.ipa Payload/
Amars-Mac:sandbox amarekano$ ideviceinstaller -i TubeMap_resigned.ipa
WARNING: could not locate iTunesMetadata.plist in archive!
Copying "TubeMap_resigned.ipa" to device... DONE.
Installing "com.example.amarekano.repackdemo"
Install: CreatingStagingDirectory (5%)
......
Install: GeneratingApplicationMap (90%)
Install: Complete
4.6運行重新打包的應用程序
重新打包的應用程序成功安裝到目標設備上之後,使用idevicedebug啟動它,然後連接到生成的Frida伺服器。
Amars-Mac:sandbox amarekano$ frida -H 192.168.1.67:8080 -n Gadget
____
/ _ | Frida 10.7.7 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about "object"
. . . . exit/quit -> Exit
. . . .
. . . . More info at http://www.frida.re/docs/home/
[Remote::Gadget]-> %resume
[Remote::Gadget]-> String(ObjC.classes.NSBundle.mainBundle().objectForInfoDictio
naryKey_("CFBundleName"))
"Tube Map"
[Remote::Gadget]-> String(ObjC.classes.NSBundle.mainBundle().objectForInfoDictio
naryKey_("CFBundleIdentifier"))
"com.example.amarekano.repackdemo"
[Remote::Gadget]->
結束時的思考
重新打包應用程序並不總是可以順利完成,在運行重新打包應用程序時,研究人員偶爾會遇到問題。這可能有幾個原因。其中包括通過在運行時檢查捆綁id、檢測調試器等應用程序實現重新打包檢測。為了在出現問題時進行調試,應該在運行重新打包的應用程序時掃描設備syslog和dmesg的錯誤/警告。這兩個來源提供了關於運行過程的有價值的信息。
最後,本指南提供的信息是幫助安全研究人員評估iOS應用程序的安全漏洞。
※盤點迄今為止Mirai的7大變種
※利用發件人策略框架自動進行反網路釣魚攻擊行為偵察
TAG:嘶吼RoarTalk |