Jak zweryfikować odcisk palca SSL za pomocą wiersza polecenia? (wget, curl,…)

32

Korzystanie z wiersza poleceń internetowej downloader, takie jak wget, curllub dowolny inny jeden ... W skrypcie ...

Posiadam odciski palców SHA-1 i SHA-256. Ze względów bezpieczeństwa ( 1 ) ( 2 ) nie chcę korzystać z publicznego systemu urzędu certyfikacji SSL. Odcisk palca musi być zakodowany na stałe.

Czy aplikacja typu wget może sprawdzić odcisk palca SSL?

wget nie ma takiej funkcjonalności. ( 3 )

Używając wget --ca-certificatelub curl --cacertmusiałbym uruchomić własny lokalny urząd certyfikacji, czemu chciałbym zapobiec, ponieważ powoduje to dużą złożoność. Jest to również bardzo trudne i nikt wcześniej tego nie robił. ( 4 )

Czy nie ma takiego narzędzia
download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com?

Rozwiązanie nie może oczywiście być wrażliwe na TOCTOU. ( 5 ) MITM może pozwolić zwrócić prawidłowy odcisk palca dla żądania klienta openssl i manipulować następującą prośbą wget.

James Mitch
źródło
Prawdopodobnie potrzebuję trochę magii OpenSSL, takiej jak: cyberciti.biz/faq/…
Justin Andrusk
Odwiedzający: zauważcie, że zostało to zamieszczone w infosec SE . Jedna z odpowiedzi została skopiowana stamtąd. To jest marne zachowanie, btw.
Félix Saparelli

Odpowiedzi:

31

Źródło

Zainstaluj wymagane oprogramowanie:

apt-get install ca-certificates curl

Pobierz publiczny certyfikat SSL:

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

Albo lepiej:

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

Uzyskaj odcisk palca SHA-1:

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

Uzyskaj odcisk palca SHA-256:

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

Ręcznie porównaj odciski palców SHA-1 i SHA-256 z torproject.org FAQ: SSL .

.

Opcjonalnie możesz uczynić certyfikaty ca bezużytecznymi do celów testowych. Korzystanie pozwijane tutaj, ale wget ma błąd Bug i wykorzystuje CA-plików w każdym razie.

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

Pobierz za pomocą curl i przypiętego certyfikatu:

curl --cacert ./torproject.pem https://check.torproject.org/ > check.html
James Mitch
źródło
nie działa to jednak w obecności pełnomocnika: - /
Frederick Nord
Pamiętaj, że opcja -CAfile jest całkowicie ignorowana w twoim przykładzie.
Lars,
11

W tcsh:

echo | openssl s_client -connect host.example.com:443 |& openssl x509 -fingerprint -noout
użytkownik273818
źródło
3
działa w zsh, powinien też działać na bash
numer 5
10

To też wystarczy:

openssl x509 -fingerprint -in server.crt
rundekugel
źródło
Dodaj -md5opcję pobierania odcisku palca MD5. -md5nie wolno umieszczać pomiędzy -ini server.crt.
林果 皞
4

Jest to dość łatwe do wykonania dzięki opensslpoleceniu i jego funkcjom klienta.

Poniższy mały skrypt pobierze daną domenę (bez prefiksu https) i odcisk palca SHA-1 i zakończy działanie bez błędu (0), jeśli pobrany odcisk palca pasuje, ale z kodem wyjścia 1, jeśli nie ma dopasowania. Następnie możesz włączyć go do skryptu, po prostu testując ostatni kod wyjścia $?:

#! / bin / bash
FPRINT = `echo -n | openssl s_client -connect $ 1: 443 2> / dev / null \ | openssl x509 -noout -fingerprint | cut -f2 -d '=' ' if [„$ 2” = „$ FPRINT”]; następnie wyjście 0 jeszcze wyjście 1 fi
ish
źródło
Jest podatny na atak TOCTOU. [1] MITM może pozwolić zwrócić prawidłowy odcisk palca dla żądania klienta openssl i manipulować następującą prośbą wget. [1] en.wikipedia.org/wiki/Time_of_check_to_time_of_use
James Mitch
To prawda, w teorii. Byłoby dość łatwo go zmodyfikować wgeti skompilować za pomocą OpenSSL, aby działał on tak, jak chcesz, ale to jest poza zakresem odpowiedzi AU.
ish
A co powiesz na użycie s_client do odzyskania dokumentu? Coś jak (echo -ne "Host: ${HOST}\n\rGET ${URL}\n\r" && yes) 2>/dev/null | openssl s_client -connect ${HOST}:443powinno działać, nie? Cóż, musisz oddzielić informacje o sesji SSL od rzeczywistej odpowiedzi na treść.
taneli
3

źródło

#!/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;
}

Jak opisano w dokumentacji Net :: SSLeay, ta metoda oznacza weryfikację po transakcji HTTP i dlatego nie należy jej używać, jeśli chcesz sprawdzić, czy rozmawiasz z właściwym serwerem przed wysłaniem im danych. Ale jeśli wszystko, co robisz, to decydujesz, czy zaufać temu, co właśnie pobrałeś (co brzmi jak z referencji nr 4), nie ma sprawy.

James Mitch
źródło
1

To mój codzienny skrypt:

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

Ouput:

* 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
źródło