Wie überprüfe ich den SSL-Fingerabdruck über die Befehlszeile? (wget, curl,…)

32

Verwenden einer Befehlszeile Website Downloader, wie wget, curloder jede andere ... In einem Skript ...

Ich habe den SHA-1 und den SHA-256 zertifizierten Fingerabdruck einer Website. Aus Sicherheitsgründen ( 1 ) ( 2 ) möchte ich das öffentliche SSL-Zertifizierungsstellensystem nicht verwenden. Der Fingerabdruck muss fest codiert sein.

Kann eine Anwendung wie wget den SSL-Fingerabdruck überprüfen?

wget hat keine solche Funktionalität. ( 3 )

Mit wget --ca-certificateoder curl --cacertmüsste ich meine eigene lokale Zertifizierungsstelle betreiben, was ich verhindern möchte, da dies eine Menge Komplexität mit sich bringt. Es ist auch extrem schwierig und das hat noch niemand gemacht. ( 4 )

Gibt es kein Werkzeug
download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com?

Die Lösung darf natürlich nicht anfällig für TOCTOU sein. ( 5 ) Das MITM kann einen gültigen Fingerabdruck für die Anforderung des openssl-Clients zurückgeben lassen und die folgende wget-Anforderung manipulieren.

James Mitch
quelle
Möglicherweise
Justin Andrusk
Besucher: Bitte beachten Sie, dass dies an die infosec SE weitergeleitet wurde . Eine der Selbstantworten wurde von dort kopiert. Das ist übrigens verpöntes Verhalten.
Félix Saparelli

Antworten:

31

Quelle

Installieren Sie die erforderliche Software:

apt-get install ca-certificates curl

Laden Sie das öffentliche SSL-Zertifikat herunter:

openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt >./x.cert </dev/null

Oder besser:

echo -n | openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./torproject.pem

SHA-1-Fingerabdruck abrufen:

openssl x509 -noout -in torproject.pem -fingerprint -sha1

SHA-256-Fingerabdruck abrufen:

openssl x509 -noout -in torproject.pem -fingerprint -sha256

Vergleichen Sie die Fingerabdrücke von SHA-1 und SHA-256 manuell mit den häufig gestellten Fragen zu torproject.org: SSL .

.

Optional können die CA-Zertifikate für Testzwecke unbrauchbar gemacht werden. Verwenden Sie hier curl , aber wget hat einen Bug Bug und verwendet trotzdem die ca-Dateien.

sudo mv /usr/share/ca-certificates /usr/share/ca-certificates_

Download mit Wellung und angeheftetem Zertifikat:

curl --cacert ./torproject.pem https://check.torproject.org/ > check.html
James Mitch
quelle
Dies funktioniert jedoch nicht in Gegenwart eines Proxys: - /
Frederick Nord
Bitte beachten Sie, dass die Option -CAfile in Ihrem Beispiel vollständig ignoriert wird.
Lars
11

In tcsh:

echo | openssl s_client -connect host.example.com:443 |& openssl x509 -fingerprint -noout
user273818
quelle
3
Funktioniert in zsh, sollte auch für Bash
funktionieren
10

Das reicht auch:

openssl x509 -fingerprint -in server.crt
rundekugel
quelle
In -md5Option MD5 - Fingerabdruck abrufen. -md5darf nicht zwischen -inund gesetzt werden server.crt.
30.
4

Dies ist mit dem opensslBefehl und seiner Client-Funktionalität relativ einfach zu bewerkstelligen.

Das folgende kleine Skript verwendet eine bestimmte Domäne (kein https-Präfix) und einen SHA-1-Fingerabdruck und beendet das Programm ohne Fehler (0), wenn der abgerufene Fingerabdruck übereinstimmt, aber mit dem Beendigungscode 1, wenn keine Übereinstimmung vorliegt. Sie können es dann in Ihr Skript integrieren, indem Sie einfach den letzten Beendigungscode testen $?:

#! / bin / bash
FPRINT = `echo -n | openssl s_client -connect $ 1: 443 2> / dev / null \ | openssl x509 -noout -fingerprint | cut -f2 -d '=' ` if ["$ 2" = "$ FPRINT"]; dann Ausfahrt 0 sonst Ausfahrt 1 fi
ish
quelle
Es ist anfällig für TOCTOU. [1] Das MITM kann einen gültigen Fingerabdruck für die openssl-Clientanforderung zurückgeben und die folgende wget-Anforderung manipulieren. [1] en.wikipedia.org/wiki/Time_of_check_to_time_of_use
James Mitch
In der Theorie wahr. Es wäre ziemlich einfach wget, es mit OpenSSL zu modifizieren und zu kompilieren, damit es das leistet, was Sie inline wollen, aber das würde den Rahmen einer AU-Antwort sprengen.
ish
Wie wäre es also mit s_client, um auch das Dokument abzurufen? Sowas (echo -ne "Host: ${HOST}\n\rGET ${URL}\n\r" && yes) 2>/dev/null | openssl s_client -connect ${HOST}:443sollte doch funktionieren, oder? Nun, Sie müssen die SSL-Sitzungsinformationen von der eigentlichen Inhaltsantwort trennen.
Taneli
3

Quelle

#!/usr/bin/perl
# https://security.stackexchange.com/questions/20399/how-to-verify-the-ssl-fingerprint-by-command-line-wget-curl
# Code snippets taken from Net::SSLeay documentation and mildly modified.
# Requires a newer version of SSLeay (tested with 1.48)
# Needless to say, verify correct $host and $fingerprint before testing!!!

use Net::SSLeay qw(get_https3);

$host = "www.google.com";
$port = 443;
$fingerprint = "C1:95:6D:C8:A7:DF:B2:A5:A5:69:34:DA:09:77:8E:3A:11:02:33:58";

($p, $resp, $hdrs, $server_cert) = get_https3($host, $port, '/');
if (!defined($server_cert) || ($server_cert == 0)) {
    warn "Subject Name: undefined, Issuer  Name: undefined";
} elsif (Net::SSLeay::X509_get_fingerprint($server_cert, "sha1") ne $fingerprint) {
    warn 'Invalid certificate fingerprint '
        .  Net::SSLeay::X509_get_fingerprint($server_cert, "sha1")
        . ' for ' . Net::SSLeay::X509_NAME_oneline(
             Net::SSLeay::X509_get_subject_name($server_cert));
} else {
    print $p;
}

Wie in der Net :: SSLeay-Dokumentation beschrieben, bedeutet diese Methode eine Überprüfung nach der HTTP-Transaktion und sollte daher nicht verwendet werden, wenn Sie überprüfen möchten, ob Sie mit dem richtigen Server sprechen, bevor Sie Daten senden. Aber wenn Sie nur entscheiden, ob Sie dem, was Sie gerade heruntergeladen haben, vertrauen wollen oder nicht (was so klingt, als wären Sie aus Ihrer Referenz 4), ist dies in Ordnung.

James Mitch
quelle
1

Das ist mein alltägliches Drehbuch:

curl --insecure -v https://www.google.com 2>&1 | awk 'BEGIN { cert=0 } /^\* Server certificate:/ { cert=1 } /^\*/ { if (cert) print }'

Ausgang:

* Server certificate:
*    subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
*    start date: 2016-01-07 11:34:33 GMT
*    expire date: 2016-04-06 00:00:00 GMT
*    issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*    SSL certificate verify ok.
* Server GFE/2.0 is not blacklisted
* Connection #0 to host www.google.com left intact
Antonio Feitosa
quelle