iOS逆向(3)-APP重簽名

轉(zhuǎn)載:原文地址

本文將從原理分析,到利用原理的漏洞,再到具體過程,最后利用腳本全自動(dòng)實(shí)現(xiàn)。

作為一名iOS開發(fā)者肯定知道iOS開發(fā)證書,那么證書具體是什么呢?為什么到我們本地的不是證書本身,而是一個(gè)稱之為描述文件的東西。而這「描述文件」又具體是什么呢?
在知道這「描述文件」后,我們是不是可以通過將「描述文件」替換為我們自己的「描述文件」進(jìn)行一些有意思的事情呢?比如這篇文章的主題,對(duì)一個(gè)APP進(jìn)行重簽名,讓他在我們的XCode中運(yùn)行起來,運(yùn)用我們強(qiáng)大的LLDB進(jìn)行調(diào)試,分析其UI和部分邏輯。當(dāng)然作為一個(gè)正直的開發(fā)者,我們?cè)谶@片文章肯定不會(huì)對(duì)她進(jìn)「代碼注入」這樣讓人不(興)齒(奮)的事情的(下一篇就會(huì) O(∩_∩)O哈哈~)。

片頭先給福利:點(diǎn)擊下載Demo:AppReSign,使用方法詳見demo的Readme

接下來我們會(huì)從以下幾點(diǎn)來玩一玩「APP重簽名」

  • 分析Apple對(duì)App加密的需求
  • 什么是雙層簽名
  • 手動(dòng)對(duì)APP進(jìn)行重簽名
  • 使用Shell腳本進(jìn)行重簽

1、分析Apple對(duì)App加密的需求

首先明確一點(diǎn),對(duì)App加密肯定是用要非對(duì)稱加密而不是對(duì)稱加密!這我默認(rèn)大家都懂了,應(yīng)該不用解釋。

Step 1 安裝App到手機(jī)的渠道分析

如果所有的APP都是從App Store下載的那么,這就簡(jiǎn)單了,只需要對(duì)APP進(jìn)行一層RSA加密就可以了,App Store持有私鑰,我們iPhone持有公鑰。那么問題就解決了。但事實(shí)上肯定不是這樣,我們已知的渠道除了App Store就包括XCode打包,ADHOC證書分發(fā),企業(yè)證書分發(fā)等等。為了解決這個(gè)問題,我們就得先了解Apple的具體需求是什么。

Step 2 分析需求

  • App Store下載
  • XCode直接安裝
  • 限制ADHoc打包的APP安裝設(shè)備
  • ...等等

2、什么是雙層簽名

針對(duì)以上三種(包括但不只)場(chǎng)景,蘋果給出「雙層簽名」的機(jī)制。
什么是「雙層簽名」,先上一張PPT。

雙層簽名流程圖

看不懂?沒關(guān)系,下面會(huì)一步步,詳細(xì)的接受雙層簽名的始末。

1、向服務(wù)器申請(qǐng)證書
  • 什么是CSR文件
    申請(qǐng)過開發(fā)者證書的都知道,要申請(qǐng)證書,都有「Mac本地通過CSR文件向服務(wù)器」這樣的一步。那么這一步到底做了寫什么呢?
    先看看什么是CSR

CSR是Certificate Signing Request的英文縮寫,即證書請(qǐng)求文件,也就是證書申請(qǐng)者在申請(qǐng)數(shù)字證書時(shí)由CSP(加密服務(wù)提供者)在生成私鑰的同時(shí)也生成證書請(qǐng)求文件,證書申請(qǐng)者只要把CSR文件提交給證書頒發(fā)機(jī)構(gòu)后,證書頒發(fā)機(jī)構(gòu)使用其根證書私鑰簽名就生成了證書公鑰文件,也就是頒發(fā)給用戶的證書。

通俗一點(diǎn),就是Mac本地有一對(duì)公鑰(公鑰M)和私鑰(私鑰M)(什么是公鑰私鑰?),在Mac上對(duì)公鑰M進(jìn)行了一層包裝,這包裝后的新東西就是CSR。

  • 服務(wù)器通過CSR返回證書
    本地有了CSR文件之后,將CSR上傳到Apple的服務(wù)器。
    Apple服務(wù)器其實(shí)也是有一對(duì)公鑰(公鑰A)和私鑰(私鑰A),在收到Mac上傳過來的的CSR文件之后,取出其中的公鑰M,用Apple服務(wù)器的私鑰A對(duì)公鑰M進(jìn)行一次數(shù)字簽名(什么是數(shù)字簽名?)得到開發(fā)證書,然后將開發(fā)證書附入描述文件(描述文件還有哪些東西下文會(huì)有講到),最后將描述文件傳回給我們的Mac電腦。
