Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1376 lines (1152 sloc) 39.4 KB
<#
.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
{
}
}