ugrás a tartalomhoz

CVE-2014-6271: remote code execution through bash

H.Z. · 2014. Szep. 26. (P), 13.49
Régen létező hiba a Bash shellben, ami akár távolról kezdeményezett kódfuttatást is lehetővé tehet
 
1

Akiket a lényeg érdekel

vbence · 2014. Szep. 26. (P), 15.13
Akiket a lényeg érdekel:

Current bash versions use an environment
variable named by the function name, and a function definition
starting with “() {” in the variable value to propagate function
definitions through the environment. The vulnerability occurs because
bash does not stop after processing the function definition; it
continues to parse and execute shell commands following the function
definition.

The fact that an environment variable with an arbitrary name can be
used as a carrier for a malicious function definition containing
trailing commands makes this vulnerability particularly severe;


Vagyis többnyire CGI szkriptek vannak veszélyben, de kihasználható akár PHP-n keresztül is, ha parancsot futtatunk (és az alapértelmezett shell a bash, nem pedig az sh - bár sok helyen az sh csak egy symlink a bash-re), valamint ha a futtatott parancs maga egy shellscript (ami behívja a bash-t), vagy a futtatott parancs meghív valamit ami meghív valamit, ami használja a bash-t.

Néhány változó egy-az-egyben tartalmazza a usertől kapott stringet (HTTP_COOKIE, HTTP_QUERY_STRING, HTTP_USER_AGENT).

Extrém esetben akár egy mail() meghívása is lehetőséget teremethet (ami alapértelmezésben a sendmail programot hajtja végre), hiszen a sendmail lehet egy shellscript az adott Linux disztribúcióban.

A sebezhetőség testelhető a következő paranccsal:
env x='() { :;}; echo vulnerable' bash -c 'echo hello'
(ha megjelenik a "vulnerable" szó, akkor igen; ha hibaüzenet, akkor nem).

Gyorssegély a patchelés előtt: a PHP szkript elején (ugyebár single entry pointot használunk, úgyhogy ez egyszerű) végigiterálni az _ENV tömbbön és, ha bármely érték a "() {" stringgel kezdődik nyomunk egy die()-t. - Esetleg egy error_log-ot előtte, hogy meglegyen az IP későbbre.

összefoglaló írás
még egy összefoglaló
teszt módszerek
2

_ENV

zzrek · 2014. Szep. 26. (P), 16.35
És hogyan kerülhet ilyen az _ENV tömbbe? (Saját webszerveren, vagy mondjuk egy shared hoston?)
3

Érdekelne pl. janoszen

H.Z. · 2014. Szep. 26. (P), 16.40
Érdekelne pl. janoszen véleménye az egész témáról.
Annyi hajmeresztő dolgot olvastam tegnap óta, hogy kétlem, akár a tizedük is igaz lenne.
4

Írtam pár példát

vbence · 2014. Szep. 27. (Szo), 21.50
Az Apache populálja a CGI-knél megszokott környezeti változókat PHP szkript esetén is. Próbáld ki egy phpinfoval (fent írtam pár példát is).
5

Nem erre gondoltam

zzrek · 2014. Szep. 27. (Szo), 23.59
Nem erre gondoltam (vagy lehet, hogy félreértek valamit), hanem hogy hogyan kerülhet valamelyik környezeti változóba támadó kód, "() {" string ?
6

Ha például engedélyezve van a

H.Z. · 2014. Szep. 28. (V), 01.44
Ha például engedélyezve van a CGI futtatás, akkor szépen rámész a szerverre telnet hostname 80 paranccsal (feltételezve, hogy hostname a szervered neve és 80-as porton ül a webszervered) és beírsz valami ilyet:

GET /cgi-bin/mukodo-cgi-script-neve.sh HTTP/1.1
Host: hostname
User-Agent: () { :; }; echo 123 >>/tmp/zzzz


A végén két üres enter kell.
Ha ez megvan és megnézed a szerveren a /tmp tartalmát, elvileg ott van egy zzzz nevű fájl, 123 tartalommal.

Nem állítom, hogy ez így működik, de valahogy így sikerült kipróbálni a saját virtuális gépeim egyikén.
16

Hozzáférés?

zzrek · 2014. Szep. 28. (V), 17.11
Ahhoz, hogy a telneten keresztül ezt megtedd, nem kell ismerned semmilyen felhasználónév/jelszó párost?
19

Nem

Poetro · 2014. Szep. 28. (V), 18.42
A telnettel igazából csak TCP / IP kapcsolatot létesítesz. Azon felül akár milyen protokolt használhatsz (jelen esetben HTTP-t, mert 80-as porton HTTP fejléceket küldesz). Amennyiben a 80-as porton felhasználó nevet és jelszót kér tőled a távoli gép, akkor azt meg kell adnod (de egy HTTP szerver ritkán kér tőled jelszót, legfeljebb Basic Auth-ot)
22

User Agent

zzrek · 2014. Szep. 28. (V), 19.58
Akkor itt a trükk az, hogy a user agent is egy környezeti változóba lesz betéve?
7

Vektor

vbence · 2014. Szep. 28. (V), 10.11
A PHP fastcgi módban kell hogy fusson. Késztesz egy info.php-t (ami egy phpinfo függvényhvást tartalmaz).

Behvod a böngészőben, majd a konzolba berod:
document.cookie='a b=1';
Frissited az oldalt. Az alsó táblázatban a következő fog feltűnni:
_ENV["HTTP_COOKIE"]	a b=1
(...láthatjuk, hogy a space valóban space és nem %20 vagy +).
17

OMG

zzrek · 2014. Szep. 28. (V), 17.34
Fhhh... Szóval a cookie-ban az adatok is környezeti változóban vannak, és a bash ezeket is "végrehajthatja"?
Már csak arra lennék kíváncsi, hogy aki azt kitalálta, hogy a bash-nak az összes környezeti változót végig kell néznie és bármelyik hatással lehet rá, az miért gondolta, hogy ez jó lesz. ???
21

Hát...

vbence · 2014. Szep. 28. (V), 19.53
Igen, mondjuk szebb lenne egy fix előtagot kötelezővé tenni.
8

Jobban érzem magam

Poetro · 2014. Szep. 28. (V), 11.33
Mennyivel jobban érzem magam, hogy már évek óta nem használok Apache HTTPD-et, hanem csak Java illetve Node.js HTTP szervereket. Ezeknek nincs szüksége paraméter átadáshoz környezeti változókat beállítani.
9

Nem számít

Hidvégi Gábor · 2014. Szep. 28. (V), 13.33
A webszerverek ebből a szempontból jó helyzetben vannak, mivel "élő" dolgok, használják őket, frissítik, így nagy valószínűséggel hamar felkerül rájuk a folt. Cserébe több helyen írják, hogy nagy veszélyben igazán a beágyazott rendszerek, routerek és egyéb, okosnak titulált eszközök vannak, amelyeket már nem támogatnak, vagy rendszergazda híján soha nem is frissítenek.

Ezek után el lehet képzelni, mi lesz, ha megvalósul a felhőben élő marketingesek által kitalált eszközök internettye. Amikor a saját hűtőd fog DDOS támadást indítani a node.js szervered ellen, akkor a te mosolyod sem lesz őszinte.
10

A beágyazott és mobil

H.Z. · 2014. Szep. 28. (V), 13.33
A beágyazott és mobil eszközök talán nincsenek akkora veszélyben emiatt a hiba miatt. Amit ismerek, azon egyiken sincs bash telepítve, inkább busybox a jellemző. ("okos" tévét még nem láttam, a upc-s dobozok viszont gyanúsak :) )
Az viszont gáz, hogy az említett rendszereken egyéb lyukak is lehetnek, amiket tényleg a kutya sem fog befoltozni, ugyanakkor hosszú évekig rajta lesznek a neten...