2、描述文件

配置描述文件是 XML 文件,包含以下內(nèi)容:設(shè)備的安全策略和限制、VPN 配置信息、無線局域網(wǎng)設(shè)置、電子郵件帳戶和日歷帳戶以及可允許 iPhone、iPod touch 和 iPad 配合您的企業(yè)系統(tǒng)使用的鑒定憑證。配置描述文件能快速地將設(shè)置和授權(quán)信息載入到設(shè)備上。有些 VPN 和無線局域網(wǎng)設(shè)置只能使用配置描述文件來設(shè)定,而且如果您使用的不是 Microsoft Exchange,則將需要使用配置描述文件來設(shè)定設(shè)備密碼策略。

描述文件包括的東西,如:

  • 開發(fā)證書
  • APP的Bundle Id
  • 證書所信任的Device Id
  • 還有一些權(quán)限文件(如:Apple Pay,通知,VPN,iCloud)
3、Mac打包APP

在Mac本地有了描述文件之后,就可以對(duì)APP進(jìn)行打包了,打包這個(gè)過程除了對(duì)APP的壓縮之外,更重要的其實(shí)是指對(duì)APP的加密。
之前本地把公鑰M發(fā)送給Apple服務(wù)器,本地剩下的私鑰M就是用來加密APP的,得到一個(gè)APP的簽名文件,再將上一步得到的描述文件,以及MachO文件一起打包壓縮,最終就得到了我們的ipa包了。
所以ipa其實(shí)包含以下三種東西

  • MachO文件
  • APP的簽名文件
  • 描述文件
4、iPhone驗(yàn)證ipa文件

上文提到的私鑰A是用來加密了公鑰M,與之對(duì)應(yīng)的公鑰A其實(shí)在我們激活iPhone的同時(shí)已經(jīng)下載好了,一直躺在我們的iPhone里面。
有了公鑰M,那么一切就簡(jiǎn)單了,

  • 公鑰A解開ipa中攜帶的描述文件中的證書得到公鑰M
  • 對(duì)公鑰M進(jìn)行Hash,對(duì)比證書中的Hash
  • 對(duì)比通過之后,用公鑰M對(duì)加密的APP進(jìn)行解密,得到最終APP。

3、手動(dòng)對(duì)APP進(jìn)行重簽名 (如果不想看具體過程,可以跳到本節(jié)末尾,有流程總結(jié))

從上面可以得知,雙層簽名其實(shí)本質(zhì)就是如下三個(gè)步驟:

  • APP的Bundle id的驗(yàn)證
  • 描述文件本身的驗(yàn)證
  • 對(duì)APP簽名的驗(yàn)證

注:對(duì)APP進(jìn)行重新簽名,前提是這個(gè)APP已經(jīng)被砸殼了。
下載已經(jīng)砸殼成功的APP,以下例子用微信舉例:越獄版本微信7.0.2 提取碼: 2w87

具體步驟:

Step 1 進(jìn)入WeChat目錄

解壓出 Wechat7.0.2越獄 ,進(jìn)入WeChat目錄

// 進(jìn)入WeChat的目錄
cd /Users/dengbin/Desktop/分享/主目錄/資料/Wechat7.0.2越獄/Payload

Step 2 查看APP的證書情況

codesign -d -vv「WeChat.app路徑」

查看APP證書情況

Step 3 查看驗(yàn)證APP是否被加密

進(jìn)入APP的包內(nèi)容可以看到其中有一個(gè)WeChat的可執(zhí)行文件,也就是是MachO文件,就是要查看這個(gè)MachO文件時(shí)候被加密

WeChat目錄
WeChat_MachO
otool -l WeChat | grep cryp

其中cryptid0代表已經(jīng)砸殼,即解密,為1或者2表示以第1類或者第2類加密方案加密。

有些老鐵回復(fù)說復(fù)制代碼運(yùn)行后會(huì)報(bào)錯(cuò),有兩種情況:
1、電腦里沒有Xcode-select,應(yīng)該先去裝一次,很簡(jiǎn)單,自行百度。
2、如果還不行,代碼不要復(fù)制,自己敲一遍,就可以。(為何有些人復(fù)制不行就不得而知了)。

