本文是根据蒸米大佬的文章《iOS冰与火之歌:Objective-C Pwn and iOS arm64 ROP》做的一个操作实践。
(原文地址:https://bbs.pediy.com/thread-212714.htm)
在实践过程中也遇到一些问题,逐步解决,最终成功实现。
越狱设备:iphone5s
手机系统:iOS 8.4,越狱
电脑设备:Macbook Pro
电脑系统:macOS 10.15.1
ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术,可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。
在iOS上默认是开启ASLR+DEP+PIE的。ASLR和DEP很好理解,PIE的意思是program image本身在内存中的地址也是随机的。
所以我们在iOS上使用ROP技术必须配合信息泄露的漏洞才行。
虽然在iOS上写ROP非常困难,但有个好消息是虽然program image是随机的,但是每个进程都会加载的dyld_shared_cache这个共享缓存的地址在开机后是固定的,并且每个进程的dyld_shared_cache都是相同的。
伪造objc对象,修改类缓存里的方法指向地址指向一个CoreFoundation库的一个gadget,当方法再次被调用时,跳转到特定的gadget,实现调用 system 进程并在手机的 /tmp 目录下创建一个iceAndFire文件。
dyld_shared_cache文件一般保存在/System/Library/Caches/com.apple.dyld/这个目录下:
从手机导出 dyld_shared_cache_arm64 到电脑备用。
从dyld_shared_cachearm64 提取系统库文件:
详细方法见此文:iOS逆向抽取iOS真机系统库文件
https://mp.weixin.qq.com/s/y2hwD4gPc8eJVBAS_o2DXg
从导出的文件中找到 CoreFoundation 库的二进制文件:
接下来就是从CoreFoundation库的二进制文件中寻找合适gadget。
工具:ROPgadget
命令:ROPgadget --binary /路径/CoreFoundation
打印:
蒸米大神原文中用的gadget是:
我们从刚才的打印信息中找到一个几乎一样的gadget:
此gadget的地址是 0x0000000181ccef6c
把CoreFoundation的二进制文件拖入IDA中分析,找到 0x0000000181ccef6c 对应的汇编:
再看一下IDA里CoreFoundation的起始地址:
计算地址偏移量:
0x0000000181ccef6c - 0x000000181BF0000 = 0xDEF6C
0xDEF6C 就是后面要用到的地址偏移量。
这个偏移地址,必须根据你的测试设备中提取的CoreFoundation来计算。
上面伪造的代码中,fake_receiver_t 这个结构体中的元素结构是跟gadget的汇编有关:
汇编"LDR x1,[x0,#0x98]",此时汇编中的x0是 fake_receiver ,所以[x0,#0x98]就是[fake_receiver,#0x98],[fake_receiver,#0x98] 对应的地址就是fake_receiver_t 中的 uint64_t x1; 汇编"LDR x0,[x0,#0x70]"中 [x0,#0x70] 对应 fake_receiver_t 中的 uint64_t x0;
我觉得结构体 fake_receiver_t 中的
uint8_t pad1[0x70-0x8]
和
uint8_t pad2[0x98-0x70-0x8]
都是起到占空间的作用,为了能匹配gadget汇编中的地址长度,顺利找到想要的值。
main函数中的代码:
看看代码中的注释,进一步理解整个过程。
最终编译代码,生成ioshello执行程序,把ioshello复制到越狱机上,"chmod +x ioshello"给它添加执行权限,测试执行ioshello结果如下:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-8-6 18:33
被luoyanbei编辑
,原因: