fbpx Skip to content

Az alábbi cikket Ys. írta a 0×90 blogon, és mivel a cikksorozata kapcsolódik az iPhone-hoz, mi érdekesnek gondoljuk a számotokra is, így ezeket engedelmével egymás után át is emelnénk ide, a Szifonra.

***

Az SSL az az intézmény, ami A használható eszköz hálózati forgalom bevédésére. Tulajdonképpen nem is nagyon van olyan hálózati forgalmat bonyolító alkalmazás, ami így vagy úgy, de ne használná. Kicsit távolabbról nézve a dolgot, az SSL olyan, mint a Mátrix: “It is all around us.”

Az SSL voltaképp a bizalomról szól, arról, hogy mennyire bízunk egy nyilvános kulcsban. Könnyed bevezetőként először is nézzük felhasználói oldalról a dolgot: mi történik az iOS felületén, ha büdös a tanúsítvány pl. a Safariban? Milyen üzenettel tájékoztatja a felhasználót? “Kedves felhasználó! Valaki megpróbálja épp lehallgatni a hálózati forgalmadat! Ha ezt engedni akarod, üssél rá a Continue gombra, de inkább ne tegyél így, ha érzékeny adatokat szeretnél forgalmazni!” Neeeeem.

Akkor most egészen pontosan mi is az üzenet? Safarit érintő hibáról tájékoztatja a felhasználót: nem tudta verifikálni a beütött HTTPS-szerver identitását. Ez azt sugallja, hogy amúgy minden rendben van, de a Safari b@szakodik megint, valami gyíkja van. Ilyen felvezetővel viszont a felhasználók nem fogják megnézni, hogy a “Details” gomb után mi lehet – amúgy ha meg is nézik, maximum egyszer fognak így tenni, ugyanis a “Details” gomb után feldobja a certificatenézegető beállításpanelt, további leírás vagy tájékoztatás nélkül. Teljesen biztos vagyok abban, hogy ez még az életben senkit sem tántorított el attól, hogy Continue-t üssön reflexből.

Az Apple amúgy is notórius vendor olyan tekintetben, hogy az openSSL “hivatalos” branchéhez képest akár évekkel később javítanak ki sebezhetőségeket (pl. Basic Constraintes Marlinspike-támadás 2002-es publikálásához képest a 4.3.5-ös iOS-ben fixálták ki a hibát 2011-ben. No comment.)

Amikor iOS-es alkalmazások SSL-kezelését teszteljük, van néhány tipikus hibaforrás, ami az esetek 99%-ában megtalálható, amikor az adott alkalmazás először jár nálunk a homokozóban.

A medve nem játék, az iPades alkalmazás meg nem böngésző.

A legtöbb SSL-implementációs probléma onnét ered, hogy a kütyük tömeges elterjedéséig böngészőkben találkoztunk vele meg desktop alkalmazásokban, ahol a támadó maximum a hálózati folyamhoz férhet hozzá pl. ARP poisoninggel, de nem valószínű, hogy hozzáfér fizikailag az eszközhöz. Ez a helyzet gyökeresen megváltozott azzal, hogy egy iPhone-t vagy iPadet caklipakli el lehet lopni, és a tesztelt alkalmazások fejlesztőinek számolniuk kell az eszközhöz fizikailag is hozzáférő támadó esetével.

Böngészők esetében ugye az alábbiakat nézzük meg a tanúsítványon:

  1. Érvényes (nem járt le)
  2. Annak a webszervernek a neve szerepel a CN mezőben, akitől kaptuk
  3. Aláírta valami megbízható CA a tanúsítványlánc elejét

Ez a megközelítés hatástalan abban az esetben, ha a támadó hozzáfér az iOS felületéhez, ugyanis ebben az esetben simán hozzá tud adni egy új tanúsítványkiadó hatóságot (CA) az eszközben található listához, generál egy érvényes tanúsítványt a HTTP/TCP proxy-jához és zokszó nélkül azon keresztül fogja az alkalmazás bonyolítani a forgalmát.

Egy esetben a fejlesztők ennek a MiTM-es támadásnak a kivédésére két változtatást implementáltak a következő verzióban, ami postafordultával visszajött a riportunk után, és ezek remekül rávilágítanak arra, hogy mennyire nehéz is a feladat:

  1. Kliensoldali tanúsítványt tettek be, jelszóval. Enélkül a szerver SSL szinten dobja el a kapcsolatot.
  2. Az alkalmazás nem veszi figyelembe az iOS-es HTTP-proxy beállításokat, minden esetben közvetlenül próbálkozik.

Az első pontot úgy cseleztük ki, hogy az alkalmazás binárisát felboncolva megtaláltuk a bedrótozott és base64-enkódolt tanúsítványt, a jelszavát pedig pár sorral arrébb találtuk meg IDÁban. A második probléma megoldásához pedig egyszerűen annyit csináltunk, hogy a saját DNS szerverünket adtuk meg a DHCP-válaszban, amikor az (ellopott) eszközzel csatlakoztunk a homokozós wifihez.

Oké, akkor mi legyen most, jöhet a kérdés – lássunk két gyakori megoldást-megoldási kísérletet, előnyökkel és hátrányokkal, ha már az iOS default ellenőrzését ilyen ügyesen ki tudjuk cselezni. Nyitott vagyok minden javaslatra, ha van gondolatotok, ne tartsátok vissza a kommentekben.

