По следам SSH

от автора

В 2015 году поднялась большая шумиха, когда по всему миру на различных узлах были обнаружены одинаковые SSH-отпечатки. Далее шума дело не пошло, но осадок остался. Попробуем разобраться, в чем основная опасность таких «дублей». Большая часть собранных данных актуальна для 2015 года.

Что такое отпечаток

SSH-отпечаток — это число, которое вычисляется от открытого ключа, который хранится по пути /etc/ssh в файле с разрешением pub. Когда вы впервые подключаетесь к узлу, вам предлагается его аутентифицировать. И в качестве валидатора выступает строка вида 56:ca:17:72:0b:d4:3c:fd:5e:23:fb:7b:9e:9a:c8:42 — MD5-сумма от открытого ключа.

The authenticity of host '192.168.100.124 (192.168.100.124)' can't be established. RSA key fingerprint is 56:ca:17:72:0b:d4:3c:fd:5e:23:fb:7b:9e:9a:c8:42. Are you sure you want to continue connecting (yes/no)? 

Если вы впервые подключаетесь к узлу, то увидеть такое сообщение естественно. Но если вы уже аутентифицировали этот узел и подключались к нему прежде, то стоит задуматься: «Почему произошло изменение отпечатка?». Возможно, вы переустанавливали целевую систему или сгенерировали новый ключ? А может, вы подключаетесь совсем не к той машине, к которой собирались?..

Как считается отпечаток

Итак, SSH-отпечаток — это хеш-сумма. В нашем случае это MD5-сумма от открытой части RSA-ключа.

Открытая часть ключа:

root@ubuntu:/etc/ssh# cat /etc/ssh/ssh_host_rsa_key.pub   ssh-rsa   AAAAB3NzaC1yc2EAAAADAQABAAABAQCrID5HFOZiQlq6DDUCsLOG5xJFOMbxtqPTtgL0BfEyRVQ1AGD9kwSWnAU7bm/uFmfkfG5ff/8S02PKaQo26sYIWi8/NyOGMyLNnCLpMJkJ+CT12qrqpD+3Q749DpVzBBbCUaYiDNg7RbKxbbnSZUe9k69P4FE0itS4MQDFAnD0XY78aQuxNpIQUexTIP0b4QuIaShV0c6FXmpHHqr85uZ9t1cTdLtl3Kphv3yu6Z+bkGBd+c80pdV+islTUGa+YJse0rvi/qP8AU67KNXscAc4UDe1yaMG5Y3eUshvt3OTCXliYQKw3NIw/KzXbbY6s/sB49LAvDOal4FK6ZAA+HUP root@ubuntu 

Декодируем строку AAAAB....A+HUP из base64 и подсчитаем MD5-сумму получившейся строки:

root@ubuntu:/etc/ssh# awk '{print $2}' ssh_host_rsa_key.pub | base64 -d | md5sum 56ca17720bd43cfd5e23fb7b9e9ac842  

Мы получили исходный отпечаток.

В трафике ключ передается так:

Вместо RSA могут использоваться и другие ключи, например ECDSA, ED25519. При помощи утилиты ssh-keyscan мы можем получить открытую часть ключа SSH сервера целевой машины.

root@ubuntu:/etc/ssh# ssh-keyscan -t ED25519 192.168.100.124 # 192.168.100.124 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 192.168.100.124 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF8GXOsOnWBf1NY6Px6upViTXX0ZOw9txOEjwxMORafZ 

root@ubuntu:/etc/ssh# ssh-keyscan -t RSA 192.168.100.124 # 192.168.100.124 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 192.168.100.124 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrID5HFOZiQlq6DDUCsLOG5xJFOMbxtqPTtgL0BfEyRVQ1AGD9kwSWnAU7bm/uFmfkfG5ff/8S02PKaQo26sYIWi8/NyOGMyLNnCLpMJkJ+CT12qrqpD+3Q749DpVzBBbCUaYiDNg7RbKxbbnSZUe9k69P4FE0itS4MQDFAnD0XY78aQuxNpIQUexTIP0b4QuIaShV0c6FXmpHHqr85uZ9t1cTdLtl3Kphv3yu6Z+bkGBd+c80pdV+islTUGa+YJse0rvi/qP8AU67KNXscAc4UDe1yaMG5Y3eUshvt3OTCXliYQKw3NIw/KzXbbY6s/sB49LAvDOal4FK6ZAA+HUP 

Также мы можем видеть баннер, который сообщает нам версию сервера, номер протокола и версию ОС: # 192.168.100.124 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6.

Поиск одинаковых отпечатков. Сравнение поисков

