📜 ⬆️ ⬇️

Who lost the keys: in the wake of SSH



In 2015, there was a big sensation when the same SSH prints were found on different nodes around the world. Further noise did not matter, but the sediment remained. Let's try to figure out what the main danger of such “duplicates” is. Most of the data collected is relevant for 2015.

What is a print


SSH fingerprint is a number that is calculated from the public key, which is stored in the file / etc / ssh in the file with the permission pub. When you first connect to a host, you are prompted to authenticate it. And the validator is the string 56:ca:17:72:0b:d4:3c:fd:5e:23:fb:7b:9e:9a:c8:42 - MD5-sum from the public key.
')
  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)?

If you are connecting to a host for the first time, then it’s natural to see such a message. But if you have already authenticated this node and connected to it before, then it is worth thinking: “Why did the print change happen?”. Did you reinstall the target system or generated a new key? Or maybe you're not connecting to the machine you were going to? ..

How is the imprint


So, SSH imprint is a hash sum. In our case, this is the MD5 sum from the open part of the RSA key.

The open part of the key:

 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 

We decode the AAAAB line AAAAB....A+HUP from base64 and calculate the MD5 sum of the resulting line:

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

We got the original print.

In traffic, the key is transmitted as follows:



Other keys can be used instead of RSA, for example, ECDSA, ED25519. Using the ssh-keyscan utility, we can get the public part of the target server's SSH key.

 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 

We can also see a banner that tells us the server version, the protocol number and the OS version: # 192.168.100.124 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 .

Search for identical prints. Search comparison


Service shodan.io has already collected all the statistics we need. Shodan suggests looking for prints like this:

 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']) 

During the analysis of prints, the service behaved unstably. For a long time there was no possibility of filtering facets in the country. The construction of the form api.count('port:22 country:RU', facets=[('ssh.fingerprint', 20)]) did not work. As a result, we had to do a sample through facets for a specific footprint by top countries api.count('e2:40:24:40:b8:87:4e:41:1f:d4:68:69:67:b2:22:5d', facets=[('country', 20)]) .

Compare output:

 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'} 

AND

 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'} 

A noticeable difference of 14%.

Most likely, it is due to the fact that the service was actively looking for banners and putting them into the database, but the indexation of the database was delayed.

You can also search for prints in the forehead:

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

There is a limit of sampling of 100 records per page, but you can select the results by page:

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

It is interesting to look at the statistics of key distribution by country.

 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 

Compare the values ​​of different years:

Top 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 

Top 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 

As you can see, some prints began to occur less frequently, and some, on the contrary, more often.

Fingerprint Map


Next, display the keys and their statistics. Statistics are collected on the 30 most frequent countries. It contains the name of the country in the format iso alpha2 (2-letter designation) and the proportion of matches in the total number of fingerprints.

 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) 

Yes, 146% percent may be due to the fact that the data in the database is not fully indexed.

For 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
For 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 

You may notice that there are prints that are found only in one country or almost only in one (90%).

For example:

  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% 

Take, for example, Poland:

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

Statistics on banners in which there is an imprint:

 [('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: 4: -––:: 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) ]

Judging by the NetArt trademark, this is most likely nazwa.pl - Polish hosting.
Statistics for the imprint dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0 shown in the original article This is the Dropbear v0.46 SSH server pre-installed key. Very old vulnerable SSH server. The number of devices with this key is still very large.

Statistics for Russia for 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 

findings


As we see, since 2015 the situation has not changed dramatically. Duplicate prints have met before and are now. Some of them began to occur less frequently, some more often. Updated software - and some keys are gone, and some have appeared.

So what are the dangerous "doubles"? Suppose an attacker has compromised a key, and now he knows the private key corresponding to this public key. Vendors of equipment and hosters this key is already known, since they are involved in its release. In this case, you can conduct a MitM attack, for example, ARP Spoofing or DNS Spoofing. The attacker replaces the source server with his own and waits for the connection, while the victim does not receive messages about the untrusted server. Thus, the attacker is able to find out the victim's password.

The potential victims of such an attack are all users of the preinstalled software. For example, ready assemblies, such as Bitnami and TurnKey. It would seem that just changing the password ... but not everything is so simple. Not all change the preset passwords, what to say about the release of new keys?

As we see, hundreds of thousands of users all over the world can suffer from such actions. In this case, in the case of authorization by keys, this will not happen.

Be careful in time to update the software.

Author : Arthur Garipov, Positive Technologies

Source: https://habr.com/ru/post/281445/


All Articles