A felhasználó jelszava nyitja ki a kliensoldali tanúsítványt, hogy mindenképpen kelljen megfelelően authentikáló felhasználói interakció a hálózati forgalom elindításához. Trükkös gondolat, viszont ha HTTP-szerű működésben gondolkodunk, akkor a kliensoldali tanúsítvány akkor ér valamit, ha a szerver el is tudja utasítani. Egy lehetséges támadás ez ellen a módszer ellen az, hogy lecserélem/átütöm a kliensoldali certet valami ismert jelszavú tanúsítványra, gdb-t használva becsempészem a valódi jelszót és amikor az app forgalmazni kezd, az én kis mindent elfogadós HTTP proxy-mban már látom is, hogy az alkamazás mit akart küldeni a szervernek.

Ellenőrizzük, hogy a tanúsítványt aláíró CA rootcertjének fingerprintje ismert és előzőleg tárolt érték-e. Nyilvánvaló hátránya a módszernek, hogy ha új certet deployolnak, akkor hirtelen nem fog működni az alkalmazás, plusz a támadó ezt az “ismert jó” fingerprintet simán felül tudja csapni a binárisban.

További érdekes kérdés, hogy mi történjen az olyan alkalmazások esetében, amik rendszeresen bejelentkeznek (pl. VoIP appok, gTalk). Ha nyafog a cert miatt, az rontja a felhasználói élményt, ha nem, az meg a biztonságot. Ha csendben nem csatlakozik megfelelő cert hiányában, az a legrosszabb, a felhasználó annyit fog látni, hogy “van internet”, de nem tudja használni az alkalmazást – és itt bele is csöppentünk a használhatóság vs. biztonság nehézsúlyú ökölvívómérkőzés következő menetébe.

Összességében annyit mondhatunk, hogy nincs általános érvényű megoldás a hálózati kommunikáció védelmére, mindig az adott alkalmazás működéséhez kell igazítani a megoldást. Ami működik a böngésző-szerver világban, az nem fog, ha egy az egyben átültetjük iOS-es alkalmazásra.

Néhány pont a végére, gondolatébresztőnek:

  1. Minél többféle hálózati kommunikáció zajlik a háttérben, annál nehezebb megvédeni. Többféle kommunikáció alatt olyasmit értek, hogy pl. egy tipikus VoIP app fenntart egy sessionkezelési és egy SRTP-s csatornát.
  2. Minél inkább pattanós felhasználói érzést szeretnénk nyújtani, annál nehezebb megvédeni a hálózati kommunikációt (a “pattanós érzés” itt a seamless user experience magyarítása próbál lenni).
  3. Ha az alkalmazást rá lehet venni arra, hogy hálózati kommunikációba kezdjen, mielőtt a felhasználó authentikálta volna magát a GUI-n, akkor nagyon nehéz kivédeni, hogy dönthető legyen.

Update.

A certificate-kezelés kérdésére két megoldásba is belefutottam, mióta kiraktam a posztot. Az egyiket dc4420-on hallottam, a másikat meg a belsős fejlesztőcsapatunk ötlötte ki – hiába no, tanulnak a srácok. 🙂

Egy. Tudta-e Ön, hogy az iOS-es Twitter-app legfrissebb verziójában már certificate pinninget használ? Bele van derótozva a binárisba egy certificate, és minden esetben ezt a certet keresi, különben dobja a kapcsolatot. A defconos kolléga szerint ez elsősorban az iráni/szíriai/líbiai kormány tömeges MiTM-támadásai ellen lett bevezetve.

Kettő. A belsős iOS fejlesztőteamünk talált ki egy egészen ügyes megoldást arra, hogy hogy lehet kliensoldali certet deployolni úgy, hogy ne legyen bedrótozva a jelszó a binárisba. Pofonegyszerű: amikor felrakod az appot, nem működik a hálózati szinkronizálás – ahhoz, hogy ez a fícsör használható legyen, iTunes-on keresztül be kell rántani egy frissen generált kliensoldali certet, amit a felhasználó erős jelszava nyit. Ez a megoldás meg ügyesen kihúzza a méregfogát a “difótból jön a cert”-megközelítésnek.

Olvasd el a hozzászólásokat is

2 Comments

  1. Annak idején az SSL-t, mint titkosítási eljárást úgy találták ki, hogy belátható időn belül sem online sem offline nem lehetett törni egy bizonyos időn belül. Alapvetően a titkosítási algoritmusok valamelyikével és 3db kulcspárral lehet megoldani a tökéletes titkosítást szerver – kliens között.
    Név szerint: szerver cert és kulcs, kliens cert és kulcs és aláíró cert és kulcs.
    Amit ma SSL titkosítás gyanánt használnak a legtöbb helyen, az sajnos korántsem elégíti ki a a titkosítási eljárás minimális szintjét. Előszeretettel szeretik elhagyni a kliens certificate -et, nyilván költség megtakarítás miatt, különben az SSL használata nagyon drága lenne.

    De azért ne feledkezzünk meg róla, hogy az SSL akkor SSL, ha megvan a két tanusítvány és azt egy közbenső (mindkét fél által elfogadott) aláíró aláírta. Amíg ez nincs meg, addig ha ott is van, hogy SSL, a biztonság csak illúzió. Megtörése nem csak idő kérdése, mint az eredeti koncepció szerint.

    Írásomra bizonyítékot is találhattok a bankok ÁSZF -ében, ahol semmiféle felelősséget nem vállalnak az adatkapcsolatra… 😀

    Akit ez a dolog bővebben érdekel, az olvasson esetleg utána a Men in the midlle attack nevű támadási eljárásnak. 😀

  2. @kotta: Igen, a man-in-the-middle egy jo pelda erre, ugye az in-app vasarlasokat “ingyenesito” orosz hacker is pontosan azt csinalta, amit YS itt leir: sajat proxy, sajat cert, oszt hadd szoljon 😀


Add a Comment