报告编号: B6-2018-051501
报告来源: 360CERT
报告作者: 360CERT
更新日期: 2018-05-15
0x00 漏洞描述
操作系统的开发者没有正确处理Intel 64和IA-32架构软件开发人员手册的系统编程指南中的一则声明,导致MOV SS/POP SS指令延迟的#DB异常可能产生意外的行为,引起操作系统崩溃甚至可以被用来提权(CVE-2018-8897)。在KVM中也存在类似的问题(CVE-2018-1087)。该漏洞影响范围广,危害等级重要。
0x01 漏洞影响面
漏洞影响Windows/MacOS/FreeBSD/Linux内核等现代流行的操作系统和KVM/Xen等虚拟化系统。
0x02 技术细节
假设现在要执行下面这两条指令:
同时设置了一个硬件访问断点,刚好mov ss, [rax]指令会触发这个硬件访问断点。
由于mov ss和pop ss指令会悬挂异常和中断,所以mov ss, [rax]指令虽然会产生硬件中断,但中断会被挂起,直到下一条指令执行完毕后才响应中断。执行int 3指令优先响应 int 3中断,CPU切入内核,执行IDT对应的3号中断向量。int 3中断会判断此次int 3来自R3还是R0,如果来自R3,选择交换GS。
但是此时还悬挂一个硬件中断,所以当执行第一条之前,就会立马去执行IDT 对应的1号中断向量,此时还没有交换GS。int 1属于中断门,此时是由int 3 响应代码中断过来的,权限为R0,会使用原来的GS。这样就在内核模式异常处理程序中运行了用户模式中设置的GS,可能会造成意外的后果。
下面是对公布在github上的在windows上利用此漏洞的提权代码中关键点的简要分析。
windows系统崩溃时会执行KeBugCheckEx,KeBugCheckEx中会执行RtlCaptureContext和KiSaveProcessorControlState,这给了我们获取程序控制流的机会。
如果我们通过设置DR寄存器在gs:20h+0x40+0xA0处设置一个硬件访问断点(作者给的偏移是gs:20h+0x100+0xA0),就能在KeBugCheckEx中进入到KiDebugTrapOrFault,KiDebugTrapOrFault->…->RtlCaptureContext,用户空间中的线程读取一次RSP,继续KiDebugTrapOrFault->…->RtlCaptureContext,用户空间中的线程再读取一次RSP,因为执行的流程一样,根据两次RSP值的差可以计算出下一次调用RtlCaptureContext时RSP的值,减去0x8是返回指针存放的位置。
接下来构造了一个禁用SMEP并跳转到shellcode的ROP链,存在XMM13-XMM15中。
前面把返回指针存放的位置减去XMM13在Context结构体中的偏移存在了伪造的PCR的结构中,之后恢复Context写XMM13-XMM15的时候ROP链覆盖了返回指针,从而执行了shellcode。成功利用之后效果如下。
0x03 修复建议
目前多家受影响的厂商已经提供了相关的补丁,360CERT建议广大用户按照提示进行更新,防范利用该漏洞的攻击。
Apple:https://support.apple.com/en-us/HT208742
FreeBSD Project:https://www.freebsd.org/security/advisories/FreeBSD-SA-18:06.debugreg.asc
Microsoft:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8897
Red Hat:https://access.redhat.com/security/vulnerabilities/pop_ss
Ubuntu:https://usn.ubuntu.com/3641-1/
Ubuntu:https://usn.ubuntu.com/3641-2/
Xen:https://xenbits.xen.org/xsa/advisory-260.html
Linux Kernel:https://patchwork.kernel.org/patch/10311005/
Linux Kernel:https://patchwork.kernel.org/patch/10310757/
0x04 时间线
2018-05-08 漏洞披露,公布POC
2018-05-14 研究人员根据披露的细节公布构造的EXP
2018-05-15 360CERT做出预警