最近更新|軟件分類(lèi)|單機(jī)游戲|軟件專(zhuān)題|手機(jī)版|軟件發(fā)布 盤(pán)古越獄原理分析 讓我們一起來(lái)看清它如何越獄的!
首頁(yè)>軟件新聞>盤(pán)古越獄原理分析 讓我們一起來(lái)看清它如何越獄的!

盤(pán)古越獄原理分析 讓我們一起來(lái)看清它如何越獄的!

我要評(píng)論2014/10/27 10:53:45來(lái)源:9553編輯:

盤(pán)古團(tuán)隊(duì)的ios8.X的越獄工具是目前備受?chē)?guó)人矚目的熱點(diǎn),那么問(wèn)題來(lái)了,盤(pán)古工具究竟是怎么使用漏洞進(jìn)行越獄的呢?接下來(lái)給大家揭開(kāi)謎團(tuán)。。。

盤(pán)古在用戶(hù)空間主要利用了iOS安裝程序的一個(gè)漏洞,這里先列出安裝一個(gè)應(yīng)用的主要過(guò)程:

\

整個(gè)安裝過(guò)程分為12個(gè)階段,上圖只是列出了起點(diǎn)、終點(diǎn)還是對(duì)盤(pán)古越獄來(lái)說(shuō)比較重要的階段。大家注意上圖紅線所示的時(shí)間區(qū)間,在這個(gè)區(qū)間內(nèi)如果在“Staging Directory”中創(chuàng)建一個(gè)符號(hào)鏈接指向沙盒之外,就可以利用解壓程序向系統(tǒng)目錄寫(xiě)入文件。同時(shí)也可以通過(guò)控制壓縮包中的文件列表,在起始處放一個(gè)大文件,從而在解壓過(guò)程中創(chuàng)建一個(gè)符號(hào)鏈接。這是在盤(pán)古在安裝過(guò)程中利用的主要漏洞,后面介紹的盤(pán)古在用戶(hù)空間的行為基本都是圍繞這個(gè)漏洞。

主要的組件

盤(pán)古主要由四部分組成:

1、桌面程序:提供資源,控制越獄流程。

2、com.pangu.ipa1.ipa:Socket Server,與桌面程序配合制造競(jìng)態(tài)條件。

3、pangu.dylib,Socket Server,利用內(nèi)核漏洞安裝Untecher,Cydia等。

4、pangu.tar,Untecher

這里主要涉及的是前兩個(gè)組件,及第三個(gè)組件中用戶(hù)空間相關(guān)的部分。

工作流程

說(shuō)明:為了驗(yàn)證自己的分析是正確的,用Python重新實(shí)現(xiàn)了盤(pán)古桌面程序的功能,利用盤(pán)古的Payload可以實(shí)現(xiàn)越獄,下面會(huì)在主要階段給出相應(yīng)示例代碼。

階段一:安裝輔助程序,獲取相關(guān)資源

1、安裝com.pangu.ipa1.ipa

def install_pangu():

lockdown = LockdownClient()

afc = AFCClient(lockdown)

mci = lockdown.startService("com.apple.mobile.installation_proxy")

file_name = "com.pangu.ipa1.ipa"

afc.set_file_contents("/PublicStaging/" + file_name, open("payload/" + file_name,"rb").read())

mci.sendPlist({"Command":"Install", "PackagePath": "/PublicStaging/" + file_name})

while True:

status = mci.recvPlist()

if not status:

break

completion = status.get("PercentComplete")

if completion:

print "Installing, %s: %s %% Complete" % ("com.pangu.ipa1.ipa", status["PercentComplete"])

if status.get("Status") == "Complete":

print "Installation %s " % status["Status"]

break

mci.close()

afc.stop_session()

lockdown.stop_session()

首先利用AFC服務(wù)將IPA傳到設(shè)備上,然后利用 Installation Proxy 安裝應(yīng)用。

2、獲取Cache

def download_caches():

fc = FileRelayClient()

data = fc.request_sources(["Caches"])

fc.stop_session()

if data:

file_path = "./payload/caches.gz"

output_path = "./payload/caches"

open(file_path,"wb").write(data)

print "Data saved to: %s " % file_path

with open(file_path, "r") as f:

gz = gzip.GzipFile(mode="rb", fileobj=f)

cpio = CpioArchive(fileobj=BytesIO(gz.read()))

cpio.extract_files(files=None,outpath=output_path)

else:

print "Fail to get caches"

raise Exception("Fail to get caches")

調(diào)用 FileRelay 服務(wù),獲取Cache,主要是從中拿到com.apple.mobile.installation.plist

3、修改 com.apple.mobile.installation.plist修改是針對(duì)盤(pán)古程序的,具體修改如下:

CFBundleExecutable = "../../../../../../usr/libexec/lockdownd";

EnvironmentVariables = { DYLD_INSERT_LIBRARIES = "/private/var/mobile/Media/Pangu-Install/pangu.dylib"; };

4、修改盤(pán)古程序的Info.plist

CFBundleExecutable = "../../../../../../usr/libexec/lockdownd";

5、構(gòu)造applicationState.plist

{ "com.pangu.ipa1" = { SBApplicationAutoLaunchForVoIP = :true; }; }

