解决 iOS 12.4 Killed: 9 的问题

解决 iOS 12.4 Killed: 9 的问题

随着 iOS 12.4 的越狱出来之后,不少人的手机都升级到 12.4,最近我也在使用 12.4 做调试机,一开始 debugserver 也遇到一些坑,不过好在都解决了。最后剩下一个很头疼的问题,就是自己写的 App 上传到手机 /Applications 目录下,发现既然不能运行,提示 Killed: 9。

按照老套路,使用 codesign 或者 ldid 签名:

codesign -s - --entitlements ent.plist -f test12

由于 iOS 12 需要添加 platform-application,和签名 debugserver 一样,完整的 ent.plist 如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.backboardd.debugapplications</key>
	<true/>
	<key>com.apple.backboardd.launchapplications</key>
	<true/>
	<key>com.apple.diagnosticd.diagnostic</key>
	<true/>
	<key>com.apple.frontboard.debugapplications</key>
	<true/>
	<key>com.apple.frontboard.launchapplications</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
	<key>com.apple.springboard.debugapplications</key>
	<true/>
	<key>com.apple.system-task-ports</key>
	<true/>
	<key>get-task-allow</key>
	<true/>
	<key>platform-application</key>
	<true/>
	<key>run-unsigned-code</key>
	<true/>
	<key>task_for_pid-allow</key>
	<true/>
</dict>
</plist>

签名之后再次上传到 /Applications,运行还是提示 Killed 9,尝试 setuid(0); setgid(0);,还有设置文件权限也都不管用,都是提示 Killed 9

chown root:wheel test12
chmod u+s test12

不过发现之前写的插件打包成 deb 可以在 iOS 12.4 运行,文件也是会释放到 /Applications 目录,于是尝试把 test12.app 制作成 deb 包,上传到 /var/mobile/test12.deb,使用 dpkg 命令安装,安装成功后发现果然是可以执行。

 dpkg -i /var/mobile/test12.deb
 uicache

使用 ldid -e /Applications/test12.app/test12 >> /var/mobile/test12.plist,将 entitlement 导出查看比之前的多了两条,不过添加上这两条重新签名依然是不行。

<key>com.apple.private.skip-library-validation</key>
<true/>
<key>com.apple.private.security.no-container</key>
<true/>

思考一个问题,为什么手动上传的文件不能运行,而制作成 deb 包安装就可以呢?这两者有什么区别吗?尝试对 deb 安装后的文件静态修改,插入 LoadCommand 加载动态库,发现只要静态改过可执行文件,运行就提示 Killed 9,但是改过的文件打包成 deb,发现又可以运行了。

看样子是因为 dpkg 做了什么特殊的操作。在手机上找到 /usr/bin/dpkg,载入 IDA 静态分析,在 dir_sign_file 函数中找到了一条和签名相关的命令,猜测可能是和这个命令有关系,在释放完文件后,执行了签名命令。如下图所示:

最终得到的签名命令是这个,使用下面的命令对文件进行签名即可解决 Killed 9 的问题。

/usr/bin/ldid -P -K/usr/share/jailbreak/signcert.p12 -S/usr/share/entitlements/global.xml -M /Applications/test12.app/test12

Author: exchen

5 Likes

:+1:学习了,让我想起了分析unc0ver越狱环境时候的一些特性。这个global.xml有了解过,不过没想到是dpkg在安装deb包的时候会用到。
/usr/share/entitlements/global.xml这个文件里面有以下字段

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>platform-application</key>
	<true/>
	<key>com.apple.private.skip-library-validation</key>
	<true/>
	<key>com.apple.private.security.no-container</key>
	<true/>
</dict>
</plist>

并且这个/usr/share/entitlements/global.xml是unc0ver越狱里面jailbreak-resources.deb这个deb包导出的,这个文件在coolstar的chimera上是没有的。不仅如此,unc0ver的subtrate的工作原理也和之前的越狱有很大区别。

unc0ver在iOS12上的越狱设计包含有很多有意思的东西,当然目前我很多也没搞明白。

1 Like

