XCON : PWN你的iOS设备PPT - CD-Team

Download Report

Transcript XCON : PWN你的iOS设备PPT - CD-Team

PWN你的iOS设备
DarkMage & WindKnown
CD-Team(http://cd-team.org)
大纲
• iOS 保护机制
• 用户态利用技术
• 内核的利用技术
• 攻击Bootrom
• JBM 3.0
• 结论
iOS 保护机制
iOS 保护机制
• 沙盒 (Seatbelt)
– iOS 的沙盒是基于TrustBSD策略框架的内核扩展
模块
– 针对每个进程都可以制定特殊的沙盒配置文件
– 沙盒配置文件编译后以2进制的方式保存在
KernelCache文件中(iOS下)
– 需反汇编成可读的文本格式来查看内核中的沙盒
规则
iOS 保护机制
• 沙盒规则的例子 (针对MobileSafari)
– 采用正则表达式的规则语句
– iokit-open
• (allow
iokit.math(“(^IOSurfaceRootUserCl
ient)
|(^IOMobileFramebufferUserClient)
...”))
iOS 保护机制
• 更多关于Apple的沙盒机制
• 请阅读 “The Apple Sandbox” by
Dionysus Blazakis
iOS 保护机制
• 代码签名
• 所有的可执行文件、库文件都需要Apple签名后
才可以运行在iOS中
– 内核会在调用execve之前检测Mach-o文件中
的LC_CODE_SIGNATURE段是否有效和可
信任的
– 无法分配RWX属性的内存页面
– iOS启动的时候同样也会检测KernelCache的
签名是否有效
iOS 保护机制
• 页面执行保护
– XN (execute never) 标志位在ARMv6
中被引入,从而在硬件上支持执行保
护
– iOS中的栈和堆都是不可执行的
– 内核不允许将页面保护标志设置为
RWX
iOS 保护机制
• ASLR(地址空间随机化)
– Antid0te project是第一个针对越狱iPhone提供
ASLR保护的程序
– 随后Apple正式的在iOS 4.3中加入了ASLR的支
持
– 加入ASLR的目的主要是防御用户态的ROP利用
方法,例如JBM 2.0越狱程序
– 同时ASLR也增加了越狱的难度
iOS 保护机制
• ASLR细节
– 所有的模块都已经被映射到
dyld_shared_cache文件中
– dyld_shared_cache整个文件被加载到一个随
机的地址
– dyld和程序主文件的随机偏移是相同的
– MobileSafari的插件同样会被加载到随机地址
用户态利用技术
用户态利用技术
• ARM基础知识
– 32位RISC指令集
– 通用寄存器:R0 ~ R10
– 特殊寄存器:SP LR PC
– Thumb指令集合
• 16位代码
用户态利用技术
• ARM调用规定
– R0~R3用于传递前4个参数
– 返回结果存储在R0和R1中
– 系统函数调用
• 设置R12为函数调用号,然后执行
“svc 0x80”
用户态利用技术
• ROP技术可用于绕过XN执行保护
• 没有公开的方法来绕过ASLR
– 至少需要一个信息泄露的漏洞配合
– 获得任何一个模块的随机偏移可以允许攻
击者在所有模块中利用ROP
• 所有模块的随机偏移是一致的
用户态利用技术
• ROP要求
– 切换栈
• 首先要求控制SP寄存器
– 控制R0~R3来传递参数
– 控制返回地址
用户态利用技术
• 选择ROP的模块
– 许多模块都可以用来实现ROP
• 针对iOS < 4.3,可以选择dyld
– dyld加载在固定地址 - 0x2FE00000
• 针对iOS 4.3,由于所有模块ASLR的偏移是一
样的,任何模块都可以被利用
– JBM3选取了几个模块的指令来完成ROP
用户态利用技术
• JBM3使用的ROP举例
• 栈切换
• 将 sp 设置为之前栈中的某个值
用户态利用技术
•
JBM3使用的ROP举例
•
控制R0~R3传递参数
•
函数调用
•
保存函数返回值
•
读取函数返回值
内核的利用技术
内核的利用技术
• iOS内核以及内核扩展均已加密的方式存储在
KernelCache文件中
• 可以在theiphonewiki上查询各个版本的解密Key
• iOS的内核没有ASLR保护
• 需要用ROP的方式来编写内核的利用程序
– 需要比windows下更加复杂和完善的ROP
framework
内核的利用技术
• iOCoreSurfaceRoot 内核整数溢出
• 在处理IOSurface properties存在一个整数
溢出漏洞 (iOSurfaceWidth 等)
• 该漏洞用于JBM2.0中越狱,针对iOS <=
4.0.1
• shellcode patch了suser()函数,并且当
MobileSafari进程中调用setuid(0)时候同时
提升权限.
内核的利用技术
•
Packet Filter 漏洞
• 该漏洞可以减任意内核地址的值
• 例如可以减某个系统调用的handler地址直至指向
shellcode映射的地址
• 当再次调用该系统调用时可以在内核空间中执行任
意代码
• 需要root权限触发该漏洞,配合limera1n的bootrom
漏洞可以进行完美越狱
内核的利用技术
• HFS Legacy volume 桟溢出漏洞
• 漏洞存在于
hfs_to_utf8/mac_roman_to_utf8 函数
• 提供一个超长的volume名触发该桟溢
出
• 同样也需要root权限触发! 在
GreenPosi0n越狱程序中使用该漏洞
来进行完美越狱
内核的利用技术
• ndrv_setspec() 整数溢出漏洞
– 用户可控并且未作检测的demux_count 变量
– 直接传递该变量用于内存分配,导致一个整数溢
出
– MALLOC(ndrvDemux, struct ndrv_demux_desc*,
ndrvSpec.demux_count * sizeof(struct
ndrv_demux_desc), ... )
– 需要root权限触发,用于redsn0w配合bootrom的
漏洞来进行完美越狱
内核的利用技术
• 完美越狱利用技术
– 可以使用只有root权限触发的内核漏洞
– 通常会和bootrom的漏洞配合使用,因为
bootrom的exploit可以直接获得root权限
– 在内核利用程序获得内核内存的读写权限后,
需要在内核中关闭代码签名,并且hook函数
来替换内核中的沙盒等来达到完美越狱的目
的
内核的利用技术
• Incomplete codesign exploit (早期的iOS
中)
– 使用libgmalloc的技巧来向launchd进程
(iOS的第一个用户态进程)注入一个
dylib
– 重定向dylib导出函数指向ROP代码
– 在ROP代码中利用一个内核漏洞来修改
内核(随系统启动运行)
内核的利用技术
• Incomplete codesign exploit (iOS 4.x)
– 使用mach-o 初始化/结束函数指针
• 构造一个mach-o可执行文件,并且指定
S_MOD_INIT(TERM)_FUNC_POINTERS
标志
• 即使该mach-o可执行文件代码签名校验失
败
• ImageLoaderMachO::doModInitFunction/d
oTermination 仍会调用该函数指针
内核的利用技术
•
内核调试比较困难
•
需要GDB + KDP串口调试
•
需要一条特殊的USB至Dock connector的线,并且支持串
口通讯
•
并且用redsn0w来设置iOS的启动参数
– -a “-v debug=0x09” 进入调试模式
•
关于更多的如何调试细节可以参考Syscan的“Targeting
iOS kernel”
攻击Bootrom
攻击Bootrom
• iOS 启动顺序 (正常模式)
•
•
•
•
Bootrom
Low level boot loader (LLB)
iBoot (2 stage boot loader)
OS (Kernel / Application)
攻击Bootrom
• iOS 启动顺序 (恢复模式)
– Bootrom
– Low Level Boot Loader (LLB)
– iBoot (2nd stage boot loader)
– Kernel (Ramdisk, can be restored)
攻击Bootrom
• iOS 启动顺序 (DFU)
– Bootrom
– iBSS
– iBEC
– Kernel (Ramdisk, can be restored)
攻击Bootrom
• limera1n bootrom exploit
– 利用一个DFU模式下USB控制消息的
溢出漏洞(0x21),针对所有A4的设备
– shellcode patch了bootrom中
RSA/IMG 等多处检测的代码
– 修改iBSS在载入KernelCache的时候
修补关于代码签名的指令来进行不完
美的越狱
攻击Bootrom
• iBSS payload
– Shellcode hook iBSS的jump_to函数
– 在jump_to函数中搜索KernelCache的内
存,并且修改内核关于代码签名的。
– 修改完内核以后,unhook jump_to函数,
然后重新调用自身来载入KernelCache
– Chronic-Dev’s cyanide 是一个非常实用的
iBoot/iBSS payload开发框架,推荐使用。
JailBreakMe 3.0
JailBreakMe 3.0
• 用户态漏洞利用 - CVE-2011-0226
– FreeType 2.4.6 版本之前,t1decode.c文件
中存在有符号整形使用不当的bug
– 攻击者通过精心构造嵌入Type 1 font的PDF
文档可以远程执行任意代码
– 漏洞存在于
CoreGraphics.framework/libCGFreetype.dyli
b
JailBreakMe 3.0
•
CVE-2011-0226细节
– t1_decoder_parse_charstrings函数
• 解码处理op_callothersubr命令时
• arg_cnt被声明为FT_Int并且是从“top”中读取
• 当arg_cnt是一个负数时
– 绕过了边界检查
– “top”可以超过边界,指向栈 - 使得攻击者可以
读写栈
JailBreakMe 3.0
• 漏洞代码
JailBreakMe 3.0
•
分析JBM3样本
– 解压字体文件
• 样本中只包含了一个stream,就是字体文件
– Type 1 字体文件格式 - 第6章 CharStrings字典
• 解释了 charstring 命令
– callothersubr/pop/return
• ROP是在运行时刻由charstring的代码生成的
• T1_DecoderRec结构用于解码charstring
JailBreakMe 3.0
• T1_DecoderRec结构
– 该结构在调用函数存储在栈中
– 结构定义可以在psaux.h中查找
• decoder->stack
– 用于存储charstring指令的中间数和结果
• decoder->buildchar
– 由字体文件中的/BuildCharArray指令来
定义
JailBreakMe 3.0
• JBM3是如何构造ROP的
– 利用charstring命令将指令写到
decoder->buildchar
• <val> <idx> 2 24 callothersubr
– decoder->buildchar[idx] = top[0];
• op_callsubr
– 字体文件中还包含一些子过程
JailBreakMe 3.0
• JBM3如何绕过ASLR
– 这个漏洞允许攻击者读写栈
– decoder结构存储在栈中
• decoder->parse_callback存储了
T1_Parse_Glyph函数指针
• 获取parse_callback的值 -> 获取
libCGFreetype模块的随机偏移
JailBreakMe 3.0
•
绕过ASLR细节
– 设置arg_cnt = (0xfea50000 >> 16)
• top = top + 0x15b
– op_setcurrentpoint
• y = top[1]; // y = T1_Parse_Glyph函数地址
– 设置top[0] = 默认T1_Parse_Glyph函数地址 (没有ASLR偏
移的情况下)
– <arg1> <arg2> 2 21 callothersubr pop
• top[0] -= top[1]; // 计算出ASLR偏移
JailBreakMe 3.0
• 最后触发漏洞
– 构造完ROP
– 覆盖decoder->parse_callback指针
– op_seac
• t1_decoder_parse_glyph
– decoder->parse_callback
» 开始执行ROP
JailBreakMe 3.0
•
JBM3 ROP 代码
– 首先溢出了一个内核漏洞
• mach_task_self
• IOServiceMatching
• IOKitWaitQuiet
• IOServiceGetMatchingServices
• IOServiceOpen
• IOConnectCallScalarMethod
• IOConnectCallStructMethod
• IOServiceClose
JailBreakMe 3.0
•
JBM3 ROP 代码
– 随后释放可执行文件并运行
• buffer = malloc(0x8670)
• uncompress(buffer, &size, subroutine 0 data, 0x2d49)
– zlib压缩的mach-o文件
• open(“/tmp/locutus”)
• write(file, buffer, 0x8670)
• close
• posix_spawn - 运行 locutus
JailBreakMe 3.0
• IOMobileFrameBuffer 内核提权利用
– IOMobileFrameBuffer kext 允许被
MobileSafari通过
IOMobileFramebufferUserClient接口调用
– IOConnectCallScalarMethod
• HotPluginNotify 0x15
– IOConnectCallStructMethod
• SwapEnd 0x05
JailBreakMe 3.0
• IOMobileFrameBuffer 内核提权利用
– 导致 IOMobileFrameBuffer::swap_submit函数
的 transaction结构中一个指针被修改
– 内核ROP!
– 增加0号系统调用的代码,任何进程调用
syscall(0)直接拥有r00t权限
• /tmp/locutus
JailBreakMe 3.0
• 关闭代码签名
– 修改vm_map_enter(protect)函数允许创建
RWX内存页
– 修改“cs_enforcement_disable”变量为
TRUE
– 修改PE_i_can_has_debugger函数中的一个
变量为TRUE
– 修改AMFI模块里面某个函数强制返回为
TRUE
JailBreakMe 3.0
• 替换sandbox
– 在内核中hook sb_evaluate函数
– 对除了User应用程序
(/private/var/mobile)以外的任何程序
关闭沙盒
JailBreakMe 3.0
• 替换Sandbox
JailBreakMe 3.0
• 修改 JBM3
– JBM3同样能带来危害,攻击者可以修改JBM3的
样本来传播iOS恶意软件
– 替换locutus应该是最简单的方式
– Locutus大小是固定的
• 0x2d49 (压缩后的大小)
• 我们可以替换一个更小的mach-o文件
JailBreakMe 3.0
•
替换 Locutus
– Locutus 文件存储在字体文件的 subroutine 0
– 解压获取字体文件 -> 替换 subroutine 0 数据 -> 重新压缩字体文件 (保证
大小不变) -> 替换 PDF 中的字体文件
– 此外还需要修改一个变量 - 0x2d49
• 该值在uncompress时使用
• 搜索 “ff 10 00 2d 49”
• 替换为新locutus压缩后的大小
– 新 locutus
• 调用syscall(0)获取root权限
JailBreakMe 3.0
• 修改 JBM3 Demo演示
结论
iOS 4.3.4(5)
• 修补JBM 3.0的两个漏洞
• 修补了ft_var_readpacketpoints()函数缓冲区溢出
漏洞
– 另外的一个字体格式的漏洞,Freetype已在一年
前修补
• 修补了ndrv_setspec() 完美越狱的内核漏洞
• 在dyld中修补了Incomplete codesign的利用技术
感谢!
X'con/0x557/CD-team
疑问?
CD-Team介绍
CD-Team(CN Dev Team) 是一个由来自国内计
算机安全行业的专业人士组成的iOS设备越狱
研究小组。团队成员以前主要是从事
windows/linux/unix/mac 等系统的漏洞挖掘/逆
向分析研究, 由于大家都对iOS设备有深厚的兴
趣,所以走到一起,一起研究和学习。
CD-Team http://cd-team.org
加入CD-Team?
如果您对iOS设备的安全研究有兴趣的话,可以加
入我们.
要求:
•熟悉ARM 逆向
•熟悉XNU 内核
•熟悉MAC/IOS下漏洞挖掘技术
•熟悉WCDMA/CDMA通信协议
•熟悉手机底层硬件模块、有高通芯片底层开发经验
•熟悉C/OBJ-C开发