Egyébként a node.js saját webszervert futtat, nem cgi-ként működik?
11

"okos"

Hidvégi Gábor · 2014. Szep. 28. (V), 13.41
Nekem van egy médialejátszóm, abban busybox és azon belül csh és sh van, és az utóbbiban (bár más szerveren) működött a bug.

Manapság általánosan elterjedt, hogy az okosnak nevezett eszközöket eleve csak egy-két évig támogatják, mert közben kihoznak ezer új változatot, és nincs rá elég erőforrás. A beágyazott rendszerekben tipikusan régi linux van, zárt forrású binárisokkal, csak a legnépszerűbbek mögött van közösség, akik foglalkoznak vele tovább is.

A node.js-ben van beépített webszerver, azt csak valószínűsíteni tudom, hogy fut cgi-ként is.
13

No várj, az "sh" az

H.Z. · 2014. Szep. 28. (V), 13.50
No várj, az "sh" az eredetileg a Bourne shellt jelentette, manapság többnyire egy symlink, ami mögött bármi lehet. Pl. nekem van olyan linuxom, ahol sh néven egy teljes értékű bash indul.
A busybox az önmagában tartalmaz shellt, de ismereteim szerint az valami nagyon szűkített dolog, sem a bash, sem a C shell dolgai nem működnek benne igazán. (valójában van egy busybox nevű bináris és attól függően viselkedik, hogy milyen (sym)linken keresztül hívod meg)
De ha valaki másképp tudja, szóljon, mert nem jártam utána!
14

