iOS逆向之從砸殼到重簽名

一、概述

筆者做了多年的業務開發,以前對逆向知之甚少,好像我們做iOS的開發者對應用本身的安全問題總不是那麼上心,總以爲Apple自身的加密簽名機制足夠安全了,我們除了關心業務網絡安全,對自身App包的安全重視度總是不夠。然而一旦我們的包被有心人破解,那麼無論是對自身業務還是用戶數據都是致命的。真正開始研究逆向,才發現我們App是如此的不堪一擊。所以研究逆向其實是研究Hacker是如何攻破我們的應用,從而更好地保護自身應用安全。

研究逆向,首當其衝的就是重簽名,重簽名就是用自己的證書籤名別人的應用,從而進行分發。重簽名說白了就是套殼別人的應用,挺火的微信雙開,其實就是對微信進行了重簽名。而重簽名首先要做的就是對應用砸殼。

二、手機越獄與應用砸殼

我們從App store 下載的應用是經過蘋果加密簽名過的,是無法進行重簽名的。所以重簽名首先要做的就是對應用進行砸殼,而砸殼需要你有一臺越獄手機。

1. 手機越獄

目前主流的越獄平臺有PP助手、愛思助手做到比較好,提供一鍵越獄功能。我自己使用的愛思助手,下載愛思助手電腦版,選擇【工具箱】-【一鍵越獄】,此時會匹配你當前手機版本的越獄工具,選擇工具進行越獄。



我使用的是 iphone SE,系統版本是14.4,按照提示完成越獄就OK了。

需要注意,這種越獄方式是不完美的越獄,當你重啓手機後會重新變回非越獄狀態,需要重新走一遍越獄流程。不過對於我們研究逆向足夠了。

還沒完,越獄完成後需要安裝一個插件:Apple File Conduit"2",安裝這個插件的目的是,讓我們的電腦端能訪問設備的根文件目錄,安裝方式也很簡單,可以參考這篇文章Apple File Conduit"2"安裝,這裏不再贅述。當我們安裝完成後,愛思助手連接手機,可以看到在【文件管理】中多了個欄目【文件系統(越獄)】,這就是越獄狀態下的系統根目錄。

2. ipa應用砸殼

首先了解什麼是應用砸殼:我們提交到App Store發佈的App都是經過Apple加密的,這樣可以確保安裝到我們手機的應用都是蘋果審覈授權的,當然通過企業級證書或者開發者證書生成的App是不需要砸殼的。對於App Store加密的應用,我們無法通過Hopper等反編譯靜態分析,也無法class-dump,在逆向分析過程中,需要對加密的二進制文件進行解密纔可以進行靜態分析,這一過程就是大家熟知的砸殼。
砸殼主要有兩種方式:

  • 靜態砸殼
    靜態砸殼就是在已經掌握和了解到了殼應用的加密算法和邏輯後,在不運行殼應用程序的前提下將殼應用程序進行解密處理。靜態脫殼的方法難度大,而且加密方發現應用被破解後,就可能會改用更加高級和複雜的加密技術。
  • 動態砸殼
    動態砸殼就是從運行在進程內存空間中的可執行程序映像(image)入手,來將內存中的內容進行轉儲(dump)處理來實現脫殼處理。這種方法實現起來相對簡單,且不必關心使用的是何種加密技術。所以目前市面上的砸殼工具都是基於動態砸殼進行的。動態砸殼有多種工具:ClutchdumpdecryptedCrackerXI App,前兩種對系統要求較嚴格,而且年久失修很容易砸殼失敗,我們直接介紹最方便的第三種方式:利用CrackerXI App進行砸殼。

(1) 在Cydia中下載CrackerXI App

Cydia類似於越獄前的App Store,越獄後我們所有的軟件都是通過Cydia來進行安裝。打開Cydia後,選擇【軟件源】-右上角【編輯】-點擊【添加】,輸入http://apt.wxhbts.com/,【添加源】等待添加完成。添加軟件源完成後,搜索CrackerXI App,點擊安裝完成後【重啓springboard】,回到桌面,可以看到桌面上安裝完成了CrackerXI+App.

(2) 砸殼