Сервис shodan.io уже собрал всю необходимую нам статистику. Shodan предлагает искать отпечатки так:

import shodan api = shodan.Shodan(YOUR_API_KEY) # Get the top 1,000 duplicated SSH fingerprints results = api.count('port:22', facets=[('ssh.fingerprint', 1000)]) for facet in results['facets']['ssh.fingerprint']: print '%s --> %s' % (facet['value'], facet['count']) 

Во время анализа отпечатков сервис вел себя нестабильно. Долгое время отсутствовала возможность фильтрации фасетов по стране. Не работала конструкция вида api.count('port:22 country:RU', facets=[('ssh.fingerprint', 20)]). Как следствие, приходилось делать выборку через facets для конкретного отпечатка по топ-странам api.count('e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d', facets=[('country', 20)]).

Сравните результаты вывода:

fa = api.count('e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d', facets=[('country', 20)]) for i in range(len(fa['facets']['country'])): 	if fa['facets']['country'][i]['value']=='RU': print fa['facets']['country'][i] {u'count': 60433, u'value': u'RU'} 

И

api.count('port:22 country:RU', facets=[('ssh.fingerprint', 10)])['facets']['ssh.fingerprint'][0] {u'count': 52929, u'value': u'e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d'} 

Заметная разница в 14%.

Скорее всего, она обусловлено тем, что сервис активно искал баннеры и заносил их в базу, но индексация базы происходила с задержкой.

Также можно искать отпечатки в лоб:

results = api.search('e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d') results['total'] 

Есть ограничение выборки в 100 записей на страницу, но можно выбирать результаты по страницам:

api.search('e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d', page=2) 

Интересно посмотреть на статистику распределения ключей по странам.

fp30 = {} for i in api.count('port:22', facets=[('ssh.fingerprint', 30)])['facets']['ssh.fingerprint']: 	fp={} 	fp['count'] = i['count'] 	fp['country']= api.count(i['value'], facets=[('country', 100)])['facets']['country'] 	fp30[i['value']]=fp print fp30 

Сравним значения разных годов:

Топ-10 — 2015:

dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0, 321014  32:f9:38:a2:39:d0:c5:f5:ba:bd:b7:75:2b:00:f6:ab, 245499  d0:db:8a:cb:74:c8:37:e4:9e:71:fc:7a:eb:d6:40:81, 161471  34:47:0f:e9:1a:c2:eb:56:eb:cc:58:59:3a:02:80:b6, 149775  df:17:d6:57:7a:37:00:7a:87:5e:4e:ed:2f:a3:d5:dd, 105345  81:96:a6:8c:3a:75:f3:be:84:5e:cc:99:a7:ab:3e:d9, 97778  7c:a8:25:21:13:a2:eb:00:a6:c1:76:ca:6b:48:6e:bf, 93686  c2:77:c8:c5:72:17:e2:5b:4f:a2:4e:e3:04:0c:35:c9, 88393  1c:1e:29:43:d2:0c:c1:75:40:05:30:03:d4:02:d7:9b, 87218 03:56:e6:52:ee:d2:da:f0:73:b5:df:3d:09:08:54:b7, 64379

Топ-2016:

e7:86:c7:22:b3:08:af:c7:11:fb:a5:ff:9a:ae:38:e4, 343048 34:47:0f:e9:1a:c2:eb:56:eb:cc:58:59:3a:02:80:b6, 138495 dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0, 109869 32:f9:38:a2:39:d0:c5:f5:ba:bd:b7:75:2b:00:f6:ab, 46451 62:5e:b9:fd:3a:70:eb:37:99:e9:12:e3:d9:3f:4e:6c, 41578 d0:db:8a:cb:74:c8:37:e4:9e:71:fc:7a:eb:d6:40:81, 39126 7c:a8:25:21:13:a2:eb:00:a6:c1:76:ca:6b:48:6e:bf, 38816 8b:75:88:08:41:78:11:5b:49:68:11:42:64:12:6d:49, 34203 1c:1e:29:43:d2:0c:c1:75:40:05:30:03:d4:02:d7:9b, 32621 03:56:e6:52:ee:d2:da:f0:73:b5:df:3d:09:08:54:b7, 29249 c2:77:c8:c5:72:17:e2:5b:4f:a2:4e:e3:04:0c:35:c9, 28736 59:af:97:23:de:61:51:5a:43:16:c3:6c:47:5c:11:ee, 25110 7c:3e:bc:b9:4b:0d:29:91:ed:bd:6e:4c:6b:60:49:14, 22367