Step 4 查看本地證書并記錄需要用到的證書

security find-identity -v -p codesigning

本地證書列表

Step 5 刪除不可簽名的插件(還有Watch中的插件)

由于本地存在一些插件,這些插件是不可被我們重簽,并且這個(gè)過程我們用不著,所以我們索性就刪掉。
其中包括:整個(gè)目錄PlugIns目錄和整個(gè)Watch目錄(因?yàn)閃atch.app中也有個(gè)PlugIns)

PlugIns
Watch

Step 6 Framework重簽名

這一步就是比較繁瑣的了,需要將Frameworks下的所有Framework進(jìn)行重簽名,運(yùn)用到XCode提供的codesign指令,參數(shù)中的證書就是Step 4中的一個(gè)。具體使用哪個(gè)就看個(gè)人了

codesign –fs 「證書串」 「文件名」
Frameworks
Frameworks證書重簽

Step 7 給MachO添加可執(zhí)行權(quán)限

由于MachO本身就有可執(zhí)行權(quán)限,所以這一步跳過。

Step 8 App重簽名

  • 新建一個(gè)WeChat同名工程(下文稱NewWeChat,原來的微信APP稱之為WeChat)

  • Build NewWeChat工程,進(jìn)入被編譯出的WeChat.App目錄,找到其中的embedded.mobileprovision文件,將其復(fù)制到WeChat.App(越獄微信)中

    Build后的WeChat
    embedded.mobileprovision文件
    復(fù)制后的結(jié)果
  • 在WeChat.App找到info.plist,并修改其中的BundleId為NewWeChat的BundleId

    更改BundleId
  • 查看embedded文件

security cms -D -i 「 embedded文件路徑」

找到其中的entitlements字段,并且復(fù)制entitlements字段和其中的內(nèi)容

查看embedded
entitlements字段
  • 在NewWeChat中新建entitlements.plist文件,將上一步復(fù)制得到的「entitlements字段內(nèi)容」拷貝入新的entitlements.plist文件,然后將entitlements.plist復(fù)制到WeChat.app的同級(jí)目錄下。

    拷貝entitlements
    復(fù)制entitlements
  • 對(duì)APP重新簽名
    進(jìn)入WeChat目錄,對(duì)APP使用新的描述文件進(jìn)行重簽

codesign -fs 「證書串」 --no-strict --entitlements=entitlements.plist
對(duì)App進(jìn)行重簽
  • 壓縮Playload
 zip –ry 「輸出文件名」 「輸入文件名」
壓縮Playload

Step 9 安裝新的ipa

可以通過各種途徑安裝ipa,如Xcode,PP助手,fir,iTunes等等, 如果手機(jī)上有正版的微信,在安裝完我們重簽名的ipa包后會(huì)發(fā)現(xiàn)手機(jī)上就有兩個(gè)微信啦!!!

如果想用LLDB調(diào)試微信,可以將重簽后的WeChat.app替換NewWeChat Build后的WeChat.app,然后直接運(yùn)行(Run)項(xiàng)目,就會(huì)發(fā)現(xiàn)我們可以用LLDB了。

Step 10 再次驗(yàn)證新的ipa是否真的重簽成功

這一步其實(shí)是重復(fù)Step 3

codesign -d -vv「WeChat.app路徑」

步驟總結(jié):

1、cd WeChat // 進(jìn)入WeChat的目錄
2、codesign -d -vv「WeChat.app路徑」 // 查看APP的證書情況
3、otool –l WeChat | grep cryp // 查看APP是否被加密
4、security find-identity -v -p codesigning // 查看本地證書
5、刪除不可簽名的插件(還有Watch中的插件)
6、codesign –fs 「證書串」 「文件名」 // Framework重簽名
7、chmod +x 可執(zhí)行文件   // 給文件添加權(quán)限
8、App重簽名
     ① 新建一個(gè)項(xiàng)目并且命名為 WeChat(下文稱NewWeChat,原來的微信APP稱之為WeChat) -> Build -> 找到APP中的權(quán)限文件 embedded.mobileprovision
     ② 復(fù)制embedded.mobileprovision到WeChat.app中
     ③ 修改WeChat.app中info.plist的BundleId
     ④ security cms -D -i 「 embedded文件路徑」 //查看WeChat中的embedded文件,復(fù)制WeChat中entitlements.plist文件的entitlements字段
     ⑤ 在NewWeChat中新建entitlements.plist文件,將上一步復(fù)制得到的「entitlements字段和其中的內(nèi)容」拷貝入新的entitlements.plist文件
     ⑥ codesign -fs 「證書串」 --no-strict --entitlements=entitlements.plist //復(fù)制新的entitlements到WeChat.app的同級(jí)目錄,并且對(duì)APP重新簽名
     ⑦ zip –ry 「輸出文件名」 「輸入文件名」 // 壓縮Playload
