Protokoll lehallgatás SSL-n keresztül

Sziasztok, következő a szitu:

Adott egy program, amely egy szerverrel kommunikál a 443-as porton (azaz SSL), viszont nem webszerver. Nyilván egy wireshark mit sem tud kezdeni a csomagok tartalmával, hiszen a szerver privát kulcsa nélkül nem tudom visszafejteni az adatokat. Szeretném kideríteni, hogy HOGYAN kommunikál a kliens a szerverrel.

Az ötletem az volt, hogy csinálok egy SSL szervert (openssl s_server ...), átirányítom a cél IP-t az általam létrehozott szerverre, és látom, hogy a kliens milyen adatot küld. Ezután egy klienssel (openssl s_client ...) csatlakozok az eredeti szerverhez, elküldöm azt, amit a lokális szerveren kaptam a programtól, és megkapom rá a választ. Eddig meg is vagyok.

Ámde ezt szeretném automatizálni (azaz ne kelljen csomagonként ezt eljátszanom), vagy még jobb egy olyan környezetet kialakítani, amelyet wireshark-al tudok monitorozni. Alapvetően azt szeretném elérni, hogy egy teljesen transzparens réteget húzzak a program és az eredeti szerver közé.

Az ncat és openssl -l próbálok bűvészkedni, de nem jutok egyről a kettőre. Főleg az a gondom, hogy az ncat -nek egyszerre nem tudom használni az SSL támogatását és a szkript végrehajtást / session output-t.

Röviden mit szeretnék elérni: Egy meglévő SSL-es szerver-kliens közé tenni egy általam létrehozott SSL-es kliens-t és szervert, amelyek megfelelő irányban továbbítják az adatokat. Ekkor már az általam létrehozott szerver privát kulcsával (jól gondolom?) belenézhetek a csomagokba.

Tudtok valamit javasolni? Köszi.

Update: openssl s_client és openssl s_server illetve a megfelelő IP forward beállítások mellett szépen tudok kommunikálni a szerverrel és a klienssel is plaintext-ben (legalább az account jelszavát titkosítva küldik...). Ebből az következik, hogy se kliens-oldali, se szerver-oldali azonosítás nincs. Most a socat tool-al próbálkozok, ígéretesnek tűnik, mert tud shell-scriptet futtatni SSL mellett ami így első ránézésre elég lesz nekem. Ha van fejlemény, megírom.

Megoldás:
A megoldás csak olyan esetben működik, amikor nincs kliens oldali és szerver oldali azonosítás! A lenti megoldáshoz feltételezzük, hogy a valós szerver (REALS) címe 1.2.3.4 és mint mondtam, a szolgáltatás a 443-as porton üzemel. A valós kliens (REALC) tehát ehhez kapcsolódik. A megoldás módszere az, hogy létrehozunk egy SSL klienst (VIRTUALC) és szervert (VIRTUALS), és biztosítjuk, hogy kétirányú kommunikáció történjen REALC <-> VIRTUALS, VIRTUALS <-> VIRTUALC és VIRTUALC <-> REALS között. Másrészt el kell térítenünk a valós forgalmat, hogy rajtunk menjen keresztül. Na nézzük:

1. REALS certificate-jének beszerzése
$ openssl s_client -host 1.2.3.4 -port 443, majd a kapott certificate-t elmentjük a reals.crt fájlba.

2. VIRTUALS certificate készítése

$ openssl genrsa -out server.key 1024
$ openssl req -new -key server.key -x509 -days 3653 -out server.crt
$ cat server.key server.crt > server.pem; rm server.key

3. Forgalomirányítás

$ sudo iptables -t nat -A OUTPUT -p tcp --destination 1.2.3.4 -j DNAT --to-destination 127.0.0.1:4000
$ sudo iptables -t nat -A OUTPUT -p tcp --destination 10.10.10.10 -j DNAT --to-destination 1.2.3.4:443

A második irányítást nemsoká látjuk, hogy miért is kell.

4. VIRTUALC és VIRTUALS beizzítása

$ socat -v SSL:10.10.10.10:443,cafile=reals.crt SYSTEM:"openssl s_server -accept 4000 -cert server.pem -no_dhe -no_ecdhe" 2> txrx.log

A socat-nek nem jó az SSL-LISTEN módja a jobb oldalra, mert valami miatt több egymás utáni kapcsolatot nem volt képes kezelni még a fork,reusaddr kombóval sem. Másrészt a bal oldalra nem írhatjuk a valós szerver címét (1.2.3.4), hiszen a forgalomirányítás miatt egy körkörös láncot kapnánk. Ezért kellett bevezetni egy új címet, és azt irányítani a valós címre.

Ez a megoldás ha jól gondolom (javítsatok ki, ha nem) használható MITM támadásra is, amennyiben a forgalomirányítást meg lehet csinálni az adott hálózatban, és mint mondtam, nincs kliens oldali és szerver oldali azonosítás (amely sajnos nagyban igaz).

Huhh, sokat tanultam ma is. :) Használjátok egészséggel, saját felelősségre.

Hozzászólások

Ha ertelmesen csinaltak meg ezt a programot, akkor benne van a server publikus kulcsa, szoval csak vele lesz hajlando kommunikalni. Ez direkt az ilyen man-in-the-middle attack ellen jo, amivel te is probalkozol.

--
Az emberek azt állítják, hogy múlik az idő, az idő viszont csak mosolyog, mert látja, hogy az emberek múlnak. - tibeti közmondás

