Скучно о работе дешифрации NGFW
Если вы хотите окончательно испортить первое свидание — поговорите с девушкой о дешифрации. Да и в случае последующих — тоже не стОит.
Наша встреча с вами не первая, поэтому в этом тексте речь снова пойдет о дешифрации.
Да, я вновь расскажу об SSL. Могу обрадовать себя и вас тем, что это второй и последний материал на эту тему. Возможно.
В прошлый раз мы выяснили, зачем может понадобиться дешифровать многострадальный SSL.
В этом материале разберём, как именно работает дешифрация с подменой сертификата.
Что нам для этого нужно?
Для начала вспомним, как работает SSL. Я кратко опишу основные моменты.
После установления TCP-сессии между клиентом и сервером происходит SSL Handshake. В его рамках обе стороны обмениваются сообщениями Client Hello и Server Hello.
Дамп установления SSL-соединения с vk.com
Client Hello описывает поддерживаемые параметры шифрования, Server Hello содержит выбранные из предложенных клиентом параметры. Обмен Client Hello и Server Hello можно использовать как индикатор установления SSL-сессии. При появлении этих сообщений устройство (vFTD в нашем случае) просматривает сконфигурированные политики дешифрации для принятия решения — нужно ли в дальнейшем дешифровать сессию или нет.
Если настроенные политики диктуют дешифровать трафик, устройство становится man-in-the-middle (MITM) и дешифрует передаваемые данные. При удачном запуске MITM мы имеем две установленные SSL-сессии.
Первая — между клиентом и дешифрующим устройством (vFTD). Вторая — между дешифрующим устройством и сервером. Зашифрованные данные приходят от клиента на vFTD. Расшифровываются. Проверяются всевозможными политиками (доступа, IPS, файловыми, AMP и т.д.). Если дешифрованные данные от клиента проходят проверку, они снова шифруются и отправляются серверу. Если не проходят какую-либо проверку, данные либо просто блокируются (не отправляются в сторону сервера), либо сбрасывается сессия. Ответы от сервера обрабатываются аналогично.
Чтобы устройство стало MITM в SSL-сессии, требуется немногое.
На этапе SSL handshake помимо аутентификации и прочих действий происходит формирование общего сеансового ключа. Именно с его помощью будут зашифрованы передаваемые данные. Для этого будет использован симметричный алгоритм.
Есть два наиболее распространённых в Интернете способа формирования общего сеансового ключа по открытым каналам связи: RSA и ECDH (Диффи-Хеллман). Процесс формирования сеансовых ключей показан на диаграммах ниже (взяты из материала «Анализ SSL/TLS трафика в Wireshark»):
Формирования сеансового ключа при использовании RSA
В случае RSA клиент генерирует предварительный секрет (pre-master secret). Шифрует его открытым ключом из сертификата сервера и передаёт его. Расшифровать предварительный секрет можно только с помощью закрытого ключа, который известен исключительно серверу.
Теперь у обеих сторон есть предварительный секрет. Они формируют главный секрет и далее общий сеансовый ключ.
Формирование сеансового ключа при использовании ECDH
В случае с ECDH пара ключей SSL-сертификата не используется для шифрования вообще. Клиент и сервер формируют пары случайных ключей Диффи-Хеллман — открытый и закрытый. Каждая сторона передаёт свой открытый ключ другой стороне в незашифрованном виде.
Далее, с помощью алгоритма Диффи-Хеллмана клиент и сервер вычисляют из собственного секретного ключа и чужого открытого, общий предварительный секрет. После этого каждая сторона формирует общий главный секрет и сеансовый ключ.
При использовании ECDH необходимо сохранить целостность передаваемых открытых ключей Диффи-Хеллман. Сервер подписывает собственный открытый ключ Диффи-Хеллман с помощью своего закрытого ключа сертификата. Клиент может проверить подлинность полученного открытого ключа Диффи-Хеллман, используя открытый ключ сертификата сервера.
Таким образом, чтобы организовать MITM для SSL-сессии в большинстве случаев будет достаточно подменить сертификат сервера на собственный. Если подмена пройдёт успешно, можно будет получить общий с клиентом сеансовый ключ и иметь возможность дешифровать данные.
В случае с RSA, MITM-устройство сможет расшифровать предварительный секрет с помощью собственного закрытого ключа сертификата. Если используется ECDH, устройство сможет подписать свой открытый ключ Диффи-Хеллман таким образом, чтобы на стороне клиента подпись считалась валидной.
Чтобы подменить сертификат сервера на собственный (для которого мы будем знать закрытый ключ), нам необходимо, чтобы собственный сертификат обеспечивал корректную аутентификацию сервера на стороне клиента. Проще говоря — нужно, чтобы браузер клиента не выдал никаких предупреждений или блокировок при подмене сертификата. Для этого в большинстве случаев необходимо, чтобы:
- Поле subject сертификата содержало параметр Common Name со значением, равным тому, что введено в адресной строке браузера;
- Сертификат был подписан доверенным центром сертификации.
Обратная сторона — если wildcard-сертификат будет каким-либо образом скомпрометирован, пострадают сразу все сервисы. Ведь на всех серверах будет установлен одинаковый закрытый ключ.
Безусловно, чтобы сертификат считался валидным на стороне клиента, должны выполняться и другие условия: он не должен быть отозван, просрочен и т.д. Но все эти условия учитываются на этапе подписи сертификата собственным центром сертификации.
Chrome ругается на SHA-1
Подробности
Чтобы избежать таких предупреждений центр сертификации должен использовать строгие алгоритмы формирования ХЭШ для подписи сертификатов — семейство SHA-2.
При использовании Certificate pinning, сертификат сервиса должен быть подписан строго определённым центром сертификации. Если это не так, доступ на ресурс блокируется даже в том случае, если сертификат подписан доверенным центром.
Соответственно, для ресурсов с certificate pinning дешифрация с подменой сертификата работать не будет.
Таким образом, чтобы организовать MITM в SSL-сессии, устройство должно сгенерировать новый сертификат с такими же полями, как сертификат удалённого сервера. При этом у нас будет известный закрытый ключ. Новый сертификат необходимо подписать с помощью доверенного центра сертификации.
На практике это реализуется следующим образом:
В компании должен существовать собственный центр сертификации, корневой сертификат которого помещён в доверенные на всех устройствах компании. Это необходимое условие.
На центре сертификации запрашивается новый сертификат по шаблону «подчинённый центр сертификации» (Subordinate certificate authority, далее SubCA). Особенность данного сертификата в том, что с помощью его закрытого ключа можно подписывать другие сертификаты (выставлен флаг CA в расширении «основные ограничения сертификата»).
Так как SubCA подписан доверенным корневым сертификатом, клиентские машины будут доверять как ему самому, так и любому сертификату, подписанному с его помощью. SubCA и соответствующий ему закрытый ключ устанавливается на устройство, которое должно стать MITM в SSL-сессии. Благодаря этому при каждой попытке клиента установить SSL-сессию с HTTPS-сервером наше устройство сможет:
- Перехватывать сертификат сервера;
- Создавать закрытый ключ;
- Генерировать новый сертификат с такими же полями, как у подменяемого;
- Подписывать созданный сертификат с помощью SubCA.
Если всё корректно настроить, пользовательский браузер не будет выдавать никаких предупреждений при открытии https-страниц. Пользователь сможет определить факт подмены сертификата, только если полезет в настройки.
Цепочка сертификатов в Mozilla
Если посмотреть поля конечного сертификата, увидим, что поле субъект содержит корректное значение Common Name.
Поле Common Name
Если сравнить реальный и подменённый сертификаты, увидим, что фактически они отличаются значениями открытых ключей и цифровыми подписями (в данном случае я пренебрегаю серийным номером, и т.п.).
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1482311739306634470 (0x14923aac5bc36ce6)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=RU, ST=Moscow, O=CBS, OU=Computers, CN=proxy.cbs.com.ru/emailAddress=uskov@cbs.ru
Validity
Not Before: Sep 4 21:17:41 2015 GMT
Not After : Sep 16 11:56:55 2018 GMT
Subject: OU=Domain Control Validated, CN=*.vk.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:a1:09:76:bf:21:ce:9b:e7:e2:34:03:f0:74:02:
84:13:7f:2e:51:0b:e8:4a:11:e2:34:d8:3a:d9:39:
5b:ea:87:50:33:dc:64:5b:2e:f2:0d:33:36:47:3c:
0a:97:a7:ce:23:7d:d7:8f:76:85:17:42:f9:63:b6:
d1:91:ea:18:de:98:3c:e1:c5:5b:59:4a:d0:e5:e2:
b7:ce:e0:75:74:93:d9:35:b4:8b:85:70:4c:8e:c9:
e0:53:7c:2f:9f:4b:e1:48:f0:3f:a5:70:f7:4e:99:
f1:74:0b:2a:21:6a:9d:9f:20:f4:e5:fa:94:89:43:
61:82:0b:c1:98:7a:e3:7c:4e:cf:8b:6c:ad:6b:ce:
1b:0f:4d:e3:db:d4:47:5c:e8:77:aa:71:ea:62:8f:
17:c9:3b:a3:e2:29:ce:62:e2:31:71:a8:83:2a:41:
d9:6b:a7:b8:75:d0:07:fc:10:f1:6e:69:84:4b:b1:
11:f8:ae:20:94:44:0d:b0:7b:0f:d2:bd:b3:1d:1c:
7c:ae:f8:cf:37:e2:aa:4a:d2:de:24:60:50:06:f9:
c6:65:f0:9c:63:4f:53:eb:db:59:a4:93:14:b2:6f:
aa:b3:fb:50:ae:6e:e4:b9:3f:fa:69:b3:43:32:3f:
7a:4b:57:41:2d:7e:c8:41:00:f8:68:6a:43:53:83:
5c:c3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
DNS:*.vk.com, DNS:vk.com
X509v3 Subject Key Identifier:
18:91:5E:8A:5A:58:5D:AB:86:73:6D:C0:06:57:C2:6C:62:4E:5C:64
Signature Algorithm: sha256WithRSAEncryption
8d:bc:a8:ce:af:5d:39:fc:6a:ac:48:39:9a:7e:32:01:27:68:
de:95:5c:4b:24:3a:51:5d:d2:90:e4:22:c1:55:5e:65:ea:4f:
59:2c:76:b0:48:53:d8:6e:c6:e3:2a:cb:26:e6:40:e3:9a:36:
4c:6b:29:52:1c:b5:83:c6:10:8e:cb:f8:6d:a9:ae:d7:71:1b:
92:69:99:c0:1e:de:2f:02:82:17:d6:1d:52:35:65:f7:ca:a7:
9c:fe:e6:1f:3b:a4:36:c2:4a:4e:e2:f2:7d:66:e1:c4:ea:e9:
ca:d0:a9:76:fc:84:f1:55:e7:d8:04:45:04:9a:15:0d:23:c9:
e1:0a:b0:9e:cb:3b:c0:86:d3:e4:23:3e:c5:8a:13:20:96:ac:
6d:d8:79:ea:b9:83:b9:a7:fe:79:67:41:3d:7d:1f:22:eb:20:
b9:6c:06:34:cb:fb:17:a7:b3:fc:5a:2c:a2:4f:86:0a:80:53:
ea:f2:71:4a:36:80:a3:fb:2e:42:76:c6:f8:68:6c:78:f0:5c:
5d:cd:c4:0a:05:29:a3:c5:a7:87:c4:87:af:5c:29:54:a1:8e:
94:2f:72:89:54:c4:76:cb:0b:87:f9:29:a1:18:4e:55:97:e2:
1f:86:2e:97:ca:15:40:6e:d4:29:25:eb:1c:5a:2e:b9:3d:e6:
bb:5e:4d:18
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 7817290772096849405 (0x6c7c988a18c595fd)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
Validity
Not Before: Sep 4 21:17:41 2015 GMT
Not After : Sep 16 11:56:55 2018 GMT
Subject: OU=Domain Control Validated, CN=*.vk.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:db:c0:ab:97:82:f1:70:06:3f:d9:9d:79:85:a8:
7c:11:d2:17:c5:9a:61:b1:72:06:d7:5e:21:7f:3d:
3b:c2:cd:dd:f4:d8:62:8a:7b:23:b7:cb:08:70:db:
bf:e8:85:f7:23:92:09:56:1c:bc:e4:f8:cd:81:01:
82:43:8d:37:b9:f1:6a:14:ac:68:fa:a4:ef:fd:5b:
99:ad:f1:df:04:00:1a:e2:8a:7e:80:6a:27:b3:60:
71:27:8d:dd:37:d2:df:2d:22:fe:f3:cb:cf:68:62:
65:d4:ff:88:47:6a:78:4d:bf:8f:8f:0d:06:47:3a:
b0:84:f0:a4:ea:9e:69:59:97:e5:03:a9:36:0e:93:
e6:2e:4e:d6:2a:bd:ea:bc:64:b8:9c:7d:a3:5e:c4:
ce:1c:74:82:4d:95:bc:00:a0:01:3e:d1:3f:2a:18:
7c:49:7c:af:6a:41:61:4b:99:1d:af:95:f4:77:c6:
e0:4e:60:aa:96:63:ee:68:96:63:33:fc:81:41:e5:
2c:15:0f:1d:39:f8:00:ac:05:13:f2:80:dd:96:00:
2d:42:4b:d5:c9:f7:26:08:67:68:f8:15:e4:25:43:
cd:e1:09:4c:5c:ab:15:23:d8:30:f1:89:b7:83:92:
fd:15:ad:b6:5b:e4:5c:b2:fa:7d:d1:b2:00:43:39:
d9:a3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.godaddy.com/gdig2s1-118.crl
X509v3 Certificate Policies:
Policy: 2.16.840.1.114413.1.7.23.1
CPS: http://certificates.godaddy.com/repository/
Authority Information Access:
OCSP - URI:http://ocsp.godaddy.com/
CA Issuers - URI:http://certificates.godaddy.com/repository/gdig2.crt
X509v3 Authority Key Identifier:
keyid:40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
X509v3 Subject Alternative Name:
DNS:*.vk.com, DNS:vk.com
X509v3 Subject Key Identifier:
18:91:5E:8A:5A:58:5D:AB:86:73:6D:C0:06:57:C2:6C:62:4E:5C:64
Signature Algorithm: sha256WithRSAEncryption
80:61:fc:da:a9:f2:ea:f3:4a:70:4e:8a:39:3e:eb:9b:77:c2:
c9:5d:da:30:20:7a:31:8f:19:f8:2f:b5:1b:4a:87:74:fb:99:
59:78:0f:45:1b:9d:9d:76:29:5f:48:90:08:a5:f8:c8:2e:9f:
55:ea:54:33:c1:a1:a3:7e:7f:8c:32:c5:a8:0f:9b:04:c7:d1:
55:30:7e:09:87:03:7e:88:82:32:0a:cb:0c:66:f0:50:85:b2:
e4:43:67:38:88:50:84:54:41:4b:bc:3e:b0:47:8f:71:46:e4:
9a:cf:f1:a4:39:a9:4b:ca:63:44:c3:34:7d:7b:ca:de:6c:91:
5b:15:09:06:b3:4c:56:6d:23:03:1b:dc:c5:d1:e5:a3:9f:d2:
4d:be:d2:ff:62:4a:75:f7:4f:29:a4:7d:35:cf:33:06:83:6a:
50:f6:25:ce:a7:59:ac:05:fe:74:7b:c7:89:06:f5:a8:2e:4e:
d4:34:a1:e1:68:7b:66:8b:53:a8:41:ba:a7:50:72:49:94:e6:
4a:ad:2d:26:95:a3:5d:ce:e3:8b:d9:6c:d2:1e:31:4b:28:ab:
e2:33:c5:5e:3f:82:dd:e1:e8:36:a2:b5:08:d8:b3:2e:23:b4:
9b:b4:e6:4a:ab:21:2d:6b:aa:5f:fd:56:31:dc:86:32:85:04:
01:5a:b9:64
Последнее, что хотел отметить, vFTD для генерации любого подменённого сертификата использует одну и ту же пару ключей. Что собственно и логично: зачем тратить ресурсы и без того нагруженного шифрацией/дешифрацией устройства на генерацию новых пар ключей. Если открыть страничку ya.ru и просмотреть полученный сертификат, увидим, что открытый ключ будет таким же, как у подменённого сертификата для vk.com.
Подмененный и реальный сертификат
На этом описание механизма дешифрации SSL на NGFW завершаю. Приветствую всех бодрствующих, мы наконец сделали это! Это было мучительно, но зато вы теперь знаете об SSL чуточку больше. Стоило это того или нет — это уже на ваше усмотрение.
P.S.: И да, передаю поздравление от коллег (и присоединяюсь): всех с наступающим Новым Годом!
Пусть в новом году у вас будет меньше багов, костылей и танцев с бубном!
P.P. S.: Для тех, кому интересно, как эта кухня настраивается на FirePOWER — вэлкам в подкат.
openssl rand -out ./private/.rand 1024
openssl genrsa -out ./private/cakey.pem -aes256 -rand ./private/.rand 2048
openssl req -new -key ./private/cakey.pem -out subcareq.pem -config openssl.cnf -sha256
После того, как получаем подписанный сертификат, устанавливаем его на FMC. Переходим на вкладку Objects → Object Management → PKI → Internal CAs и жмем Import CA:
Будет предложено загрузить сертификат и его закрытый ключ. Их мы получили ранее с помощью openssl и корпоративного CA. Задаем имя для новой CA и вводим пароль закрытого ключа (при необходимости):
Всё готово к созданию политики дешифрации. Идём в Policies → SSL:
Нажимаем «New Policy», задаём имя политики, default action и, пишем свой Opus Magnum в описании:
Политики дешифрации в привычных табличках. Их поля описывают шаблон трафика, подлежащего дешифрации:
Нажимаем Add Rule и описываем шаблон трафика. В простейшем случае можно сделать правило без указания каких-либо параметров. В этом случае любой SSL-трафик будет дешифрован. В качестве действия выбираем «Decrypt — Resign». В поле после слова «with» выбираем загруженный на предыдущих шагах сертификат. Это и есть тот самый SubCA, которым мы будем подписывать подменённый сертификат.
Как видите на скриншоте, FMC даёт широчайшие возможности по описанию шаблона трафика для дешифрации. Трафик можно выбирать по пользователям, типу приложений, категории URL, по параметрам сертификата сервера (DN, Cert Status, Cipher Suite, Version) и т.д.
Например, скриншот вкладки Cert Status:
После настройки всех необходимых правил, нажимаем Save. Политика дешифрации готова. Но для того, чтобы она начала работать, её необходимо привязать к политике доступа. Идём в Policies → Access Control:
Выбираем интересующую нас политику доступа и нажимаем на карандаш. В раскрывшейся вкладке нам нужно выбрать созданную на предыдущем шаге политику дешифрации:
Нажимаем Save. Не забываем выполнить deploy изменений на управляемое устройство (vFTD в моём случае):