Skip to content

Instantly share code, notes, and snippets.

@snovvcrash
Last active September 27, 2023 16:06
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save snovvcrash/3d5008d7e46d1cc60f0f8bdc8cdb66a5 to your computer and use it in GitHub Desktop.
Save snovvcrash/3d5008d7e46d1cc60f0f8bdc8cdb66a5 to your computer and use it in GitHub Desktop.
#include <windows.h>
#include <stdio.h>
#define RTL_MAX_DRIVE_LETTERS 32
#define RTL_USER_PROC_PARAMS_NORMALIZED 0x00000001
#define STATUS_SUCCESS 0
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) == STATUS_SUCCESS)
// https://github.com/RedTeamOperations/Advanced-Process-Injection-Workshop/blob/66a2d3ffe6540c981182a2fb38cc92b0909c4b7f/CWLProcessDoppelganging/CWLProcessDoppelganging/CWLImplant.cpp
// https://github.com/huntandhackett/concealed_code_execution/blob/e688551bac50d8525b4ca7490da3981999cbff52/Injection/SampleDlls/3.NoDependencies/dllmain.c
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR pBuffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
typedef struct _CURDIR
{
UNICODE_STRING DosPath;
HANDLE Handle;
} CURDIR, *PCURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
HANDLE ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StandardInput;
HANDLE StandardOutput;
HANDLE StandardError;
CURDIR CurrentDirectory;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS];
ULONG EnvironmentSize;
ULONG EnvironmentVersion;
PVOID PackageDependencyData;
ULONG ProcessGroupId;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _SECTION_IMAGE_INFORMATION
{
PVOID TransferAddress;
ULONG ZeroBits;
ULONG MaximumStackSize;
ULONG CommittedStackSize;
ULONG SubSystemType;
union
{
struct
{
WORD SubSystemMinorVersion;
WORD SubSystemMajorVersion;
};
ULONG SubSystemVersion;
};
ULONG GpValue;
WORD ImageCharacteristics;
WORD DllCharacteristics;
WORD Machine;
UCHAR ImageContainsCode;
UCHAR ImageFlags;
ULONG ComPlusNativeReady: 1;
ULONG ComPlusILOnly: 1;
ULONG ImageDynamicallyRelocated: 1;
ULONG Reserved: 5;
ULONG LoaderFlags;
ULONG ImageFileSize;
ULONG CheckSum;
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
typedef struct _RTL_USER_PROCESS_INFORMATION {
ULONG Size;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
CLIENT_ID ClientId;
SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
typedef NTSTATUS (NTAPI *_RtlCreateProcessParametersEx)(
_Out_ PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
_In_ PUNICODE_STRING ImagePathName,
_In_opt_ PUNICODE_STRING DllPath,
_In_opt_ PUNICODE_STRING CurrentDirectory,
_In_opt_ PUNICODE_STRING CommandLine,
_In_opt_ PVOID Environment,
_In_opt_ PUNICODE_STRING WindowTitle,
_In_opt_ PUNICODE_STRING DesktopInfo,
_In_opt_ PUNICODE_STRING ShellInfo,
_In_opt_ PUNICODE_STRING RuntimeData,
_In_ ULONG Flags
);
typedef NTSTATUS (NTAPI *_RtlCreateUserProcess)(
_In_ PUNICODE_STRING NtImagePathName,
_In_ ULONG AttributesDeprecated,
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
_In_opt_ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
_In_opt_ HANDLE ParentProcess,
_In_ BOOLEAN InheritHandles,
_In_opt_ HANDLE DebugPort,
_In_opt_ HANDLE TokenHandle,
_Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
typedef NTSTATUS (NTAPI *_RtlDestroyProcessParameters)(
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters
);
typedef NTSTATUS (NTAPI *_NtResumeThread)(
_In_ HANDLE ThreadHandle,
_Out_opt_ PULONG PreviousSuspendCount
);
typedef NTSTATUS (NTAPI *_NtClose)(
_In_ HANDLE Handle
);
void main()
{
_RtlCreateProcessParametersEx pRtlCreateProcessParametersEx = (_RtlCreateProcessParametersEx)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCreateProcessParametersEx");
if (pRtlCreateProcessParametersEx == NULL)
{
printf("[-] Error RtlCreateProcessParametersEx API not found!\n");
return;
}
_RtlCreateUserProcess pRtlCreateUserProcess = (_RtlCreateUserProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCreateUserProcess");
if (pRtlCreateUserProcess == NULL)
{
printf("[-] Error pRtlCreateUserProcess API not found!\n");
return;
}
_RtlDestroyProcessParameters pRtlDestroyProcessParameters = (_RtlDestroyProcessParameters)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlDestroyProcessParameters");
if (pRtlDestroyProcessParameters == NULL)
{
printf("[-] Error pRtlDestroyProcessParameters API not found!\n");
return;
}
_NtResumeThread pNtResumeThread = (_NtResumeThread)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtResumeThread");
if (pNtResumeThread == NULL)
{
printf("[-] Error pNtResumeThread API not found!\n");
return;
}
_NtClose pNtClose = (_NtClose)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtClose");
if (pNtClose == NULL)
{
printf("[-] Error pNtClose API not found!\n");
return;
}
NTSTATUS status;
PRTL_USER_PROCESS_PARAMETERS processParams;
RTL_USER_PROCESS_INFORMATION processInfo;
UNICODE_STRING spoofedImagePathName;
spoofedImagePathName.pBuffer = L"\\??\\C:\\Users\\user\\Music\\WerFault.exe";
for (spoofedImagePathName.Length = 0; spoofedImagePathName.pBuffer[spoofedImagePathName.Length]; spoofedImagePathName.Length++);
spoofedImagePathName.Length = spoofedImagePathName.Length * sizeof(WCHAR);
spoofedImagePathName.MaximumLength = spoofedImagePathName.Length + sizeof(UNICODE_NULL);
UNICODE_STRING currentDirectory;
currentDirectory.pBuffer = L"C:\\Windows\\System32\\";
for (currentDirectory.Length = 0; currentDirectory.pBuffer[currentDirectory.Length]; currentDirectory.Length++);
currentDirectory.Length = currentDirectory.Length * sizeof(WCHAR);
currentDirectory.MaximumLength = currentDirectory.Length + sizeof(UNICODE_NULL);
UNICODE_STRING commandLine;
commandLine.pBuffer = L"C:\\Windows\\System32\\";
for (commandLine.Length = 0; commandLine.pBuffer[commandLine.Length]; commandLine.Length++);
commandLine.Length = commandLine.Length * sizeof(WCHAR);
commandLine.MaximumLength = commandLine.Length + sizeof(UNICODE_NULL);
UNICODE_STRING imagePathName;
imagePathName.pBuffer = L"\\??\\C:\\Windows\\System32\\WerFault.exe";
for (imagePathName.Length = 0; imagePathName.pBuffer[imagePathName.Length]; imagePathName.Length++);
imagePathName.Length = imagePathName.Length * sizeof(WCHAR);
imagePathName.MaximumLength = imagePathName.Length + sizeof(UNICODE_NULL);
status = pRtlCreateProcessParametersEx(
&processParams,
&spoofedImagePathName,
NULL,
&currentDirectory,
&commandLine,
NULL,
&imagePathName,
NULL,
NULL,
NULL,
RTL_USER_PROC_PARAMS_NORMALIZED
);
if (!NT_SUCCESS(status))
return;
status = pRtlCreateUserProcess(
&imagePathName,
0,
processParams,
NULL,
NULL,
GetCurrentProcess(),
TRUE,
NULL,
NULL,
&processInfo
);
pRtlDestroyProcessParameters(processParams);
if (!NT_SUCCESS(status))
return;
pNtResumeThread(processInfo.ThreadHandle, NULL);
pNtClose(processInfo.ProcessHandle);
pNtClose(processInfo.ThreadHandle);
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment