Discovery/Discovery.psm1
<# .Synopsis Perform Whois Query .DESCRIPTION Performs a Whois query for a given Domain. .EXAMPLE Perfrom a whois query for google.com PS C:\> Get-Whois google.com #> function Get-Whois { [CmdletBinding(DefaultParameterSetName="Domain")] Param ( # Param1 help description [Parameter(Mandatory=$true, ParameterSetName = "Domain", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Domain #[string]$IPAddress ) Begin { # Need to generate hash from http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml, # http://www.iana.org/assignments/ipv6-address-space # http://www.iana.org/assignments/multicast-addresses } Process { if ($Domain) { [WebTools.Whois]::lookup($Domain, [WebTools.Whois+RecordType]::domain) } } End { } } <# .Synopsis Enumerates all mDNS records in the local subnet. .DESCRIPTION Unsing mDNS the function qill query and resolve all mDNS records for devices advertising on the local subnet. .EXAMPLE Shows only the A and AAAA Records for hosts in the local subnet Get-MDNSRecords | where recordtype -like "A*" .EXAMPLE Show only HTTP servers in the local subnet Get-MDNSRecords | where name -like "*_http._tcp*" #> function Get-MDNSRecords { [CmdletBinding()] param() $mdns = new-object -typename ARSoft.Tools.Net.Dns.MulticastDnsOneShotClient -ArgumentList 4 $records = $mdns.Resolve("_services._dns-sd._udp.local",[ARSoft.Tools.Net.Dns.RecordType]::Any) $doms = @(); $records| sort -Unique | foreach-object { $_.answerrecords| foreach { Write-Verbose $_.PointerDomainName $doms += $_.PointerDomainName } } $results = @() $doms | foreach-object { Write-Verbose "Resolving $($_)" $queryres = $mdns.Resolve($_,[ARSoft.Tools.Net.Dns.RecordType]::Ptr) $results += $queryres.answerrecords $results += $queryres.additionalrecords } $results | sort -Unique } <# .Synopsis Generates a IP Address Objects for IPv4 and IPv6 Ranges. .DESCRIPTION Generates a IP Address Objects for IPv4 and IPv6 Ranges given a ranges in CIDR or range <StartIP>-<EndIP> format. .EXAMPLE PS C:\> New-IPvRange -Range 192.168.1.1-192.168.1.5 Generate a collection of IPv4 Object collection for the specified range. .EXAMPLE New-IPRange -Range 192.168.1.1-192.168.1.50 | select -ExpandProperty ipaddresstostring Get a list of IPv4 Addresses in a given range as a list for use in another tool. #> function New-IPRange { [CmdletBinding(DefaultParameterSetName="CIDR")] Param( [parameter(Mandatory=$true, ParameterSetName = "CIDR", Position=0)] [string]$CIDR, [parameter(Mandatory=$true, ParameterSetName = "Range", Position=0)] [string]$Range ) if($CIDR) { $IPPart,$MaskPart = $CIDR.Split("/") $AddressFamily = ([System.Net.IPAddress]::Parse($IPPart)).AddressFamily # Get the family type for the IP (IPv4 or IPv6) $subnetMaskObj = [IPHelper.IP.Subnetmask]::Parse($MaskPart, $AddressFamily) # Get the Network and Brodcast Addressed $StartIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessNetworkAddress($IPPart, $subnetMaskObj) $EndIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessBroadcastAddress($IPPart,$subnetMaskObj) # Ensure we do not list the Network and Brodcast Address $StartIP = [IPHelper.IP.IPAddressAnalysis]::Increase($StartIP) $EndIP = [IPHelper.IP.IPAddressAnalysis]::Decrease($EndIP) [IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP) } elseif ($Range) { $StartIP, $EndIP = $range.split("-") [IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP) } } <# .Synopsis Generates a list of IPv4 IP Addresses given a Start and End IP. .DESCRIPTION Generates a list of IPv4 IP Addresses given a Start and End IP. .EXAMPLE Generating a list of IPs from CIDR Get-IPRange 192.168.1.0/24 .EXAMPLE Generating a list of IPs from Range Get-IPRange -Range 192.168.1.1-192.168.1.50 #> function New-IPv4Range { param( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $StartIP, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)] $EndIP ) # created by Dr. Tobias Weltner, MVP PowerShell $ip1 = ([System.Net.IPAddress]$StartIP).GetAddressBytes() [Array]::Reverse($ip1) $ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address $ip2 = ([System.Net.IPAddress]$EndIP).GetAddressBytes() [Array]::Reverse($ip2) $ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address for ($x=$ip1; $x -le $ip2; $x++) { $ip = ([System.Net.IPAddress]$x).GetAddressBytes() [Array]::Reverse($ip) $ip -join '.' } } <# .Synopsis Generates a list of IPv4 IP Addresses given a CIDR. .DESCRIPTION Generates a list of IPv4 IP Addresses given a CIDR. .EXAMPLE Generating a list of IPs PS C:\> New-IPv4RangeFromCIDR -Network 192.168.1.0/29 192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.1.5 192.168.1.6 192.168.1.7 #> function New-IPv4RangeFromCIDR { param( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $Network ) # Extract the portions of the CIDR that will be needed $StrNetworkAddress = ($Network.split("/"))[0] [int]$NetworkLength = ($Network.split("/"))[1] $NetworkIP = ([System.Net.IPAddress]$StrNetworkAddress).GetAddressBytes() $IPLength = 32-$NetworkLength [Array]::Reverse($NetworkIP) $NumberOfIPs = ([System.Math]::Pow(2, $IPLength)) -1 $NetworkIP = ([System.Net.IPAddress]($NetworkIP -join ".")).Address $StartIP = $NetworkIP +1 $EndIP = $NetworkIP + $NumberOfIPs # We make sure they are of type Double before conversion If ($EndIP -isnot [double]) { $EndIP = $EndIP -as [double] } If ($StartIP -isnot [double]) { $StartIP = $StartIP -as [double] } # We turn the start IP and end IP in to strings so they can be used. $StartIP = ([System.Net.IPAddress]$StartIP).IPAddressToString $EndIP = ([System.Net.IPAddress]$EndIP).IPAddressToString New-IPv4Range $StartIP $EndIP } <# .Synopsis Performs a DNS Reverse Lookup of a given IPv4 IP Range. .DESCRIPTION Performs a DNS Reverse Lookup of a given IPv4 IP Range. .EXAMPLE Perfrom a threaded reverse lookup against a given CIDR PS C:\> Invoke-ReverseDNSLookup -CIDR 192.168.1.0/24 .EXAMPLE Perfrom a reverse lookup against a given range given the start and end IP Addresses PS C:\> Invoke-ReverseDNSLookup -Range 192.168.1.1-192.168.1.20 #> function Invoke-ReverseDNSLookup { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, ParameterSetName = "Range", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Range, [Parameter(Mandatory=$true, ParameterSetName = "CIDR", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$CIDR, [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$MaxThreads=30, [Parameter( ValueFromPipelineByPropertyName=$true, Position=2)] [int]$TimeOut = 200 ) Begin { # Manage if range is given if ($Range) { $rangeips = $Range.Split("-") $targets = New-IPv4Range -StartIP $rangeips[0] -EndIP $rangeips[1] } # Manage if CIDR is given if ($CIDR) { $targets = New-IPv4RangeFromCIDR -Network $CIDR } } Process { $RvlScripBlock = { param($ip) try { [System.Net.Dns]::GetHostEntry($ip) } catch {} } #Multithreading setup # create a pool of maxThread runspaces $pool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads) $pool.Open() $jobs = @() $ps = @() $wait = @() $i = 0 # How many servers $record_count = $targets.Length #Loop through the endpoints starting a background job for each endpoint foreach ($ip in $targets) { Write-Verbose $ip # Show Progress $record_progress = [int][Math]::Ceiling((($i / $record_count) * 100)) Write-Progress -Activity "Performing DNS Reverse Lookup Discovery" -PercentComplete $record_progress -Status "Reverse Lookup - $record_progress%" -Id 1; while ($($pool.GetAvailableRunspaces()) -le 0) { Start-Sleep -milliseconds 500 } # create a "powershell pipeline runner" $ps += [powershell]::create() # assign our pool of 3 runspaces to use $ps[$i].runspacepool = $pool # command to run [void]$ps[$i].AddScript($RvlScripBlock).AddParameter('ip', $ip) #[void]$ps[$i].AddParameter('ping', $ping) # start job $jobs += $ps[$i].BeginInvoke(); # store wait handles for WaitForAll call $wait += $jobs[$i].AsyncWaitHandle $i++ } $waitTimeout = get-date while ($($jobs | ? {$_.IsCompleted -eq $false}).count -gt 0 -or $($($(get-date) - $waitTimeout).totalSeconds) -gt 60) { Start-Sleep -milliseconds 500 } # end async call for ($y = 0; $y -lt $i; $y++) { try { # complete async job $ScanResults += $ps[$y].EndInvoke($jobs[$y]) } catch { # oops-ee! write-warning "error: $_" } finally { $ps[$y].Dispose() } } $pool.Dispose() } end { $ScanResults } } <# .Synopsis Performs a Ping Scan against a given range of IPv4 IP addresses. .DESCRIPTION Performs a Ping Scan against a given range of IPv4 IP addresses by sending ICMP Echo Packets. .EXAMPLE Perform Ping Scan against a given range in CIDR format PS C:\> Invoke-PingScan -CIDR 192.168.1.0/24 .EXAMPLE Perform Ping Scan against a given range given the start and end IP Addresses PS C:\> Invoke-PingScan -Range 192.168.1.1-192.168.1.10 #> function Invoke-PingScan { [CmdletBinding()] Param ( # IP Range to perform ping scan against. [Parameter(Mandatory=$true, ParameterSetName = "Range", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Range, # IP CIDR to perform ping scan against. [Parameter(Mandatory=$true, ParameterSetName = "CIDR", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$CIDR, # Number of concurrent threads to execute [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=1)] [string]$MaxThreads=10, # Timeout in miliseconds for the ICMP Echo request. [Parameter(ValueFromPipelineByPropertyName=$true, Position=2)] [int]$TimeOut = 200 ) Begin { # Manage if range is given if ($Range) { $rangeips = $Range.Split("-") $targets = New-IPv4Range -StartIP $rangeips[0] -EndIP $rangeips[1] } # Manage if CIDR is given if ($CIDR) { $targets = New-IPv4RangeFromCIDR -Network $CIDR } } Process { $PingScripBlock = { param($ip, $TimeOut) $ping = New-Object System.Net.NetworkInformation.Ping $result = $ping.Send($ip, $TimeOut) if ($result.Status -eq 'success') { new-object psobject -Property @{Address = $result.Address; Time = $result.RoundtripTime} } } #Multithreading setup # create a pool of maxThread runspaces $pool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads) $pool.Open() $jobs = @() $ps = @() $wait = @() $i = 0 # How many servers $record_count = $targets.Length #Loop through the endpoints starting a background job for each endpoint foreach ($ip in $targets) { Write-Verbose $ip # Show Progress $record_progress = [int][Math]::Ceiling((($i / $record_count) * 100)) Write-Progress -Activity "Performing Ping Discovery" -PercentComplete $record_progress -Status "Pinged Host - $record_progress%" -Id 1; while ($($pool.GetAvailableRunspaces()) -le 0) { Start-Sleep -milliseconds 500 } # create a "powershell pipeline runner" $ps += [powershell]::create() $ps[$i].runspacepool = $pool # command to run [void]$ps[$i].AddScript($PingScripBlock).AddParameter('ip', $ip).AddParameter('Timeout', $TimeOut) # start job $jobs += $ps[$i].BeginInvoke(); # store wait handles for WaitForAll call $wait += $jobs[$i].AsyncWaitHandle $i++ } write-verbose "Waiting for scanning threads to finish..." $waitTimeout = get-date while ($($jobs | ? {$_.IsCompleted -eq $false}).count -gt 0 -or $($($(get-date) - $waitTimeout).totalSeconds) -gt 60) { Start-Sleep -milliseconds 500 } # end async call for ($y = 0; $y -lt $i; $y++) { try { # complete async job $ScanResults += $ps[$y].EndInvoke($jobs[$y]) } catch { write-warning "error: $_" } finally { $ps[$y].Dispose() } } $pool.Dispose() } end { $ScanResults } } <# .Synopsis Performs full TCP Connection and UDP port scan. .DESCRIPTION Performs full TCP Connection and UDP port scan against a given host or range of IPv4 addresses. .EXAMPLE Perform TCP Scan of known ports against a host PS C:\> Invoke-PortScan -Target 172.20.10.3 -Ports 22,135,139,445 -Type TCP Host Port State Type ---- ---- ----- ---- 172.20.10.3 135 Open TCP 172.20.10.3 139 Open TCP 172.20.10.3 445 Open TCP #> function Invoke-PortScan { [CmdletBinding()] Param ( # Param1 help description [Parameter(Mandatory=$true, ParameterSetName = "SingleIP", ValueFromPipelineByPropertyName=$true, Position=0)] [Alias("IPAddress,Host")] [string]$Target, [Parameter(Mandatory=$true, ParameterSetName = "Range", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Range, [Parameter(Mandatory=$true, ParameterSetName = "CIDR", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$CIDR, [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, Position=1)] [int32[]]$Ports, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$false, Position=2)] [ValidateSet("TCP", "UDP")] [String[]]$Type, [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, Position=3)] [ValidateSet("TCP", "UDP")] [int32]$Timeout=100 ) Begin { # Expand the needed address ranges if ($Range) { $rangeips = $Range.Split("-") $targets = New-IPv4Range -StartIP $rangeips[0] -EndIP $rangeips[1] } # Expnd CIDR if ($CIDR) { $targets = New-IPv4RangeFromCIDR -Network $CIDR } # Manage single target if ($Target) { $targets = @($Target) } # Set the default ports } Process { foreach ($t in $Type) { if ($t -eq "TCP") { foreach ($ip in $targets) { foreach($p in $Ports) { try { $TcpSocket = new-object System.Net.Sockets.TcpClient #$TcpSocket.client.ReceiveTimeout = $Timeout # Connect to target host and port $TcpSocket.Connect($ip, $p) $ScanPortProps = New-Object -TypeName System.Collections.Specialized.OrderedDictionary $ScanPortProps.Add("Host",$ip) $ScanPortProps.Add("Port",$p) $ScanPortProps.Add("State","Open") $ScanPortProps.Add("Type","TCP") $scanport = New-Object psobject -Property $ScanPortProps # Close Connection $tcpsocket.Close() $scanport } catch { Write-Verbose "Port $p is closed" } } } } elseif ($t -eq "UDP") { foreach ($ip in $targets) { foreach($p in $Ports) { $UDPSocket = new-object System.Net.Sockets.UdpClient $UDPSocket.client.ReceiveTimeout = $Timeout $UDPSocket.Connect($ip,$p) $data = New-Object System.Text.ASCIIEncoding $byte = $data.GetBytes("$(Get-Date)") #Send the data to the endpoint [void] $UDPSocket.Send($byte,$byte.length) #Create a listener to listen for response $Endpoint = New-Object System.Net.IPEndPoint([system.net.ipaddress]::Any,0) try { #Attempt to receive a response indicating the port was open $receivebytes = $UDPSocket.Receive([ref] $Endpoint) [string] $returndata = $data.GetString($receivebytes) $ScanPortProps = New-Object -TypeName System.Collections.Specialized.OrderedDictionary $ScanPortProps.Add("Host",$ip) $ScanPortProps.Add("Port",$p) $ScanPortProps.Add("State","Open") $ScanPortProps.Add("Type","UDP") $scanport = New-Object psobject -Property $ScanPortProps $scanport } catch { #Timeout or connection refused Write-Verbose "Port $p is closed" } finally { #Cleanup $UDPSocket.Close() } } } } } } End { } } <# .Synopsis Performs an ARP scan against a given range of IPv4 IP Addresses. .DESCRIPTION Performs an ARP scan against a given range of IPv4 IP Addresses. .EXAMPLE Invoke an ARP Scan against a range of IPs specified in CIDR Format PS C:\> Invoke-ARPScan -CIDR 172.20.10.1/24 MAC Address --- ------- 14:10:9F:D5:1A:BF 172.20.10.2 00:0C:29:93:10:B5 172.20.10.3 00:0C:29:93:10:B5 172.20.10.15 #> function Invoke-ARPScan { param ( [Parameter(Mandatory=$true, ParameterSetName = "Range", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Range, [Parameter(Mandatory=$true, ParameterSetName = "CIDR", ValueFromPipelineByPropertyName=$true, Position=0)] [string]$CIDR, [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$MaxThreads=50 ) Begin { $sign = @" using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.NetworkInformation; using System.Runtime.InteropServices; public static class NetUtils { [System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)] static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen); public static string GetMacAddress(String addr) { try { IPAddress IPaddr = IPAddress.Parse(addr); byte[] mac = new byte[6]; int L = 6; SendARP(BitConverter.ToInt32(IPaddr.GetAddressBytes(), 0), 0, mac, ref L); String macAddr = BitConverter.ToString(mac, 0, L); return (macAddr.Replace('-',':')); } catch (Exception ex) { return (ex.Message); } } } "@ try { Write-Verbose "Instanciating NetUtils" $IPHlp = Add-Type -TypeDefinition $sign -Language CSharp -PassThru } catch { Write-Verbose "NetUtils already instanciated" } # Manage if range is given if ($Range) { $rangeips = $Range.Split("-") $targets = New-IPv4Range -StartIP $rangeips[0] -EndIP $rangeips[1] } # Manage if CIDR is given if ($CIDR) { $targets = New-IPv4RangeFromCIDR -Network $CIDR } } Process { $scancode = { param($IPAddress,$IPHlp) $result = $IPHlp::GetMacAddress($IPAddress) if ($result) {New-Object psobject -Property @{Address = $IPAddress; MAC = $result}} } # end ScanCode var $jobs = @() $start = get-date write-verbose "Begin Scanning at $start" #Multithreading setup # create a pool of maxThread runspaces $pool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads) $pool.Open() $jobs = @() $ps = @() $wait = @() $i = 0 # How many servers $record_count = $targets.Length #Loop through the endpoints starting a background job for each endpoint foreach ($IPAddress in $targets) { # Show Progress $record_progress = [int][Math]::Ceiling((($i / $record_count) * 100)) Write-Progress -Activity "Performing ARP Scan" -PercentComplete $record_progress -Status "Addresses Queried - $record_progress%" -Id 1; while ($($pool.GetAvailableRunspaces()) -le 0) { Start-Sleep -milliseconds 500 } # create a "powershell pipeline runner" $ps += [powershell]::create() # assign our pool of 3 runspaces to use $ps[$i].runspacepool = $pool # command to run [void]$ps[$i].AddScript($scancode).AddParameter('IPaddress', $IPAddress).AddParameter('IPHlp', $IPHlp) #[void]$ps[$i].AddParameter() # start job $jobs += $ps[$i].BeginInvoke(); # store wait handles for WaitForAll call $wait += $jobs[$i].AsyncWaitHandle $i++ } write-verbose "Waiting for scanning threads to finish..." $waitTimeout = get-date while ($($jobs | ? {$_.IsCompleted -eq $false}).count -gt 0 -or $($($(get-date) - $waitTimeout).totalSeconds) -gt 60) { Start-Sleep -milliseconds 500 } # end async call for ($y = 0; $y -lt $i; $y++) { try { # complete async job $ScanResults += $ps[$y].EndInvoke($jobs[$y]) } catch { write-warning "error: $_" } finally { $ps[$y].Dispose() } } $pool.Dispose() } end { $ScanResults } } <# .Synopsis Enumerates the DNS Servers used by a system .DESCRIPTION Enumerates the DNS Servers used by a system returning an IP Address .Net object for each. .EXAMPLE C:\> Get-SystemDNSServer Address : 16885952 AddressFamily : InterNetwork ScopeId : IsIPv6Multicast : False IsIPv6LinkLocal : False IsIPv6SiteLocal : False IsIPv6Teredo : False IsIPv4MappedToIPv6 : False IPAddressToString : 192.168.1.1 #> function Get-SystemDNSServer { $DNSServerAddresses = @() $interfaces = [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() foreach($interface in $interfaces) { if($interface.OperationalStatus -eq "Up") { $DNSConfig = $interface.GetIPProperties().DnsAddresses if (!$DNSConfig.IsIPv6SiteLocal) { $DNSServerAddresses += $DNSConfig } } } $DNSServerAddresses } <# .Synopsis Enumerates common DNS SRV Records for a given domain. .DESCRIPTION Enumerates common DNS SRV Records for a given domain. .EXAMPLE PS C:\> Invoke-EnumSRVRecords -Domain microsoft.com Type : SRV Name : _sip._tls.microsoft.com Port : 443 Priority : 0 Target : sip.microsoft.com. Address : @{Name=sip.microsoft.com; Type=A; Address=65.55.30.130} Type : SRV Name : _sipfederationtls._tcp.microsoft.com Port : 5061 Priority : 0 Target : sipfed.microsoft.com. Address : @{Name=sipfed.microsoft.com; Type=A; Address=65.55.30.130} Type : SRV Name : _xmpp-server._tcp.microsoft.com Port : 5269 Priority : 0 Target : sipdog3.microsoft.com. Address : @{Name=sipdog3.microsoft.com; Type=A; Address=131.107.1.47} #> function Invoke-EnumSRVRecords { Param( [Parameter(Mandatory = $true)] [string]$Domain, [Parameter(Mandatory = $false)] [string]$NameServer, [Parameter(Mandatory = $false)] [int32]$TimeOut, [Parameter(Mandatory = $false)] [int32]$Retries ) Begin { # Records to test against $srv_rcds = @('_gc._tcp.', '_kerberos._tcp.', '_kerberos._udp.', '_ldap._tcp.', '_test._tcp.', '_sips._tcp.', '_sip._udp.', '_sip._tcp.', '_aix._tcp.', '_aix._tcp.', '_finger._tcp.', '_ftp._tcp.', '_http._tcp.', '_nntp._tcp.', '_telnet._tcp.', '_whois._tcp.', '_h323cs._tcp.', '_h323cs._udp.', '_h323be._tcp.', '_h323be._udp.', '_h323ls._tcp.', '_https._tcp.', '_h323ls._udp.', '_sipinternal._tcp.', '_sipinternaltls._tcp.', '_sip._tls.', '_sipfederationtls._tcp.', '_jabber._tcp.', '_xmpp-server._tcp.', '_xmpp-client._tcp.', '_imap.tcp.', '_certificates._tcp.', '_crls._tcp.', '_pgpkeys._tcp.', '_pgprevokations._tcp.', '_cmp._tcp.', '_svcp._tcp.', '_crl._tcp.', '_ocsp._tcp.', '_PKIXREP._tcp.', '_smtp._tcp.', '_hkp._tcp.', '_hkps._tcp.', '_jabber._udp.', '_xmpp-server._udp.', '_xmpp-client._udp.', '_jabber-client._tcp.', '_jabber-client._udp.', '_kerberos.tcp.dc._msdcs.', '_ldap._tcp.ForestDNSZones.', '_ldap._tcp.dc._msdcs.', '_ldap._tcp.pdc._msdcs.', '_ldap._tcp.gc._msdcs.', '_kerberos._tcp.dc._msdcs.', '_kpasswd._tcp.', '_kpasswd._udp.', '_imap._tcp.') $dnsopts = new-object JHSoftware.DnsClient+RequestOptions # Set the NS Server if one givem if ($nameserver) { try { # Check if what we got is an IP or a FQDN $IPObj = [Net.IPAddress]::Parse($nameserver) $IPCheck = [System.Net.IPAddress]::TryParse($nameserver,[ref]$IPObj) if ($IPCheck) { $dns = [System.Net.IPAddress]$nameserver $dnsopts.DnsServers += $dns } else { Write-Error "$nameserver is not a valid IP Address" } } catch { $nsip = [Net.Dns]::GetHostAddresses($nameserver)[0] $dns = $nsip $dnsopts.DnsServers += $dns } } # Set the timeout if ($TimeOut) { $dnsopts.TimeOut = New-TimeSpan -Seconds $TimeOut } # Set Retries if ($Retries) { $dnsopts.RetryCount = $Retries } # Collection of records found $found = @() } Process { $i = 0 $record_count = $srv_rcds.Length foreach($srv in $srv_rcds) { $record_progress = [int][Math]::Ceiling((($i / $record_count) * 100)) Write-Progress -Activity "Enumerating Common SRV Records" -PercentComplete $record_progress -Status "Records - $record_progress%" -Id 1; $target = $srv+$domain try { $found += [JHSoftware.DnsClient]::Lookup($target,[JHSoftware.DnsClient+RecordType]::SRV,$dnsopts).AnswerRecords } catch { } $i++ } foreach($recond in $found) { $data_info = $recond.Data.split(' ') New-Object psobject -Property ([ordered]@{Type=$recond.Type; Name =$recond.name; Port=$data_info[2];Priority=$data_info[1]; Target=$data_info[3] Address = & { if ($NameServer) { Resolve-HostRecord -Target $data_info[3] -NameServer $NameServer} else { Resolve-HostRecord -Target $data_info[3] } } }) } } } <# .Synopsis Resolve a given FQDN .DESCRIPTION Resolves a given FQDN to its A, AAAA and CNAME record. .EXAMPLE C:\> Resolve-HostRecord ipv6.google.com Name Type Address ---- ---- ------- ipv6.google.com CNAME ipv6.l.google.com. ipv6.l.google.com AAAA 2607:f8b0:4002:c02::93 #> function Resolve-HostRecord { param( [Parameter(Mandatory = $true)] [string]$Target, [Parameter(Mandatory = $false)] [string]$NameServer, [Parameter(Mandatory = $false)] [int32]$TimeOut, [Parameter(Mandatory = $false)] [int32]$Retries ) begin { $dnsopts = new-object JHSoftware.DnsClient+RequestOptions # Set the NS Server if one givem if ($nameserver) { try { # Check if what we got is an IP or a FQDN $IPObj = [Net.IPAddress]::Parse($nameserver) $IPCheck = [System.Net.IPAddress]::TryParse($nameserver,[ref]$IPObj) if ($IPCheck) { $dns = [System.Net.IPAddress]$nameserver $dnsopts.DnsServers += $dns } else { Write-Error "$nameserver is not a valid IP Address" } } catch { $nsip = [Net.Dns]::GetHostAddresses($nameserver)[0] $dns = $nsip $dnsopts.DnsServers += $dns } } # Set the timeout if ($TimeOut) { $dnsopts.TimeOut = New-TimeSpan -Seconds $TimeOut } # Set Retries if ($Retries) { $dnsopts.RetryCount = $Retries } } process { $ARecs = @() # Resolve A Record try { $answer = [JHSoftware.DnsClient]::Lookup($target,[JHSoftware.DnsClient+RecordType]::A,$dnsopts).AnswerRecords foreach ($A in $answer) { $ARecs += Select-Object -InputObject $A -Property Name,Type,@{Name='Address';Expression={$A.Data}} } } catch {} try { # Resolve AAAA Recod $answer = [JHSoftware.DnsClient]::Lookup($target,[JHSoftware.DnsClient+RecordType]::AAAA,$dnsopts).AnswerRecords foreach ($AAAA in $answer) { $ARecs += Select-Object -InputObject $AAAA -Property Name,Type,@{Name='Address';Expression={$AAAA.Data}} } } catch {} } end { $ARecs } } <# .Synopsis Query for specific DNS Records against a Nameserver .DESCRIPTION Query for specific DNS Records against a Nameserver .EXAMPLE C:\> Resolve-DNSRecord -Target microsoft.com -Type MX Name Type TTL Data ---- ---- --- ---- microsoft.com MX 1001 10 microsoft-com.m... .EXAMPLE C:\> Resolve-DNSRecord -Target microsoft.com -Type NS Name Type TTL Data ---- ---- --- ---- microsoft.com NS 14893 ns1.msft.net. microsoft.com NS 14893 ns2.msft.net. microsoft.com NS 14893 ns3.msft.net. microsoft.com NS 14893 ns4.msft.net. microsoft.com NS 14893 ns5.msft.net. #> function Resolve-DNSRecord { param( [Parameter(Mandatory = $true)] [string]$Target, [Parameter(Mandatory = $false)] [string]$NameServer, [Parameter(Mandatory = $false)] [int32]$TimeOut, [Parameter(Mandatory = $false)] [int32]$Retries, [string] [ValidateSet('A','A6','AAAA','AFSDB','ANY','APL','ATMA','CERT','CNAME', 'DHCID','DLV','DNAME','DNSKEY','DS','EID','GID','GPOS','HINFO', 'HIP','IPSECKEY','ISDN','KEY','KX','LOC','MB','MD','MF','MG', 'MINFO','MR','MX','NAPTR','NIMLOC','NS','NSAP','NSAPPTR','NSEC', 'NSEC3','NSEC3PARAM','NULL','NXT','OPT','PTR','PX','RP','RRSIG', 'RT','SRV','SINK','SIG','SOA','SPF','SSHFP','TA','TXT','UID', 'UINFO','UNSPEC','WKS','X25')] $Type ) begin { $dnsopts = new-object JHSoftware.DnsClient+RequestOptions # Set the NS Server if one givem if ($nameserver) { try { # Check if what we got is an IP or a FQDN $IPObj = [Net.IPAddress]::Parse($nameserver) $IPCheck = [System.Net.IPAddress]::TryParse($nameserver,[ref]$IPObj) if ($IPCheck) { $dns = [System.Net.IPAddress]$nameserver $dnsopts.DnsServers += $dns } else { Write-Error "$nameserver is not a valid IP Address" } } catch { $nsip = [Net.Dns]::GetHostAddresses($nameserver)[0] $dns = $nsip $dnsopts.DnsServers += $dns } } # Set the timeout if ($TimeOut) { $dnsopts.TimeOut = New-TimeSpan -Seconds $TimeOut } # Set Retries if ($Retries) { $dnsopts.RetryCount = $Retries } } process { # Resolve A Record $answer = [JHSoftware.DnsClient]::Lookup($target,[JHSoftware.DnsClient+RecordType]::$Type,$dnsopts).AnswerRecords foreach ($A in $answer) { $A } } end { } } <# .Synopsis Convert a string representation of an IPV4 IP to In-Addr-ARPA format. .DESCRIPTION Convert a string representation of an IPV4 IP to In-Addr-ARPA format for performing PTR Lookups. .EXAMPLE ConvertTo-InAddrARPA -IPAddress 192.168.1.10 10.1.168.192.in-addr.arpa #> function ConvertTo-InAddrARPA { [CmdletBinding()] [OutputType([String])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, Position=0)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [Alias("IP")] $IPAddress ) Begin { } Process { try { $IPObj = [System.Net.IPAddress]::Parse($IPAddress) $ipIpaddressSplit = $IPAddress.Split(".") "$($ipIpaddressSplit.GetValue(3)).$($ipIpaddressSplit.GetValue(2)).$($ipIpaddressSplit.GetValue(1)).$($ipIpaddressSplit.GetValue(0)).in-addr.arpa" } catch { Write-Host "Value provided is not an IP Address" } } End { } } |