PHP ~remote exploit

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2225

hivatalos javitas meg nincs, ha nem hivsz user inputra unserialize-t akkor valoszinuleg nem kihasznalhato.

update:
megszuletett a javitas, a kovetkezo php release-ekkel erkezik.
ez ~julius 22. korul lesz esedekes, ha minden jol megy.

update:
elerheto a syscan-es slide:
http://www.slideshare.net/i0n1c/syscan-singapore-2010-returning-into-th…

Tyrael

Hozzászólások

Nem mintha szabad lenne vakon unserialize-t hivni user inputra...
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

igazabol eddig csak hulyesegnek tunt, mostmar veszelyesnek is.
a masik problema, hogy serializalt stringet eleg nehez validalni unserializalas nelkul.
illetve ott van ugye a problema, hogy a session szuperglobalis tomb is serializalodik/unserializalodik, szoval esetleg netalantan elofordulhat, hogy akar egy nem levizsgalt string session-be mentesevel is triggerelheto a hiba.
illetve ha van olyan sql oszlopod, amiben serializalt adatot tarolsz, akkor egy sql injectionbol lokalis kodfuttatasig emelheto a hiba.

Tyrael

Igazabol a serializalas mindig is veszelyes, mert nem tudhatod, mit unserializalsz vissza. A session-nal meg elojon az, hogy aki nem validal egy nem-belso tombot, azt maglyan kell felkotni.
Egyebkent pedig sajat "serializacio" irasa nem olyan nehez, egy tombot vagy egy hash-t (ha nem mely es nem objektumokat tarolsz bennuk) siman at lehet alakitani stringge kezzel (megoldva ezzel az SQL oszlopos problemat).
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Vagy ha nem kell nagyon faramuci tipusokra serializalni, meg mindig jo JSON-re alakitani, van ra beepitett tamogatas (es legalabb a kliens is konnyebben megerti, ha kesobb at akarnad adni).

--
What's the difference between the Israeli navy and Somali pirates?
If you negotiate with Somali pirates,you can prevent them from murdering their victims. - sickipedia

Vagy ha nem kell nagyon faramuci tipusokra serializalni, meg mindig jo JSON-re alakitani, van ra beepitett tamogatas (es legalabb a kliens is konnyebben megerti, ha kesobb at akarnad adni).

Igen, de ettol fuggetlen a json-nak is megvannak ugyanazok a hatranyai(nem lehet decode-olas nelkul validalni, etc.), ami az unserialize-nek kiveve hogy abban nincs jelenleg ismert sebezhetoseg (najo, az igaz hogy cross platform), raadasul egy csomo helyen nincs lehetoseged, vagy csak nagyon maceras modon lehet lecserelni a serializalast (php beepitett session kezeloje serializalast hasznal, es hiaba definialod felul a set_session_save_handler-rel, mar ott is pl. a save method serializalt stringet kap, szoval macera).

Tyrael

"Igen, de ettol fuggetlen a json-nak is megvannak ugyanazok a hatranyai(nem lehet decode-olas nelkul validalni, etc.)"

?????????????????????????
A JSON - a serialize formatumaval ellentetben - plaintext dolog, siman lehet validalni. Szerintem a neten biztos talalsz egy halom regexet, ami JSON-t validal.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

ugye tudod hogy a php serialize altal generalt adat is sima plain text dolog?

ebbol a szempontbol ugyanugy viselkedik mindket megoldas.

btw: kicsit tulzasba viszed az irasjelek hasznalatat.

ps: http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html

It is quite easy to prove, that it is not possible to properly detect and parse recursive structures using regular expressions. When you have studied computer science you of course know Chomsky hierarchies and therefore know, that regular expressions are a type 3 grammar, also called regular languages, which are equivalent to finite state machines. (So you also know, that each regular expression is quite easy to transform into a FSM).

Tyrael

Parsing != Validating.
Egyebkent a regex hasznalata egyszerubb mint az allapotgepeke, es sokszor gyorsabb is osszerakni egy megfelelo regexet.

A serialize altal generalt adat csak majdnem plaintext, mivel tartalmaz \0 karaktereket is, ami mar nincs benne a nyomtathato karakterek tartomanyaban, raadasul en meg nem talaltam ra maganak a serialize-nek a szintaxisara. Ellenben a JSON ember altal is olvashato, es jol definialt szintaxisu, valamint egyaltalan nem tartalmaz nem-nyomtathato karaktert.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Parsing != Validating.