這個(gè)會(huì)造成盤(pán)古程序在設(shè)備重啟后自動(dòng)運(yùn)行。

6、com.apple.LaunchServices-056.csstore 主要是為了更新程序列表

7、com.apple.backboardd.plist 禁用“看門(mén)狗”

基于上述文件盤(pán)古會(huì)構(gòu)造三個(gè)Payload。

def generate_upgrade_bundle1():

guid_str = get_guid()

with ZipFile("./payload/upgrade1.zip", "w") as payload:

payload.write("./payload/upgrade_bundle/bigfile", "/tmp/bigfile")

payload.write("./payload/upgrade_bundle/com.apple.LaunchServices-056.csstore", "/mobile/Library/Caches/com.apple.LaunchServices-056.csstore")

payload.write("./payload/upgrade_bundle/com.apple.mobile.installation.plist", "/mobile/Library/Caches/com.apple.mobile.installation.plist")

payload.write("./payload/upgrade_bundle/applicationState.plist", "/mobile/Library/BackBoard/applicationState.plist")

payload.write("./payload/upgrade_bundle/com.apple.backboardd.plist", "/mobile/Library/Preferences/com.apple.backboardd.plist")

payload.write("./payload/upgrade_bundle/Info.plist", "/mobile/Applications/" + guid_str + "/ipa1.app/Info.plist")

def generate_upgrade_bundle2():

# os.remove("./payload/upgrade2.zip")

guid_str = get_guid()

with ZipFile("./payload/upgrade2.zip", "w") as payload:

payload.write("./payload/upgrade_bundle/bigfile", "/tmp/bigfile")

payload.write("./payload/upgrade_bundle/com.apple.mobile.installation.plist", "/mobile/Library/Caches/com.apple.mobile.installation.plist")

def generate_upgrade_bundle3():

# os.remove("./payload/upgrade3.zip")

guid_str = get_guid()

with ZipFile("./payload/upgrade3.zip", "w") as payload:

payload.write("./payload/upgrade_bundle/bigfile", "/tmp/bigfile")

payload.write("./payload/upgrade_bundle/com.apple.LaunchServices-056.csstore", "/mobile/Library/Caches/com.apple.LaunchServices-056.csstore")

這個(gè)階段會(huì)知道三個(gè)程序升級(jí)包,供下一階段使用。

另外,可以簡(jiǎn)單的理解為:執(zhí)行完這個(gè)階段就對(duì)應(yīng)著盤(pán)古提示用戶(hù)在手機(jī)上啟動(dòng)程序。

階段二:利用競(jìng)態(tài)條件安裝文件,構(gòu)造環(huán)境執(zhí)行pangu.dylib

當(dāng)用戶(hù)在手機(jī)上啟動(dòng)程序后,手機(jī)上的App會(huì)啟動(dòng)一個(gè)Socket Server,等待桌面程序的握手,這個(gè)握手的暗語(yǔ)挺有意思。桌面向App發(fā)送:PING,App收到后回應(yīng)桌面:PONG。在握手完成后,盤(pán)古開(kāi)始利用靜態(tài)條件將如上構(gòu)造的三個(gè)Payload安裝到手機(jī)上。

具體過(guò)程為首先利用安裝服務(wù)安裝升級(jí)包,在安裝的過(guò)程中桌面向App發(fā)送starthook,具體hook的內(nèi)容可以通過(guò)調(diào)試App確定是創(chuàng)建一個(gè)符號(hào)鏈接:

"/private/var/tmp/install_staging.eP7ZzJ/foo_extracted" ---> "/var/"

其中后綴部分會(huì)因?yàn)槊看伟惭b而不同。

示例代碼:

def fire_race_condition(lockdown, file_name):

mci = lockdown.startService("com.apple.mobile.installation_proxy")

sock = get_sock()

print "----->PING"

sock.send("PING")

msg = sock.recv(4)

if msg == "PONG":

print "<-----PONG "

upgrade_pangu(mci, file_name)

print "----->starthook"

sock.send("starthook")

msg = sock.recv(4)

if msg == "succ":

print "<-----success "

else:

print "<-----fail "

在完成安裝三個(gè)Payload之后,盤(pán)古會(huì)上傳文件到Media中的 Pangu-Install目錄:

Cydia.tar

packagelist.tar

pangu.dylib

pangu.tar

pangu_ex.tar

至此,盤(pán)古基本完成了用戶(hù)空間的行為,在界面上的反應(yīng)為:盤(pán)古會(huì)第一次重啟設(shè)備。

階段三:利用漏洞安裝Untecher,Cydia

設(shè)備重啟完成后,pangu.dylib會(huì)被加載,并啟動(dòng)一個(gè) Socket Server。桌面程序在檢測(cè)到設(shè)備加載后會(huì)向 pangu.dylib 發(fā)送:55AA,pangu.dylib 接到 55AA后開(kāi)始安裝Untecher、Cydia。

階段四:清理

在pangu.dylib完成工作后,向桌面程序發(fā)送:AA55,桌面程序開(kāi)始清理臨時(shí)文件,刪除Provisional文件,恢復(fù)設(shè)備時(shí)間等操作。在完成清理操作后,桌面程序會(huì)第二次重啟設(shè)備,至此越獄完成。

關(guān)鍵詞: 盤(pán)古越獄 盤(pán)古越獄原理分析