A Shellshock margójára

 ( Zahy | 2014. szeptember 28., vasárnap - 23:56 )

Ahogy újabb és újabb infókat csipegetek fel, úgy fogom egyre jobban a fejemet. Pár apróság, amitől a hajam égnek áll:

- a bash (a javítás előtt) engedélyezte olyan shell-függvény létrehozását, aminek a nevében / szerepel, pl egy peccseletlen bash-ban ez megtehető:

bash$ function /bin/ls { echo jaj ;}
bash$ type /bin/ls
/bin/ls is a function
/bin/ls ()
{
echo jaj
}
bash$ /bin/ls
jaj
bash$ exit

Ez már önmagában agyrém.

- ugye ami igazán szép, hogy kitalálták az exportálható shell-függvény című agybajt. Mivel a környezet UNIX/Linux alatt csak változók (izé=ecet) átadására volt felkészítve, zseniális trükköt használtak agyszüleményük megvalósítására. Ha egy függvényt az "export -f fname" paranccsal exportáltak, akkor tulajdonképpen átkonvertálták változó értékadásnak, és azt a változót aztán exportálták. És hogy a dolog működjön, kellett egy második pont is. Ha a bash találkozott egy olyan környezeti változóval, aminek az értéke a "() {" karakterekkel kezdődött (így néz ki ugye egy shell függvény kezdete), akkor úgy döntött, hogy az ott egy ilyen exportált függvény, amit azon nyomban definiálni kellett - azaz létrehozta (visszakonvertálta) a változóból a parancsot. És persze amikor ez megtörtént, akkor ugyebár lefuttatott egy (vagy több) parancsot. Itt ráadásul elég trehány is volt a drága programozó úr/hölgy, kb leszarta, hogy a shell fv végét a záró kapcsos zárójel elég jól jelzi, ami utána van, annak nem nagyon kéne bármiféle értelmet tulajdonítani. (Ezt jól mutatta a legismertebb teszt.) Természetesen környezeti változó létrehozására elég sok lehetőség adódik, de az, hogy azt a "cél-alkalmazáson" kívül esetleg más saját hatáskörben megcsócsálja, arra az egyszeri ember max a dokumentált dolgokig szokott gondolni. Ez a fenti borzalom viszont nem volt dokumentálva (no jó, én nem találtam, persze ha valaki olvasta, nyugodtan dobhat egy linket).

Fenti két pontot összekombinálva. Valami shellben, ami nem bash, csinálhatok környezeti változót, extrém tartalommal. (Ha az a valami a bash, akkor még eléggé unortodox nevűt shell-fv-t is.) De például az env parancs már boldogan csinál furcsa nevű környezeti változókat is. A bash-ban mind a kettő shell-függvényként látszik:

$ export ls='() { echo jaj;}'
$ env /bin/ls='() { echo jajjaj;}' bash
bash$ ls
jaj
$ /bin/ls
jajjaj
bash$ type ls /bin/ls
ls is a function
ls ()
{
echo jaj
}
/bin/ls is a function
/bin/ls ()
{
echo jajjaj
}
bash$

Fenti példa azt mutatja, hogy bash shell esetén külső parancs innentől sem elérési úttal, sem elérési út nélkül megadva nem biztos, hogy azt a műveletet hajtja végre, amire gondoltunk.

Csavarjunk még egyet a dolgon. Van a bash-ban shell alias, shell-függvény, és shell belső parancs. A bash tetszőleges X parancs futtatásakor ebben a sorrendben ellenőrzi, hogy mit kell csinálnia. (És ha ezek egyike sem ad találatot, akkor jön csak a PATH, és a külső parancsok megkeresése - ami fentek alaján már nem túl megbízható.) De mivel a shell-függvények keresése korábban történik, mint a shell saját, belső parancsainak megkeresése, ezért bármelyik shell-parancs felüldefiniálható egy jól elnevezett, extrém tartalommal bíró környezeti változó segítségével. Ha tehát csinálok pl. az

