2009. június 29., hétfő

Port scanning 1x1

Sok kérés érkezett azzal kapcsolatban, hogy írjunk az nmap-ról bővebben. Az alábbi összefoglaló a BME "Unix/Linux rendszerek üzemeltetése" c. tárgyában elhangzott előadás jegyzete. A jegyzet a 4.20-as nmap-hoz készült, a legújabb (4.90RC1) verzió számtalan egyéb szolgáltatást is tud - ehhez tessék megnézni az nmap officiál dokumentációját. További ajánlott irodalom a "man nmap" :)

A portscannelésről általában

TCP/IP-s protokollstacket használva gépünk több, mint 65.000 különféle porton kommunikálhat. Egy portnak alapvetően hat állapota lehet:

  • Open: a portra érkező csomagokkal foglalkoznak és van egy alkalmazás, amely reagál az ide érkező adatokra. A portscannelés legfontosabb célja, hogy az összes ilyet megtaláljuk.
  • Closed: a port reagál a kérésekre, de nincs alkalmazás, amely használná.
  • Filtered: a legidegesítőbb mind közül. A portot szűrik, és az nmap ebben az esetben nem tudja eldönteni, hogy open vagy closed állapotban van-e (azaz ha pl. egy tűzfallal kiszűrik valamelyik irányban a csomagokat, vagy kéréseink egy DROP-actionben végződnek a célgép iptables-beállításaiban.)
  • Unfiltered: bár a csomagjainkat nem szűrik, az nmap mégsem tudja eldönteni a port állapotát. Az ACK-szkennelés eredményezi.
  • Open/filtered: az nmap nem tud dönteni, hogy a port open vagy filtered. Az olyan szkennelési módoknál kapunk eredményt, amelyeknél az jelzi a port nyitott állapotát, hogy nem érkezik válasz (UDP, FIN, PROT, Xmas scantípusok).
  • Closed/filtered: ld. feljebb, csak itt a close és a filtered között vacilálunk. IPID idle scan esetén.

