Hlavní navigace

Pozor na logování!

26. 9. 2000
Doba čtení: 3 minuty

Sdílet

Objevil se nám v linuxovém kernelu docela zajímavý červíček. Tentokrát byl zavrtaný docela překvapivě v logu, respektive v klogd, což je démon který zajišťuje, aby bylo všem řádně na vědomí dáno, že kernelu se stalo to anebo tamto.

A tak když klogd dostane od kernelu něco zajímavého co stojí za to zalogovat, hezky odiskejpuje všechna procenta, aby se zbavil problémů s formátováním (to znamená že ‚%‘ bude nahrazeno ‚%%‘ – samotné ‚%‘ a nějakých pár znaků za ním mívá v některých řetězcích speciální význam, že se na ono místo má vložit hodnota nějaké proměnné – a když zároveň není uvedena někde i ta proměnná, jejíž hodnota se má použít, jsou z toho pak zbytečné nepříjemnosti ;). Ale v tom řetězci který se zalogovává mohou existovat speciální údaje uzavřené v ‚[<‘ a ‚>]‘. to mezi nimi bývá adresa, na které si kernel usmyslel že zavolá klogd aby něco zalogoval, a tu adresu klogd už převede na nějaké hezké symbolické jméno (třebas z c0130287 to udělá insert_inode_hash) – tak víme nejen co se kernelu stalo, ale také kde se mu to stalo.

Ale je tu problém, protože cokoliv mezi těmi závorkami unikne onomu nahrazování ‚%‘ za ‚%%‘. A tak, pokud přinutíte kernel aby vygeneroval nějaký požadavek na zalogování, který bude obsahovat něco jako ‚[<%s %s %s %s>]‘, tak klogd prostě a jednoduše vykvikne ‚Segmentation fault‘ a tvrdě dopadne do slzavého údolí zabitých procesů… To by nebyla zas až taková tragédie, ale dá se to zneužít i k získání roota, takže pozor (viz níže).

Tenhle bug byl dostatečně vykřičen hlavně díky záplavě záplat postupně vydaných všemi významnějšími distribucemi, přičemž každá uznala za vhodné zvlášť to vykřičet někde kde by to slyšelo co nejvíce lidí, takže třeba na linuxtoday.com :). Svojí distribuci si můžete najít třeba tady, kde jsou k dostání patche i na jiné bugy (třeba hezky s glintem – často instalujete RPMka jako root? zkontrolujte si předtím /tmp ;).

Šikulkové by mohli využít toho že klogd běží na roota a zabydlet se u vás… (hlavní nebezpečí je ze strany lokálních uživatelů, ti vzdálení to budou mít těžší :) – a jak, ptáte se? Lokálně třeba pomocí špatně inicializované struktury sockaddr – to vygeneruje zprávičku do logu, která obsahuje i jméno programu – jméno programu se vezme z task_struct->comm, což je 16-bitový buffřík – a jsme skoro doma… potřebné [< zaplácne dva bajty takže už máme trochu méně, ale snad si vystačíme :).
Hm, a co takhle speciální kernelové moduly které volají printk() nebo různé ovladače? Můžeme třeba využít /dev/mixer a hnedka můžeme psát do logu…
No jo, ale jak to všechno využít? Není to už zas tak jednoduché, ale možné to je – staré dobré buffer overflowy. Buffery pro sestavování těchto stringů jsou staticky alokované takže budou někde nízko v paměti – nic uživatelsky definovaného nebo do stacku strčeného. Třeba když tam umístíme %1024d, co se asi stane v funkci vsyslogd()? Ta je volána ze Syslog() a spoléhá se na něj a nic už sama nekontroluje… Takže teď už jsme v lokálním bufferku vsyslogd(), respektive kousek za ním ;). A na závěr ještě poznámečku že jde využít i knfsd, který jde donutit aby vyprintk()nul nějaké cesty – a ejhle máme tu opět exploitek :)..

Cloud23

Mh, já vím že už je trochu pozdě, vzhledem k tomu že se objevil tenhle bug už 13.9., ale lepší pozdě než nikdy :)…

část převzata od Securityfocusů a jouko@solutions.fi

Autor článku