nem allitottam azt, viszont ahogy a linkelt cikkben is all, rekurziv strukturakat nem lehet tokeletesen validalni regexel.

Egyebkent a regex hasznalata egyszerubb mint az allapotgepeke, es sokszor gyorsabb is osszerakni egy megfelelo regexet.

persze, de ettol meg mindig nem lehet vele rekurziv strukturat tokeletesen validaltatni csak regexel.

A serialize altal generalt adat csak majdnem plaintext, mivel tartalmaz \0 karaktereket is, ami mar nincs benne a nyomtathato karakterek tartomanyaban, raadasul en meg nem talaltam ra maganak a serialize-nek a szintaxisara. Ellenben a JSON ember altal is olvashato, es jol definialt szintaxisu, valamint egyaltalan nem tartalmaz nem-nyomtathato karaktert.

ez igaz, de ez meg mindig irrevelans az eredeti problemammal kapcsolatban (barmely rekurziv struktura csak a struktura kibontasaval validalhato.)

btw: amugy irtam anno php sessionoket iro olvaso osztalyt, az meg kicsit elbaszottabb format is kovet (asszem a session tomb kulso a:x:{} -ja hianyzik a struktura korul), szoval lehet ra irni ilyesmit (utolag persze inkabb session_encode/session_decode lett belole)

Tyrael

Igazabol a serializalas mindig is veszelyes, mert nem tudhatod, mit unserializalsz vissza.

Mint irtam nekem az a problemam a serializalassal (legyen az serialize, vagy json_encode -dal letrehozott adat) hogy az igy kepzett stringet mar nem lehet validalni anelkul, hogy vegrehajtanad rajta a unserialize/json_decode eljarast, ergo ha az adott fuggvenyekben van sebezhetoseg, akkor az szopo.

A session-nal meg elojon az, hogy aki nem validal egy nem-belso tombot, azt maglyan kell felkotni.

Itt megint inkabb arra kell gondolni, hogy a sajat rendszeredben lehet valid alairas/felhasznalonev/egyeb. pl. az a string, ami fel tud boritani egy unserialize hivast.

Egyebkent pedig sajat "serializacio" irasa nem olyan nehez, egy tombot vagy egy hash-t (ha nem mely es nem objektumokat tarolsz bennuk) siman at lehet alakitani stringge kezzel (megoldva ezzel az SQL oszlopos problemat).

persze, meg irhatnek relacios adatbaziskezelot is, ami nem erzekeny az injection-re, de nem ertem hogy ez miert zarja ki, hogy a sajat implementaciomban is maradjon kihasznalhato sebezhetoseg.

Tyrael

"ami fel tud boritani egy unserialize hivast."
Akkor arra is validalni kell. Es akkor maris a sajat rendszerben sem lesz valid.

"de nem ertem hogy ez miert zarja ki, hogy a sajat implementaciomban is maradjon kihasznalhato sebezhetoseg."
Nem azt mondtam, hogy hibatlan lesz, de mas fajta serializacio eseteben masfajta hibak vannak. Az, ami a beepitett serializaciot megboritja, jo esellyel a sajat implementaciot nem boritja meg. Es a rossz szandeku felhasznalok elsosorban az elterjedt hibakat fogjak kihasznalni, mert azzal meg mindig tobb oldalt tudnak feltorni, mint egy teljesen custom eljarassal valo kinlodassal.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Akkor arra is validalni kell. Es akkor maris a sajat rendszerben sem lesz valid.

nem erted a lenyeget.
az volt a problema hogy a php unserialize methodja invalid serializalt adattol nem a var viselkedest hozza.
egyreszt ezt en nem tudhatom elore
masreszt ha tudom is hogy van egy ilyen bug, eleg maceras egy tetszoleges melysegu es tartalmu tombbol egy a specifikacio szerinti modon letrehozott stringet validalni.
ha erre irok egy jo validatort, akkor gyakorlatilag megirtam a php unserialize methodjat php-ban.

Nem azt mondtam, hogy hibatlan lesz, de mas fajta serializacio eseteben masfajta hibak vannak. Az, ami a beepitett serializaciot megboritja, jo esellyel a sajat implementaciot nem boritja meg. Es a rossz szandeku felhasznalok elsosorban az elterjedt hibakat fogjak kihasznalni, mert azzal meg mindig tobb oldalt tudnak feltorni, mint egy teljesen custom eljarassal valo kinlodassal.