9、安裝ipa 
10、再次驗(yàn)證新的ipa是否真的重簽成功

  • 注意:有些人會(huì)安裝失敗,或者安裝成功會(huì)有Crash的問題,這是因?yàn)楫?dāng)前描述文件在我們的手機(jī)還不受信任,用新工程N(yùn)ewWeChat在手機(jī)上跑一遍,然后刪除NewWeChat,在嘗試安裝新的ipa,問題可以解決。

4、使用Shell腳本進(jìn)行重簽

上面所有的步驟其實(shí)是固定不變的,而且所有需要操作的文件相對(duì)于ipa文件的「相對(duì)地址」也是固定的,所以就可以用腳本來代替所有的操作。
以下腳本適用于適用XCode直接調(diào)試,點(diǎn)擊下載Demo:AppReSign,使用方法詳見demo的Readme

附上腳本代碼

# ${SRCROOT} 它是工程文件所在的目錄
TEMP_PATH="${SRCROOT}/Temp"
#資源文件夾,我們提前在工程目錄下新建一個(gè)APP文件夾,里面放ipa包
ASSETS_PATH="${SRCROOT}/APP"
#目標(biāo)ipa包路徑
TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa"
#清空Temp文件夾
rm -rf "${SRCROOT}/Temp"
mkdir -p "${SRCROOT}/Temp"

#----------------------------------------
# 1\. 解壓IPA到Temp下
unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
# 拿到解壓的臨時(shí)的APP的路徑
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# echo "路徑是:$TEMP_APP_PATH"

#----------------------------------------
# 2\. 將解壓出來的.app拷貝進(jìn)入工程下
# BUILT_PRODUCTS_DIR 工程生成的APP包的路徑
# TARGET_NAME target名稱
TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
echo "app路徑:$TARGET_APP_PATH"

rm -rf "$TARGET_APP_PATH"
mkdir -p "$TARGET_APP_PATH"
cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH"

#----------------------------------------
# 3\. 刪除extension和WatchAPP.個(gè)人證書沒法簽名Extention
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"

#----------------------------------------
# 4\. 更新info.plist文件 CFBundleIdentifier
#  設(shè)置:"Set : KEY Value" "目標(biāo)文件路徑"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"
#----------------------------------------

# 5\. 給MachO文件上執(zhí)行權(quán)限
# 拿到MachO文件的路徑
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#上可執(zhí)行權(quán)限
chmod +x "$TARGET_APP_PATH/$APP_BINARY"

#----------------------------------------
# 6\. 重簽名第三方 FrameWorks
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do

# 簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi

這邊文章主要講了關(guān)于雙層簽名的原理,已經(jīng)利用雙層簽名的原理對(duì)APP(已越獄)進(jìn)行重簽,但其實(shí)其中有一點(diǎn)非常非常重要的內(nèi)容在這片文章知識(shí)被一筆帶過,那就是LLDB,能夠用LLDB調(diào)試我們的APP意味著無限的可能。
所以對(duì)LLDB運(yùn)用,也是咱們逆向的必經(jīng)之路。后續(xù)文章也會(huì)提到,待更新。

注意!!!
警告!!!
警告!!!
警告!!!
重簽后不要用自己的賬號(hào)登錄,有封號(hào)的危險(xiǎn)!!!


推薦文集

* 抖音效果實(shí)現(xiàn)

* BAT—最新iOS面試題總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,619評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,155評(píng)論 3 425
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,635評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,539評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,255評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,646評(píng)論 1 326
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,655評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,838評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,399評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,146評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,338評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,893評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,565評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,983評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,257評(píng)論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,059評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,296評(píng)論 2 376

推薦閱讀更多精彩內(nèi)容