Как видим, некоторые отпечатки стали встречаться реже, а какие-то, наоборот, чаще.

Карта отпечатков

Далее выведем на экран ключи и их статистику. Статистику собираем по 30 самым частым странам. Она содержит название страны в формате iso alpha2 (2-буквенное обозначение) и долю совпадений в общем числе нахождений отпечатка.

for i in fp30: 	print i, fp30[i]['count'] 	sum = fp30[i]['count'] 	for j in fp30[i]['country']: 		if 100*j['count']/sum > 0: print '%s: %s' % (j['value'], 100.0*j['count']/sum) 

Да, 146% процентов может получиться из-за того, что данные в базе неполностью индексированы.

За 2015 год:

dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0 332493 ES: 90.0605953479 TW: 3.56833133558 US: 2.1252561631 http://chartsbin.com/view/32232 

32:f9:38:a2:39:d0:c5:f5:ba:bd:b7:75:2b:00:f6:ab 254856 CN: 54.5263608791 TW: 41.3041225361 DO: 1.22736474116 US: 1.18763860965 

d0:db:8a:cb:74:c8:37:e4:9e:71:fc:7a:eb:d6:40:81 162800 US: 54.9035226422 JP: 45.0382223913 

34:47:0f:e9:1a:c2:eb:56:eb:cc:58:59:3a:02:80:b6 151027 DE: 69.7611572028 US: 27.9946735249 ES: 1.41647682396 

df:17:d6:57:7a:37:00:7a:87:5e:4e:ed:2f:a3:d5:dd 108057 CN: 99.7404030473 http://chartsbin.com/view/32227 

81:96:a6:8c:3a:75:f3:be:84:5e:cc:99:a7:ab:3e:d9 101156 TW: 100.0 

8b:75:88:08:41:78:11:5b:49:68:11:42:64:12:6d:49 75760 PL: 100.0 http://chartsbin.com/view/32225 

57:94:42:63:a1:91:0b:58:a6:33:cb:db:fe:b5:83:38 39167 IN: 38.2145131455 AU: 9.01840676835 US: 8.73335961428 TR: 6.34381538648 AE: 4.14531340025 ZA: 3.3538526852 SA: 3.15977802711 MX: 3.0384813658 GB: 2.80498529278 FR: 2.56542438669 IR: 2.5199381387 IT: 2.3440579798 TH: 2.32889589714 DE: 2.31676623101 BR: 2.19243715317 MY: 1.98623282894 NG: 1.47678685144 KE: 1.46465718531 TW: 1.14625344937 http://chartsbin.com/view/32196 

За 2016 год:

e7:86:c7:22:b3:08:af:c7:11:fb:a5:ff:9a:ae:38:e4 343048 US: 99.9988339824 

34:47:0f:e9:1a:c2:eb:56:eb:cc:58:59:3a:02:80:b6 138495 DE: 54.827972129 US: 42.5546048594 GB: 1.33795443879 ES: 1.27946857287 

dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0 109869 ES: 88.2241578607 TW: 4.07485277922 US: 3.3376111551 DK: 1.1104133104 VC: 1.0594435191 

32:f9:38:a2:39:d0:c5:f5:ba:bd:b7:75:2b:00:f6:ab 46451 CN: 49.5188478181 TW: 44.5932272717 DO: 1.59738218768 US: 1.22494671805 

62:5e:b9:fd:3a:70:eb:37:99:e9:12:e3:d9:3f:4e:6c 41578 US: 84.3907835875 SG: 9.02881331473 NL: 6.58521333397 

Можно заметить, что есть отпечатки, которые встречаются только в одной стране или почти только в одной (90%).

Например:

81:96:a6:8c:3a:75:f3:be:84:5e:cc:99:a7:ab:3e:d9 TW: 100.0% 8b:75:88:08:41:78:11:5b:49:68:11:42:64:12:6d:49 PL: 100.0% df:17:d6:57:7a:37:00:7a:87:5e:4e:ed:2f:a3:d5:dd CN: 99.7404030473% 59:af:97:23:de:61:51:5a:43:16:c3:6c:47:5c:11:ee US: 99.9953928728% c2:52:47:0f:8b:82:b9:3c:74:ee:64:b5:35:f4:c5:c3 MY: 99.7626425793%

Возьмем, например, Польшу:

8b:75:88:08:41:78:11:5b:49:68:11:42:64:12:6d:49 PL: 100.0%

