From e26512ae0152cbe504bc0d3f99b0b3c191d0befb Mon Sep 17 00:00:00 2001 From: vxunderground <57078196+vxunderground@users.noreply.github.com> Date: Sun, 11 Sep 2022 21:05:39 -0500 Subject: [PATCH] CreateProcessViaNtCreateUserProcess --- .../CreateProcessFromIShellDispatchInvoke.cpp | 2 +- ...ocessFromShellExecuteInExplorerProcess.cpp | 2 + .../CreateProcessViaNtCreateUserProcess.cpp | 314 ++++++++++++++++++ VX-API/Internal.h | 11 + VX-API/Main.cpp | 8 +- VX-API/VX-API.vcxproj | 2 + VX-API/VX-API.vcxproj.filters | 6 + VX-API/Win32Helper.h | 2 + 8 files changed, 342 insertions(+), 5 deletions(-) create mode 100644 VX-API/CreateProcessViaNtCreateUserProcess.cpp diff --git a/VX-API/CreateProcessFromIShellDispatchInvoke.cpp b/VX-API/CreateProcessFromIShellDispatchInvoke.cpp index cc44ed8..7301935 100644 --- a/VX-API/CreateProcessFromIShellDispatchInvoke.cpp +++ b/VX-API/CreateProcessFromIShellDispatchInvoke.cpp @@ -1,6 +1,6 @@ #include "Win32Helper.h" -DEFINE_GUID(IClassFactorClsid, 0x13709620, 0xc279, 0x11ce, 0xa4, 0x9e, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00); +const static GUID IClassFactorClsid = { 0x13709620, 0xc279, 0x11ce, { 0xa4, 0x9e, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 } }; DWORD CreateProcessFromIShellDispatchInvokeW(_In_ PWCHAR BinaryPath) { diff --git a/VX-API/CreateProcessFromShellExecuteInExplorerProcess.cpp b/VX-API/CreateProcessFromShellExecuteInExplorerProcess.cpp index 794030a..bbb99b7 100644 --- a/VX-API/CreateProcessFromShellExecuteInExplorerProcess.cpp +++ b/VX-API/CreateProcessFromShellExecuteInExplorerProcess.cpp @@ -3,6 +3,8 @@ #include #include +#pragma comment(lib, "shlwapi.lib") + HRESULT UnusedSubroutineGetShellDispatchFromView(IShellView* ShellView, REFIID Riid, PVOID* Dispatch2) { HRESULT Result = S_OK; diff --git a/VX-API/CreateProcessViaNtCreateUserProcess.cpp b/VX-API/CreateProcessViaNtCreateUserProcess.cpp new file mode 100644 index 0000000..7f4de1c --- /dev/null +++ b/VX-API/CreateProcessViaNtCreateUserProcess.cpp @@ -0,0 +1,314 @@ +#include "Win32Helper.h" + +#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff +#define PS_ATTRIBUTE_THREAD 0x00010000 +#define PS_ATTRIBUTE_INPUT 0x00020000 +#define PS_ATTRIBUTE_ADDITIVE 0x00040000 + +typedef enum _PS_ATTRIBUTE_NUM +{ + PsAttributeParentProcess, + PsAttributeDebugPort, + PsAttributeToken, + PsAttributeClientId, + PsAttributeTebAddress, + PsAttributeImageName, + PsAttributeImageInfo, + PsAttributeMemoryReserve, + PsAttributePriorityClass, + PsAttributeErrorMode, + PsAttributeStdHandleInfo, + PsAttributeHandleList, + PsAttributeGroupAffinity, + PsAttributePreferredNode, + PsAttributeIdealProcessor, + PsAttributeUmsThread, + PsAttributeMitigationOptions, + PsAttributeProtectionLevel, + PsAttributeSecureProcess, + PsAttributeJobList, + PsAttributeChildProcessPolicy, + PsAttributeAllApplicationPackagesPolicy, + PsAttributeWin32kFilter, + PsAttributeSafeOpenPromptOriginClaim, + PsAttributeBnoIsolation, + PsAttributeDesktopAppPolicy, + PsAttributeMax +} PS_ATTRIBUTE_NUM; + +#define PsAttributeValue(Number, Thread, Input, Additive) \ + (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \ + ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \ + ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \ + ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0)) + +#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01 +#define PS_ATTRIBUTE_IMAGE_NAME \ + PsAttributeValue(PsAttributeImageName, FALSE, TRUE, FALSE) + +typedef struct _PS_ATTRIBUTE +{ + ULONG_PTR Attribute; + SIZE_T Size; + union + { + ULONG_PTR Value; + PVOID ValuePtr; + }; + PSIZE_T ReturnLength; +} PS_ATTRIBUTE, * PPS_ATTRIBUTE; + +typedef struct _PS_ATTRIBUTE_LIST +{ + SIZE_T TotalLength; + PS_ATTRIBUTE Attributes[2]; +} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST; + +typedef enum _PS_CREATE_STATE +{ + PsCreateInitialState, + PsCreateFailOnFileOpen, + PsCreateFailOnSectionCreate, + PsCreateFailExeFormat, + PsCreateFailMachineMismatch, + PsCreateFailExeName, + PsCreateSuccess, + PsCreateMaximumStates +} PS_CREATE_STATE; + +typedef struct _PS_CREATE_INFO { + SIZE_T Size; + PS_CREATE_STATE State; + union { + struct { + union { + ULONG InitFlags; + struct { + UCHAR WriteOutputOnExit : 1; + UCHAR DetectManifest : 1; + UCHAR IFEOSkipDebugger : 1; + UCHAR IFEODoNotPropagateKeyState : 1; + UCHAR SpareBits1 : 4; + UCHAR SpareBits2 : 8; + USHORT ProhibitedImageCharacteristics : 16; + } s1; + } u1; + ACCESS_MASK AdditionalFileAccess; + } InitState; + struct { HANDLE FileHandle; } FailSection; + struct { USHORT DllCharacteristics; } ExeFormat; + struct { HANDLE IFEOKey; } ExeName; + struct { + union { + ULONG OutputFlags; + struct { + UCHAR ProtectedProcess : 1; + UCHAR AddressSpaceOverride : 1; + UCHAR DevOverrideEnabled : 1; + UCHAR ManifestDetected : 1; + UCHAR ProtectedProcessLight : 1; + UCHAR SpareBits1 : 3; + UCHAR SpareBits2 : 8; + USHORT SpareBits3 : 16; + } s2; + } u2; + HANDLE FileHandle; + HANDLE SectionHandle; + ULONGLONG UserProcessParametersNative; + ULONG UserProcessParametersWow64; + ULONG CurrentParameterFlags; + ULONGLONG PebAddressNative; + ULONG PebAddressWow64; + ULONGLONG ManifestAddress; + ULONG ManifestSize; + } SuccessState; + }; +} PS_CREATE_INFO, * PPS_CREATE_INFO; + + +DWORD CreateProcessViaNtCreateUserProcessA(PCHAR BinaryPath) +{ + typedef NTSTATUS(NTAPI* NTCREATEUSERPROCESS)( + PHANDLE, + PHANDLE, + ACCESS_MASK, + ACCESS_MASK, + POBJECT_ATTRIBUTES, + POBJECT_ATTRIBUTES, + ULONG, + ULONG, + PRTL_USER_PROCESS_PARAMETERS, + PPS_CREATE_INFO, + PPS_ATTRIBUTE_LIST + ); + + typedef NTSTATUS(NTAPI* RTLCREATEPROCESSPARAMETERSEX)( + PRTL_USER_PROCESS_PARAMETERS*, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + PVOID, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + ULONG + ); + + typedef NTSTATUS(NTAPI* RTLDESTROYPROCESSPARAMETERS)(PRTL_USER_PROCESS_PARAMETERS); + + NTCREATEUSERPROCESS NtCreateUserProcess; + RTLCREATEPROCESSPARAMETERSEX RtlCreateProcessParametersEx; + RTLDESTROYPROCESSPARAMETERS RtlDestroyProcessParameters; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; + UNICODE_STRING NtImagePath; + WCHAR MsDosFullPath[MAX_PATH * sizeof(WCHAR)] = { 0 }; + PS_CREATE_INFO CreateInfo = { 0 }; + HMODULE hModule; + PPS_ATTRIBUTE_LIST AttributeList = NULL; + HANDLE hHandle = NULL, hThread = NULL; + DWORD dwError = ERROR_SUCCESS; + WCHAR wBinaryPath[MAX_PATH * sizeof(WCHAR)] = { 0 }; + + CreateInfo.Size = sizeof(CreateInfo); + CreateInfo.State = PsCreateInitialState; + + hModule = GetModuleHandleExW(L"ntdll.dll"); + if (hModule == NULL) + return GetLastErrorEx(); + + NtCreateUserProcess = (NTCREATEUSERPROCESS)GetProcAddressA((DWORD64)hModule, "NtCreateUserProcess"); + if (NtCreateUserProcess == NULL) + return GetLastErrorEx(); + + RtlCreateProcessParametersEx = (RTLCREATEPROCESSPARAMETERSEX)GetProcAddressA((DWORD64)hModule, "RtlCreateProcessParametersEx"); + if (RtlCreateProcessParametersEx == NULL) + return GetLastErrorEx(); + + RtlDestroyProcessParameters = (RTLDESTROYPROCESSPARAMETERS)GetProcAddressA((DWORD64)hModule, "RtlDestroyProcessParameters"); + if (RtlDestroyProcessParameters == NULL) + return GetLastErrorEx(); + + CharStringToWCharString(wBinaryPath, BinaryPath, StringLengthA(BinaryPath)); + StringCopyW(MsDosFullPath, (PWCHAR)L"\\??\\"); + StringConcatW(MsDosFullPath, wBinaryPath); + + RtlInitUnicodeString(&NtImagePath, MsDosFullPath); + + if (RtlCreateProcessParametersEx(&ProcessParameters, &NtImagePath, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROCESS_PARAMETERS_NORMALIZED) != ERROR_SUCCESS) + return GetLastErrorEx(); + + AttributeList = (PPS_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeapEx(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE)); + if (AttributeList) + { + AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE); + AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME; + AttributeList->Attributes[0].Size = NtImagePath.Length; + AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer; + + if (NtCreateUserProcess(&hHandle, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, NULL, NULL, NULL, NULL, ProcessParameters, &CreateInfo, AttributeList) != ERROR_SUCCESS) + dwError = GetLastErrorEx(); //? + } + + if (AttributeList) + HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, AttributeList); + + if (ProcessParameters) + RtlDestroyProcessParameters(ProcessParameters); + + return dwError; +} + + +DWORD CreateProcessViaNtCreateUserProcessW(PWCHAR BinaryPath) +{ + typedef NTSTATUS(NTAPI* NTCREATEUSERPROCESS)( + PHANDLE, + PHANDLE, + ACCESS_MASK, + ACCESS_MASK, + POBJECT_ATTRIBUTES, + POBJECT_ATTRIBUTES, + ULONG, + ULONG, + PRTL_USER_PROCESS_PARAMETERS, + PPS_CREATE_INFO, + PPS_ATTRIBUTE_LIST + ); + + typedef NTSTATUS(NTAPI* RTLCREATEPROCESSPARAMETERSEX)( + PRTL_USER_PROCESS_PARAMETERS*, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + PVOID, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + PUNICODE_STRING, + ULONG + ); + + typedef NTSTATUS(NTAPI* RTLDESTROYPROCESSPARAMETERS)(PRTL_USER_PROCESS_PARAMETERS); + + NTCREATEUSERPROCESS NtCreateUserProcess; + RTLCREATEPROCESSPARAMETERSEX RtlCreateProcessParametersEx; + RTLDESTROYPROCESSPARAMETERS RtlDestroyProcessParameters; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; + UNICODE_STRING NtImagePath; + WCHAR MsDosFullPath[MAX_PATH * sizeof(WCHAR)] = { 0 }; + PS_CREATE_INFO CreateInfo = { 0 }; + HMODULE hModule; + PPS_ATTRIBUTE_LIST AttributeList = NULL; + HANDLE hHandle = NULL, hThread = NULL; + DWORD dwError = ERROR_SUCCESS; + + CreateInfo.Size = sizeof(CreateInfo); + CreateInfo.State = PsCreateInitialState; + + hModule = GetModuleHandleExW(L"ntdll.dll"); + if (hModule == NULL) + return GetLastErrorEx(); + + NtCreateUserProcess = (NTCREATEUSERPROCESS)GetProcAddressA((DWORD64)hModule, "NtCreateUserProcess"); + if (NtCreateUserProcess == NULL) + return GetLastErrorEx(); + + RtlCreateProcessParametersEx = (RTLCREATEPROCESSPARAMETERSEX)GetProcAddressA((DWORD64)hModule, "RtlCreateProcessParametersEx"); + if (RtlCreateProcessParametersEx == NULL) + return GetLastErrorEx(); + + RtlDestroyProcessParameters = (RTLDESTROYPROCESSPARAMETERS)GetProcAddressA((DWORD64)hModule, "RtlDestroyProcessParameters"); + if (RtlDestroyProcessParameters == NULL) + return GetLastErrorEx(); + + StringCopyW(MsDosFullPath, (PWCHAR)L"\\??\\"); + StringConcatW(MsDosFullPath, BinaryPath); + + RtlInitUnicodeString(&NtImagePath, MsDosFullPath); + + if (RtlCreateProcessParametersEx(&ProcessParameters, &NtImagePath, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROCESS_PARAMETERS_NORMALIZED) != ERROR_SUCCESS) + return GetLastErrorEx(); + + AttributeList = (PPS_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeapEx(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE)); + if (AttributeList) + { + AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE); + AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME; + AttributeList->Attributes[0].Size = NtImagePath.Length; + AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer; + + if (NtCreateUserProcess(&hHandle, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, NULL, NULL, NULL, NULL, ProcessParameters, &CreateInfo, AttributeList) != ERROR_SUCCESS) + dwError = GetLastErrorEx(); //? + } + + if (AttributeList) + HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, AttributeList); + + if (ProcessParameters) + RtlDestroyProcessParameters(ProcessParameters); + + return dwError; +} diff --git a/VX-API/Internal.h b/VX-API/Internal.h index ddadcb6..bb473d2 100644 --- a/VX-API/Internal.h +++ b/VX-API/Internal.h @@ -1,6 +1,8 @@ #pragma once #include + + #define PROCESSOR_FEATURE_MAX 64 #define InitializeObjectAttributes(p, n, a, r, s) \ @@ -19,6 +21,15 @@ typedef struct _LSA_UNICODE_STRING { 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; + typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; diff --git a/VX-API/Main.cpp b/VX-API/Main.cpp index d8947f7..3f31be8 100644 --- a/VX-API/Main.cpp +++ b/VX-API/Main.cpp @@ -2,9 +2,8 @@ #include "Internal.h" #include "StringManipulation.h" #include "Win32Helper.h" -#include -#pragma comment(lib, "shlwapi.lib") + /* TODO: - Ping with 'IcmpSendEcho2Ex' @@ -13,10 +12,11 @@ KNOWN ISSUES - Dynamically resolve IUnknown_QueryService in UnusedSubroutineGetShellViewForDesktop in CreateProcessFromShellExecuteInExplorerProcess */ + + int main(VOID) { DWORD dwError = ERROR_SUCCESS; return ERROR_SUCCESS; -} - +} \ No newline at end of file diff --git a/VX-API/VX-API.vcxproj b/VX-API/VX-API.vcxproj index eadbdc0..1b92b92 100644 --- a/VX-API/VX-API.vcxproj +++ b/VX-API/VX-API.vcxproj @@ -141,7 +141,9 @@ + + diff --git a/VX-API/VX-API.vcxproj.filters b/VX-API/VX-API.vcxproj.filters index 93b1a7d..fea2c1e 100644 --- a/VX-API/VX-API.vcxproj.filters +++ b/VX-API/VX-API.vcxproj.filters @@ -333,6 +333,12 @@ Source Files\Windows API Helper Functions\Evasion + + Source Files\Windows API Helper Functions\Evasion + + + Source Files\Windows API Helper Functions\Evasion + diff --git a/VX-API/Win32Helper.h b/VX-API/Win32Helper.h index 0750124..8bf5caf 100644 --- a/VX-API/Win32Helper.h +++ b/VX-API/Win32Helper.h @@ -127,6 +127,8 @@ DWORD CreateProcessFromShellExecuteInExplorerProcessW(_In_ PWCHAR BinaryPath); DWORD CreateProcessFromShellExecuteInExplorerProcessA(_In_ PCHAR BinaryPath); DWORD CreateProcessFromIShellDispatchInvokeW(_In_ PWCHAR BinaryPath); DWORD CreateProcessFromIShellDispatchInvokeA(_In_ PCHAR BinaryPath); +DWORD CreateProcessViaNtCreateUserProcessW(PWCHAR FullBinaryPath); +DWORD CreateProcessViaNtCreateUserProcessA(PCHAR FullBinaryPath); //antidebug BOOL AdfCloseHandleOnInvalidAddress(VOID);