[Windows翻译]Windows调试和利用第四部分:NTQuerySystemInformation

1,215 阅读9分钟

原文地址:www.trustwave.com/en-us/resou…

原文作者:

发布时间:2020年3月2日

简介

又见面了! 我们又回来了,有更多的Windows内部知识,现在是时候进入正题了。我们已经介绍了如何设置环境WinDBG基础知识,并讨论了WinDBG时间旅行调试。在我博客系列的第四部分,我将简要介绍一个内部API,它被广泛用于泄露内核信息,用于大多数Windows LPE(本地特权升级)漏洞。我们将谈一谈NTQuerySystemInformation这个函数。

NTQuerySystemInformation和系统信息类

函数NTQuerySystemInformation是在NTDLL上实现的。作为一个内核API,它在Windows版本中总是在不经意间被更新。如前所述,这是一个私有函数,所以没有被微软正式记录下来。从早期的Windows NT-family系统开始,它就被用于不同的系统调用ID,你可以在下表中看到[j00ru.vexillium.org/syscalls/nt…

/Windows XP到Windows 7Windows 8 & 2012 SP0Windows 8.1 & 2012 R2Windows 10
NTQuerySystemInformation0x00330x00340x00350x0036

该函数基本上从环境中检索特定信息,其结构非常简单。

NtQuerySystemInformation(
      SYSTEM_INFORMATION_CLASS   SystemInformationClass,
      PVOID   SystemInformation,
      ULONG   SystemInformationLength,
      PULONG  ReturnLength);

在第一个参数SYSTEM_INFORMATION_CLASS(ULONG)中,我们将设置要检索的信息。这些类被命名为Windows系统信息类,并在 winternl.h中定义。

有许多数据可以和函数一起使用这些类来检索。关于系统、进程、对象和其他的信息。

下面,列出了一些可以使用的类。

注意。

  • late 5.0从Windows 2000 SP4开始。
  • 5.1后期从Windows XP SP2开始。
  • 非常晚的5.1版本从Windows XP SP3开始。
  • 5.2后期从Windows Server 2003 SP1开始。
  • 晚期6.0版本从Windows Vista SP1开始。
  • 6.1后期开始于Windows 7 SP1。
数值符号名称版本备注
0x00系统基本信息3.10及以上版本
0x01系统处理器信息3.10及以上版本
0x02系统性能信息3.10及以上版本
0x03系统时间信息3.10及更高版本
0x04系统路径信息3.10及更高版本
0x05系统进程信息3.10 及以上版本
0x06系统呼叫次数信息3.10及更高版本
0x07系统设备信息3.10及更高版本
............
0x40系统扩展手柄信息5.1及以上版本
0x41系统丢失延迟写入信息5.1及更高版本
0x42未知数晚期5.1独有
0x42SystemBigPoolInformation5.2及以上
0x43SystemSessionPoolTagInformation5.2及更高版本
0x44SystemSessionMappedViewInformation5.2及更高版本
............
0x58系统进程标识信息6.0及以上版本
0x59SystemErrorPortInformation6.0及更高版本
0x5A系统启动环境信息6.0 及以上版本
0x5B系统管理员信息6.0 及以上版本
0x5C系统验证器信息6.0及更高版本
0x5D系统时区信息6.0及更高版本
0x5E系统图像文件执行选项信息6.0及以上版本
0x5F系统覆盖信息6.0及更高版本
0x60系统取样信息6.0及更高版本
............
0xA8SystemAllowedCpuSetsInformation10.0 及以上
0xA9系统Dma保护信息10.0及更高版本
0xAA系统中断CpuSets信息10.0及更高版本
0xAB系统安全启动政策完整信息10.0及更高版本
0xAC系统代码完整性政策完整信息10.0 及更高版本
0xAD系统化中断处理器信息10.0及更高版本
0xAE系统根基信息10.0及更高版本
............
0xC7SystemCodeIntegrityVerificationInformation1803以上
0xC8系统固件分区信息1803以上
0xC9系统配置控制信息1803以上
0xCASystemDmaGuardPolicyInformation1803以上
0xCB系统飞地启动控制信息1803以上

来源:www.geoffchappell.com/studies/win…

使用方法

我们可以使用多个信息类,而这个过程的一部分,就是要发现哪一个在我们的开发方法中会有用。如果我们需要发现一个EPROCESS或一个驱动程序的基本地址,对于每一个都有一个特定的类,我们可以实现。对于每一个类,我们都需要定义其结构。一些例子。

SystemModuleInformation (0x0b)
typedef struct SYSTEM_MODULE {
        PVOID  Reserved1;
        PVOID  Reserved2;
        PVOID  ImageBase;
        ULONG  ImageSize;
        ULONG  Flags;
        USHORT Index;
        USHORT NameLength;
        USHORT LoadCount;
        USHORT PathLength;
        CHAR   ImageName[256];
}

typedef struct SYSTEM_MODULE_INFORMATION {
       ULONG                ModulesCount;
       SYSTEM_MODULE        Modules[0];
} 

在SYSTEM_MODULE_INFORMATION->ModulesCount[i].ImageBase,你会发现任何内核模块的基础地址。这可以用来计算HalDispatchTable,例如,使用内核基址。这个表包含了在利用过程中可能被覆盖的函数指针。

SystemHandleInformation (0x10)
typedef struct SYSTEM_HANDLE {
        ULONG ProcessId;
        UCHAR ObjectTypeNumber;
        UCHAR Flags;
        USHORT Handle;
        PVOID Object;
        ACCESS_MASK GrantedAccess;
}

typedef struct SYSTEM_HANDLE_INFORMATION
{
        ULONG HandleCount;
        SYSTEM_HANDLE Handles[1];
}

在这种情况下,在SYSTEM_HANDLE_INFORMATION->Handles[i].Object中,你可以从一个特定的手柄中找到内核空间中的对象地址,例如,可以通过进程ID进行过滤(参见概念验证)。

这只是两个可以利用的信息类的例子,然而还有更多有用的类,如SystemExtendedHandledInformation、SystemLockInformation、SystemExtendedProcessInformation等等。

值得注意的是,所有这些结构都是没有记录的,感谢Mateusz Jurcyzk、Alex Ionescu和其他研究人员的伟大工作,我们现在有了准确的描述。

关于信息类的更多信息:j00ru.vexillium.org/papers/2011…

概念验证

我开发了一个简单的代码,使用SystemHandleInformation从运行中的进程中检索出打开的句柄地址。我试图尽可能的简单,以便对你进行教育。因此,你可能想探索这个和其他信息类,以发现它们的功能并确定还能做什么。

C:\>NTQuerySystemInformation-PoC1.exe
NTQuerySystemInformation() PoC -- Bruno Oliveira @mphx2
Address: 0xFFFFC90441603180, Object Type: 37, Handle: 4
Address: 0xFFFFC9043F8B7E60, Object Type: 16, Handle: 8
Address: 0xFFFFC9043F8B7F60, Object Type: 16, Handle: c
Address: 0xFFFFC90444662D50, Object Type: 36, Handle: 10
Address: 0xFFFFC90440581C40, Object Type: 35, Handle: 14
Address: 0xFFFFC90440096D70, Object Type: 30, Handle: 18
Address: 0xFFFFC90446352290, Object Type: 21, Handle: 1c
Address: 0xFFFFC904446633D0, Object Type: 36, Handle: 20
Address: 0xFFFFC90446353060, Object Type: 21, Handle: 24
Address: 0xFFFFC90444662EF0, Object Type: 36, Handle: 28
Address: 0xFFFFC9043FD7A0F0, Object Type: 50, Handle: 2c
Address: 0xFFFFC9043FDA1450, Object Type: 50, Handle: 30
Address: 0xFFFFC9043FDA0730, Object Type: 50, Handle: 34
Address: 0xFFFFA204CB57A840, Object Type: 3, Handle: 38
Address: 0xFFFFC9043F8B9EE0, Object Type: 16, Handle: 3c
Address: 0xFFFFC9043F8C0B60, Object Type: 16, Handle: 40
Address: 0xFFFFC90446A4EBD0, Object Type: 37, Handle: 44
Address: 0xFFFFC90446A4D140, Object Type: 37, Handle: 48
Address: 0xFFFFC9043FDA0E30, Object Type: 50, Handle: 4c
Address: 0xFFFFC90440074710, Object Type: 37, Handle: 50
Address: 0xFFFFC90440073C20, Object Type: 37, Handle: 54
Address: 0xFFFFC90440073C20, Object Type: 37, Handle: 58
Address: 0xFFFFC9043ED774F0, Object Type: 46, Handle: 5c
Address: 0xFFFFC9043FDA18B0, Object Type: 50, Handle: 60
Address: 0xFFFFC9043FDA1A70, Object Type: 50, Handle: 64
Address: 0xFFFFC9043FDA0810, Object Type: 50, Handle: 68
Address: 0xFFFFC9043FDA2B00, Object Type: 35, Handle: 6c
Address: 0xFFFFC90445354740, Object Type: 30, Handle: 70
Address: 0xFFFFC904463602C0, Object Type: 21, Handle: 74
Address: 0xFFFFC90444663090, Object Type: 36, Handle: 78
Address: 0xFFFFC904463603D0, Object Type: 21, Handle: 7c
Address: 0xFFFFC90444662460, Object Type: 36, Handle: 80
Address: 0xFFFFA204E5D57670, Object Type: 44, Handle: 84
Address: 0xFFFFA204E5D83E70, Object Type: 44, Handle: 8c

C:\>

PoC源码可在:github.com/bmphx2/PoC-…

检查WinDBG上的地址。

lkd> !object 0xFFFFC90441603180
Object: ffffc90441603180 Type: (ffffc904384f8380) File
    ObjectHeader: ffffc90441603150 (new version)
    HandleCount: 2 PointerCount: 65536
    Directory Object: 00000000 Name: \Reference {ConDrv}

漏洞

这种信息泄露对于绕过内核随机化KASLR(内核地址空间布局随机化)非常有用。假设我们已经通过一些 "写什么 "的漏洞控制了内核,我们需要知道我们到底应该在哪里修改,以提升我们的权限。通过利用这个API,我们现在能够定位内核空间上的多个对象,并计算出我们可能需要的任何其他对象的偏移量。使得这个函数非常特别的是,它可以被一个没有特权的用户调用。换句话说,你不需要是SYSTEM来请求操作系统的内部信息。有多个利用这一事实运行的漏洞。浏览Windows的LPE漏洞很容易识别。请随意自己做一些分析。

好奇心

2017年和2018年,Google Project Zero在NTQuerySystemInformation函数本身上发现了漏洞。

bugs.chromium.org/p/project-z…

bugs.chromium.org/p/project-z…

这些漏洞发生在一些特定的信息类中,并且披露的内容超过了它们应该做的。具有讽刺意味的是,一个众所周知的被用作漏洞开发者资源的函数,竟然存在漏洞¯_(ツ)_/¯。

总结

在讨论Windows系统上的漏洞利用时,我再一次试图带来一些信息来设定一个基本的知识。在这个时候,我解释了一点关于这个使用任何无特权用户泄露内核空间信息的重要功能,这种数据对于大多数LPE漏洞来说是最基本的,在解释这个话题的时候不可避免地要讨论。

希望我们在每一篇文章中都能开始让事情变得更加精彩! 再次强调,如果有任何疑问或你想让我知道的事情,请联系我,祝你黑客攻击愉快


www.deepl.com 翻译