Autor: v6ak | 18.7.2011 |
Pár SSH klíčů bývá vygenerován nejpozději při instalaci SSH daemona, protože ten bez něj nemůže normálně fungovat. Na Debianu jsem jej měl uložený v /etc/ssh. Pokud tedy nainstaluji základní server (včetně funkčního SSH daemona), udělám jeho obraz a ten budu distribuovat více uživatelům, všichni budou mít stejný serverový pár SSH klíčů, tedy budou mít i stejný soukromý klíč. (Předpokládám, že si nenechají vygenerovat nový.) Připustíme-li, že alespoň jeden z těchto uživatelů by mohl mít zájem o útok na jiného uživatele, dostáváme se do situace, kdy útočník má k dispozici serverový soukromý klíč oběti a tedy není splněna základní podmínka bezpečnosti. Jakmile se oběť pokusí připojit přes SSH, útočník se může úspěšně pokusit o MITM, má-li přístup k síti.
Myslíte si, že situace s distribucí obrazů serverů je jen uměle vykonstruovaná? Evidentně ne. Je to celkem přímočarý způsob, jak na VPS poskytnout uživatelům snadnou a rychlou instalaci serveru. Nedávno jsem se navíc přesvědčil, že jde zřejmě o používaný způsob. Mám svoji VPS u jednoho (zatím nejmenovaného) poskytovatele. A toho jsem prozkoumal.
Děkuji Emkeimu za konzultace při psaní článku.
Článek slouží k popisu problému, aby se z něj mohli čtenáři poučit a problému se vyhnout. Budete-li číst dále, souhlasíte, že jej (mimo případných laboratorních pokusů v mezích zákona) nebudete používat k útoku! Deklaruji, že jakékoli pokusy jsem provedl za účelem zvýšení bezpečnosti apod., nikoli za účelem útoku nebo nabádání k němu.
Možná ne. Napadá mě, že random seed je také citlivá informace. Po určitém čase ale riziko klesá na minimum. Jiná rizika mě nenapadají. (Existovat ale mohou.)
Představa, že útočník zkoumá uživatele VPSky, složitě zjisťuje (nebo odhaduje) jeho připojení na internet a nakonec za ním jede mu zaútočit na WiFi hotspot nebo spojení (o tom jsou jiné články...), aby mohl udělat MITM, zní směšně. Na takový útok by musel dost možná vynaložit celkem velké náklady a nemuselo by se mu to vyplatit.
Ale přesto bych to bral vážně. Nejen z principu. Provést útok zevnitř VPSky by teoreticky mohlo jít celkem účinně. Dost to ale závisí na jejich síti. V mém případě jsem to nezkoumal a to ze dvou důvodů. Kromě nedostatečných zkušeností se sítěmi (to je asi ten menší problém) jsem se bál balancovat na hraně zákona.
Svoji IP adresu prostě znám, to je jasné. Podle této IP adresy jsem určil rozsah 256 IP adres, které jsem následně prozkoumal, protože je zřejmé, že patří pod stejného poskytovatele.
Opatřil jsem si tedy seznam fingerprintů všech IP z tohoto rozsahu. Pro reálné využití to bude zřejmě potřebovat nějaké úpravy, ale myšlenku snad dostatečně popisuje tento (možná trošku neohrabaný) bashovský příkaz:
for i in $(seq 0 255); do (ssh 1.2.3.$i &); done
Je ale potřeba podotknout, že někteří správci sítě nemají takovéto průzkumy rádi, já za to ve škole dostal týdenní ban.
Jinými slovy, pokusíme se připojit ke všem zkoumaným IP adresám na SSH. U těch, na které jsem se ještě nepřipojoval, mi SSH zobrazí i tzv. fingerprint veřejného klíče, abych si jej mohl z nějakého důvěryhodného zdroje ověřit a tím si být jistý, že se skutečně připojuji na požadovaný server. Lze očekávat, že servery se stejným fingerprintem budou používat stejný serverový pár SSH klíčů. V případě VPS lze očekávat i velice snadný přístup k mnohým z těchto klíčů. Teoreticky jsou možná i alternativní vysvětlení, ale dostávám-li delší dobu z více míst ke každému ze tří různých fingerprintů desítky různých serverů a používám-li jeden z těchto klíčů na svém serveru, považuji všechna z nich za krajně nepravděpodobná.
Když už mám seznam různých fingerprintů, pokusil jsem se vygrepovat (etc.) ty opakující se. Vypadá to na cca 147 nalezených serverů s dostupným SSH, přičemž tyto fingerprinty se (podle oka) opakují (v závorkách počty výskytů na scanovaných adresách):
e0:1e:36:4f:c6:50:12:c1:5b:6d:55:5d:bc:b7:62:af (26) 05:2e:85:82:a3:14:69:e6:60:5e:55:fd:0e:98:33:94 (31) 3e:66:b1:b1:1a:1b:5e:d9:74:af:72:03:15:c1:15:e5 (21)
Kompromitovaných serverů ale může být samozřejmě více. Pokud některý z těchto klíčů používáte, měli byste jej neprodleně vyměnit. Ale ještě se pokusím vytvořit řádky do known_hosts pro revokaci těchto zřejmě kompromitovaných klíčů.
Pokud máme některý z kompromitovaných klíčů schválený v ~/.ssh/known_hosts (popř. /etc/ssh/known_hosts), můžeme to odhalit jednoduše. Seznam schválených serverových klíčů a informace o nich (včetně fingerprintů) nám prozradí tento příkaz:
ssh-keygen -lv -f ~/.ssh/known_hosts
Chceme-li hledat podle konkrétního fingerprintu, můžeme zkusit něco jako toto:
ssh-keygen -lv -f ~/.ssh/known_hosts |
grep '05:2e:85:82:a3:14:69:e6:60:5e:55:fd:0e:98:33:94'
Tím dostaneme základní informace o záznamech, které patří pod daný fingerprint:
2048 05:2e:85:82:a3:14:69:e6:60:5e:55:fd:0e:98:33:94 |1|cooosiveefoorrmaaatuuubase64=|cooosiveefoorrmaaatuuubase64= (RSA)
Vypadat to může různě, závisí i na tom, zda si necháváte adresy hashovat nebo je máte uloženy v otevřené podobě. Každopádně díky tomu lze nalézt příslušný řádek (příslušné řádky) v ~/.ssh/known_hosts, který (které) si zaslouží revokaci. Ten totiž mohu najít podle |1|cooosiveefoorrmaaatuuubase64=|cooosiveefoorrmaaatuuubase64=
a může vypadat zhruba takto:
|1|cooosiveefoorrmaaatuuubase64=|cooosiveefoorrmaaatuuubase64= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxHguFIlZRIcXSnkLwvbxBAr+2oFAQOuV5wqIDvhyl+3NFZ/q6F3jxUamqzIw6/kjnXum09aAC+Qqhb9GnLZBT1eE/aKZduNU+TENb86ahoPfBDqY7NnRo2JhKrGyLPOZuxQgUJN6rjtyGcZgLkwJ/OrOr5AYoHfcsWGqvH1ksom10fuEZV2yJ250vb2+DDEtz324nhtyLqw1h0SpmY9R+zY1ty8ZEICV4h5zRgsm5e/wWhPzNlrbFq63/e8AfNVNne5TEyisHlYBft/7tKYGl0+0K80yIy3H+7T2aerJcjM+J2HNxPHvkZiNP1fTAxyxPxcFNFLlGqVdVhhICX0oqQ==
V této podobě jej máme schválený. Ale můžeme tento řádek upravit a klíč považovat za neplatný pro libovolný server:
@revoked * ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxHguFIlZRIcXSnkLwvbxBAr+2oFAQOuV5wqIDvhyl+3NFZ/q6F3jxUamqzIw6/kjnXum09aAC+Qqhb9GnLZBT1eE/aKZduNU+TENb86ahoPfBDqY7NnRo2JhKrGyLPOZuxQgUJN6rjtyGcZgLkwJ/OrOr5AYoHfcsWGqvH1ksom10fuEZV2yJ250vb2+DDEtz324nhtyLqw1h0SpmY9R+zY1ty8ZEICV4h5zRgsm5e/wWhPzNlrbFq63/e8AfNVNne5TEyisHlYBft/7tKYGl0+0K80yIy3H+7T2aerJcjM+J2HNxPHvkZiNP1fTAxyxPxcFNFLlGqVdVhhICX0oqQ==
Jedna z výhod tohoto přístupu oproti smazání je, že nám SSH tento klíč odmítne, i když se pokusíme se připojit na jiný server s tímto klíčem. Jde-li o nějaký hromadně používaný klíč, může to vyvolat ostražitost při pokusu o připojení na cizí server, který klíč nevyměnil. Pokud jsem tedy SSH klíč nevyměnil, dostanu při pokusu o připojení chybovou hlášku (předpokládám, že můj server je 1.2.3.4):
$ ssh franta@1.2.3.4 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REVOKED HOST KEY DETECTED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The RSA host key for 1.2.3.4 is marked as revoked. This could mean that a stolen key is being used to impersonate this host. RSA host key for 1.2.3.4 was revoked and you have requested strict checking. Host key verification failed.
Tu ale dostanu i v případě pokusu o připojení na jakýkoli jiný server s tímto kompromitovaným klíčem.
Takže mi přibyly tyto tři řádky v ~/.ssh/known_hosts (tento web je ořezává, ale zkopírování by nemělo být problém):
@revoked * ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuHSOJktxbp+PW8kYcCDbjTwFdlWgC8EfslECZQbndKm5r6m6JBhoBz6YmsVTisN3CimcTEVp9FOHYbbbOX7bIQF1pG1caXm1BE1STVMwq4Xqbpplt3+JmkUDDUtYIanPfUKakeXbN6zSDw3gaFbxMfTr4Of5ntAMHkXVs0EILS9LuC4kPdCZcyjUaqz6QrYkL7oC2fuRKrOBo6G82JYOyml+W7dRokQ74dNi2BwTER5oKbAVG4jbUdbHpZqNRzZaRrW2FxHo8Byk0iY2dDywPBVmPbUom81aGNdy4ySwk8Vfbkk3qXWLadPFFI6GGbuJ1y0wPK4Y7TJ7eokjyp9bzQ== @revoked * ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxHguFIlZRIcXSnkLwvbxBAr+2oFAQOuV5wqIDvhyl+3NFZ/q6F3jxUamqzIw6/kjnXum09aAC+Qqhb9GnLZBT1eE/aKZduNU+TENb86ahoPfBDqY7NnRo2JhKrGyLPOZuxQgUJN6rjtyGcZgLkwJ/OrOr5AYoHfcsWGqvH1ksom10fuEZV2yJ250vb2+DDEtz324nhtyLqw1h0SpmY9R+zY1ty8ZEICV4h5zRgsm5e/wWhPzNlrbFq63/e8AfNVNne5TEyisHlYBft/7tKYGl0+0K80yIy3H+7T2aerJcjM+J2HNxPHvkZiNP1fTAxyxPxcFNFLlGqVdVhhICX0oqQ== @revoked * ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDaDxa54wzQenGcW+WuQGAO6K17tCz+cnh0n2+Dr8SWOza5NpcW+d8FK118HyGslJx0XXbVPlOcWE1vxErWcXgxgWqSu/c3VXPU0U/62f7P/ldyI9SKKVHQ8S7Zm499BYKkYuKqPdJ8xNY+FxczUQ61X1M9Gk1Uj6S2tTiYDtczgklcmfMTmTpXivgyMVcv5kKhFjAxvpOrwjflkbNEx1HhJJYvW6lI6+9FHBy/qrVcPv7UM42iPuK2xF5i6cOvk1IyKbS4z5gUbDNVGe3JNeNx/tDmO7zJ6roTFQ6rklx8qtIXuiJLkPP/gX+kracZZydmC263RsXxqTPqiSs28GEv
Seznam ale nemusí být kompletní, scanoval jsem jen pár adres.
Snad je tento odstavec nošením dříví do lesa. Je-li serverový klíč kompromitován, je důležité na to uživatele upozornit, abychom snížili pravděpodobnost zneužití. Také bude vhodné informovat o novém fingerprintu nějakou důvěryhodnou nebo aspoň nezávislou cestou.
Je-li klíč neplatný, je vhodné vygenerovat nový pár klíčů, jinak by se uživatelé neměli jak připojit.
1. Přihlásíme se ke svému účtu. Ideální je nějaký nezávislý zabezpečený kanál, kterému můžeme důvěřovat, například VNC. Dost zde závisí na tom, co máme od poskytovatele k dispozici. V nejhorším případě můžeme použít ono SSH (dočasně vyhodit revokaci) a doufat, že toho nebude zneužito. Pořád je lepší riskovat jednou než riskovat neustále.
2. Jdeme do adresáře /etc/ssh/:
cd /etc/ssh/
3. Odstraníme stávající klíče z /etc/ssh/. (Pozor, připojujeme-li se přes SSH, můžeme si takto odstřihnout cestu.) Já smazal i soubor moduli. Podle stručných popisů významu tohoto souboru to asi není nutné, ale jistota je jistota...
rm moduli # pro jistotu - nejsem si jist, zda je to nutné rm ssh_host_* # určitě # prostě radši jsem smazal vše, co vypadá vygenerovaně, jen konfiguráky jsem ponechal
4. Vygenerujeme soubor moduli znovu, pokud jsme jej odstranili:
ssh-keygen -G moduli.candidates # trvalo asi 5 minut ssh-keygen -T moduli -f moduli.candidates # toto mi trvalo přes čtvrt hodiny
5. Vygenerujeme nové SSH klíče:
ssh-keygen -t rsa -f ssh_host_rsa_key # chvilka
6. Zjistíme fingerprint nového klíče:
ssh-keygen -lf ssh_host_rsa_key.pub
7. Zkusíme se přihlásit na server z SSH a ověříme fingerprint.
8. A ještě jednou připomínám distribuci nového fingerprintu mezi uživatele...