Substrate还是Saurik的Substrate,Unc0ver在iOS12上独特的地方是因为iOS12引入了一个新的二进制程序签名验证流程CoreTrust,只有带了苹果有效签名的二进制文件才能被内核接受并执行,否则就killed:9。这就是Chimera官网宣传的这段话的含义。
(我没法贴图 具体就请参考Chimera官网chimera.sh Full-fledged为标题的那一段的内容)
然而Unc0ver实际上目前并没有一个完整的CoreTrust Bypass。所以它目前的做法是使用dpkg将每个即将被安装的软件包中的所有二进制文件都签上一个苹果的证书(/usr/share/jailbreak/signcert.p12)来绕过这个限制。
实际上这并不意味着Unc0ver没有CoreTrust Bypass。如果不越狱尝试让系统调用一个被签过证书的其它来源的二进制程序(方法很多)还是会被killed:9
实际上pwn已经掌握了完整CoreTrust Bypass的技术了只不过目前还没有把它加进Unc0ver里面。
https://gist.github.com/pwn20wndstuff/a57b213a6f8c75cb3b9a8c6002ae5756
我问过pwn本人关于加进完整CoreTrust Bypass的计划,他说会把完整的CoreTrust Bypass和他的新Substitute一起推出。之后A7-A11就不需要每个二进制程序都重签名了。(但是未来的Unc0ver for A12由于使用PAC-less模式的原因所以可能依然需要给二进制程序重签名)
由于这个原因在,一些开发者给自己的插件加上文件完整性校验类的DRM的时候可能在Chimera上工作正常,在Unc0ver上运行就会出问题。所以建议开发者换一些别的思路来给自己的软件加DRM(如果确实需要的话)

2 Likes

话说我都已经把新手教程做完了 为什么还是不能贴图/发链接

Substrate确实是Saurik的Substrate。我的意思是Substrate和之前的可以说完全不同,由一个/usr/libexec/substrated来完成程序的代码实际patch,并且还会加载pwn2own他们提供的Library/MobileSubstrate/ServerPlugins/Unrestrict.dylib来完成进程的各种权限问题,所以说Unc0ver导出了tpf0给用户层的工具去完成一些操作,然而Chimera应该是在越狱的时候内核就完成了CoreTrust的patch。一个很明显的区别在于,我在进行代码段patch的时候在chimera上是没问题的,但是在unc0ver上面就是报codesign的问题。分析下Substrate就会发现在patch的时候会做进程提权。既然你问过了他本人会有完整CoreTrust Bypass的计划,这还是比较期待的。

1 Like

你现在可以发图了

牛批#滑稽

Chimera内含一组PAC Bypass所以就有了kernel execution的权限,自然CoreTrust Bypass起来会方便很多很多。他甚至可以hook一些dyld start的操作。而pwn的这个几乎全部是r/w操作,所以以后的兼容性可能会更好一点。包括现在pwn说的pacless其实他核心的实现原理是分析内核的数据结构,针对特定特性的内存块进行识别。就好比他们的A12 remount,到底就是一个kernel write。我们用kernel execution能比较轻松的拿到对应的vnode。那么在没有kernel execution的情况下,分析对应的数据结构依然可以找到这个vnode,然后在root层走一个fastcall就绕过了pac。

我们来整理一下我们在没有pacbypass的情况下目前有的东西
1 非敏感数据的内核内存任意rw
2 没了 (如果说XNU的源码也算的话那就算上吧😂

目前来看coreTrust的几种bypass方法:
1 用Xcode相同的办法使用_TEXT PPL SEGMENT的方法注入 是可能需要kernel execution的
2 分析数据然后rw ram,被APRR保护了写不动
3 问问installd有没有办法 (摊手

其实说到最后pac和APRR是相互保护的一套比较成熟的机制,继KPRR之后,这个内核真是越来越难搞了。(生活不易 毛毛叹气

3 Likes

原来如此,怪不得Unrestrict.dylib里面全是读写内核的代码。Lakr tql!

1 Like

Unc0ver的A12版已经不需要签p12了