Az nmap scantípusai

  • sP: ping scan. Egyszerűen megpingeti a célpontol és ha választ kap, örülünk - máris van mire célozni a többi scantípust. Az alap mód az ICMP echo request/reply, ezt azonban mostanra sok helyen szűrik. Az ICMP azonban lehetőséget ad többfajta módra is, amivel a célpontot válaszra lehet bírni: ezeket nagyon nehézkes szűrni, és ha szűrik, fennakadásokat okoz a legitim hálózati forgalomban.
    • PE/PP/PM: ICMP echo, timestamp és netmask kéréseket küld a célpontnak.
    • PS/PA/PU: SYN, ACK és UDP csomagokkal bírja válaszra a célpontot. Fontos megjegyezni, hogy a -PS 80 működése nem azonos a portscannelés közbeni SYN csomagokéval: az előbbi célja egyszerűen annyi, hogy kiderítse, működik-e az adott IP-n valaki.
  • sS: a default, SYN scan. A TCP-s háromutas kapcsolatfelvételi mechanizmus első (SYN) csomagját küldi el a célportra. Ha érkezik rá SYN/ACK, akkor a port open, ha RST, akkor closed állapotban van. Ha ICMP port unreachable vagy semmi sem érkezik, akkor a port filtered. A leggyorsabb és legkedveltebb az összes scantípus közül, viszont kellő körültekintéssel kell élni az intenzitás megválasztásánál: gyakorlatilag DoS is megvalósítható vele és figyelmes rendszergazdák szűrni szokták.
  • sT: az aktuális oprendszer TCP protokoll-implementációjának connect() függvényét használja a kapcsolódásra, nem közvetlenül küldi ki a kapcsolatfelvételi csomagot. Akkor használatos, ha valamiért nem tudunk közvetlenül SYN csomagot küldeni (pl. nem root-ként indítjuk el az nmap-ot. Erre a „sorry, dude!” hibaüzenettel figyelmeztet is. Érdekes scantípus olyan szempontból, hogy ez a legzajosabb, ugyanakkor a legnagyobb rejtőzködést is ez biztosíthatja: zajos, mivel a kapcsolatokat minden esetben megpróbálja felépíteni, viszont megvan az az óriási előnye a többi scantípussal szemben, hogy proxyzható.
  • sM, sF, sX, sN: Maimon, FIN, Xmas és NULL scan. Gyakorlatilag ugyanarra a logikára működnek: beállítunk egy bizonyos értelmetlen flagbit-kombinációt a TCP fejlécében, majd útjára engedjük a csomagot. A Maimonnél a FIN+ACK, FIN-nél csak a FIN, az Xmas-nél a FIN+PSH+URG flagek vannak bekapcsolva, NULL-nál értelemszerűen semmi. Az egész játék arra megy ki, hogy a TCP RFC-jét teljes egészében megvalósító implementációk eldobják az ilyen értelmetlen csomagot, ha a porton értelmes forgalmat várnak (azaz nyitva van) és RST-t küldenek vissza, ha a port closed. Butább állapotmentes tűzfalakon keresztül is működik a dolog, azonban mivel a figyelmes rendszergazdák is olvassák az nmap dokumentációját, könnyen szűrhető - másrészt az nmap lehetőséget nyújt arra is, hogy a nyolc flagbitet tetszés szerint kapcsolgassuk a tapogatózáshoz (--scanflags kapcsoló).
  • sA: ACK scan. Különbözik az előzőektől – soha nem mondja azt, hogy a port open (ugyanis mindenképp RST csomag jön vissza, akármelyik állapotban is van igazából a port). Arra használatos, hogy a célgép előtt őrködő tűzfal szabályait puhatoljuk ki. A kipuhatolás olyan módon történhet, hogy megscannelünk egy gépet, amelyről biztosan tudjuk, hogy a tűzfal mögött található. Ha a tűzfal helyesen beállított állapottartó, akkor nem fogunk választ kapni a csomagjainkra (ugyanis ACK csomagok nem kezdhetnek legitim kommunikációt). Ha azonban figyelmetlenül van bekonfigurálva és egy-egy portot szabadon hagy, akkor a célgép RST csomagot fog válaszul küldeni függetlenül attól, hogy a simogatott port open vagy closed állapotban van-e. Az nmap ezeket a portokat unfiltered-ként fogja jelölni.
  • sW: Window scan. Pontosan ugyanúgy működik, mint az ACK scan, viszont bizonyos rendszerek/implementációk esetén képes különbséget tenni a szűretlen portok open/closed állapotai között. Az alapötlet az, hogy a visszaérkező RST csomag TCP fejlécében a window mező értéke ezen implementációk esetében nulla, ha a port closed, viszont pozitív, ha open. Ha a éppenséggel nem jön be a window mezők különbözősége, széttárja a karját ésnem azt mondja, hogy unfiltered - ilyen értelemben pedig használhatóbb, mint a mezei ACK scan.
  • sI: Idle scan. A legkifinomultabb mind közül - azon alapszik, hogy nem a saját gépünkről végezzük a scannelést, hanem egy Ártatlan Áldozat forgalmát manipuláljuk úgy, hogy végül is portscannelést hajtson végre a célgépen. Ennek megfelelően a scan eredménye azon portok listája lesz, amelyet az áldozat lát! A következőképp működik: az operációs rendszer minden általa kiküldött csomagnak egyedi számot ad: ez az IP fejlécben lévő IPID érték. Butább operendszerek (pl. Xp, vagy a legtöbb nyomtató oprendszere) inkrementálisan növelgetik ezt a mezőt az egymás utáni csomagok kiküldésekor. A Támadó két dolgot csinál egyszerre: egyrészt folyamatosan SYN csomagokat küld a zombi egy ismert, unfiltered portjára, amire az annak rendje-módja szerint válaszol. A kettes pályán olyan csomagokat küld a hálózatra, amelyek feladója a zombi, címzettje pedig a célpont: a célpont nyilván a zombinak fog válaszolni ezekre a csomagokra. A varázslat itt jön: ha a célpont nyitott portját szólította meg a csomag, akkor a zombi egy SYN/ACK-ot kap, amire neki RST-t kell küldenie. A kiküldött RST viszont ugrást fog okozni az egyes pályán, a támadónak visszaküldött RST-k (nyitott port esetén SYN/ACK-ok) IPID-szekvenciájában - a támadó pedig pont erre figyel. Számos tulajdonsága közül a tisztasága a legvonzóbb; a saját ip-tartományunk vagy MAC-címünk soha nem kerül a célpontra felügyelő IDS-ek elé. Hogy hogyan találhatunk zombit? Nagyon egyszerű: használjuk a Nessust, vagy az nmap -A kapcsolós scan után is megmondja.
  • sO: Kitapogatja, hogy az IP-re épülő protokollok (UDP, TCP, ICMP, IGMP,...) közül melyekre hallgat a célpont, így igazából nem is portscanner a szó hagyományos értelmében. A TCP fejlécben beállítjuk a tapogatott protokoll azonosítóját, majd elküldjük a csomagot a célgépnek. A headerek korrekt kitöltésével a legtöbb esetben nem is foglalkozik az nmap: ha ICMP protocol unreachable érkezik vissza, akkor a protokollt closed-nak nyilvánítjuk. Ha érkezik válasz az adott protokollra, akkor open, ha pedig egyéb ICMP hibaüzenetet kapunk, a protokoll filtered. Ha az újraküldés után sem érkezik semmi, a protokoll open/filtered.
  • b: FTP bounce scan. Az eredeti RFC szerint való FTP-szerverekben van egy feature, ami azt csinálja, hogy csatlakozva egy FTP-szerverhez kérhetjük, hogy a file-okat egy harmadik félnek küldje! (Egy ideális világban ezzel lehetne megoldani egyszerűen azt, hogy az A gépen ülő júzer a B gépen lévő fájlokat a C gépre juttassa úgy, hogy az A gépen csak a parancscsatorna megy keresztül, maguk a másolt fájlok nem.) Ezen a sec. hole-on persze egy tankhajó is keresztülfér, így aztán a legtöbb implementációban egyszerűen nem engedélyezik ezt a proxy-szerű funkciót. (Gondoljunk bele: pl. wardrivinggal lesniffelünk egy plaintext ftp-bejelentkezést, majd a megszerzett usernévvel-jelszóval feltöltjük az ftp-szerverre az exploit kódját és ha az ftp-szerver támogatja ezt a proxy-funkciót, akármelyik hosztra ráuszíthatjuk a vállalati hálózaton...) Portscanre eléggé triviális rávenni az ilyen ftp-proxyt: egyszerűen megmondjuk a célgép ip-jét és a minket érdeklő port számát és az ftp-szerver elvégzi a piszkos munkát azzal, hogy megpróbál áttölteni valamit.
  • sU: UDP scan. A TCP-től eltérően az UDP kapcsolat- és állapotmentes, így a scan úgy történik, hogy egy üres UDP csomagot küldünk a célgép egy portjára. Ha ICMP port unreachable jön vissza, a port closed, ha egyéb ICMP hiba, akkor open/filtered. Ha értelmes válasz érkezik UDP-n, akkor a port nyitva van. Tipikus használati módok: DHCP, Kazaa, játékok stb. felderítésére (egyébként érdemes elgondolkozni, hogy a hentelés közben harmadszorra is felugró, figyelmeztető tűzfalablakon a felhasználók legnagyobb része mindent megenged az adott játéknak). A legnagyobb nehézséget az UDP-s scannelésben az jelenti, hogy megfelelő időlimitet válasszunk a port felé küldött csomagok között. Fontos megjegyezni, hogy bámelyik TCP-s scan móddal használható karöltve, TCP-s scanmódokat nem lehet egymással zatyulni!
Az NMAP portkezelése


Az NMAP lehetőséget ad arra is, hogy megadjuk a minket érdeklő portok listáját. Az alábbi kapcsolók segítségével érhető el a portkezelés:

  • -p: megadható port, porttartomány. Ha -sO kapcsolóval együtt használjuk protokollscannelésre, a protokollok kódját kell értelmszerűen megadnunk.
  • -F: gyorsított scannelés, a leggyakoribb portok listáját pörgeti végig. Ha kerülni szeretnénk a feltűnést, kiváló választás; az nmap_services file-ban lehet személyre szabni a listát.
  • -r: nem keveri meg a kipróbált portok sorrendjét, hanem egyszerűen elindul az 1-esen és addig megy, amíg el nem éri a 65535-öt.
  • --allports: nem hagy ki egy portot sem a portscanből. Általában érdemes átugrani a 9100-as portot, mivel sok nyomtató egyszerűen kiírja az ide érkező adatokat (ezáltal sok-sok mókusnak otthont adó erdőt kell kivágni az elpazarolt papír miatt, amint számtalan oldalnyi SSL-handshake-et vagy HTTP-kérést nyomtatunk nagy lelkesen).


Hátborzongatás

A fenti funkciók mellett az nmap még egy sereg dologra is képes, ezek között vannak elég hátborzongatóak is (jelen sorok írója például egészen elképedt, hogy egy háromnapos, tűzfalazott, otthoni használatra szánt Xp-n mennyi nyitott port is van és hogy az nmap a nyitott portok mellett egy sereg információt is megmond a gépről...) Ezen funkciók közül az operációs rendszer és a rajta futó szolgáltatások típusának és verziószámának(!) kiderítése a leghasznosabb - mind a rendszergazda, mind a Gonosz Cracker szempontjából.

A hátborzongató funkciók elérésére szolgáló kapcsolók az alábbiak:

  • sV, A, : verziódetektálás. Az nmap a tcp stack tulajdonságai és különféle nem szabványos csomagokra történő válaszok alapján több száz oprendszert tud felismerni és ha nem biztos a dolgában, három-négy lehetőséget ad vissza.
  • O: operációs rendszer detektálása. Az A kapcsoló tartalmazza.
  • --version-intensity: azt állíthatjuk be vele, hogy mennyire gyanakodjon szokatlan helyeken futó szolgáltatásokra. 1-től 9-ig lehet értéket adni - minél magasabb, annál valószínűbb a helyes diagnózis, viszont annál hosszabb ideig tart a scannelés.
  • --version-light: ~--version-intensity 2
  • -sR: RPC-re szolgáló portok felderítésére használható. Portscan után végignézi a nyitott portokat és a SunRPC NULL parancsával elárasztja őket abban a reményben, hogy valamelyik válaszol. A verziófelismerés már tartalmazza ezt, így önmagában ritkán használatos - ha viszont gyanakszunk valamelyik portra, hogy RPC céljából van nyitva, jó választás.

"Udvariasság"

A portscannelést végre lehet hajtani pokoli gyorsan (a szerző tapasztalatai szerint egy 100Mbit-es egyetemi/kollégiumi hálózaton ideális esetben nem egész egy másodperc alatt végigpörgethetők a portok), azonban ez nagyjából annyira csendes és észrevehetetlen, mintha a zsebtolvajt egy teljes hangerőn játszó tűzoltózenekar követné. Nagyon könnyű észrevenni - ha IPS működik a célpont hálózatán, szinte biztos, hogy valamilyen szankciót fog bevezetni az IP-nkről érkező csomagokkal szemben, másrészt pedig feltehetőleg jelzi a rendszergazdának, hogy mi történt. Vannak célpontok persze, amelyeknél annyi portscan történik úgyis, hogy eggyel több vagy kevesebb semmit sem számít - ilyen pl. a google.com, a whitehouse.gov és társaik.

Az időzítési tulajdonságok szempontjából a legfontosabb szabály az, hogy a scan időigénye O(n*p), ahol n a simogatott hosztok, p a vizsgált portok számát jelenti. Ennek megfelelően egy több száz gépből álló (pl. vállalati) hálózat okos, csendes felderítése akár több napig is eltarthat.

A -M kapcsoló segítségével megadható a párhuzamosan scannelt portok max. száma, ilyen módon jó kis DoS támadásokat lehet végrehajtani az nmap segítségével. Csak kiadjuk, hogy

nmap -T 5 -M 1000 -sT 1.2.3.4

és várunk.

Jelmagyarázat: a lehető leggyorsabb portscan, egyszerre 1000 porton(!) próbálkozik egyszerre kapcsolatfelvétellel. A szerző saját, SP2 nélküli Xp professionaljét gyakorlatilag megölte az iménti parancs kikapcsolt tűzfallal, ha viszont be volt kapcsolva akárcsak a difót vindózos tűzfal, akkor is jelentős lassulást tapasztalt.

Tűzfalak, IDS-ek és egyéb házörzők

Az nmap számtalan opciót tartalmaz, amely igyekszik minél nehezebben felderíthetővé tenni a tevékenységét. Ezt az nmap fórumain néhányan nehezményezik: szerintük túlozottan megkönnyítik a crackerek dolgát azzal, hogy konkrét eszközöket integrálnak tűzfalak és IDS-ek elkerülésére az nmap-ba. Az nmap készítői azzal reagáltak a felvetésekre, hogy mivel a szoftver open-source, előbb-utóbb valaki biztosan beleteszi ezeket az opciókat, így viszont a rendszergazdák is próbára tehetik saját hálózatuk biztonságát.

A mezei portscan elég egyszerűen észrevehető, ha nem kellő körültekintéssel választjuk meg a paramétereit: lényegében egy olyan egyszerű, netflow statisztikákat megevő algoritmus is elég jól detektálja, amely egyszerűen a 60byte-os csomagokra érkező 40byte-os válaszokra figyel. Ha ilyenből egy hoszt sokat összeszed, akkor valószínűleg portscant hajt végre.

Csomagszinten figyelő tűzfalak és IDS-ek kijátszására jók az alábbi kapcsolók:

  • f: ezen kapcsoló használatakor a simogató csomagok nem egyben érkeznek meg a célpont közelébe, hanem apró fragmentek formájában - a célpont úgyis összerakja őket, viszont ha a csomag részeit külön-külön megvizsgálja egy csomagszűrő tűzfal, sokkal nehezebb dolga lesz a portscan azonosításakor. Az IP fejléc mögé 8byte-os adagokba pakolgatja a TCP header darabkáit - így pl. egy 20byte-os csomag helyett hármat küldünk ki, 8 byte-os mérettel. Óvatosan bánjunk ezzel a kapcsolóval, ugyanis sok kiszolgáló nem tudja megfelelően kezelni ezeket a parányi csomagocskákat, így előfordulhat, hogy a szolgáltatás felfedezése helyett jól seg.faultra futtatjuk a kiszolgálót. Kis kitérő: fragrouter.
  • --mtu: a paraméterül megadott MTU értéket veszi figyelembe, nyolccal oszthatónak kell lennie. Ekkora fragmentekben küldi ki az összes csomagot (még a ping-et is). Az -f kapcsolóval együtt nem használható.
  • D: decoy scan használata. Hamisított TCP/IP fejlécek segítségével a célpontban (és a körülötte őrködőkben) azt a (tév)képzetet kelti, hogy a portscan nem csak a mi címünkről jön, hanem az összes, a listában megadott hoszt egyszerre scanneli a célpontot. Ez persze nagyon hasznos, ugyanis a célpontnak fogalma sem lesz arról, hogy melyik támadó az igazi. Mindazonáltal óvatosan kell eljárni az ilyen "beárulásokkal", ugyanis a célpont a portscanre küldött csomagokat a "beárult" hosztoknak is elküldi, ilyen módon floodolja őket és csinosan leterheli a hálózatot. A kapcsoló szintaktikája szerint a "beárult" hosztokat vesszővel kell elválasztani és akár a saját IP-t jelentő ME string is beletehető. Az nmap fejlesztői szerint a hatodik helyre bebökve a legtöbb portscan-detektor nem fogja észlelni a címünket a sok hamis cím között (a szerző ezt némileg kétkedve fogadja, de ám legyen.) Kis kitérő: mire jó ez? Milyen esetekben lehet komoly szolgáltatáskiesést okozni?
  • S: IP-cím spoofolása. Bővebb magyarázatot nem igényel. Házi feladat: vajon mire lehet jó?
  • --source-port: forrásport meghamisítása. Hasznos pl., ha a tűzfal forrásport alapján szűr (pl. ha gonosz módon az irodából szeretnénk portscannelni, de csak a 80-as van kiengedve.) Másrészt aktív FTP-szerverekkel történő kommunikáció esetében vonzó lehetőség, hogy a buta tűzfalon nyitva hagyjuk az utat azoknak a kapcsolatoknak, amelyek a 20-as portról érkeznek (azaz a szerver számára lehetőséget biztosítsunk arra, hogy visszakapcsolódjon a kliensre). A crackerek számára egyébként ez a hozzáállás termi meg leginkább a gyümölcsét: a lusta rendszergazdák nem csinálják meg a bonyolult, ám biztonságos megoldást, hanem egy olyat vezetnek be, amelyik egyszerűen megcsinálható még az ebédszünet előtt, viszont kis tapogatózás után kihasználható.
  • --data-length: lehetőség van arra is, hogy random számokkal töltsük fel a csomagjaink payload részét (alapból ugye payload nélkül küldi ki a csomagokat, ami meg elég könnyen detektálható). Érdemes megnézni egyébként pl. a snort nmap-ra vonatkozó szabályait, ezeket egyesével lehet kicselezni különféle kapcsolókkal. Házi feladat: nézzétek meg a snort.org szabályai között az nmap-osakat, és cselezzétek ki őket! Nagyon tanulságos játék egyébként...
  • --ip-options: a megadott IP-fejlécmezőkkel küldhetjük ki a csomagjainkat. Gyakorlatilag az összes fenti opciót megadhatjuk így, de ezzel lényegében teljesen testre (és hálózatra) szabhatjuk a scant.
  • --randomize-hosts: ha több scannelt célgépet adunk meg, ezzel véletlenszerű sorrendben veszi őket, ezáltal nehezítve a házőrzők dolgát.
  • --spoof-mac: önmagáért beszél. Megadhatunk gyártót is (ebben az esetben a fennmaradó byte-okat véletlenszerűen tölti ki az nmap).
  • --badsum: helytelen ellenőrző összeggel küldi ki a csomagokat. Mivel ebben az esetben a célpont nem dolgozza fel a csomagot, ha választ kapunk ilyenre, akkor az szinte biztosan egy checksumot nem ellenőrző tűzfaltól jött.

Mire jó az nmap?

A fenti kapcsolókkal szó szerint több ezer üzemmódban lehet használni a kicsi, parancssoros nmap-ot. Mire lehet használni? Csak néhány tipp:

  • Hálózatra betörve portok feltérképezése.
  • Tűzfalak szabályrendszerének kiderítése.
  • DoS (no comment...)
  • Tömeges reverse DNS-feloldás.
  • ARP táblák ellenőrzése lokális hálózaton.
  • Hálózatmonitorozás (á la Nagios).
  • Szolgáltatásmonitorozás.
  • Hálózati eszközök katalógusának automatizált összeállítása.
  • Hálózati eszközök terhelésvizsgálata (stress test).
  • Szolgáltatások terheléses vizsgálata (pl. Apache).
  • Stb.

2 megjegyzés:

  1. nemsemmi, de nem gondoltam volna, hogy az nmap-ot oktatják is valahol (nem jártam bme-re:(). Nekem ha nem is kedvenc, de leggyakrabban használt progim talán :)

    VálaszTörlés
  2. --allports == -p-

    Ha nem akarsz annyit gépelni... :-)

    VálaszTörlés

Kommentek