alias, unalias, set, unset, export, function, type, builtin, command

parancsokkal megegyező nevű környezeti változót (a szokásos "() {" kezdetű tartalommal), akkor ezekből az azonos nevű shell belső parancsok felüldefiniálása lesz. Ha kellően ügyes vagyok, akkor ezeket megírhatom úgy is, hogy látszólag jól működjenek, de persze mégse. Gyakorlatilag minden parancsot felül lehet definiálni, egyedül a shell-aliasok azok, amelyeket a bash hamarabb dolgoz fel, mint a shell-függvények. Következésképpen látszólag csak bash-ban gyárilag definiált aliasok esetén lehet bízni abban, hogy nem tudom felüldefiniálni. No most az aliasok kezelése gyakorlatilag egyszerű szövegcsere, azaz:

bash$ alias x=y
bash$ x
bash: y: command not found
bash$

Nyilván elég nekem az y parancsot felüldefiniálnom, és máris megint nem az történik, amit eredetileg tervezett az a drágalátos szoftverfejlesztő. És ha ehhez hozzáveszem, hogy bash-ban a gyárilag definiált aliasok száma 0, akkor eljutottunk odáig, hogy bash-ból *semmilyen* parancsnál nem lehetek biztos abban, hogy mi fog történni.

(A patch egyik következménye ha jól tudom, hogy már legalább a /bin/ls szerű dolgokat - azaz az elérési úttal adott parancsokat - nem lehet ezekkel az exportált változókkal felüldefiniálni. Szuper. Kár, hogy tudtommal az exportált shell-függvényt mint lehetőséget nem akarják megszüntetni.)

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Ezért és az ezekhez hasonló dolgokért szoktam mindig csak szépen mosolyogni, amikor egyesek nagy magabiztossággal mondják, hogy a root bejelentkezés helyett a user login + su az sokkal biztonságosabb... Ha ugyanis valaki megszerzi a user jelszót, akkor az az extra su / root jelszó már nem fogja megállítani attól, hogy a su helyett egy saját scriptet hivasson meg a userrel és szépen leloggolja a root jelszavát. ;)

Mondjuk a su-nak és sudo-nak szerintem lenne olyan értelme is, hogy ittasan és másnaposan azért ilyen parancsolat már ne adjunk ki, amikhez kellhet :D
Engem, most az zavar, hogy a BASH oldalán már a harmadik patchet adták ki a shellshock miatt. Igaz, hogy fél órája néztem, azóta már lehet hogy öt van :D

Tudom, az ember gyarló, de ittasan k.rvára ne menjen valaki dolgozni. Vagy ha ez nem megoldható, akkor ne igyon, mielőtt dolgoznia kell.

Nem csak a munkahelyunkon hasznalunk "bash-like" shellt.

Ja, tényleg, az átlag számítógéphasználók 0.001%-a otthon is használ parancssoros felületet. Őket is beleszámoltam, csak nem vettem említésre méltónak. :)

És azóta is jönnek az új kiadások. Miután ezt írtad, jött egy 4.3.28-as, jelenleg 4.3.30-as van Fedora 21-en.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Én is pont ebben a pillanatban láttam, hogy bekerült a FreeBSD-ports-ba is a 30-as.

A saját script hívási lehetőséget kell letiltani legalább ennél a parancsnál. Gondolom ez megoldható.

......................
Egymás segítésére még: http://pc-kozosseg.com