Статистика по баннерам, в которых присутствует отпечаток:

 [('SSH-2.0-OpenSSH_5.9p1 Debian-8netart1\r\n', 37188), ('SSH-2.0-OpenSSH_6.2p2 Ubuntu-7netart1\r\n', 10390), ('SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-15netart2\nKey type: ssh-rsa\nKey: AAAAB3NzaC1yc2EAAAADAQABAAABAQCnt2+LOdS1Gy/47UXMfHDYQERQQR5M4/CYsfT7IE3FYQ/m\nwJO6rLKLcUo+q4U+0iIH6uBSXG5HNa4569rg2eWH5lUiJHEL1pPIA9wKKZ+MpMoE9nkr1xaXxVK5\nqO1gUfaYCo+VYre2CJDe3HIJlUht3PITdxmQTwnL/tJHHBkR8xrgEpjF+9FjFKwdE7ZCNObqvhK0\nPio/318DyUiRK/JaIqggL0K9KzoGytq7uKSkECFMYCDTqPmdDerCEiT+C5Lxy6ZOdp4yTyxjOM7E\nsr0C/ePzPvT8rCLayz3GzBnEwZ4QKlOxbZHl/48LxtWlY/vROkiLTuU3kcpFqvo0Uc/3\nFingerprint: 8b:75:88:08:41:78:11:5b:49:68:11:42:64:12:6d:49', 3421), ('SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-15netart2\nKey type: ssh-rsa\nKey: AAAAB3NzaC1yc2EAAAADAQABAAABAQCnt2+L', 3421), ('SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-15netart2\r\n', 2)] 

Судя по торговой марке NetArt, это, скорее всего, nazwa.pl — польский хостинг.
Статистика для отпечатка dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0 показана в исходной статье. Это предустановленный ключ SSH-сервера Dropbear v0.46. Очень старый уязвимый SSH-сервер. Количество устройств с этим ключом до сих пор очень велико.

Статистика по России за 2015 год:

e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d 50107 {'Dropbear sshd_0.46': 50107}  ------------------------------------- OJSC Rostelecom 49794 OJSC Rostelecom, Vladimir branch 160 OJSC RTComm.RU 46 OJSC Bashinformsvyaz 32 CJSC ER-Telecom Holding 11  1c:1e:29:43:d2:0c:c1:75:40:05:30:03:d4:02:d7:9b 26286 {'Dropbear sshd_0.52': 26286}  ------------------------------------- OJSC Rostelecom 19596 OJSC Bashinformsvyaz 1025 MTS OJSC 1024 CJSC Teleset-Service 645 VimpelCom 340  2d:7b:35:e5:33:66:d5:ee:0d:58:19:cb:ae:e7:90:ea 24036 {'Dropbear sshd_0.53.1': 23413, 'Dropbear sshd_0.28': 623} ------------------------------------- National Cable Networks 14860 OJSC Rostelecom 8179 VimpelCom 214 Net By Net Holding LLC 101 CJSC ER-Telecom Holding 94  f5:50:8d:ca:f7:5a:07:41:08:81:65:2e:b3:a4:d6:48 14065 {'Dropbear sshd_2011.54': 14065} ------------------------------------- Net By Net Holding LLC 13923 OJSC Central telegraph 73 Optilink Ltd 29 Web Plus ZAO 23 Iskratelecom CJSC 10 

Выводы

Как видим, с 2015 года ситуация кардинально не поменялась. Повторяющиеся отпечатки встречались раньше и встречаются сейчас. Какие-то из них стали встречаться реже, какие-то чаще. Обновилось ПО — и некоторые ключи пропали, а некоторые появились.

Так чем опасны «дубли»? Допустим, злоумышленник скомпрометировал ключ, и теперь он знает соответствующий данному открытому ключу закрытый ключ. Вендорам оборудования и хостерам этот ключ уже известен, так как они причастны к его выпуску. В этом случае можно провести MitM-атаку, например ARP Spoofingили DNS Spoofing. Злоумышленник подменяет исходный сервер своим и ждет соединения, при этом жертва не получает сообщения о недоверенном сервере. Таким образом злоумышленник в состоянии узнать пароль жертвы.

Потенциальные жертвы подобной атаки — все пользователи предустановленного ПО. Например, готовых сборок, таких как Bitnami и TurnKey. Казалось бы, достаточно просто сменить пароль… но не все так просто. Не все меняют предустановленные пароли, что же говорить о выпуске новых ключей?

Как мы видим, от подобных действий могут пострадать сотни тысяч пользователей по всему миру. При этом в случае авторизации по ключам этого не произойдет.

Будьте внимательны, вовремя обновляйте ПО.

Автор: Артур Гарипов, Positive Technologies

ссылка на оригинал статьи https://habrahabr.ru/post/281445/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *