PowerShell und DNSClient
Die meisten Commandlets arbeiten auch mit dem Parameter "Computer", "DomainController" o.ä. Und akzeptieren dort natürlich auch Hostnamen. Aber was macht man, wenn man wirklich mal selbst eine DNS-Abfrage stellen will? Das NET-Framework stellt dazu eine Klasse bereit, die aber eher rudimentär ist. Gerade für Lync hingegen ist z.B. die Abfrage eines SRV-Records interessant und auch die Überprüfung, ob ein Name auf mehrere IP-Adressen auflöst. Und nicht immer ist NSLOOKUP der passende Weg.
NSLOOOKUP Fallback
Über viel Jahre habe ich wirklich meine "Tests" über den Umweg mit NSLookup gemacht. Aus PowerShell heraus wurde NSLOOKUP mit den passenden Parametern aufgerufen und die Rückgabe als Textstring geparsed. Hier z.B. ein Codeteil aus einer VBScript-Routine
Hier der gesamte Code als Download
psdns-ocsdns.1.2.vbs.txt
Das gleiche geht natürlich auch per PowerShell aber es ist nicht elegant und zudem auch abhängig von der Sprache, da hier der Rückgabetext analysiert werden muss.
- PowerShell v2 and DNS
Queries...
http://www.coretekservices.com/2013/01/24/PowerShell-v2-and-dns-queries
DNS bis PowerShell 2
Wer auf PowerShell 2 aufbaut, der kann neben NSLOOKUP auch WMI-Anfragen oder eben das .NET Framework nutzen, z.B.
[System.Net.Dns]::GetHostAddresses("www.msxfaq.de")
Das Ergebnis ist dann eine .NET Objekt mit folgende Informationen (Stand Jul 2014)
TypeName: System.Net.IPAddress Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object comparand) GetAddressBytes Method byte[] GetAddressBytes() GetHashCode Method int GetHashCode() GetType Method type GetType() MapToIPv4 Method ipaddress MapToIPv4() MapToIPv6 Method ipaddress MapToIPv6() ToString Method string ToString() Address Property long Address {get;set;} AddressFamily Property System.Net.Sockets.AddressFamily AddressFa IsIPv4MappedToIPv6 Property bool IsIPv4MappedToIPv6 {get;} IsIPv6LinkLocal Property bool IsIPv6LinkLocal {get;} IsIPv6Multicast Property bool IsIPv6Multicast {get;} IsIPv6SiteLocal Property bool IsIPv6SiteLocal {get;} IsIPv6Teredo Property bool IsIPv6Teredo {get;} ScopeId Property long ScopeId {get;set;} IPAddressToString ScriptProperty System.Object IPAddressToString {get=$this
In meinem Fall ergibt dies:
c:PS C:\> [System.Net.Dns]::GetHostAddresses("www.msxfaq.de") | fl Address : 3947144530 AddressFamily : InterNetwork ScopeId : IsIPv6Multicast : False IsIPv6LinkLocal : False IsIPv6SiteLocal : False IsIPv6Teredo : False IsIPv4MappedToIPv6 : False IPAddressToString : 82.165.68.235
Auf dem gleichen Weg kann eine IP-Adresse rückwärts auf einen Host aufgelöst werden. Allerdings funktioniert dies nur für A, AAAA und PTR-Records. Selbst ein MX-Record kann so nicht aufgelöst werden.
- System.Net.DNS
http://msdn.microsoft.com/de-de/library/system.net.dns(v=vs.110).aspx - System.Net.DNS:
GetHostAddresses
http://msdn.microsoft.com/de-de/library/system.net.dns.gethostaddresses(v=vs.110).aspx - Windows PowerShell One
Liner: Name to IP Address
http://blogs.msdn.com/b/PowerShell/archive/2006/06/26/647318.aspx - Hey, Scripting Guy! How Do I
Query and Retrieve DNS
Information?
http://blogs.technet.com/b/heyscriptingguy/archive/2009/02/26/how-do-i-query-and-retrieve-dns-information.aspx - Resolving Reverse DNS
Lookups in PowerShell (and some
issues to be aware of)
http://blog.forrestshields.com/post/2012/08/01/Resolving-Reverse-DNS-Lookups-in-PowerShell.aspx - Bulk DNS Lookup in Windows
PowerShell – Better than
NSLookup!
https://www.geekynick.co.uk/bulk-dns-lookup-in-windows-PowerShell-better-than-nslookup-2/
Resolve-DNSName mit PS3+
Seit Windows 8/Windows 2012 und PowerShell 3.0 gibt es endlich ein eigenes Commandlet für die Auflösung von DNS-Namen, welches fast alle Wünsche abdeckt:
- Resolve-DnsName
http://technet.microsoft.com/en-us/library/jj590781.aspx
Damit lassen sich nicht nur "Hostnamen" auflösen sondern auch MX-Records, SRV-Records und einiges mehr. Die Microsoft Hilfe beschreibt aber schön die einzelnen Optionen. Voraussetzung ist natürlich die Installation von PowerShell 3 oder 4. Sie finden den Download bei der Suche nach "Windows Management Framework 4.0"
Achtung: Das .Net Framework 4.5 muss vorher installiert sein. Das WMF4 Setup weist darauf NICHT hin und stoppt auch nicht, wenn das Framework nicht installiert ist.
Windows Management Framework 4.0
http://www.microsoft.com/de-de/download/details.aspx?id=40855
Microsoft .NET Framework 4.5
http://www.microsoft.com/en-us/download/details.aspx?id=30653
Die PowerShell 4 funktioniert auch auf Windows 7 SP1 und anderen Plattformen. Prüfen Sie aber unbedingt die Systemvoraussetzungen. Bestimmte ältere Software, z.B. Exchange 2007) ist nicht damit kompatibel.
Leider ist das Commandlet
per Default NICHT auf Windows 7 damit schon
installiert. Das entsprechende Modul, welches in
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\DnsClient
liegt, wird bei Windows 7 nicht mit installiert.
Tipp: Es funktioniert aber, wenn Sie das
komplette Verzeichnis von einem Windows 2012
Server oder Windows 8 Client einfach kopieren.
Eine entsprechende Lizenz benötigen Sie
natürlich.
Erst dann steht ihnen der "Resolve-DNSName" zur Verfügung. Hier ein paar Beispiele:
PS C:\> Resolve-DnsName _sipfederationtls._tcp.netatwork.de -Type SRV | fl Name : _sipfederationtls._tcp.netatwork.de Type : SRV TTL : 86392 NameTarget : sip.netatwork.de Priority : 0 Weight : 0 Port : 5061
Nun kann man per PowerShell sehr einfach endlich auch SRV-Records auslesen
Wenn ein Anbieter die Last auf mehrere Server verteilt, dann bekommen Sie auch mehrere Records in einem Objekt
PS C:\> Resolve-DnsName www.google.de | ft -AutoSize Name Type TTL Section IPAddress ---- ---- --- ------- --------- www.google.de AAAA 178 Answer 2a00:1450:4008:800::100f www.google.de A 139 Answer 173.194.32.223 www.google.de A 139 Answer 173.194.32.216 www.google.de A 139 Answer 173.194.32.215 www.google.de A 139 Answer 173.194.32.207
Bei Microsoft hingegen sieht es (Jun 2014) etwas anders aus.
PS C:\> Resolve-DnsName www.microsoft.com Name Type TTL Section NameHost ---- ---- --- ------- -------- www.microsoft.com CNAME 241 Answer toggle.www.ms.akadns.net toggle.www.ms.akadns.net CNAME 241 Answer g.www.ms.akadns.net g.www.ms.akadns.net CNAME 241 Answer lb1.www.ms.akadns.net Name : lb1.www.ms.akadns.net QueryType : A TTL : 31 Section : Answer IP4Address : 65.55.57.27 Name : akadns.net QueryType : SOA TTL : 22 Section : Authority NameAdministrator : hostmaster.akamai.com SerialNumber : 1403167478 TimeToZoneRefresh : 90000 TimeToZoneFailureRetry : 90000 TimeToExpiration : 90000 DefaultTTL : 180
Das sind genau genommen fünf Einträge, von denen die ersten drei auf CNAME verweisen, der vierte Eintrag ein "A-Record" und der Eintrag 5 der SOA ist. Selbst wenn man den Type mit angibt, bekommt man die CNAME Einträge mit:
PS C:\> Resolve-DnsName www.microsoft.com -Type a Name Type TTL Section NameHost ---- ---- --- ------- -------- www.microsoft.com CNAME 105 Answer toggle.www.ms.akadns.net toggle.www.ms.akadns.net CNAME 105 Answer g.www.ms.akadns.net g.www.ms.akadns.net CNAME 105 Answer lb1.www.ms.akadns.net Name : lb1.www.ms.akadns.net QueryType : A TTL : 159 Section : Answer IP4Address : 65.55.57.27
Hier sollten Sie also eventuell noch etwas weiter filtern und prüfen, z.B. mit
PS C:\> Resolve-DnsName www.microsoft.com | where {$_.type -eq "a"} Name Type TTL Section IPAddres s ---- ---- --- ------- -------- lb1.www.ms.akadns.net A 86 Answer 65.55.57 .27
Bild sollten Sie sich also nicht auf die Antworten verlassen, sondern zumindest damit umgehen, das die Rückgabe mehrere Records enthält. Ist ein Name nicht auflösbar, wird natürlich eine Exception geworfen.
PS C:\> Resolve-DnsName www.microsoft.egal Resolve-DnsName : www.microsoft.egal : Der DNS-Name ist nicht vorhanden In Zeile:1 Zeichen:1 + Resolve-DnsName www.microsoft.egal + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ResourceUnavailable: (www.microsoft.egal:String)[Resolve-DnsName], Win32Exception + FullyQualifiedErrorId : DNS_ERROR_RCODE_NAME_ERROR,Microsoft.DnsClient.Commands.ResolveDnsName
Der Umgang mit Try/Catch ist hier also ratsam.
DNS_ANY Probleme
Auf eine andere Besonderheit sollten Sie achten, wenn Sie möglichst alle DNS-Einträge suchen und daher nach "ANY" suchen. Nicht alle DNS-Server erlauben ein ANY.
Per Wireshark ist auch zu sehen, dass hier keine Antwort kommt.
Eine Abfrage mit "A" oder "A_AAAA" führt aber zu einen Erfolg. Ich habe dann natürlich verschiedene DNS-Server angefragt aber alle haben auf einen "ANY" nichts mehr geliefert. Resolve-DNS nutzt by Default übrigens "A_AAA" als Default, womit aber auch CNAME-Einträge aufgelöst werden.
Die Reaktion auf ANY-Anfragen müssen DNS-Server aber nicht mehr beantworten, da Sie über UDP zu leicht für DDoS-Attacken missbraucht werden können. Als Angreifer stellen Sie eine DNS ANY-Abfrage per UDP mit gefälschter IP-Adresse an einen DNS-Server, der seine auch längere Antwort an das Ziel sendet. Aus einer kleinen DNS-Abfrage wird so eine große Antwort an ein drittes System.
- Resolve-DnsName
https://docs.microsoft.com/en-us/powershell/module/dnsclient/resolve-dnsname?view=win10-ps - Alert (TA13-088A) DNS Amplification
Attacks
https://us-cert.cisa.gov/ncas/alerts/TA13-088A - RFC8482 - Saying goodbye to ANY
https://blog.cloudflare.com/rfc8482-saying-goodbye-to-any/ - Deep Inside a DNS Amplification DDoS
Attack
https://blog.cloudflare.com/deep-inside-a-dns-amplification-ddos-attack/ - Deprecating the DNS ANY meta-query type
https://blog.cloudflare.com/deprecating-dns-any-meta-query-type/ - DNS ANY query
https://docs.citrix.com/en-us/netscaler/12/dns/dns-any-query.html
Resolve-DNSName mit CNAME
Interessant ist auch anderes Verhalten, was ich habe von "Invoke-Webrequest" schon ähnlich kenne. Sowohl bei DNS als auch HTTP gibt es die Möglichkeit einer Weiterleitung. Was bei HTTP ein Code 302/301 ist, ist bei DNS der CNAME. Das kann zu durchaus interessanten Ergebnissen führen, wenn Sie z.B. mit DKIM Abfragen machen. Um z.B. die Funktion DKIM mit Office 365 zu nutzen, legt Microsoft einen TXT-Record mit dem öffentlichen RSA-Token an und der Domaininhaber muss einen CNAME anlegen. Das kann ich per Resolve-DNS einfach abfragen.
PS C:\> Resolve-DnsName -Type CNAME -Name selector1._domainkey.msxfaq.com |fl Name : selector1._domainkey.msxfaq.com Type : CNAME TTL : 86400 Section : Answer NameHost : selector1-msxfaq-com._domainkey.msxfaq.onmicrosoft.com
In einem zweiten Schritte kann ich dann den TXT-Record abfragen:
PS C:\> Resolve-DnsName -Type txt -Name selector1-msxfaq-com._domainkey.msxfaq.onmicrosoft.com | fl Name : selector1-msxfaq-com._domainkey.msxfaq.onmicrosoft.com Type : TXT TTL : 3579 Strings : {v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCY2i1orZ9zezwp/+xOcq2xc31F099nXV SuDJxeXEVUr9FP788r/fr5FumyaBf/y1LAPz2hRouIvJdSx6OCVHcCvzJorbWfixFxIHL6p2PN0XmVngQM2doEyg1 YZhAQDUIegT1YwvKzo2SS2pHikTFhIlLL+4IqZVnF1kM3mzGHuQIDAQAB; n=1024,1450894448,1}
Interessant wird es aber, wenn ich nicht den CNAME sondern den TXT-Record abfrage. Ein DKIM-Verifier muss ja nicht zwingend mit dem CNAME rechnen sondern erwartet erst einmal einen TXT-Record.
PS C:\group\Technik\Skripte\Get-O365Tenantinfo> Resolve-DnsName -Type txt -Name selector1._domainkey.msxfaq.com | fl Name : selector1._domainkey.msxfaq.com Type : CNAME TTL : 86346 Section : Answer NameHost : selector1-msxfaq-com._domainkey.msxfaq.onmicrosoft.com Name : selector1-msxfaq-com._domainkey.msxfaq.onmicrosoft.com QueryType : TXT TTL : 3546 Section : Answer Strings : {v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCY2i1orZ9zezwp/+xOcq2xc31F099n XVSuDJxeXEVUr9FP788r/fr5FumyaBf/y1LAPz2hRouIvJdSx6OCVHcCvzJorbWfixFxIHL6p2PN0XmVngQM2do Eyg1YZhAQDUIegT1YwvKzo2SS2pHikTFhIlLL+4IqZVnF1kM3mzGHuQIDAQAB; n=1024,1450894448,1}
Hier sehen Sie dann, dass ich zwei Ergebnisse erhalte. Resolve-DNS liefert mir natürlich den CNAME aber passende dazu auch gleich die Abfrage zum Zielsystem. Als PowerShell-Entwickler müssen Sie natürlich auf sowas gefasst sein, dass Sie mehrere Ergebnisse mit mehreren Rückgaben erhalten, die sie dann auch noch filtern müssen. Das ist in PowerShell natürlich einfach
PS C:\> Resolve-DnsName -Type txt -Name selector1._domainkey.msxfaq.com | ?{$_.Querytype -eq "TXT"} | fl Name : selector1-msxfaq-com._domainkey.msxfaq.onmicrosoft.com Type : TXT TTL : 3277 Strings : {v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCY2i1orZ9zezwp/+xOcq2xc31F099nXV SuDJxeXEVUr9FP788r/fr5FumyaBf/y1LAPz2hRouIvJdSx6OCVHcCvzJorbWfixFxIHL6p2PN0XmVngQM2doEyg1 YZhAQDUIegT1YwvKzo2SS2pHikTFhIlLL+4IqZVnF1kM3mzGHuQIDAQAB; n=1024,1450894448,1}
Win32 API
Für die C++-Entwickler ist der Weg zu .NET und PowerShell eher ein Umweg und Sie werden vermutlich die Win32 API nutzen. Das ist gar nicht mal so verwerflich, da die Win32-API auch in Zeiten von .NET noch alle nicht abgeschrieben ist. Zugegeben würde so ein Programm vermutlich nicht auf eine "anderen Plattform" laufen, aber bislang habe ich noch keinen ernsthaften Einsatz von .NET auf fremden Plattformen gesehen. Sicher gibt es das Projekt Mono, was das .NET Framework auf Linux bereit stellt, aber dort gibt es meines Wissens noch keine PowerShell. Daher hier nur zur Vollständigkeit ein paar Links:
- Dns Methods
http://msdn.microsoft.com/en-us/library/system.net.dns_methods.aspx - 831226 How to use the DnsQuery function to resolve host names and host addresses with Visual C++ .NET
- DnsQuery function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682016(v=vs.85).aspx -
DNS SRV lookup from PowerShell
http://blogs.technet.com/b/nettracer/archive/2013/10/13/dns-srv-lookup-from-PowerShell.aspx
Beispiel um aus PowerShell eine C++ "EXE" als Umweg zu nuzten.
Weitere Links
- DNS
- PowerShell
-
Hello Resolve-DnsName, Goodbye
NSLookup
http://tfl09.blogspot.de/2013/11/hello-resolve-dnsname-goodbye-nslookup.html -
PowerShell v3 installed modules
http://richardsPowerShellblog.wordpress.com/2012/12/14/PowerShell-v3-installed-modules/ -
PowerShell: DNS Namen auflösen
mit dem Resolve-DnsName Cmdlet
http://schneider-solingen.de/?p=51