Tweets by @buherablog
profile for buherator at IT Security Stack Exchange, Q&A for IT security professionals

A BitBetyár Blog

Túljártál a nagyokosok eszén? Küldd be a mutatványodat! (e-mail a buherator gmailkomra jöhet)

Full-Disclosure / Névjegy / Coming out


Promó

H.A.C.K.

Címkék

0day (110) adobe (87) adobe reader (21) anonymous (26) apple (60) az olvasó ír (49) blackhat (20) botnet (22) bug (200) buherablog (44) buhera sörözés (39) bukta (49) deface (38) dns (22) dos (29) esemény (82) facebook (26) firefox (64) flash (33) gondolat (31) google (59) google chrome (36) hacktivity (37) hírek (117) incidens (224) internet explorer (88) iphone (35) java (50) jog (22) kína (21) kriptográfia (68) kultúra (21) linux (24) malware (43) microsoft (142) móka (48) mozilla (23) office (26) oracle (40) os x (43) patch (197) php (20) politika (31) privacy (58) programozás (22) safari (34) sql injection (62) windows (85) xss (77) Címkefelhő

Licensz

Creative Commons Licenc

A 7.5 milliós Facebook hiba 3 lépésben

2014.01.29. 12:47 | buherator | 1 komment

A HWSW egész jó összefoglalót közölt a Reginaldo Silva által felfedezett, a Facebook által 33.500 dollárral jutalmazott sérülékenységről. Most a Sensepost közölt egy mélyebb technikai összefoglalót, melyből kiderül néhány fontos részlet azzal kapcsolatban, hogy mégis hogyan lehet egy nagyjából szabványosank tekinthető OpenID autentikációból távoli kódfuttatást kicsikarni.

1. OpenID

A történet természetesen az OpenID-val kezdődik. Az OpenID egy nyílt autentikációs protokoll, melynek segítségével egy-egy kiválasztott szolgáltató igazolhatja a felhasználók "digitális személyazonosságát" több más szolgáltató felé. Példaként az oldal jobb szélén díszeleg a StackExchange kitűzőm:

A StackExchange oldalára pedig bárki be tud lépni (OpenID terminológiában ő a Relaying Party) pl. Google vagy Facebook azonosítójával (ők az OpenID Providerek), mindezt úgy, hogy a Stack Exchange a Google/FB jelszavunkat soha nem érinti. Így egyszerűsödik a jelszómenedzsment és csökken a támadási felület, mindenki boldog. 

Mivel az OpenID-t sok különböző szolgáltató használja, természetesen sok különböző megvalósítás is létezik, a problémák pedig hagyományosan itt kezdődnek. Reginaldo első lépésben nem is a Facebook iránt, hanem a népszerű OpenID megoldások iránt érdeklődött, és talált is hibát, először a Drupal megvalósításában, majd a Google szolgáltatásaiban is (ezért a cég 500 dolláros jutalmat ajánlott fel neki).

Mielőtt azonban a konkrét hiba részleteit taglalnánk lássuk, hogy hogyan is lehet az OpenID-t megetetni adatokkal! A felhasználónak (User-Agent) először is meg kell mondania a RP-nak, hogy OpenID-val szeretne belépni, ebben a lépésben pedig azt is közli a UA, hogy hol található a kívánatos OP. Az RP ez után elballag a megadott OP címére, és mindenféle adatokat kér tőle - hogy pontosan milyeneket, az a következő fejezetből derül ki, nekünk most arra érdemes odafigyelnünk, hogy a UA (vagyis esetünkben a támadó) a kezdeti kérés mellett az OP címét vagyis az OP által visszaadott adatokat is kontrollálja!

Vegyük észre továbbá, hogy Reginaldo esetében az Facebook nem OP, hanem RP szerepben van, a támadás az RP-ket célozza!

2. XML External Entity Injection