http://en.wikipedia.org/wiki/Security_by_obscurity
ez tobbnyire csak akkor segitseg, ha te a random script kiddieg celpontja vagy.
amikor olyan rendszert fejlesztessz, ahol mar komoly penzekbe kerul, ha megnyomjak a rendszert, ott nem alapozhatsz erre.
Tyrael

Az exploitot működés közben Stefan Esser mutatta be a szingapúri SyScan'10 konferencián. A kérdés az, hogy a php jogaival futtatható tetszőleges kód vagy root jogot is lehet szerezni.

root jog szerzese fel sem merult sehol.
a php-ban nem talalhatnak olyan hibat, ami a php-t futtato user privilegium emeleset okozhatna.
az mar oprendszer/kernel lyuk lenne.

amit most lehet tudni, es a CVE-ben is benne van, hogy informacio szivarogtatas es tetszoleges kodfuttatast tesz lehetove.

amit meg erdemes tudni, hogy Stefantol szarmazo infok alapjan az altala bemutatott exploit nem mukodik suhosin patchelt php-n (ezert demozott Fedora-n, mert az az uccso major disztro amiben nincs benne)

Tyrael

Volt, hogy egy root joggal futó php-met nyomták fel, még a shutdown-t is próbálták linuxos aggyal paraméterezni, természetesen sikertelenül, dehát freebsd jail-ben ez egyébként is így járás ;)

linuxon mindez elég szomorúan végződött volna. Lehet ezért nem használom?..

[ #FreedomFlotilla ] [ hupexpertize© ] [ hupdiploma ]

miert kellett root-tal futnia btw?
a frebsd-s jail pedig egy nagyon jo dolog.
linuxot kellett volna egy grsecurity hogy ne legyen para.
ettol fuggetlenul nem jo jel, ha fel tudjak nyomni a webappot, lehet ott inkabb mar a php meg a raepulo alkalmazas volt a rendszer leggyengebb pontja.

Tyrael

Nem ertem, mi a baj a ruby szintaxisaval. Sokkal jobb, mint az ObjC-e, hidd el. Sokkal termeszetesebb, raadasul ha akarod, nyugodtan hivhatod a metodusokat method(param) formaban, senki nem akadalyoz.

Pythonnal szerintem az egyetlen nagyobb problema a tabulalas kotelezosege. Mas hibajat en nem latom.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

"Hogy érezzem hogy freebsd-n ezt is megtehetem ;))"
helyesbitek, akkor jelenleg te vagy a leggyengebb pont a rendszerben. :)

"Nem "ott", hanem mindenhol. PHP must die"
nem jon ki ra gyakrabban remote exploit mint a tobbi scriptnyelvre.
tehat nem security szempontbol szar szerintem elsodlegesen, hanem mert kurvanagy user bazis van mogotte, es egyszeruen tanulhato, emiatt sok kezdo hamar er el vele sikereket, emiatt sok a szar kod.

Tyrael

Nem csak emiatt. Mar sokszor elmondtam, hogy maga a platform (ami fuggveny/objektumkeszletet default ad a nyelv) atgondolatlan, inkonzisztens, egyszeruen hianyzik belole az egysegessek erzese. Mintha tomentelen kis apro ganyolt kulso libet hasznalnek. Es ezt nevezik core-nak. Vicces.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Sznob lennek? Lehet. De a Ruby tenyleg merfoldekkel konzisztensebb, mint a PHP, ezert is szeretem jobban.

A begin-raise-rescue pedig nem olyan rossz dolog, ha valaki kepes jol hasznalni. Persze, ehhez le kell vetkozni a C++, Java, meg egyeb attitudoket, mert a Ruby egyik sem.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

http://security.freebsd.org/advisories/FreeBSD-SA-07:01.jail.asc
http://security.freebsd.org/advisories/FreeBSD-SA-04:03.jail.asc

Lattunk mar olyan sebezhetoseget a jail-ben, amit csak jail superuserrel lehetett kihasznalni, szoval ha nem szukseges, akkor szerintem felesleges kockazat root-tal futtatni a szolgaltatast a jailben(Principle of least privilege mond valamit?).

Tyrael

szerintem ha osszeraknank az osszes usered kommentjeit (a torolteket is) akkor jocskan benne lennel a top hup "contributor" mezonyben.
mas kerdes hogy ha kizarnank minden kommented, amiben benne van a debian openssl fiasko binugz szavak valamelyike, akkor jelentosen csokkenne az ervenyes hozzaszolasok szama. :P

Tyrael