A kedvedért előveszem és

Hidvégi Gábor · 2014. Szep. 28. (V), 13.59
A kedvedért előveszem és megnézem. Egyébként a busyboxnak is van egymilliom verziója, sőt, valamelyik nap egy 7.0-s debianban is láttam.

Megnéztem, nincs benne env, emiatt a env x='() { :;}; echo vulnerable' sh -c 'echo hello' nem futott le, a debianosban viszont már van (ott meg már foltozva lett).
15

Debian 7, kifejezetten ilyen

H.Z. · 2014. Szep. 28. (V), 14.06
Debian 7, kifejezetten ilyen próbákra tartogatva, még update nélküli állapotban:

haazee@cerberus:~$ env X='() { :; }; echo hello' sh -c 'echo bye'
bye
haazee@cerberus:~$ env X='() { :; }; echo hello' bash -c 'echo bye'
hello
bye


A /bin/sh egyébként egy link a dash nevű, limitált shellre.
De kipróbáltam a busybox-ra mutatóval is:
haazee@cerberus:~$ env X='() { :; }; echo hello' ./sh -c 'echo bye'
bye
haazee@cerberus:~$ ls -l ./sh
lrwxrwxrwx 1 haazee haazee 12 Jan 10  2014 ./sh -> /bin/busybox
12

node.js

Poetro · 2014. Szep. 28. (V), 13.44
Node.js alatt te írod a saját webszervered a beépített és külsős modulok segítségével, és általában nem cgi-ként fut. Nincs is hivatalos cgi interfésze.
24

Gyorssegély a patchelés

Hidvégi Gábor · 2014. Szep. 29. (H), 11.12
Gyorssegély a patchelés előtt: a PHP szkript elején (ugyebár single entry pointot használunk, úgyhogy ez egyszerű) végigiterálni az _ENV tömbbön és, ha bármely érték a "() {" stringgel kezdődik nyomunk egy die()-t.
Ilyenkor már nem késő bármit is tenni a php szintjén?
25

Általában nem

vbence · 2014. Szep. 29. (H), 11.39
Mivel a hiba manifesztációjához szükséges, hogy a php valami külső parancsot hajtson végre (ami nem mindig egyértelmű, lásd mail függvény), a dolog még megfogható a kezdet kezdetén.

Amikor az Apache invokálja FastCGI-t nem valószínű, hogy a bash szerepet játszik még. Bár sok FastCGI kialakítás "otthon főzött" az üzemeletető által, szóval biztosnak semmi nem biztos.
26

Csak abból gondolom ezt, mert

Hidvégi Gábor · 2014. Szep. 29. (H), 12.13
Csak abból gondolom ezt, mert a FastCGI meghívásakor a környezeti változókat már készen kell átadni, azaz elképzelhetőnek tartom, hogy az alattomos parancsot már akkor lefuttatja a webszerver.
28

Fast

vbence · 2014. Szep. 29. (H), 12.45
FastCGI esetén (a klasszikus cgi-vel ellentétben), egy már a mamóriában futó interpreter kapja meg a feladatot (vagyis nincs újra és újra elindítva).

Ha a php normál CGI módban fut, legjobb tudásom szerint akkor sem a shellen keresztül indítja el az apache, ha úgy tetszik maga a php lesz a shell ami végrehajtja a szkriptet.
30

Kedvem lenne kipróbálni, de