Úgy látom nem sikerült megérteni azt, amit írtam. Röviden összefoglalom. Azzal, hogy kitalálták a bash fejlesztői az exportált shellfüggvény című bődületes marhaságot, és mivel úgy tartották jónak megvalósítani, hogy egy speciálisan kinéző környezeti változóban adják át azt, ezzel sikerült elérni, hogy nem tudsz úgy shell-scriptet írni, hogy biztos legyél benne, hogy az a parancs fog lefutni, amit te szeretnél - akár shell belső parancs (cd, set, export, alias, stb), akár standard vagy nem annyira standard külső parancs (ls, find, grep, perl) hívásával szeretnéd elérni a feladatodat. Mind a kétfélét ugyanis felül tudom definiálni megfelelően preparált exportált változóval. Valamelyik javítás már annyit javított a helyzeten, hogy ha külső parancsokat teljes elérési úttal adsz meg, azt már nem lehet felüldefiniálni. (Én legalábbis így látom jelenleg.)
Hunger meg azt magyarázza a linkelt szálban, hogy belülről *mindig* van támadási lehetőség (például akár ezzel a jelenlegi hibával is lehet sakkozni).

És újra példa, szigorúan csak a bash-ra koncentrálva:

$ env '/bin/ls=() { echo vulnerable;}' bash
bash$ /bin/ls
vulnerable
$bash$

Ez peccseletlen bash esetén a /bin/ls lefuttatásakor mást csinál, mint szeretnél. Ha kicseréled, és az env paramétereként nem /bin/ls hanem ls, vagy cd nevű preparált változót adsz át a bash-nak, akkor azon parancsok helyett is más fog lefutni, mint amire számítasz. És mivel egyszerre több változó is átadható, így akár a fél parancshalmazt át lehet definiálni.

$ env 'ls=() { echo vulnerable;}' '/bin/ls=() { echo Vulnerable;}' 'cd=() { echo VULNERABLE;}' bash
bash$ ls
vulnerable
bash$ /bin/ls
Vulnerable
bash$ cd /tmp
VULNERABLE
bash$

Környezeti változót létrehozni nem nehéz, bash-t pedig indíthatok direktben, de ha egy program system(3) vagy popen(3) hívást használ valamilyen műveletre, a háttérben már ott is indul egy shell. Amely a legtöbb Linux terjesztésben bash.

(sub)

+1

+1

------------------------------------------------------------------------------
www.woodmann.com/searchlores/welcome.htm

Nem kéne nevet váltanod? A dash állítólag nem problémás, csak a bash.

+1

+1
--
Dropbox:
Dropbox
Ubuntu One

Amit nem igazán értek. Ha olyan okosok vagyunk, milyen rossz a bash ezen része, miért nem derült ez ki kb. 20 évig?

Nem akarlak elkeseríteni, de azt, hogy ezzel a trükkel minden parancs felüldefiniálható én még nem láttam leírva, saját kútfőből okoskodtam ki - de még senkinek nem sikerült megcáfolnia. Továbbmegyek, leírva nem láttam, hogy az exportált shell-függvény így van implementálva - azt már csak a shellshock-hoz írt teszt alapján ókumláltam ki. Sose néztem a bash kódját, ők le nem írták, hogy ez így működik. Csak épp a tapasztalat az, amit leírtam. Ellenben kevés ember van, aki elég mélyen ismeri átlag shell viselkedését ahhoz, hogy ezeket mind összerakja. És valószínűleg ők se ezzel foglalkoztak. Én viszont nem vagyok bash rajongó, ezért aztán eddig én se gondolkoztam el rajta.

Nem téged bántalak ezzel - tévedésbe ne essünk - hanem azt a nem kevés embert, aki ezügyben napi szinten mozog. Kíváncsi lennék, egyáltalán hogyan derült ez ki ;)

Ezert is mondjak, hogy a bazar model csak elmeletben hasznalhato. Hiaba van az, hogy a kod nyiltsaga miatt elvileg mindenki atnezheti az adott kodot, a gaykoarlatban nagyon olyan keves ember van aki erti is hogy a kod pontosan mit es hogyan csinal, es meg ennel is kevesebb aki meg tudja allapitani, hogy a kod altal implementalt funkciokban van e olyan logikai hiba ami esetleg ilyen dolgokhoz vezethet. Es ha meg van is aki erre mind kepes, az se biztos, hogy nyilvanossagra hozza amit talal :)
____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..