易受攻击的驱动程序、物理内存、虚拟地址、相对虚拟地址 (RVA)、内联挂钩、任意物理内存访问。
利用易受攻击的 Windows 驱动程序来利用内核执行并不是一个新概念。尽管利用易受攻击的驱动程序的软件已经存在了很长时间,但还没有一个高度模块化的代码库可以用来利用暴露相同漏洞的多个驱动程序。暴露任意物理内存读写原语的 Windows 驱动程序是最丰富的易受攻击的驱动程序形式。这些驱动程序用于许多事情,从读取 CPU 风扇速度到刷新 BIOS。尽管有成千上万的驱动程序暴露了这个原语;对这些驱动程序做任何有用的事情并不一定是一项简单的任务。在这篇研究论文中,我将描述如何使用任意物理内存读写原语获得内核执行的步骤。此外,
查找公开任意物理内存读写的驱动程序就像在谷歌上搜索以下短语一样简单:Windows 的 BIOS 刷新实用程序、Windows 的 CPU 风扇速度实用程序或 Windows 的华硕超频实用程序。有成百上千个允许任意物理内存读写的驱动程序。在这篇研究论文中,我将专门讨论 phymem.sys;我在介绍本文的过程中发现的 Supermicro BIOS 刷新 Windows 实用程序。尽管有大量易受攻击的驱动程序会暴露物理内存的读写;通常,可以操作的物理内存范围是有限的。在 phymem.sys 的情况下,只有前 4GB 的物理内存可以任意读写。
一旦你认为你发现了一个易受攻击的驱动程序,确定它实际上是易受攻击的,可以通过确定用户控制的数据被传递到以下任何一个来完成:MmMapIoSpace、ZwMapViewOfSection 或 MmCopyMemory。这个用户控制的数据通过调用DeviceIoControl传递给驱动的设备控制主函数。在 phymem.sys 的情况下,用户控制的数据被传递到 MmMapIoSpace。
在确定驱动程序易受攻击后,下一步是列出如何与所述易受攻击的驱动程序交互。在对 IRP_MJ_DEVICE_CONTROL 函数进行逆向工程时应该寻找的三个最重要的值是:I/O 控制代码、IOCTL 输入和输出缓冲区长度,最后是输入和输出缓冲区。通过观察用户控制的数据是如何使用的;可以构建一个结构。
InputBufferLength = StackLocation->Parameters
.DeviceIoControl
.InputBufferLength;
OutPutBufferLength = StackLocation->Parameters
.DeviceIoControl
.OutputBufferLength;
// IRP_MJ_DEVICE_CONTROL...
if (StackLocation->MajorFunction == 0xE)
{
v22 = StackLocation->Parameters
.Read
.ByteOffset
.LowPart;
// 0x80002000 (MAP_PHYSICAL_MEMORY)
switch (v22 + 0x7FFFE000)
{
case 0u:
// mind lengths for DeviceIoControl...
if (InputBufferLength != 16i64 ||
OutPutBufferLength != 8i64)
return {}; // invalid lengths...
else
{
// 4gb of physical memory limit
UserControlledPhysicalAddress.QuadPart =
*((_QWORD*)SystemBuffer + 1)
& 0xFFFFFFFFi64;
VirtualAddress = MmMapIoSpace
(UserControlledPhysicalAddress,
*(_QWORD*)SystemBuffer, NULL);
// IoAllocateMdl
// MmBuildMdlForNonPagedPool...
// MmMapLockedPagesSpecifyCache...
对于 phymem.sys,输入缓冲区长度为 16 字节,输出缓冲区长度为 8 字节。查看清单 1 中如何使用 SystemBuffer,您可以看到它是一个包含两个 QWORD 大小的字段的结构。进一步检查得出结论,第一个 QWORD 字段包含要映射多少物理内存的字节大小值,第二个 QWORD 字段是要映射的内存的物理地址。正如您在清单 1 第 33 行中看到的,物理地址的前 32 位被忽略了。这将物理地址的大小限制为 32 位,因此驱动程序只允许我们映射位于物理内存的前 4GB 中的物理内存。
#define MAP_PHYSICAL_MEMORY 0x80002000
#define UNMAP_PHYSICAL_MEMORY 0x80002004
// 16 bytes
typedef struct _map_phys_t
{
union
{
std::uintptr_t map_size; // + 0x0
std::uintptr_t virt_addr; // + 0x0
}
std::uintptr_t phys_addr; // + 0x8
} map_phys_t, *pmap_phys_t;
一旦定义了结构;与易受攻击的驱动程序交互只需使用 NtLoadDriver 将驱动程序加载到内核中,然后使用 DeviceIoControl 控制驱动程序。
尽管物理内存可能看起来不明确,但它被组织成固定大小的块,称为页面。使用四层分页表配置的 64 位系统上的每个页面为 4kB。在这个块大小内存是连续的。每个 64 位虚拟地址的最后 12 位称为页偏移。知道这一点可以扫描特定字节的特定偏移量的每一页。
PAGE:00000001C01265F0 ; Exported entry 294. NtGdiDdDDICreateContext
PAGE:00000001C01265F0
PAGE:00000001C01265F0 ; =============== S U B R O U T I N E =======================================
PAGE:00000001C01265F0
PAGE:00000001C01265F0 ; Attributes:
PAGE:00000001C01265F0
PAGE:00000001C01265F0 public NtGdiDdDDICreateContext
PAGE:00000001C01265F0 NtGdiDdDDICreateContext proc near
PAGE:00000001C01265F0 mov [rsp+arg_8], rbx ; DxgkCreateContext
PAGE:00000001C01265F5 mov [rsp+arg_10], rdi
PAGE:00000001C01265FA mov [rsp+arg_18], r12
PAGE:00000001C01265FF push r13
PAGE:00000001C0126601 push r14
PAGE:00000001C0126603 push r15
PAGE:00000001C0126605 sub rsp, 200h
PAGE:00000001C012660C mov rax, cs:__security_cookie
PAGE:00000001C0126613 xor rax, rsp
PAGE:00000001C0126616 mov [rsp+218h+var_28], rax
PAGE:00000001C012661E mov r14, rcx
PAGE:00000001C0126621 mov [rsp+218h+var_170], rcx
PAGE:00000001C0126629 mov [rsp+218h+var_1A0], rcx
PAGE:00000001C012662E or rdi, 0FFFFFFFFFFFFFFFFh
PAGE:00000001C0126632 mov [rsp+218h+var_1C0], edi
PAGE:00000001C0126636 xor ebx, ebx
PAGE:00000001C0126638 mov [rsp+218h+var_1B8], rbx
PAGE:00000001C012663D mov rax, cs:qword_1C00AE960
PAGE:00000001C0126644 test al, 2
PAGE:00000001C0126646 jnz loc_1C01C3E8C
PAGE:00000001C012664C mov [rsp+218h+var_1B0], bl
在清单 3 中,系统例程 NtGdiDdDDICreateContext 的页面偏移量是 0x5F0。简单地在 NtGdiDdDDICreateContext 中扫描偏移 0x5F0 处的每个物理页面以获取操作码就足以获得少量结果。为了确定我们在物理内存中找到了真正的 NtGdiDdDDICreateContext ,需要测试每个事件。一次扫描每一页非常慢,因此为了加快进程,VDM 会为每个物理内存范围创建一个新线程。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。