iOS逆向之從砸殼到重簽名
一光羞、概述
筆者做了多年的業(yè)務(wù)開(kāi)發(fā)悄泥,以前對(duì)逆向知之甚少欢顷,好像我們做iOS的開(kāi)發(fā)者對(duì)應(yīng)用本身的安全問(wèn)題總不是那么上心,總以為Apple自身的加密簽名機(jī)制足夠安全了墓怀,我們除了關(guān)心業(yè)務(wù)網(wǎng)絡(luò)安全汽纠,對(duì)自身App包的安全重視度總是不夠。然而一旦我們的包被有心人破解傀履,那么無(wú)論是對(duì)自身業(yè)務(wù)還是用戶(hù)數(shù)據(jù)都是致命的疏虫。真正開(kāi)始研究逆向,才發(fā)現(xiàn)我們App是如此的不堪一擊啤呼。所以研究逆向其實(shí)是研究Hacker
是如何攻破我們的應(yīng)用卧秘,從而更好地保護(hù)自身應(yīng)用安全。
研究逆向官扣,首當(dāng)其沖的就是重簽名翅敌,重簽名就是用自己的證書(shū)簽名別人的應(yīng)用,從而進(jìn)行分發(fā)惕蹄。重簽名說(shuō)白了就是套殼別人的應(yīng)用蚯涮,挺火的微信雙開(kāi),其實(shí)就是對(duì)微信進(jìn)行了重簽名卖陵。而重簽名首先要做的就是對(duì)應(yīng)用砸殼遭顶。
二、手機(jī)越獄與應(yīng)用砸殼
我們從App store 下載的應(yīng)用是經(jīng)過(guò)蘋(píng)果加密簽名過(guò)的泪蔫,是無(wú)法進(jìn)行重簽名的棒旗。所以重簽名首先要做的就是對(duì)應(yīng)用進(jìn)行砸殼,而砸殼需要你有一臺(tái)越獄手機(jī)撩荣。
1. 手機(jī)越獄
目前主流的越獄平臺(tái)有PP助手铣揉、愛(ài)思助手做到比較好,提供一鍵越獄功能餐曹。我自己使用的愛(ài)思助手逛拱,下載愛(ài)思助手電腦版,選擇【工具箱】-【一鍵越獄】台猴,此時(shí)會(huì)匹配你當(dāng)前手機(jī)版本的越獄工具朽合,選擇工具進(jìn)行越獄。
我使用的是 iphone SE饱狂,系統(tǒng)版本是14.4曹步,按照提示完成越獄就OK了。
需要注意嗡官,這種越獄方式是不完美的越獄箭窜,當(dāng)你重啟手機(jī)后會(huì)重新變回非越獄狀態(tài),需要重新走一遍越獄流程衍腥。不過(guò)對(duì)于我們研究逆向足夠了磺樱。
還沒(méi)完,越獄完成后需要安裝一個(gè)插件:Apple File Conduit"2"
,安裝這個(gè)插件的目的是婆咸,讓我們的電腦端能訪問(wèn)設(shè)備的根文件目錄竹捉,安裝方式也很簡(jiǎn)單,可以參考這篇文章Apple File Conduit"2"安裝尚骄,這里不再贅述块差。當(dāng)我們安裝完成后,愛(ài)思助手連接手機(jī)倔丈,可以看到在【文件管理】中多了個(gè)欄目【文件系統(tǒng)(越獄)】憨闰,這就是越獄狀態(tài)下的系統(tǒng)根目錄。
2. ipa應(yīng)用砸殼
首先了解什么是應(yīng)用砸殼:我們提交到App Store發(fā)布的App都是經(jīng)過(guò)Apple加密的需五,這樣可以確保安裝到我們手機(jī)的應(yīng)用都是蘋(píng)果審核授權(quán)的鹉动,當(dāng)然通過(guò)企業(yè)級(jí)證書(shū)或者開(kāi)發(fā)者證書(shū)生成的App是不需要砸殼的。對(duì)于App Store加密的應(yīng)用宏邮,我們無(wú)法通過(guò)Hopper等反編譯靜態(tài)分析泽示,也無(wú)法class-dump,在逆向分析過(guò)程中蜜氨,需要對(duì)加密的二進(jìn)制文件進(jìn)行解密才可以進(jìn)行靜態(tài)分析械筛,這一過(guò)程就是大家熟知的砸殼。
砸殼主要有兩種方式:
- 靜態(tài)砸殼
靜態(tài)砸殼就是在已經(jīng)掌握和了解到了殼應(yīng)用的加密算法和邏輯后,在不運(yùn)行殼應(yīng)用程序的前提下將殼應(yīng)用程序進(jìn)行解密處理飒炎。靜態(tài)脫殼的方法難度大埋哟,而且加密方發(fā)現(xiàn)應(yīng)用被破解后,就可能會(huì)改用更加高級(jí)和復(fù)雜的加密技術(shù)郎汪。 - 動(dòng)態(tài)砸殼
動(dòng)態(tài)砸殼就是從運(yùn)行在進(jìn)程內(nèi)存空間中的可執(zhí)行程序映像(image)入手定欧,來(lái)將內(nèi)存中的內(nèi)容進(jìn)行轉(zhuǎn)儲(chǔ)(dump)處理來(lái)實(shí)現(xiàn)脫殼處理。這種方法實(shí)現(xiàn)起來(lái)相對(duì)簡(jiǎn)單怒竿,且不必關(guān)心使用的是何種加密技術(shù)砍鸠。所以目前市面上的砸殼工具都是基于動(dòng)態(tài)砸殼進(jìn)行的。動(dòng)態(tài)砸殼有多種工具:Clutch
耕驰、dumpdecrypted
爷辱、CrackerXI App
,前兩種對(duì)系統(tǒng)要求較嚴(yán)格,而且年久失修很容易砸殼失敗朦肘,我們直接介紹最方便的第三種方式:利用CrackerXI App
進(jìn)行砸殼饭弓。
(1) 在Cydia
中下載CrackerXI App
Cydia
類(lèi)似于越獄前的App Store,越獄后我們所有的軟件都是通過(guò)Cydia
來(lái)進(jìn)行安裝媒抠。打開(kāi)Cydia
后弟断,選擇【軟件源】-右上角【編輯】-點(diǎn)擊【添加】,輸入http://apt.wxhbts.com/
,【添加源】等待添加完成趴生。添加軟件源完成后阀趴,搜索CrackerXI App
,點(diǎn)擊安裝完成后【重啟springboard】昏翰,回到桌面,可以看到桌面上安裝完成了CrackerXI+
App.
(2) 砸殼
提前在App Store 下載好你要砸殼的App刘急,打開(kāi)CrackerXI+
,選擇【AppList】然后點(diǎn)擊你要砸殼的應(yīng)用棚菊,在彈框中選擇【YES,F(xiàn)ull IPA】叔汁,此時(shí)會(huì)打開(kāi)我們要砸殼的應(yīng)用進(jìn)行砸殼统求,完成后會(huì)看到一個(gè)砸殼后的文件地址/var/mobile/Documents/CrackerXI/*****.ipa
,這個(gè)文件就是我們?cè)覛ず蟮膇pa包。
這個(gè)路徑怎么查找相信聰明的你已經(jīng)知道了据块,去愛(ài)思助手-【文件管理】-【文件系統(tǒng)(越獄)】查找到這個(gè)ipa码邻,導(dǎo)出到桌面目錄就完成了。
(3) 驗(yàn)證
完成上面的操作后另假,我們需要驗(yàn)證一下拿到的ipa是否是被砸殼的像屋。把.ipa
包擴(kuò)展名改為.zip
,解壓后得到Payload
文件夾垢袱,右鍵【顯示包內(nèi)容】- 找到可執(zhí)行文件.
終端輸入
otool -l 值執(zhí)行文件名 | grep crypt
可以看到cryptid
的值為0综看,說(shuō)明砸殼成功厕鹃。
三奸攻、重新簽名
Apple 應(yīng)用的分發(fā)一般有一下幾種方式:
- 最常用的是從App store下載應(yīng)用斤儿。這種下發(fā)方式不受設(shè)備數(shù)的限制棋弥,只要上線App store 的應(yīng)用道伟,都會(huì)被Apple進(jìn)行簽名加密.
- 第二種方式是申請(qǐng)企業(yè)賬號(hào)葫松,把我們的應(yīng)用通過(guò)企業(yè)賬號(hào)進(jìn)行簽名凶杖,從而繞過(guò)App store惱人的審核機(jī)制胁艰,達(dá)到分發(fā)應(yīng)用的目的。這種方法分發(fā)數(shù)目也不受限制.
- 第三種是通過(guò)
TestFlight
進(jìn)行測(cè)試版本的分發(fā)智蝠,他分為內(nèi)部測(cè)試人員與外部測(cè)試人員腾么。通過(guò)分發(fā)外部測(cè)試人員,最多能給1萬(wàn)名用戶(hù)進(jìn)行分發(fā)安裝. - 第四種開(kāi)發(fā)人員通過(guò)添加設(shè)備ID安裝應(yīng)用杈湾,最多可以注冊(cè)100臺(tái)設(shè)備.
不同的開(kāi)發(fā)者賬號(hào)對(duì)應(yīng)著App不同的分發(fā)方式解虱,我們申請(qǐng)完成開(kāi)發(fā)者賬號(hào)后,創(chuàng)建應(yīng)用Id漆撞,然后創(chuàng)建其對(duì)應(yīng)證書(shū)殴泰,描述文件等一系列動(dòng)作,實(shí)際已經(jīng)決定了它的分發(fā)方式了浮驳『费矗可以這樣理解:每一個(gè)應(yīng)用Id后面對(duì)應(yīng)一套證書(shū),這套證書(shū)決定了你應(yīng)用的分發(fā)方式至会。重簽名就是為當(dāng)前的應(yīng)用換一套應(yīng)用Id與證書(shū)离咐,從而達(dá)到分發(fā)應(yīng)用的目的。現(xiàn)實(shí)的需求是奉件,如果你上線App Store的應(yīng)用宵蛀,想通過(guò)企業(yè)賬號(hào)的形式進(jìn)行分發(fā)昆著,而你又沒(méi)有源碼,或是想探究一下應(yīng)用雙開(kāi)糖埋,那么重簽名就派上用場(chǎng)了宣吱。我們介紹兩種重簽名的方式:
1.Xcode 重簽名
(1) 新建同名的工程文件
注意這里的同名并不是Bundle Identifier 相同窃这,而是跟你砸殼解壓ipa文件瞳别,Payload里面的包相同的名稱(chēng)
還需要注意,如果你重簽名的工程中是通過(guò)AppDelegate
來(lái)監(jiān)聽(tīng)App的生命周期的話杭攻,那么需要在新版的Xcode中移除SceneDelegate
這個(gè)類(lèi),重新使用AppDelegate
來(lái)監(jiān)聽(tīng)App的生命周期祟敛。重新配置完成工程后,真機(jī)運(yùn)行兆解,把描述文件安裝到手機(jī)里馆铁。
(2) 替換編譯的App包
找到我們?cè)覛み^(guò)的Payload文件夾中包,對(duì)我們編譯的包進(jìn)行替換
(3) 對(duì)二進(jìn)制文件中的FrameWork進(jìn)行重簽名
其實(shí)在這一步之前還需要對(duì)包內(nèi)的
PlugIns
插件以及Watch
相關(guān)組件進(jìn)行刪除锅睛,我們逆向包里面沒(méi)有這些組件埠巨,所以省略了。
進(jìn)入Framework 文件夾现拒,利用CodeSign
對(duì)Framework進(jìn)行證書(shū)簽名,注意要對(duì)所有FrameWork進(jìn)行重簽名辣垒。
codesign -fs "復(fù)制的你自己的證書(shū)名字" 要重簽的FrameWork名稱(chēng)
證書(shū)的名字就是你真機(jī)測(cè)試的證書(shū)的名稱(chēng),如果不知道可以去鑰匙串中查看
iPhone Developer: *** ** (********)
就是證書(shū)名稱(chēng)
(4) 重簽名后運(yùn)行
這樣我們就在沒(méi)有源碼的情況下印蔬,完成了對(duì)應(yīng)用的重簽名勋桶。
2. 使用腳本文件重簽名
利用shell
腳本進(jìn)行重簽名的原理,跟上面的簽名原理相同侥猬,只不過(guò)把重簽步驟給腳本化了例驹。
(1) 創(chuàng)建空工程(工程名隨便),并且進(jìn)行真機(jī)運(yùn)行
(2) 在工程根目錄下創(chuàng)建APP文件夾退唠,在文件中放入我們?cè)覛ず蟮膇pa包
(3) 在工程中添加腳本
在工程Build Phases
中新建腳本文件
在Run Script
中添加腳本
# Type a script or drag a script file from your workspace to insert its path.
# Type a script or drag a script file from your workspace to insert its path.
# ${SRCROOT} 為工程文件所在的目錄
TEMP_PATH="${SRCROOT}/Temp"
#資源文件夾,放三方APP的
ASSETS_PATH="${SRCROOT}/APP"
#ipa包路徑
TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa"
#新建Temp文件夾
rm -rf "$TEMP_PATH"
mkdir -p "$TEMP_PATH"
# --------------------------------------
# 1. 解壓IPA 到Temp下
unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
# 拿到解壓的臨時(shí)APP的路徑
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# 這里顯示打印一下 TEMP_APP_PATH變量
echo "TEMP_APP_PATH: $TEMP_APP_PATH"
# -------------------------------------
# 2. 把解壓出來(lái)的.app拷貝進(jìn)去
#BUILT_PRODUCTS_DIR 工程生成的APP包路徑
#TARGET_NAME target名稱(chēng)
TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
echo "TARGET_APP_PATH: $TARGET_APP_PATH"
rm -rf "$TARGET_APP_PATH"
mkdir -p "$TARGET_APP_PATH"
cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH/"
# -------------------------------------
# 3. 為了是重簽過(guò)程簡(jiǎn)化鹃锈,移走extension和watchAPP. 此外個(gè)人免費(fèi)的證書(shū)沒(méi)辦法簽extension
echo "Removing AppExtensions"
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"
# -------------------------------------
# 4. 更新 Info.plist 里的BundleId
# 設(shè)置 "Set :KEY Value" "目標(biāo)文件路徑.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"
# 5.給可執(zhí)行文件上權(quán)限
#添加ipa二進(jìn)制的執(zhí)行權(quán)限,否則xcode會(huì)告知無(wú)法運(yùn)行
#這個(gè)操作是要找到第三方app包里的可執(zhí)行文件名稱(chēng),因?yàn)閕nfo.plist的 'Executable file' key對(duì)應(yīng)的是可執(zhí)行文件的名稱(chēng)
#我們grep 一下,然后取最后一行, 然后以cut 命令分割瞧预,取出想要的關(guān)鍵信息屎债。存到APP_BINARY變量里
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#這個(gè)為二進(jìn)制文件加上可執(zhí)行權(quán)限 +X
chmod +x "$TARGET_APP_PATH/$APP_BINARY"
# -------------------------------------
# 6. 重簽第三方app Frameworks下已存在的動(dòng)態(tài)庫(kù)
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
#遍歷出所有動(dòng)態(tài)庫(kù)的路徑
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do
echo "FRAMEWORK : $FRAMEWORK"
#簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi
運(yùn)行后完成對(duì)其重簽名.
四、總結(jié)
對(duì)應(yīng)用的砸殼和重簽名僅僅是逆向的入門(mén)松蒜,后面我們會(huì)繼續(xù)探討關(guān)于逆向的其他技術(shù)扔茅。再次聲明:研究逆向的目的是為了更好的保護(hù)我們的應(yīng)用,而不是用在非法用途上秸苗。
參考文獻(xiàn):
http://blog.cnbang.net/tech/3386/
https://www.i4.cn/news_3.html