Get-TCPCert
Am 1.1. 2017 werden viele Browser eine Warnung ausgeben, wenn das per SSL angesprochene Zertifikat noch mit dem hashverfahren SHA1 signiert ist. Das Verfahren ist nicht mehr als sicher anzusehen. Nur wie finden Sie in ihrem LAN oder der DMZ heraus, welches Zertifikat wo gebunden ist und welche Eigenschaften es hat?. Das Skript Get-TCPCert hilft dabei, dies zu ermitteln, indem es eine Liste der Hosts (Namen oder IP-Adressen) und optional von Ports bekommt und per TCP eine Verbindung aufbau, das Zertifikat lädt und das Ergebnis ausgibt.
Beachte dazu auch SHA-256 und Keylänge
Das Skript scheint aktuell nicht zu arbeiten, wenn der Server eine MTLS-Authentifizierung anfordert.
Das Skript ist in PowerShell geschrieben, so dass Sie es zum einen anpassen können aber insbesondere um über die Pipeline es mit Daten zu füttern und die Ausgaben weiter zu verarbeiten. Zudem können Sie sich vielleicht die ein oder andere Umsetzung dabei auch für eigene Skripte abschauen. Ich habe anders als sonst üblich eine Debug-Ausgabe mit "Write-Host" (Siehe auch Write-Host Debugging) realisiert, da das Skript für eine interaktiven Start ausgelegt ist und daher ich nicht den Einsatz von Start-Transcript vorgesehen habe.
Einsatz
Das Skript erwartet als Eingabe den oder die Computernamen oder IP-Adressen und optional mit einem Doppelpunkt abgetrennt den Port. Alternativ können Sie nur die Computer einspeisen und die Ports als Parameter angeben. Die Ausgabe ist dann wieder ein PSObject, welches sie einfach als Tabelle oder Liste ausgeben, mit "Where" filtern oder mit "Export-CSV" in einer Datei ausgeben lassen können. Sie können das Skript also auf unterschiedlichste Weise mit Daten füllen. Ein Blick in den Source-Code zeigt die möglichen Parameter:
[cmdletbinding()] param ( [parameter(ValueFromPipeline=$True)] [string]$remotehost = "localhost", $portrange=443, $tcptimeout= 1000 # wait up to 1Sec for TCP Connection )
Der Inhalt von "Remotehost" kann also per Pipeline oder manuell übergeben werden. die Portrange ist mit 443 vorbelegt aber kann als Parameter ebenfalls angepasst werden. Hier kann auch ein Array mit mehreren Ports angegeben werden. Den TCP-TimeOut habe ich auf 1 Sekunde reduziert. Das "sollte" speziell im LAN immer reichen und beschleunigt doch das Abscannen vieler Systemen. Bei Bedarf kann der Wert natürlich angepasst werden.
Seit dem 20. Feb 2024 habe ich STARTTLS addiert, damit ich auch Zertifikate von SMTP-Servern abfragen kann.
Aufruf
Hier ein paar Beispiele:
# einfacher Aufruf mit einem Hostname und Port PS C:\Get-TCPCert> .\Get-TCPCert.1.1.ps1 -remotehost www.msxfaq.de -portrange 443 Get-TCPCert: Start ------------- Get-LANCert:Processing www.msxfaq.de Using PortRange Iteration PortRange 443 Init Result Connect to www.msxfaq.de:443 Connected Get TCP-Stream Get SSL-Stream AuthenticateAsClient HandshakeOK Read the certificatedone Parsing Certificate Data CN= CN=www.msxfaq.de Closing Connection Sending Result to Pipeline Computername : www.msxfaq.de Port : 443 Status : OK CN : CN=www.msxfaq.de Subject : CN=www.msxfaq.de NotAfter : 16.08.2017 01:59:59 NotBefore : 15.08.2016 02:00:00 Issuer : CN=Secure Site Starter DV SSL CA - G2, OU=Domain Validated SSL, O="GeoTrust, Inc.", C=US Thumbprint : 0C3E7A947B931618D0F2F087107F5B4E8BAC62B4 SerialNumber : 182CBFE914C03D9B5BB50F0EC51FBD44 SignatureAlgorithmFriendlyName : sha256RSA Done Get-LANCert:End
# Scan eines Subnetz auf WebServer (1..254) | %{"10.1.1.$_"} | .\Get-TCPCert.ps1 -portrange 443
Das sind nur ein paar Beispiele. Sie können natürlich auch z.B. mit "Get-ADComputer" alle Computer in ihrem Active Directory abfragen. Interessanter fände ich dann aber eine Abfrage aller im DNS hinterlegten A und CNAME-Einträge, Sie so auch Systeme ohne Computerkonto, z.B.: virtuelle Rechnernamen finden. das geht seit Windows 2012 auch per Powershell.
Get-DnsServerResourceRecord ` -ZoneName example.com ` | Where-Object {$_.RecordType -eq "A" -or $_.RecordType -eq "CNAME"}
Für ältere Versionen wäre dann eine WMI-Abfrage der Weg die Daten zu erhalten.
Get-WmiObject ` -Class Microsoftdns_atype ` -Namespace "root\microsoftdns" ` | where {$_.ownername.endwith(".msxfaq.de"} ` | foreach {$_.ownername} dc1.msxfaq.de sfb.msxfaq.de
Diese Liste kann man so natürlich auch an das Skript übergeben, wenn Sie Zugriff auf den DNS-Server per WMI haben.
- Get-DnsServerResourceRecord
https://technet.microsoft.com/de-de/library/jj649863.aspx
Ausgabe
Die Ergebnisse von Get-TCPCert landen über die Pipeline per Default auf dem Bildschirm. sie können diese über ein "PIPE"-Symbol natürlich an andere Prozesse weitergeben oder über eine Variablenzuweisung zwischenspeichern. Wer sich mit PowerShell auskennt, sollte keine Probleme damit haben, die folgenden Beispiele zu verstehen:
# Einsammeln der Zertifikate von cas1.excample.com bis cas9.example.com $ergebnis= ( (1..9) | %{"cas$_.example.com"} | .\Get-TCPCert.ps1 -portrange 443 # gefilterte Ausgabe auf alle mit SHA1 $ergebnis | where {$_.status -eq "WarnSHA1"} # gruppierte Ausgabe nach dem Status $ergebnis | group status Count Name Group ----- ---- ----- 2 NoConnection {@{Computername=cas1.example.com; Port=443; S 3 WarnSHA1 {@{Computername=cas4.example.com; Port=443; S 4 OK {@{Computername=cas2.example.com; Port=443; 1 AuthFail {@{Computername=cas9.example.com; Port=443; #Export der Ausgaben in eine CSV-Datei (1..254) | %{"10.1.1.$_"} | .\Get-LANCert.ps1 -portrange 443 | export-csv .\certresult.csv
Genau genommen können Sie die Ausgabe auch noch filtern und mit einem eigenen Skript zum Computerkonto den Administrator ermitteln und per Mail informieren. Die CSV-Datei können sie aber genauso einfach in Excel öffnen.
Download
Das PowerShell-Script ist keine "fertige Lösung", sondern sie müssen über die Parameter und Ausgabeauswertung die gewünschten Ergebnisse erzeugen lassen. Ich hoffe ich habe die meisten Fehler und Sonderfälle abgefangen aber es kann durchaus passieren, dass die Auswertung unvollständig ist. Es ist eine früher Version aber in Anbetracht der Deadline 1.1.2017 (Siehe SHA-256 und Keylänge) wollte ich das Skript nicht länger zurück halten.
get-tcpcert.ps1
Datei nach dem Download mit Erweiterung PS1 speichern und ggfls. mit einem Unlock-File oder Explorer entsperren.
Das Skript kann durchaus noch "verbessert" werden. Es gibt allerdings eine Einschränkung: Das Skript kann nur Zertifikate prüfen, die bei Verbindungen über TCP auch genutzt werden. Es kann z.B. keine "internen" Zertifikate prüfen, die z.B. bei Smartcards, EFS oder auch ADFS eingesetzt werden. Ein "vollständiges" Inventory ihrer jemals ausgestellten Zertifikate können Sie besser bei ihrer internen PKI auslesen. Und die externen "öffentlichen" Zertifikate können Sie im Portal der öffentlichen PKI einsehen oder auf der Rechnung in der Buchhaltung nachschauen.
Alternative: OpenSSL
Wenn Sie statt PowerShell schon OpenSSL auf ihrem Computer haben, können Sie damit natürlich auch eine TLS-Verbindung zu einem Port aufbauen.
# Verbindung zu HTTP over SSL openssl s_client -connect owa.msxfaq.de:443 # Verbindung zu IMAP over SSL openssl s_client -connect imap4.msxfaq.de:993 # Verbindung zu POP3 over SSL openssl s_client -connect pop3.msxfaq.de:995 # Verbindung zu SMTP Port 25 mit StartTLS openssl.exe s_client -connect mail.netatwork.de:25 -starttls smtp # Verbindung zu SMTPS (eher selten genutzt) openssl s_client -connect remote.host:465 # SfB/Lync/OCS Zertifikate openssl.exe s_client -connect sfbserver.sipdomain:5061 # Erweiterte um SNI openssl s_client -showcerts -connect secure.sip.easybell.de:5061 -servername secure.sip.easybell.de
- OpenSSL
- TCP Port 443 (https) Zugriff mit openssl
überprüfen
https://www.thomas-krenn.com/de/wiki/TCP_Port_443_(https)_Zugriff_mit_openssl_überprüfen
Weitere Links
- SHA-256 und Keylänge
- Write-Host Debugging
- PRTG Check ADFS
- OpenSSL
- End2End-TCP
-
TcpClient.BeginConnect-Methode: (IPAddress, Int32, AsyncCallback, Object)
https://msdn.microsoft.com/de-de/library/ms145193.aspx - Reading a Certificate off a remote SSL Server for
Troubleshooting with Powershell!
https://blogs.technet.microsoft.com/parallel_universe_-_ms_tech_blog/2014/06/26/reading-a-certificate-off-a-remote-ssl-server-for-troubleshooting-with-powershell/ - SslStream.AuthenticateAsClient-Methode: (String)
https://msdn.microsoft.com/de-de/library/ms145060(v=vs.110).aspx - Download and deploy Skype for Business certificates using
PowerShell
https://blogs.msdn.microsoft.com/surfacehub/2016/06/07/download-and-deploy-skype-for-business-certificates-using-powershell/
Nettes Sample um das Zertifikat eines Servers herunter zu laden und als CER-Datei zu speichern. - PowerShell: Es konnte kein geschützter SSL/TLS-Kanal
erstellt werden
https://www.frankysweb.de/powershell-es-konnte-kein-geschuetzter-ssltls-kanal-erstellt-werden/
So können Sie die Powershell zwingen, TLS 1.1 oder TLS 1.2 zu verwenden, wenn die Gegenseite kein TLS 1.0 mehr unterstützt. - Reading a Certificate off a remote SSL
Server für Troubleshooting with Powershell!
http://blogs.technet.com/b/parallel_universe_-_ms_tech_blog/archive/2014/06/26/reading-a-certificate-off-a-remote-ssl-server-for-troubleshooting-with-powershell.aspx - Checking SSL and TLS Versions With PowerShell
http://blog.whatsupduck.net/2014/10/checking-ssl-and-tls-versions-with-powershell.html - Test web server SSL/TLS protocol support with PowerShell
https://www.sysadmins.lv/blog-en/test-web-server-ssltls-protocol-support-with-powershell.aspx - How to test SMTP using Opportunistic TLS with Powershell and
grab the public certificate a SMTP server is using
https://gsexdev.blogspot.com/2019/10/how-to-test-opportunistic-tls-over-smtp.html - Show-Certificate.ps1 - Fetches a host's SSL certificate and
displays the cert chain info
https://gist.github.com/ChrisRomp/eee1211e7015f83c1bfed297687d4a54 - X509Certificate.Export Method
https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate.export?view=net-8.0