Як перевірити відбиток SSL за командним рядком? (wget, curl,…)


32

Використання веб - сайту завантажувач командного рядка, наприклад wget, curlабо будь-який інший ... В сценарії ...

У мене SHA-1 і SHA-256 сертифікат відбитків веб-сайту. Через проблеми ( 1 ) ( 2 ) я не хочу використовувати публічну систему авторизованих сертифікатів SSL. Відбиток пальця повинен бути чітко закодований.

Чи може такий додаток, як програма, перевірити відбиток SSL?

wget не має такого функціоналу. ( 3 )

Використовуючи wget --ca-certificateабо curl --cacertмені доведеться запустити свій власний локальний сертифікат, який я хотів би запобігти, оскільки це додає великої складності. Це також ультра важко, і ніхто раніше цього не робив. ( 4 )

Немає такого інструменту, як
download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com?

Звичайно, рішення не повинно бути вразливим до TOCTOU. ( 5 ) MITM може дозволити повернути дійсний відбиток пальця для запиту клієнта openssl та підробити наступний запит wget.


Ймовірно, потрібно зробити якусь магію OpenSSL, наприклад: cyberciti.biz/faq/…
Джастін Андруск

Відвідувачі: зауважте, що це було перекладено в Інфосек SE . Один із самих відповідей був скопійований звідти. Це нахмурена поведінка, btw.
Фелікс Сапареллі

Відповіді:


31

Джерело

Встановіть потрібне програмне забезпечення:

apt-get install ca-certificates curl

Завантажте загальнодоступний сертифікат SSL:

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

Або краще:

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:

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

Отримайте відбиток пальця SHA-256:

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

Порівняйте відбитки пальців SHA-1 та SHA-256 вручну з torproject.org FAQ: SSL .

.

Необов'язково роблять ca-сертифікати марними для тестування. Використання локона тут, але Wget є помилка Помилка і в будь-якому випадку використовує CA-файли.

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

Завантажте за допомогою curl та закріпленого сертифіката:

curl --cacert ./torproject.pem https://check.torproject.org/ > check.html

це не працює в присутності проксі-сервера: - /
Фредерік Норд

Зауважте, що параметр -CAfile у вашому прикладі повністю ігнорується.
Ларс


10

Цього також достатньо:

openssl x509 -fingerprint -in server.crt

Додати -md5опцію для отримання відбитків MD5. -md5не повинні ставити між -inі server.crt.
林果 皞

4

Це досить легко зробити з opensslкомандою та її функціональністю клієнта.

Наступний маленький сценарій займе заданий домен (без префікса https) і відбиток SHA-1 і вийде без помилок (0), якщо отриманий відбиток пальця збігається, але з вихідним кодом 1, якщо не відповідає. Потім ви можете включити його у свій сценарій, просто випробувавши останній код виходу $?:

#! / бін / баш
FPRINT = `відлуння -n | openssl s_client-підключити $ 1: 443 2> / dev / null \ | openssl x509 -noout -printprint | вирізати -f2 -d '=' ` if ["$ 2" = "$ FPRINT"]; потім вихід 0 ще вихід 1 фі

Він вразливий до TOCTOU. [1] MITM може дозволити повернути дійсний відбиток пальця для запиту клієнта openssl та підробити наступний запит wget. [1] en.wikipedia.org/wiki/Time_of_check_to_time_of_use
Джеймс Мітч

Щоправда, теоретично. Було б досить легко змінити wgetі компілювати його з OpenSSL, щоб він виконував те, що потрібно вбудовано, але це виходить за рамки відповіді на АС.
Останній

Отже, як щодо використання s_client для отримання документа? Щось подібне (echo -ne "Host: ${HOST}\n\rGET ${URL}\n\r" && yes) 2>/dev/null | openssl s_client -connect ${HOST}:443повинно працювати, ні? Ну, ви повинні розділити інформацію про сеанс SSL від фактичної відповіді на вміст.
taneli

3

джерело

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

Як зазначено в документації Net :: SSLeay, цей метод означає перевірку після транзакції HTTP, і тому його не слід використовувати, якщо ви хочете перевірити, чи говорите ви з правильним сервером, перш ніж надсилати їм дані. Але якщо все, що ви робите, - це вирішити, чи довіряти тому, що ви тільки що завантажили (це звучить так, як ви з довідки №4), це добре.


1

Ось мій щоденний сценарій:

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

Вихід:

* 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.