提前在App Store 下載好你要砸殼的App,打開CrackerXI+,選擇【AppList】然後點擊你要砸殼的應用,在彈框中選擇【YES,Full IPA】,此時會打開我們要砸殼的應用進行砸殼,完成後會看到一個砸殼後的文件地址/var/mobile/Documents/CrackerXI/*****.ipa,這個文件就是我們砸殼後的ipa包。

這個路徑怎麼查找相信聰明的你已經知道了,去愛思助手-【文件管理】-【文件系統(越獄)】查找到這個ipa,導出到桌面目錄就完成了。

(3) 驗證

完成上面的操作後,我們需要驗證一下拿到的ipa是否是被砸殼的。把.ipa包擴展名改爲.zip,解壓後得到Payload文件夾,右鍵【顯示包內容】- 找到可執行文件.

終端輸入

otool -l 執行文件名 | grep crypt

可以看到cryptid的值爲0,說明砸殼成功。

三、重新簽名

Apple 應用的分發一般有以下幾種方式:

  • 最常用的是從App store下載應用。這種下發方式不受設備數的限制,只要上線App store 的應用,都會被Apple進行簽名加密.
  • 第二種方式是申請企業賬號,把我們的應用通過企業賬號進行簽名,從而繞過App store惱人的審覈機制,達到分發應用的目的。這種方法分發數目也不受限制.
  • 第三種是通過TestFlight進行測試版本的分發,他分爲內部測試人員與外部測試人員。通過分發外部測試人員,最多能給1萬名用戶進行分發安裝.
  • 第四種開發人員通過添加設備ID安裝應用,最多可以註冊100臺設備.

不同的開發者賬號對應着App不同的分發方式,我們申請完成開發者賬號後,創建應用Id,然後創建其對應證書,描述文件等一系列動作,實際已經決定了它的分發方式了。可以這樣理解:每一個應用Id後面對應一套證書,這套證書決定了你應用的分發方式。重簽名就是爲當前的應用換一套應用Id與證書,從而達到分發應用的目的。現實的需求是,如果你上線App Store的應用,想通過企業賬號的形式進行分發,而你又沒有源碼,或是想探究一下應用雙開,那麼重簽名就派上用場了。我們介紹兩種重簽名的方式:

1.Xcode 重簽名

(1) 新建同名的工程文件

注意這裏的同名並不是Bundle Identifier 相同,而是跟你砸殼解壓ipa文件,Payload裏面的包相同的名稱

還需要注意,如果你重簽名的工程中是通過AppDelegate來監聽App的生命週期的話,那麼需要在新版的Xcode中移除SceneDelegate這個類,重新使用AppDelegate來監聽App的生命週期。重新配置完成工程後,真機運行,把描述文件安裝到手機裏。

(2) 替換編譯的App包

找到我們砸殼過的Payload文件夾中包,對我們編譯的包進行替換

(3) 對二進制文件中的FrameWork進行重簽名

其實在這一步之前還需要對包內的PlugIns插件以及Watch相關組件進行刪除,我們逆向包裏面沒有這些組件,所以省略了。

進入Framework 文件夾,利用CodeSign對Framework進行證書籤名,注意要對所有FrameWork進行重簽名。

codesign -fs "複製的你自己的證書名字" 要重籤的FrameWork名稱

證書的名字就是你真機測試的證書的名稱,如果不知道可以去鑰匙串中查看

iPhone Developer: *** ** (********) 就是證書名稱

(4) 重簽名後運行

這樣我們就在沒有源碼的情況下,完成了對應用的重簽名。

2. 使用腳本文件重簽名

利用shell腳本進行重簽名的原理,跟上面的簽名原理相同,只不過把重籤步驟給腳本化了。

(1) 創建空工程(工程名隨便),並且進行真機運行

(2) 在工程根目錄下創建APP文件夾,在文件中放入我們砸殼後的ipa包

(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"
# 拿到解壓的臨時APP的路徑
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# 這裏顯示打印一下 TEMP_APP_PATH變量
echo "TEMP_APP_PATH: $TEMP_APP_PATH"

# -------------------------------------
# 2. 把解壓出來的.app拷貝進去
#BUILT_PRODUCTS_DIR 工程生成的APP包路徑
#TARGET_NAME target名稱
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. 爲了是重簽過程簡化,移走extension和watchAPP. 此外個人免費的證書沒辦法籤extension

echo "Removing AppExtensions"
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"

# -------------------------------------
# 4. 更新 Info.plist 裏的BundleId
#  設置 "Set :KEY Value" "目標文件路徑.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"

# 5.給可執行文件上權限
#添加ipa二進制的執行權限,否則xcode會告知無法運行
#這個操作是要找到第三方app包裏的可執行文件名稱,因爲info.plist的 'Executable file' key對應的是可執行文件的名稱
#我們grep 一下,然後取最後一行, 然後以cut 命令分割,取出想要的關鍵信息。存到APP_BINARY變量裏
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`

#這個爲二進制文件加上可執行權限 +X
chmod +x "$TARGET_APP_PATH/$APP_BINARY"

# -------------------------------------
# 6. 重籤第三方app Frameworks下已存在的動態庫
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
#遍歷出所有動態庫的路徑
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do
echo "FRAMEWORK : $FRAMEWORK"
#簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi

運行後完成對其重簽名.

四、總結

對應用的砸殼和重簽名僅僅是逆向的入門,後面我們會繼續探討關於逆向的其他技術。再次聲明:研究逆向的目的是爲了更好的保護我們的應用,而不是用在非法用途上。

參考文獻:

http://blog.cnbang.net/tech/3386/
https://www.i4.cn/news_3.html
https://www.i4.cn/news_detail_1623.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章