SSL gyakorlatilag csak akkor biztonságos kliens-szerver között, ha
1. nem hálózaton keresztül van a pubkulcs csere
2. nem hálózaton keresztül van a pubcert csere
3. nem bízol meg csak saját CA-ban s azt is megsemmisítetted, amint kiadtad a két végére a kulcsot/certeket/ca certet és mind a két végén sk betetted a programba

Ha a fentiek nem teljesülnek jó eséllyel lehet MITM támadást csinálni. Persze vannak különböző nehezítések... csak ügye az emberi tényező... (ha az user el akarja érni az adott oldalt, addig tekergeti a biztonsági beállításokat amíg az nem működik -tisztelet a kivételnek-... innentől kezdve mind1)

Zorp mint fentebb írták vállalati szférának applikációs tűzfalán csináltak ilyesmi megoldást (amúgy szerintem jogilag megkérdőjelezhető ez az elvű belenézés a forgalomba)... valamint több programi is szakosodott arra (pl Cain&Abel windows alatt), hogy reptében generál egy új kulcsot azonos névvel mint az eredeti, majd proxyzza a kettőt és kész.

Szóval nem lehetetlen amit fent írsz, kérsz... erkölcsileg megkérdőjelezhető (nem kell erre válaszolnod), s elsősorban a felhasználók hülyesége, megtévesztésén múlik.. illetve ha van kontrollod a kliens gépen, akkor egyszerűen saját CA-t telepítesz bele, amiben maximálisan megbízik... s onnantól azt generálsz olyan névvel amit akarsz...

Bár amit szeretnék elérni felfogható MITM támadásnak is, de mivel az egészet saját magam és a szerver közé teszem, és magamtól elviselem a "támadást", ezért erkölcsileg magamnak megbocsájtok! :D

Egyébként ha sikerül(ne) teljesen feltérképeznem a protokollt ahogyan kommunikálnak, és megvalósítok egy saját klienst, az milyen módon támadható jogilag? Gyakorlatilag arról van szó, hogy nem tetszik a kliens, de az adat, ami jön az kell. :)

"Bár amit szeretnék elérni felfogható MITM támadásnak is, de mivel az egészet saját magam és a szerver közé teszem, és magamtól elviselem a "támadást", ezért erkölcsileg magamnak megbocsájtok! :D"
ettol meg az EULA-t sertheti, bar torvenyt nem: http://en.wikipedia.org/wiki/Reverse_engineering#European_Union de mielott meg kiadod a sajat klienst elolvasnam az aprobetut mert konnyen kiperelhetnek a nagragodbol.

Tyrael

Az, hogy 443-as port, egyáltalán nem jelenti, hogy ssl is megy ott. Ha valaki valami random protokollon szeretne az interneten beszélgetni, és elvárás, hogy a kliensek mindenféle belső hálózatokból tudjanak kommunikálni, akkor meglehetősen elterjedt módszer, hogy a 443-as portra rakjuk a szervert, arra ugyanis még proxy szerveren keresztül is ki szokták engedni a belső hálókból a gépeket.

Ha tényleg ssl megy ott, akkor a szerver certjére, és az ahhoz tartozó privát kulcsra lesz szükséged, ha a kliens ellenőrzi a szerver certjét. Ha nem ellenőrzi, akkor bármilyen certet használhatsz.
Ha a szerver certjéhez nem férsz hozzá (nem nálad fut valahol a szerver), és a kliensben nem kezelhető/állítható, hogy milyen certeket fogadjon el (azaz bele van hardkódolva, hogy csak a szervert üzemeltetők certjét fogadja el), akkor a nyilvános kulcsú titkosítás tökéletes megoldásával állsz szemben, azaz nem tudod az általad említett módon lehallgatni a beszélgetést. Az egyetlen megoldás ilyenkor, hogy bruteforce technikával feltöröd a kommunikációhoz használt kulcsot.

"Ekkor már az általam létrehozott szerver privát kulcsával (jól gondolom?) belenézhetek a csomagokba."
Nem, viszont a ket ssl-es komponensed kozotti kommunikacioba belenezhetsz.

"Tudtok valamit javasolni? Köszi."
Mi ilyenkor vagy ezt hasznaljuk, vagy (ha nagyon okos, meg amugyis szet akarjuk turni), akkor binary patching-el kihajitjuk belole az ssl-t.

--
"You're NOT paranoid, we really are out to get you!"

sslsniff vagy hasonlo(ssl mitm).
ettol fuggetlenul meg konnyeden elofordulhat (elo kellene hogy forduljon), hogy a a program tudja, hogy csak bizonyos certet, esetleg bizonyos kibocsajto altal alairt certet fogad el az ssl handshake soran.

Tyrael

Az SSL kapcsolatok szűrésére képes tűzfalak is ezt csinálják, pl zorp. De ebben az esetben minden tanúsítvány ami átmegy a tűzfalon, érvénytelen lesz. Kivéve ha minden böngészőbe fölveszed a tűzfalat mint cert server.

3. pontnál, sshuttle-ös megoldással:
ami átmegy forgalom az sshuttle-en fix értékre állítja a ttl-t, így azok a csomagok nem redirektálódnak...

-t nat -A OUTPUT -j sshuttle-12300
-t nat -A sshuttle-12300 -d 127.0.0.0/8 -p tcp -j RETURN
-t nat -A sshuttle-12300 -d REALS -p tcp -m ttl ! --ttl-eq 42 -j REDIRECT --to-ports 12300

jelen esetben 12300 porton fut az sshuttle