H.Z. · 2014. Szep. 29. (H), 12.55
Kedvem lenne kipróbálni, de az apache+php+fastcgi triót nem sikerült működésre bírnom a patch-eletlen gépemen. :(
Nekem úgy rémlik, hogy ott azért indul shell, függetlenül attól, hogy cgi v. fastcgi... De ne legyen igazam!
27

Az a baj, hogy ha CGI-ként

H.Z. · 2014. Szep. 29. (H), 12.18
Az a baj, hogy ha CGI-ként fut a PHP, akkor ott már késő. A CGI ugyanis önálló programként indítja a PHP-t, külön shellből és az a shell fogja megkapni a hackelt változókat.
Ennek egy esetben van értelme: ha apache-on, mod_php-t használsz, nem cgi-t.
29

Fent

vbence · 2014. Szep. 29. (H), 12.49
Engedelmeddel Gábornak válaszoltam, de ugynazt írjátok.
32

Na most tartok ott, hogy

H.Z. · 2014. Szep. 30. (K), 20.17
Na most tartok ott, hogy egyre kevésbé értem a dolgot: sima CGI szkripteket futtatva működik az exploit (ha pl. a localhost/cgi-bin/x.sh egy futtatható szkript).
Ha nginx vagy apache2 van a gépen, de fastcgi-vel futtatom a PHP-t, akkor - már bocs - tojik a fejemre, nem működik, hiába bugos a bash.
Akkor most mi van? Még sincs akkora gáz, mint ahogy azt híresztelték?
Vagy csak én rontottam el valamit?
Metasploithoz még mindig nem értek, szóval fogalmam sincs, mi a helyzet.
33

Ott nincs bash

vbence · 2014. Okt. 1. (Sze), 00.29
Szerintem szkript futtatásához fastcgi módban nem indít új shellt (pont az a lényege, hogy a memóriában lakó interpretert használja) a kérés feldolgozásához.

Ebben a WL cikkben kitérnek pár részletre.
34

Félreérthetően fogalmaztam:

H.Z. · 2014. Okt. 1. (Sze), 00.34
Félreérthetően fogalmaztam: azt korábban is írtad, hogy fastcgi esetében nem indul új shell úgy, ahogy hagyományos cgi esetében (nem tudom, első menetben hogy jött össze mégis, csak feltételezni tudom, hogy timeoutra ment a telnet és az echo már a parancssorból futott, ahová a telnet visszadobott)

Viszont az nagyon nem világos, hogy ha az általam elterjedtként ismert módokon nem okoz problémát (apache mod_php, fastcgi, nodejs, wsgi stb), akkor miért lett ekkora cirkusz belőle?
Hagyományos cgi-t ki használ még?
35

Mást használnak

Poetro · 2014. Okt. 1. (Sze), 08.24
Mert (szerencsére) nem mindenki használ PHP-t. Egyesek olyan elvetemültek, hogy CGI kódokat futtatnak, illetve valamilyen más nyelv alól bash szkripteket, vagy csak egyszerűen nincs jól beállítva a webszerverük.
36

Weben amivel mostanában

H.Z. · 2014. Okt. 2. (Cs), 22.40
Weben amivel mostanában találkoztam:
PHP különböző variációkban,
Java,
RoR,
node.js
Python (django framework vagy "mezítlábas" wsgi környezetben)
Ezek úgy tudom, nincsenek veszélyben.
Még a PHP-ből kiadott system hívás okozhatna gondot, de egy alapbeállításokkal felrakott debianos szerveren nem kapott meg az így hívott shell semmit az eredeti környezetből.
(egyéb rendszereken nem tudom, mi a helyzet a külső programok hívásával, de úgy rémlik, máshol végképp nem jellemző, hogy a webes felületről érkező adatok környezeti változóba kerüljenek)

CGI-ről tíz-tizenöt éve hallottam utoljára.
(Windows szervereken meg annyira nem jellemző a bash használata)
Biztosan van más, biztosan van ahol cgi-t használnak, de érzésem szerint elhanyagolható lehet ezek száma.

U.n. embedded rendszerekről nem sokat tudok, amit ismerek, azon nincs bash. (Router, mobil stb.)


Update: ma találtam valahol egy írást, miszerint a cPanel használóinak okozhat komoly gondokat ez a bug. Hm. Így már kezdem érteni a pánikot.
:(
18

Off: C64

T.G · 2014. Szep. 28. (V), 17.50
:)

20

Még jó, hogy ZX81-ed nem volt

H.Z. · 2014. Szep. 28. (V), 18.52
Még jó, hogy ZX81-ed nem volt kéznél :)))
23

Hálózat

Pepita · 2014. Szep. 28. (V), 21.59
Azért a múzeális értékeket kár keverni a nettel... :)
31

Érdekességnek Xavier Mertens

kuka · 2014. Szep. 30. (K), 15.11
Érdekességnek Xavier Mertens témával kapcsolatos cikke: Some Personal Shellshock Stats. Talán vet némi fényt a korábban elhangzott… izé… elfirkantt „hogyan” kérdésre.