Trochu podrobností, TL;DR SSH klient má buffer, kam ukládá data, která se mají odeslat, ale kvůli výpadku spojení se to nepovedlo. Problém je, že velikost bufferu i množství dat, která se mají odeslat, určuje server. Můžeme si tedy naalokovat velký buffer, skoro nic do něj nezapsat, a pak ho celý přečíst. Uvidíme, co bylo v paměti předtím (když se uvolnila).
Dobré je, že SSH klient při pokusu o útok vypisuje "[connection suspended, press return to resume][connection resumed]". Pokud tedy SSH používáte interaktivně, měli byste si toho všimnout.
Tak co, kdo z vás tu hlášku viděl? :-)
No - to je zase vec.
1) Server musi byt "zlovolny" nebo kompromitovany.
2) Co se zlovolneho serveru tyka, snad si vsichni kontroluji fingerprinty pri prvnim prihlaseni (a mame known_hosts).
3) Co se tyka kompromitovaneho serveru, zde je uz jedno, ze je mozne kompromitovat privatni klic, protoze utocnik server ovlada na urovni roota (samozrejme je to jedno pouze pokud nejsem hovado a nepouzivam jeden klic pro vice serveru).
Z toho mi vychazi, ze utok neni zase tak sileny.
Nemusíte se přihlašovat jen k serveru, kde máte roota. Třeba takový Git se běžně používá přes SSH. Zato uživatel běžně má jeden privátní klíč, kterým se přihlašuje k více serverům. Takže nějaký nevinný server, kam se přihlašujete uživatelským účtem, který tam nemá skoro žádná práva, od vás může získat privátní klíč, a pak se s ním přihlásí tam, kde opravdu máte roota.
„Klíče jsou asymetrické, takže je jedno, jestli máte jen jeden klíč všude nebo jich máte víc.“ – Mimo kontext tohoto bezpečnostního problému možná, ale v tomto kontextu toto tvrzení nedává smysl.
„SSH ve výchozí konfiguraci čte všechny klíče, tedy v paměti, odkud je ten útok krade, budou stejně.“ – Pokud vím, tak se různé klíče používají právě různou konfigurací pro různé cíle.
1. Já myslím, že moc dobře vím, jak funguje asymetrická kryptografie, a sám to tu v jiném příspěvku píšu. A při tomto útoku to zjevně jedno nebylo.
2. Mám pocit, že nešlo mít víc než 8 klíčů najednou (server měl limit kolik se jich dá vyzkoušet a pak spojení uřízl), takže pokud má předřečník opravdu na každý stroj jiný klíč, je velmi pravděpodobné, že to, který klíč se má použít, určuje optionou/konfigurákem ssh klienta.
ad 2)
Tohle se nastavuje v MaxAuthTries a výchozí hodnota je skutečně nízká. Obzvláště, pokud jsou také zapnuté další formy autentizace (gssapi apod., což v defaultu většinou jsou), tak se pár pokusů vyplýtvá, takže stačí víc klíčů v agentu a už je problém se připojit.
Osobně nastavuji větší počet pokusů (rozumně) a současně povoluji pouze metodu publickey (žádné passwordy, keyboard interactive ani SSO nechci).
Já používám jeden klíč maximálně na několik spolu souvisejících serverů. (A pravděpodobnost jejich napadení je navíc typicky poněkud korelovaná.) Ale dělám to jinak. V Qubesu si na každou aktivitu založím speciální virtuální stroj, abych od sebe jednotlivé aktivity izoloval. To, že pak používám různé klíče na různé servery (nebo malé skupiny serverů), je pak jen logickým důsledkem (ani ne primárním cílem).
Založit a následně spravovat (aktualizovat) VM je v Qubesu celkem jednoduché. Když aktualizuju šablonu, aktualizují se z ní odvozené virtuální stroje.
Tuto argumentaci jsem nepochopil - je obracene, nez jsem psal. Nehovorim o tom, ze se nekam hlasite na roota, ale ze pokud nekdo ovlada vas sshd, pak ma nejspise roota. Tudiz ziskani vaseho privatniho klice mu jiz v nicem nepomuze - samozrejme za predpokladu, ze privatni klic neni sdileny mezi servery. BTW - prime prihlasovani na roota (byt s klicem) je vhodne mit zakazano vsude.
Tudiz ziskani vaseho privatniho klice mu jiz v nicem nepomuze - samozrejme za predpokladu, ze privatni klic neni sdileny mezi servery.
Což je právě princip té chyby. Že záškodnický server může od klienta získat klíč. Takže když se hlásím na víc serverů (samozřejmě stejným klíčem, proto se klíče používají), a jeden z nich z klienta vymámí privátní klíč, může se majitel toho serveru mým jménem přihlásit na ty ostatní servery.
BTW - prime prihlasovani na roota (byt s klicem) je vhodne mit zakazano vsude.
Ne, ve spoustě případů je to zbytečné nebo dokonce kontraproduktivní.
To uz se tocite v kruhu - jak upozornoval Jenda - tak nepovazuji za rozumne pouzivat jeden klic pro vic serveru. A asymetricka kryptografie tu rozhodne neni proto, abyste sdilel klice pro vice serveru (nerikam, ze je to vzdy a za kazde okolnosti spatne).
K one kontraproduktivite se radeji nebudu vyjadrovat.
Není. Pokud někdo poskytne svůj privátní klíč kdejaké aplikaci, je chyba v tom poskytnutí privátního klíče. A řešením není používat spoustu klíčů, ale poskytnout privátní klíč jediné důvěryhodné aplikaci – v tomto případě SSH agentu. Stejný případ byl Heartbleed, a dokonce ani to nestačilo, aby SSL servery začaly držet privátní klíče v odděleném procesu s minimem funkcionality. V případě SSH je to pro uživatele mnohem jednodušší, SSH agent dávno existuje, stačí ho začít používat.
Na jednu stranu je pravda, že nemá smysl ad hoc vymýšlet opatření podle již opravených zranitelností ve stylu „Je dobře používat X, protože tím předcházím/zmírňuju zneužití nedávno objevené zranitelnosti Y.“.
Na druhou stranu ale myslím, že SSH agent může mít smysl: Když útočník získá read-only přístup k paměti procesu SSH, nedostane se ke klíči. To může IMHO nastat i v budoucnu.
(Šlo by to dovést ještě dál a mít klíč v jiném virtuálním stroji. Tím se omezí zneužitelnost útoků jako directory traversal a může se snížit praktický dopad kompletního ownu stroje. U Qubesu se o tom již diskutovalo a není to nic až tak nepředstavitelného – něco podobného je implementováno pro GPG.)
Omylem zapnutý agent forwarding – teoreticky ano, ale IMHO to není až tak pravděpodobné. Agent forwarding je sama o sobě riskantní věc (vhodná leda při specifickém threat modelu atd.). Naproti tomu problém s nevhodným čtením paměti se může objevit ledaskde.
Rozhodně tě nepovažuji za to boží zvířátko, ani nikoho z tvého okolí, ale popravdě...mám k většině serverú jeden klíč. Už jen proto, že často nejsem jediný root, protože se jedná o servery zákazníků.
Jen pro úplnost, klíče jsem generoval já a adminům ve firmách je dal já a skoro donutil je používat namísto nesmyslných hesel.
Asi je to věcí názoru ... jeden klíč, více serverů, nebo co server to klíč.
SSH podporuje víc veřejných klíčů pro přilašování ;-)
Klíč by měl identifikovat iniciátora, tedy každý admin by měl mít svůj klíč (přesněji: každý počítač každého admina), a servery by měly mít seznam veřejných klíčů, kterým dovolí přihlášení. Jak důležité to je, poznáte ve chvíli, kdy jeden z adminů ztratí notebook a tedy klíč kompromituje.
Treba ja - i kdyz ne tak doslova - ale po grupach serveru.
Navic neukladam privatni klice do defaultniho souboru a na defaultni misto. Sice se mi smejou, ze jsem paranoidni, ale dava mi to smysl. :) Bohuzel to ma i jiste nevyhody (konkretne v tom, ze nektere programy pouzivaji ssh jako transportni vrstvu a neumoznuji zadat cestu k privatnimu klici).
Samozřejmě jsem měl na mysli kompromitovaný server, který se od tebe snaží získat klíč.
On se někdo jen tak zbůhdarma připojuje svým klientem se svými drahocennými klíči na kdejaký náhodný server? Jasně, dá se namítnout útok přesměrováním na jiný cíl, ale i tak mi to přijde značně nepraktické.
Spíš mě zajímá:
Můžeme si tedy naalokovat velký buffer, skoro nic do něj nezapsat, a pak ho celý přečíst. Uvidíme, co bylo v paměti předtím (když se uvolnila).
Pokud program alokuje paměť, tu nevymaže a její obsah (včetně té části, kam nic nezapsal) klidně pošle přes sít, tak v tomto vidím mnohem větší problém, který patrně bude na více místech toho programu.
Musím si přečíst ty prodrobnosti na Qualysu.
No toto je moc hezké:
3. An OpenSSH growing-buffer that holds a private key is eventually
freed by buffer_free() (old API) or sshbuf_free() (new API), and both
functions attempt to cleanse the buffer with memset() or bzero() before
they call free(). Unfortunately, an optimizing compiler may remove this
memset() or bzero() call, because the buffer is written to, but never
again read from (an optimization known as Dead Store Elimination).
Podle tohoto:
http://www.openssh.com/txt/release-7.1p2
Vypnuli tu fci. Z kódu se v tomto patchi neodstraňuje, jen se nevolá.
> On se někdo jen tak zbůhdarma připojuje svým klientem se svými drahocennými klíči na kdejaký náhodný server?
Github-like služby, kdovíjaké stroje ve škole, kde už se vystřídalo několik adminů (dělají to studenti vždycky poslední 1-2 roky studia), stroje v brmlabu, kde má roota (a fyzický přístup) každý člen, server, který někdo vyownoval, a já se tam snažím dostat a zjistit, co se stalo, server u klienta, o jehož historii nic nevím, VPSka u vyhackovaného providera (e.g. OVH nebo Linode) a ještě k tomu s Tor exitem atd. (příklady z praxe) Ano, toto všechno považuju za v jistém smyslu za nedůvěryhodné stroje.
Pochybil jsem, že nemám pro každý stroj zvláštní klíč? Prostě mě nenapadlo, že takováto chyba je možná - celým smyslem asymetrické kryptografie bylo, že svých několik málo veřejných klíčů dám úplně všude a pak se přihlašuju a nemusím řešit mapování sta klíčů na sto strojů.
A nevím… Můžu teď dát na každý stroj zvláštní klíč, a pak někdo přijde s jinou chybou (jako třeba je ta druhá ve Qualys reportu), a zase mi někdo bude vyčítat, že jsem měl mít pro každý stroj zvláštního uživatele, chrootjail nebo tak něco. A nebo že si mám koupit deset fyzicky oddělených počítačů.
Asi má smysl mít několik klíčů, zvláštní pro tak nějak „logickou instituci“, stroje, které nějak patří k sobě. Ale zvláštní na každý stroj, to by mě asi měli za magora.
> Pokud program alokuje paměť, tu nevymaže a její obsah (včetně té části, kam nic nezapsal) klidně pošle přes sít
Vždyť o tom je ten bug.
> tak v tomto vidím mnohem větší problém
Ano, jeden ze zmíněných problémů je, že dělají bzero() a pak hned free(), což GCC vyoptimalizuje („proč dělat bzero paměti, kterou uvolňuju“), a doporučují dělat explicit_bzero().
Pak tam je ještě jeden problém, a to, že to zůstává v bufferu standardní knihovny (fopen, fread), což nevadí u klíče chráněného heslem, protože útočník dostane šifrovanou kopii (pokud se mu stejným způsobem nepodaří vyčíst z paměti i to heslo, že jo).
Github-like služby, kdovíjaké stroje ve škole...
Uff. Neškodilo by dodržovat nějaké zásady hygieny. SSH považuju za oboustranně důvěryhodné spojení mezi serverem a klientem. Klient se vždy připojuje na jasně definovanou skupinu serverů, které si ověřuje (alespoň tedy u mě, server, který není v .ssh/config jako by neexistoval). Péro taky nestrkáš do každé díry...
Pokud mě nějaký zákazník požádá o připojení na podezřelý vyownovaný server, tak rozhodně nevytáhnu pracovního klienta a nezačnu se tam připojovat (pokud se tam tedy vůbec chci připojit). Chyba nechyba. Prostě si udělám virtuálku, nebo další účet nebo něco. Stejně se to bude hodit pro další podezřelé akce na daném serveru (typu: analyzujte podezřelý skript apod.).
Asi má smysl mít několik klíčů, zvláštní pro tak nějak „logickou instituci“, stroje, které nějak patří k sobě.
Asi tak. Určitě nikdo po nikom nechce klíč per stroj. To je kravina. Ale to současně neznamená mít jeden klíč a jednoho klienta na všechno. Už jenom z důvodu výměny klíče při jeho kompromitaci. Vyměnit klíč pro 7 serverů je jednodušší, než ho vyměnit na stovkách. Stejně tak je jednodušší ověřit, zda ten klíč stihl někdo zneužít.
Stejně si klíče lidi nemění. Na kdejakém usmrkaném webu se 2048b RSA mění každý rok, nebo dokonce každé 3 měsíce, ale stejný 2048b ssh klíč pro přístup na stejný server mají třeba 5 let starý. I toto je potřeba obnovovat.
> Prostě si udělám virtuálku, nebo další účet nebo něco.
OK, relativně pohodlné používání virtuálů na každou akci řeší QubesOS (again, nenapadlo by mě mít dvacet virtuálů jenom kvůli SSH, ale ostatní jsou chytřejší). Co budeme dělat s CVE-2015-3456, CVE-2015-5154 a CVE-2015-7835?
> Už jenom z důvodu výměny klíče při jeho kompromitaci.
Podle mě se většinou ty klíče stejně budou používat všechny na jednom stroji, takže se kompromitují společně.
again, nenapadlo by mě mít dvacet virtuálů jenom kvůli SSH
No já to tak dělám k vůli ochraně serverů. Pokud se ten klient kompromituje, třeba nějaký šprímař vytvoří alias ssh=ssh "rm -rf -no-preserv-root /" nebo něco takového, tak pokud se připojím na nějaký testovací server, který se před minutou naklonoval, tak mě to sice znervózní, ale škody jsou nulové. Pokud se stejným klientem připojím na důležitý server, tak jsou škody přece jen větší (odstávka, obnova ze zálohy apod.).
Ani mě by nikdy nenapadlo, že zrovna v openssh bude chyba umožňující vytáhnout klíče klienta (a to přes funkci, která tam ani nemá být) - nehledě na to jak obtížené je její zneužití. Ale právě proto, že mě to nenapadlo a nenapadá mě hromada jiných věcí, snažím se jít cestou předběžné opatrnosti.
Co budeme dělat s
CVE-2015-3456
The Floppy Disk Controller (FDC) in QEMU, as used in Xen 4.5.x and earlier and KVM, allows local guest users to cause a denial of service (out-of-bounds write and guest crash) or possibly execute arbitrary code via the (1) FD_CMD_READ_ID, (2) FD_CMD_DRIVE_SPECIFICATION_COMMAND, or other unspecified commands, aka VENOM.
Nevím, ale tuhle jsem se ptal našeho experta na vmware, proč je ve virtuálkách definovaná FDD a další zbytečná zařízení jako IDE controler (když se používá paravirtualizovaný disk, nebo alespoň scsi) atd. Já ve virtualboxu pokaždé vypínám i zvukovku apod. ve výchozím stavu zapnutá zařízení. V KVM jsem floppy nikdy nedefinoval. Opět ne proto, že bych předpokládal, že je v tom chyba, ale prostě proto, že v tom virtálu zvuk provozovat nehodlám a floppy image žádný ani nemám.
> třeba nějaký šprímař vytvoří alias ssh=ssh "rm -rf -no-preserv-root /" nebo něco takového
Pokud se šprýmař dostane tak daleko, že může dělat aliasy na ssh klienta, asi bude moct dělat i mnohem horší věci a klíče ti ukradne všechny.
This issue affects all x86 and x86-64 based HVM Xen and QEMU/KVM guests, regardless of their machine type, because both PIIX and ICH9 based QEMU machine types create ISA bridge (ICH9 via LPC) and make FDC accessible to the guest. It is also exposed regardless of presence of any floppy related QEMU command line options so even guests without floppy disk explicitly enabled in the libvirt or Xen configuration files are affected.
Pokud se šprýmař dostane tak daleko, že může dělat aliasy na ssh klienta, asi bude moct dělat i mnohem horší věci a klíče ti ukradne všechny.
Tak jistě. Proto je potřeba nepoužívat jeden klíč a nemít je na jednom místě.
Mimochodem, jak moc jsou ty cve co posíláš reálně zneužitelné? Bez ironie.
Třeba ten bug v openssh klientovi zase tak moc použitelný není.
> Mimochodem, jak moc jsou ty cve co posíláš reálně zneužitelné? Bez ironie.
To nevím, exploit na to jsem neviděl.
> Třeba ten bug v openssh klientovi zase tak moc použitelný není.
Souhlasím, přijde mi, že první zprávičky a články to dost nafoukly. Konkrétně mi jako limitující přijde to, že šifrovaný privátní klíč zůstane nejspíš jen v bufferech, tedy ho útočník získá šifrovaný, a dále ty hlášky, které jsou vidět.
> Co budeme dělat s CVE-2015-3456, CVE-2015-5154 a CVE-2015-7835?
V kontextu SSH trosku red herring, v sirsim kontextu ta otazka ale ma smysl.
CVE-2015-3456 a CVE-2015-5154
Sandboxovat. Qubes predpoklada, ze QEMU je derave jak cednik a spousti ho v tzv. stubdomain. Kdyz pak nejaky HVM (tj. plne virtualizovany stroj) napadne svoji stubdomain (jakysi minimalisticky virtualni stroj o par desitkach MiB RAM), neziska tim zadna nova privilegia. Stubdomain tyto utoky uz nemuze zneuzit, protoze je to PV (paravirtualizovany stroj - nikdo mu neemuluje SATA apod.). A, pokud se nemylim, stubdomain lze takto infikovat nejvyse do restartu, pak by se mela spustit cista nova stubdomain.
Xen obecne nemusi pouzivat stubdomains, pak QEMU bezi v dom0 (privilegovana domena) a to je pak jiny hukot. I tak je ale precondition pro zneuziti chyby mit pristup v HVM, coz muze omezit dopad.
KVM se mimochodem pry tez snazi sandboxovat QEMU, ale jen jinym uid, takze je tu vetsi attack surface. Navic obecne lokalni uzivatel muze zkouset nejake nekalosti jako hledani citlivych dat v /proc.
CVE-2015-7835
Toto je uz ponekud vetsi prusvih, nastesti v historii Xenu celkem vzacny. Tyka se sice jen PV, ale pokud zna utocnik vhodnou diru v QEMU (jako dve vyse zminene), ma z HVM pristup k napadenemu stubdomain, ze ktereho muze utok provest. Musi je ale znat ve stejny okamzik.
Casem by mohl attack surface zmensit prechod z PV k PVH, ktere maji jednodussi spravu pameti. Dokud teda nebude dira v CPU…
KVM je AFAIK backend, zatímco libvirt je frontend pro více backendů (vč. Xenu).
OK, možná /proc si nepřečte, ale i tak bych víc věřil (z hlediska local privilege escalation) bezpečnosti paravirtualizace než Linuxového kernelu. Zvlášť když tomu prvnímu věřím tak jako tak, ale tomu druhému (z hlediska local privilege escalation) nemusím.
KVM je podpora HW virtualizace v kernelu. Pro běh pořád potřebuje userspace hostitele, nejčastěji QEMU. To klidně můžete spustit pod omezeným uživatelem a osekat přes AppArmor. Obě CVEčka se týkají právě QEMU (a Xenu).
Paravirtualizaci věříte víc než linuxovému jádru? Kde myslíte, že ta paravirtualizace běží?
Třeba OpenVZ má tak každý rok nějakou escape vulnerability. A to s ním ani nefunguje AppArmor a user namespacy.
LXC oficiálně prohlašuje, že není bezpečné. V AppArmoru ani SELinuxu pro něj nemůžete plošně zakázat přístup do /proc a /sys, jinak spousta věcí ve virtuálu přestane fungovat (protože /proc a /sys sdílí). /proc a /sys je sice mountované read-only, ale to se dá jedním remountem zevnitř virtuálu změnit.
Xen taky nemá zrovna málo CVEček. Ale alespoň jde docela dobře ořezat přes AppArmor nebo SELinux.
OK, pro KVM by asi šlo taky implementovat stubdomains bez zásahu do KVM samotného, jen jsem to nikde neviděl.
> Paravirtualizaci věříte víc než linuxovému jádru? Kde myslíte, že ta paravirtualizace běží?
1. V případě Xenu beží paravirtualizace na bare metalu a Linuxový (nebo jiný) kernel až pod Xenem.
2. I kdyby paravirtualizace běžela pod kernelem, není to podstatný argument. Bavím se o důvěře z hlediska local privilege escalation (získání roota v kernelu nebo VM escape v hypervizoru). V případě stubdomains útočníkovi totiž nepomůže zranitelnost v kernelu v jiné VM, ke které se nedostane.
Nebo ještě jinak: Běží mi VM pod hypervizorem. K tomuto VM potřebuju spustit QEMU. Předpokládám, že QEMU bude děravé a útočníkovi se podaří spustit vlastní kód v QEMU. Co bude lepší:
a. QEMU bude omezené tím stejným (nebo dost podobným) sandboxem jako ten útočící virtuální stroj. Útočník tak získá (aspoň z velké části) jen to, co už měl.
b. QEMU bude omezené Linuxovým kernelem, tedy jiným sandboxovacím mechanismem. Útočník si tedy může vybrat, jestli bude útočit na hypervizor, nebo na Linuxový kernel, podle toho, co mu přijde jednodušší.
Xen jakožto samotný hypervizor je fakticky mikrokernel s minimalistickým API oproti monolitickému Linuxovému kernelu s bohatým API. Co bude bezpečnější?
Pro Xen sice existuje dost CVEček, otázkou ale je, jak moc jsou při dobrém nastavení závažná. Něco je pouhý DoS, něco jsou zranitelnosti QEMU (jak jsem psal, se stubdomains jsou bez další zranitelnosti v Xenu nepoužitelné), atd. Realistická úplná kompromitace celého systému jsou za historii Xenu AFAIK celkem dvě CVEčka.
> A neměla by se napřed naalokovaná paměť vymazat, aby v ní nebyla předchozí data?
Podle mě by to znamenalo, že bych v GIMPu zmáčknul Undo a ono by to začlo zapisovat gigabajt nul. Proto se to nedělá a mažou se jenom data, která jsou explicitně označena za citlivá. Možná by na to mohla být volba v něčem jako grsecurity (i když tohle je spíš záležitost libc).
> Nebo je to stejný problém jako řeší NVIDIA a Apple, kdy se hádají, kdo tu paměť má vymazat?
Tohle je paměť alokovaná a uvolňovaná v rámci jednoho procesu. nVidia má problém v tom, že nemaže paměť, když ji sdílí mezi procesy.
Podle mě by to znamenalo, že bych v GIMPu zmáčknul Undo a ono by to začlo zapisovat gigabajt nul.
A to je problém? Paměť má rychlost cca 20GB/s, tj nějakých 50ms navíc. Pokud někdo neprovozuje GIMP jen k tomu, aby mačkal undo, tak to přece nemůže vadit.
Stejně tak ta nvidia. Thread je to teda hodně zábavný. :-) GK se chlubí rychlostí přenosu paměti v neuvěřitelných číslech atakujících 200GB/s (HBM dokonce šílených 1TB/s) a najednou je problém vymazat jeden framebuffer. (Tím samozřejmě neříkám, že je vina na straně NV, podle té diskuse mají máslo na hlavě všechny strany.)
Nie je najlepsi kluc s passphrasom? Kluc je sifrovany (alebo je v tom buffri uz desifrovany? Nevyznam sa az tak), ku passphrasu by sa musel utocnik dostat nejak inak (nie ze by sa nedalo), takze by to malo byt sicher, nie? Pripadne pouzivat ssh-agent, aby som ten passphrase nemusel vzdy pisat.
To máte odkud? V tom vyjádření od Qualysu se píše:
Finally, for these three reasons, passphrase-encrypted SSH keys are
leaked in their encrypted form, but an attacker may attempt to crack the
passphrase offline. On the other hand, SSH keys that are available only
through an authentication agent are never leaked, in any form.
Takže klíče čtené z disku ssh klientem jsou v paměti zašifrované, a klíče z agenta tímto způsobem uniknout nemohou.
Podle toho dokumentu https://www.qualys.com/2016/01/14/cve-2016-0777-cve-2016-0778/openssh-cve-2016-0777-cve-2016-0778.txt
je problém v bufferech při použití fopen, fgets apod. ze standardní céčkovské knihovny.
1. If a private SSH key is loaded from disk into memory by fopen() (or
fdopen()), fgets(), and fclose(), a partial or complete copy of this
private key may remain uncleansed in memory. Indeed, these functions
manage their own internal buffers, and whether these buffers are
cleansed or not depends on the OpenSSH client's libc (stdio)
implementation, but not on OpenSSH itself.
Tedy, jestli jsem to pochopil správně, ten problém je v tom, že klient načte klíče pomocí standardní knihovny, která si soubor sama bufferuje.
Proto tedy unikne ten zašifrovaný klíč, protože to uniká přímo z funkce načítající ten soubor.
Aha, už to vidím. Klient vydá jakákoli data z nově alokovaného bufferu, který není nulovaný. To už je podle mě samo o sobě špatně, paměť de facto poskytovaná po síti by měla být podle mě nulovaná při alokaci. Naštěstí kód OpenSSH nuluje paměť s klíči při uvolnění, takže se struktury obsahující klíče takto nenasdílejí. Jenže...
1) Problém nastává v glibc funkcích implementujících ANSI souborové API, které samostatně bufferuje data při čtení ze souborů a nezajišťuje vymazání dat při uvolnění bufferů.
2) Jiný problém nastává při volání realloc(), které zanechává data v původní lokaci.
3) Ještě jiný problém nastává při vynulování uvolňovaných dat, jestliže se kvůli optimalizacím vynulování neprovede.
Ale popravdě jenom u prvním problému je mi jasné, že se týká pouze klíčů načítaných přímo ze souboru. Navíc by stačilo ANSI funkce vůbec nepoužívat ve prospěch POSIX fukcí. Tak jako tak se chovají divně. U zbylých dvou je potřeba znát rozhraní SSH agenta, takže tam jsem tak trochu ze hry.
Nicméně pro všechny tyto problémy je společné to, že narušují předpoklad, že uvolněná paměť je čistá, tedy neobsahuje žádná citlivá data. Jenže s takovým předpokladem prostě nejde počítat. Takže se bavíme pouze o následcích, ale chyba je skutečně v tom, že rozhraní vůči ssh serveru umožňuje číst neinicializovanou paměť, která z principu může obsahovat citlivá data.
Nejsem expert na hardening, takže k mírnění následků (když už dojde k leakování neinicializovaného bufferu po síti) se nebudu nějak víc vyjadřovat.
Protože SSH agent je samostatný proces, a u této chyby lze číst pouze paměť SSH klienta (resp. prostě procesu, ve kterém se projevila). U jiných potenciálních chyb by mohlo jít číst libovolnou paměť, ale tam tě sestřelí segmentace operačního systému, když se pokusíš hrábnout někam, kde ti to nepatří.
Se SSH agentem jsou zase jiné veselosti, např. agent forwarding, který umožní vzdálenému serveru podepsat cokoli tvým klíčem - samozřejmě jen když mu to povolíš, ale podobně, jako tady byla zapnutá nějaká funkce (roaming), o které nikdo nevěděl, bych se bál, že se může objevit chyba, která umožní zneužít agenta.
No, kdokoli ma roota na tom stroji, kam ses prihlasil s forwardingem, tak muze:
1.) zjistit z promenne prostredi vsech tvych procesu - zejmena tveho shellu, ktery je z sshd spusten.
2.) stat se tebou ('su') a nastavit si promenne prostredi (viz 1.). Pak je od tebe z pohledu ssh klienta naprosto nerozeznatelny a muze se prihlasit kamkoli muzes ty (dokud jses na takovem stroji prihlasen).
Agent forwarding je v podstate o duvere - veris, ze na cilovem stroji neni root, ktery by chtel pouzivat tveho ssh agenta k tomu aby se dostal nekam dal.
Tak já nevím, co chceš slyšet. Chyba je v kódu pro komunikaci se serverem a umožňuje číst paměť toho procesu, který komunikuje. ssh-agent se serverem nekomunikuje (pouze si se ssh klientem vyměňují data k podepsání nějakým jiným protokolem, ve kterém chyba není), tak ho server nemůže přesvědčit, aby mu poslal svoji paměť.
Jen pokud máte dostatečně silná hesla a používáte je jen k přihlášení přes ssh. A máte je do různých serverů různá (nebo alespoň do různých "systémů"). Je to už pár let, co napadený ssh server mohl 'zalogovat' uživatelské heslo, pokud se uživatel přihlašoval heslem (resp. možná ne přímo heslo, ale informaci, která počet možných hesel omezila na nějaké směšné číslo.). Bohužel CVE nevím, jen jsem dostal upozornění od správce serveru, ať si změním heslo.
> Bohužel CVE nevím, jen jsem dostal upozornění od správce serveru, ať si změním heslo.
To bych považoval za feature, ne za bug. To heslo se prostě přenáší.
Ještě by teoreticky mohl poslat salt z /etc/shadow a ty bys spočítal hash a poslal mu ho zpátky. Ale minimálně při změně toho hesla ho vidí SSH server a PAM.
On bezny ucet uz v dnesni dobe skoro polovicni root, zvlast, pokud se dotycny vyzna. Tim chci rict, ze moznosti, jak lokalne eskalovat prava je mnohem vic nez jak se vzdalene "nejak" dostat do systemu.
Heslo na su by v takove situaci totiz hadal jen malokdo.
Ja pouzivam zaheslovany klic, i ssh mam povolene jen na vybrane adresy a rozhodne si nemyslim, ze bych byl v nejakem extra bezpeci, bohuzel.
Dneska je imo napichle skoro vsechno, aktivnima prvkama po ceste pocinaje a zasadnima lokalnima knihovnama (openssl, urco i dalsi) konce. Vzdyt co toho za posledni mesic vyplavalo... hrozne moc.