Miután megkapta az OP címét, az RP megkezdi az ún. discovery fázist, melyben lekérdezi az OP-től, hogy találhatók a tényleges szolgáltatás végpontok, ezek milyen verziójú OpenID protokollt támogatnak stb. Ezek az információk két féle forámban érkezhetnek: HTML-ben illetve XRDS-ben, utóbbi esetet nevezzük Yadis discovery-nek és lényegében egy XML alapú formátumról van szó.

Itt jön képbe az XML External Entity Injection: az XML entity-k (enetitások?) lényegében aliasok komplexebb (vagy nehezebben kifejezhető) struktúrákra, mindenki által ismert példák a < > &, melyek foglalt karaktereket helyettesíthetnek egy dokumentumban. Az entity-k behelyettesítését az XML feldolgozók általában automatikusan elvégzik. Az external entity-k annyiban különlegesek, hogy ez a behelyettesítés nem valamilyen elre definiált, szabványos módszer szerint történik, hanem a behelyettesítendő érték az XML dokumentumon kívüli, akár futtatókörnyezet, vagy operációs rendszer szinten elérhető adat alapján jön létre. Ilyen módon a következő dokumentumot (az OWASP-tól kölncsönöztem) feldolgozva az &xxe; entitás helyére a /dev/random "tartalma" kerül...

<?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///dev/random" >]><foo>&xxe;</foo>

... a folyamat (rosszabb esetben a rendszer) pedig memória hiányában összedől. Ha pedig a következő dokumentum tartalma feldolgozás után valahogy visszajut a felhasználóhoz, az /etc/passwd is kiolvashatóvá válik:

 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>

3. PHP

De hogy lesz ebből kódfuttatás? A fenti két lépés az OpeinID wikioldala elolvasása után nagyjából kézenfekvő lehet annak, aki tudja mi az az XEE, de aki kicsit beleásott a témába, az azt is tudhatja, hogy az ezek a támadások általában nem túl erősek az XML szabvány szigorú megkötései (karakterkészlet, jól formázottság) miatt. A magam részéről ilyen problémákkal szinte kizárólag Java alkalmazásoknál találkoztam - mint tudjuk, a Java meg az XML kéz a kézben jár, a népszerű javás XML feldolgozóknál pedig alapértelmezetten engedélyezett a külső entitások feldolgozása (ellentétben pl. a .NET-tel) - és a sérülékenységek besorolása általában megragadt a sárga-közepes kockázatú kategóriában. De hála a Tervezőnek, XML-t feldolgozni PHP-val is lehet...

A PHP egyik biztonsági körökben közkedvelt lehetősége a különböző erőforrás wrapperek használata. Egy egyszerű URL lekérdezéskor pl. a 'http://' wrappert hívjuk segítségül, hogy hozzáférjünk a webes tartalomhoz, de a php:// wrapperen keresztül (megfelelő konfiguráció mellett) egy helyi file include probléma egy csapásra kódfuttatássá varázsolható. 

A poén az, hogy ezek a wrapperek a XML entitások feldolgozásakor is működnek, így egy elegáns base64-el megoldhatjuk a formátumellenőrzésből fakadó problémákat:

<!ENTITY a SYSTEM 'php://filter/read=convert.base64-encode/resource=/etc/passwd'>

Az expect:// burkolóval pedig kódot is futtathatunk:

<!ENTITY a SYSTEM 'expect://id'>

Vége a játéknak.

Utóirat

Itt ragadnám meg az alkalmat, hogy (ismét) felhívjam a figyelmet az Offensive-Security összefoglalójára a saját bug bounty programjukkal kapcsolatos tapasztalataikról. Ajánlott olvasmány minden potenciális résztvevőnek, kiírónak, és hőbörgőnek!

Címkék: php facebook xml bug bounty xee xxe

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

|Z| 2014.01.29. 18:56:36

XXE is the new SQLi! :)
süti beállítások módosítása