В 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
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
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
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
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
Комментарии (9)
amarao
12.04.2016 17:08+10Во-первых, нельзя «подменить ключ». Воплей будет очень много. Можно только «прикинуться новым сервером».
Во-вторых, компрометация произойдёт только в случае использования парольной авторизации. При том, что все давно на ssh-ключах.
В третьих — да, свинство и непорядок. Обычно возникает из-за халтуры админов хостингов, которые не хотят в image'е инициализировать ключи для каждого нового инстанса.
M_Muzafarov
13.04.2016 16:57Может я придираюсь, но интересно посмотреть статистику по таким коллизиям не в свете md5, а прямо по самим ключам. Изменится ли картина?
И второе — неплохо бы научиться различать два сервера с одним ключом и один сервер с двумя адресами (который слушает ssh на всех них) — в этом случае всё так же страшно или всё же паника в исследовании преувеличена.
P.S. У меня Shodan ключа нет, поэтому только идеи подкидываю.
Zapped
возможно, зависит от настроек, но по умолчанию SSH не подключается к узлам с изменившимся ключом, а сообщает об этом и предлагает всё проверить и предварительно удалить запись из файла
known_hosts
Dreyk
да, можно настроить, чтоб не пускало. но для людей, которые даже пароли не меняют в готовых билдах-сборках, сменить настройки ссш — это из ряда фантастики
Zapped
не-не, Вы меня не поняли
SSH по-умолчанию не пускает на узлы с изменившимся ключом (в контексте Вашего «если вы уже аутентифицировали этот узел и подключались к нему прежде»)
поэтому (при повторном подключении) процитированного сообщения уже не будет, будет другое:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The ECDSA host key for HOST has changed,
and the key for the corresponding IP address IPADDR
is unchanged. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
Offending key for IP in /home/USER/.ssh/known_hosts:63
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:jYIS2egEyMoVveHLlR0......
Please contact your system administrator.
Add correct host key in /home/USER/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/USER/.ssh/known_hosts:48
ECDSA host key for HOST has changed and you have requested strict checking.
Host key verification failed.
Zolg
«SSH по-умолчанию» это вы о каком клиенте?
На OpenSSH свет клином не сошелся. Тот же Putty, подозреваю, используется не менее часто.
Да и ssh_config в разных дистрибутивах никто не обязывает быть одинаковым, строго говоря.
Zapped
давайте будем последовательны
как раз OpenSSH, насколько я могу судить (+ судя по цитатам, из Ubuntu, в которой по умолчанию стоит OpenSSH)Вы в статье цитируете сообщение
а что касается Putty/Kitty: тот также «кричит» о потенциальной угрозе
что же до ssh_config, то строго говоря, Вы, конечно, правы: «ничто не обязывает»,
Но покажите мне дистрибутив, в котором
StrictHostKeyChecking=no
к тому же Вы сами сказали:
Zolg
Проблема, описываемая в статье не связана с конкретным SSH-клиентом. Какой-то из них должен был быть приведен для примера.
естественно кричит, но вместо correct host key in /home/USER/.ssh/known_hosts предлагает просто нажать кнопку «пофиг, пляшем». Знание человеческой натуры подсказывает, что большая часть пользователей нажмет ее до того, как обдумает текст предупреждения.
Zapped
опс, простите ))) что-то я забылся ))))