Az előző packetfu postokban a layer3 és 4 magasságában mozgolódtunk, most elmaszatolunk a 2-esen is egy kicsit. Ez a post elsősorban az ethernet, és routing lehetőségeit kapirgáltuk. Az eddig leírt módszerek magasabb layereken dolgoznak, de lehet az L2-n is sumákolni. A post első felében a layer2: a switch, és Ethernet témát piszkáljuk. Nincs benne semmi fu, de a kung-fu-nak sem a verekedés a lényege. (Ezt a Kung-fu pandában hallottam. Jó film.) Szóval kellenek az alapok is. Tudom hogy sok mindenkinek ezek nem mondanak újat, de olyanok is olvassák akiknek ezekből nem volt meg minden, a hackelés alapja pedig a megismerés. Lesz azért némi fu is.
Ethernet frame
Így néz ki egy Ethernet frame (magyarosan keret, a hálózati csomag adatkapcsolati megfelelője), ha találkoztál már vele - mondjuk Wiresharkban -, akkor a 7+1 byteos Preamble és a 4 byteos CRC esetleg új lehet. Ezekkel nem találkozunk snifferben mert csak a hálókártya számára szolgáltatnak releváns információt: Mivel a küldő és a fogadó fél rendszerórája nem egyszerre jár, ezért szükség van némi szinkronizálásra, erre szolgál a Preamble. Mielőtt a hálókártya kiküldi a csomagot, számol rá egy CRC-t, a fogadó hálókártya ez alapján fogja tudni ellenőrizni hogy nem sérült-e. A fejlécben a cél és a forrás MAC cím, +2 byte az Ethertype már valószínűleg ismerős.
Az Ethertype még az érdekes, ez mondja meg hogy milyen típusú a payload, milyen protokoll van a framen belül. Néhány ismertebb:
0x0800 | IPv4 |
0x0806 | ARP |
0x8100 | 802.1Q / VLAN taggelt frame |
0x814c | SNMP |
0x86dd | IPv6 |
A MAC address 6 bytejából, ebből az első 3 az OUI vagy Company ID. Ebből vissza lehet keresni a gyártót, akár googleba "mac vendor lookup" kulcsszavakra, vagy az ieee.org-on.
Switch és Ethernet
Egy switch egy L2 device, csak az Ethernet framekkel foglalkozik, ez alapján dobálja a portjai között a csomagokat, és semmit se tud a világ igazságtalanságairól. Az egyszerűbbeken semmiféle konfigurálási lehetőség nincs, ezeket általában otthoni hálózatban vagy kis irodai környezetben használják, unmanaged switch néven emlegetjük őket. Ezek meglehetősen naív teremtmények, csak azt tartják számon, hogy melyik porton milyen MAC címekkel találkoztak. Az ezeket az összerendeléseket számontartó adatstruktúrára CAM táblaként (Content Addressable Memory), MAC táblaként, filtering databaseként szoktak hivatkozni. A Wiley féle Switch Book kicsontozza a switchek lelkületét.
A switch amikor valamelyik porton kap egy frame-t, a táblában rögzíti, hogy a küldő MAC cím ezen a porton forgalmaz, és utánanéz a táblában hogy a címzett MAC-et melyik porton látta utoljára, és arra küldi tovább a framet. Ha olyan MAC a címzett ami nem szerepel a CAM táblában akkor azt a csomagot minden portra kiküldi, a CAM mérete viszont korlátozott. Erre alapoz a MAC flood támadás, ami random source MAC címekkel teleszemeteli a CAM-et, így a minket közvetlenül kiszolgáló switch-en keresztülmenő összes forgalmat megkaphatjuk (ez önmagában lehallgatásra jó, közbeékelődésre még nem). A dsniff csomagból a macof nevű tool pont erre lett kitenyésztve.
A Port Security úgy oldja meg ezt a problémát, hogy egy bizonyos porton nem enged forgalmazni csak meghatározott MAC címeknek, de ez túlmutat a nem-menedzselt switchek képességein. Erre még visszatérünk. Ha ettől eltérővel próbálkozik valaki azon a porton, akkor vagy nem engedi át, vagy kap a port egy shutdown-t, és akkor ott van vége a kísérletezgetésnek, bár a korlátozás alapvetően elég egyszerűen, a megfelelő MAC beállításával átléphető.
VLANok
Nagyobb hálózatokban már felmerül az igény az egymástól szeparált virtuális LAN-ok, vagyis VLAN-ok használatára, ezekhez viszont ennek megfelelő eszközökre van szükség. A managed switcheknél megvan ez a lehetőség, de egy kicsit mélyebb zseb kell hozzájuk. Dióhéjban arról szól a történet, hogy a végpontok és a switchek között standard ethernet framekbe csomagolva történik a kommunikáció, de a switchek és routerek között ezeket a frameket megtoldják még néhány bytetal, azaz feltaggelik a framet.
A képet a ciscoiseasy.blogspot.hu-ról csórtam, ami egyébként egy tök jó resource Cisco témában. ^__^
Amikor egy switch kap egy Ethernet framet az egyik végpont felől, az kap egy új Ethertype mezőt 0x8100-al, ezt követi a 4 byteos 802.1Q header, és a hálózatnak a VLAN-aware részén így fog közlekedni a frame. Amikor valamelyik switchnél elhagyja a csomag a hálózat VLAN-aware szegmensét, leszedi róla a taget (visszakapjuk az eredeti csomagot), és így küldi tovább. A VLAN tag 12 bites, így összesen 4096 VLAN-t lehetne használni, de a 0x000 és a 0xFFF kimarad a játékból, így csak 4094-et. A VLAN-aware hálózaton egy taggeletlen csomag a natív VLANhoz tartozik.
Az hogy egy végpont melyik VLAN-hoz tartozik, a switchen vagy port, vagy MAC cím alapján kerül meghatározásra. Onnantól fogva azon a porton vagy azzal a MACkel érkező framek egy megadott vlanra lesznek feltaggelve. A switchek és routerek egymás között trunk portokon beszélgetnek, tehát egy trunk portról bármelyik VLANhoz hozzá lehet férni. A VLAN taggelésről a IEEE 802.1Q szól.
Port stealing / CAM table poisoning
Maga a port stealing kizárólag a switch CAM tábláját érinti, így az áldozat számára kb teljesen észrevehetetlen. Mint azt már fent említettem, a switch a source MAC addresst asszociálja a CAM táblában a megadott porthoz.
A módszer lényege hogy a célpont MAC címével forgalmazunk frameket, az tökmindegy mi van benne. A switch ekkor a mi, azaz a támadó porján fogja látni azt a MACet, és az annak küldött framek ezen a porton fognak landolni. Viszont eközben az áldozat is forgalmaz, ami bekavar a támadásnak, ezért a kamu frameket folyamatosan küldözgetni kell. Máshogy fogalmazva: a switch mindig arra a portra küldi a forgalmat, amelyiken a legutóbb látta a címzett MAC-et. A támadás természeténél fogva port security esetén ez a módszer nem használható.
http://www.blackhat.com/presentations/bh-europe-03/bh-europe-03-valleri.pdf
Routing mogyoróhéjban
Szó lesz most a routingról, és routerről. A routing a kernel dolga, ez az a varázslatos kód, ami a forgalmat terelgeti. A router Layer3 eszköz: míg a switch a fizikai portok között dobálja a frameket, a router a hálózatok között dobálja a paketokat.
Szeretnénk megpingelni a szomszéd gépet a LAN-ban aki a 192.168.1.3. Tudjuk a cél IP-t, de ez minden. Egyáltalán melyik interfacen küldjük ki a stuffot? Mi legyen a destination MAC?
Először is van egy routing táblánk.
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0
Ha az 192.168.1.3 -at szeretnénk megpingelni, akkor így első ránézésre az eth0 lesz a nyertes interface, mivel arrafele van egy 192.168.1.0/24-ünk, de a kernel nem úgy van vele mint én, hogy ránéz és azt mondja hogy "szerintem arra"... A kernel a FIB táblából (a route parancs alapból ezt mutatja) a Longest [Length] Prefix Match algoritmus alapján fogja tudni eldönteni hogy melyik a legmegfelelőbb irány. Ez tömören annyit jelent, hogy az lesz a nyertes interface, akinél a legtöbb bit egyezik. Esetünkben...
192.168.1.3 11000000.10101000.00000001.00000011
192.168.1.0/24 11000000.10101000.00000001.00000000 /eth0
192.168.2.0/24 11000000.10101000.00000010.00000000 /eth1
...az eth0 az. Ha lenne még egy interface (mondjuk eth2) ami tud egy 192.168.1.0/28 -ról, akkor az lenne a nyertes, mivel a netmask több bitet fed le.
192.168.1.3 11000000.10101000.00000001.00000011
192.168.1.0/24 11000000.10101000.00000001.00000000 /eth0
192.168.2.0/24 11000000.10101000.00000010.00000000 /eth1
192.168.1.0/28 11000000.10101000.00000001.00000000 /eth2
De nincs ilyen, ne bonyolítsuk. eth0 és eth1 van. Ott tartottunk, hogy megvan az interface hogy melyikre küldjük ki a framet. Ehhez az interface-hez tartozik egy IP cím, és egy MAC address; Ez lesz a L3 vagyis az IP csomagban a src IP cím, és a L2-n pedig az ethernet headerben ez lesz az src MAC. Jelen pillanatban ott tartunk hogy az ICMP megvan, bele tudjuk pakolni egy IP csomagba, amit belegyömöszölünk még egy ethernet frame-be. Az a baj hogy még mindig nem tudjuk hogy mi a destination MAC...
Várj.. Biztos hogy nem tudjuk? Van nekünk egy ARP táblánk is pont az ilyen esetekre. Nézzünk bele.
# arp -n
Address HWtype HWaddress Flags Mask Iface
192.168.2.44 ether 00:65:1c:c4:77:12 C eth1
192.168.1.254 ether 00:23:f4:dc:4f:01 C eth0
Hát nem. Sajnos. Márpedig amíg nem ismerjük a destination MAC-et addig elküldeni sem tudjuk azt a pinget az 192.168.1.3 -nak, szóval valahogy meg kéne tudni. Na erre való az:
ARP
Az ARP annyit tesz mint Address Resolution Protocol. Már tudjuk hogy melyik interface felé érjük el az 1.3-at, úgyhogy ezen kiküldünk egy framet ami a következőképpen épül fel: Az Ethernet frame src MAC -je az interface MAC címe lesz, a destination MAC pedig FF:FF:FF:FF:FF:FF, (szóval broadcast) amit a switch minden portjára ki fog küldeni, ergo mindenki megkapja, remélhetőleg az is aki magáénak tudja a 192.168.1.3-at. Az ethernet frame ethertype-ja 0x0806 azaz ARP. A framen belül már az ARP request figyel. Így néz ki az ARP packet.
Az ARP request tartalmazza a küldő MAC és IP címét, valamint a címzett IP címét. Erre a csomagra fog válaszolni a címzett a küldőnek egy ARP replyvel, amelyben a source az ő saját MAC és IP címe. Szóval ebben a pillanatban ha minden simán ment akkor a 192.168.1.3 küldött nekünk egy ARP replyt amely tartalmazza a MAC address-t amely birtokában már elküldhetjük azt a nyavalyás pinget. ^__^
Így működik normál körülmények között.
ARP poisoning
Ez megint csak egy MitM támadás. Az a lényeg hogy a hálózat két szereplője között eltérítjük a forgalmat úgy, hogy rajtunk haladjon keresztül. Vannak mindenféle toolok amik elvégzik ezt a feladatot, én mégis azt mondom jobb ha kézzel rakjuk össze, mert abból lehet tanulni. A dsniff csomagból az arpspoof nevű kis tool pl. pont erre való, és elég egyszerű használni is, de nem szeretem. A játékosok: 1.1 a gateway, 1.2 mi vagyunk, 1.3 az akiről szeretnénk megtudni hogy mit beszélget az internet felé. Azt szeretnénk ha a célpont nekünk küldené azokat a csomagokat amelyeket a gateway-nek szeretne küldeni. Mielőtt még bármi huncutságot csinálnánk, routerré kell változnunk, különben az áldozat által küldött csomagok soha nem érkeznek meg a rendeltetési helyükre. Linuxon ez az
echo 1 > /proc/sys/net/ipv4/ip_forward vagy a sysctl net.ipv4.ip_forward=1 parancs kiadásával érhető el.
Windowson a
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ alatt az IPEnableRouter értékének 1-re változtatásával.
A következőképpen kell kinéznie ennek a csomagnak:
- a source MAC a mi interfaceünk címe, most nálam 9c:a1:34:25:00:01
- a source IP-nek a gatewayt hazudjuk be, szóval 192.168.1.1,
- destination MAC az áldozat MAC címe, ez most 00:1c:c0:fc:bd:b7
- destination IP az áldozat IP-je, a 192.168.1.3
Akkor mostmár minden megvan, rakjunk össze egy ilyen gonosz kis meglepit, és küldözgessük mondjuk másodpercenként. Scapy, és nincs többé korpa, csak gyönyörű, dús haj:
>>> sendp(Ether(dst="00:1c:c0:fc:bd:b7") / ARP(op=2, \
hwsrc="9c:a1:34:25:00:01", hwdst="00:1c:c0:fc:bd:b7", \
psrc="192.168.1.1", pdst="192.168.1.3") \
inter=1, count=-1)
Jelen pillanatban az áldozat gépének ARP táblája szerint a gateway MAC címe a miénk, így a gw-nek címzett csomagok mind áthaladnak rajtunk.
C:\Users\Innocent Civilian>arp -a 192.168.1.1
Interface: 192.168.1.3 --- 0xb
Internet Address Physical Address Type
192.168.1.1 9c-a1-34-25-00-01 dynamic
Mondanom sem kell hogy ezzel csak azt látjuk amit a kliens küld, ami a router felől jön azt már nem, szóval ahhoz, hogy a csóró áldozatunk full forgalmát eltake-eljük a routernek is el kell kezdeni hazudni... de ezt már eleget fejtegettük, úgyhogy ezt nem fogom bekopogni.
GWScan
Legyen a scenario az hogy bevertünk valami szervert:
IP: 1.2.3.4
netmask: 255.255.255.0 (-> net: 1.2.3.0, broadcast: 1.2.3.255)
gw: 1.2.3.254
Van mellette még jópár gép de azokon nem találtunk fogást... legalábbis kintről. Most egy kicsit más helyzetbe kerültünk, annak fényében hogy tudunk játszani a L2-vel, és a routolással is. L2 helyett most inkább routolással játszunk.
A hálózaton lévő egyik-másik vas mögött talán van valami egyéb infrastruktúra: mittudomén, backend szerverek, adatbázis szerverek, office háló, vagy akármi... Még nem tudjuk, de szeretnénk megtudni. "Mindig izgis amikor ismeretlen helyeket kell felderíteni." - Shackleton :) Azt, hogy milyen hálózatokat ismernek az egyes gépek többféleképpen is kideríthetjük. A legkézenfekvőbb gondolat belesniffelni a kábelbe - amit a jól bekonfolt gépek teleböfögnek ARP requestekkel -, de ennél azért többet szeretnénk.
A packet-fu 1. -ben ismertetett timestamp-fu már sokkal átfogóbb képet tud adni, hiszen kb. tetszőleges címről megmondható így hogy ismeri-e azt a célgép vagy sem. Azt is be lehet vele lőni, hogy hogy van felosztva az a subnet amire egyébként nem látunk rá ugyan (még), de legalább már tudjuk hogy van. Már csak azért is powa feature ez, mert anélkül mappeled fel a subneteket és broadcastokat hogy akár egyetlen packetet kéne küldened abba a hálóba, szóval pl. ha ott van egy IDS akkor az nem fogja látni a kis mappelésünket.
A gwscan már erősen offenzív, de mégsem annyira mint L2-n garázdálkodni. Azokat a hostokat keressük akik routerként funkcionálnak, szóval az ip_forward = 1 (mert mondjuk ők a gatewayei a mögöttes subnetnek). A módszer lényege abban áll, hogy olyan packetokat küldünk a hostoknak amelyekben a feltételezett másik hálózaton csücsülő hostokat szólítjuk meg valamilyen módon. Ha futtattunk előtte egy tcpdumpot akkor már lehet képünk arról hogy miket keressünk elsőnek. A legegyszerűbb megpingelni őket. A leghatékonyabb ha broadcast MAC-re küldjük, de ha esetleg ellenérzésünk lenne amiatt, hogy vadbarom módjára teleordibáljuk a hálót (mint a debreceni főteret a hőbörgős hónaljszagú részeg tizenévesek szombat esténként), akkor az teljesen érthető. Rendes ninnya nem kajabál. Beszéljenek inkább a példák...
>>> a,u = srp(Ether(dst="ff:ff:ff:ff:ff:ff") \
/ IP(dst="192.168.*.1") / ICMP() ,timeout=2 )
...
>>> for p in a: p[1].sprintf("%Ether.src% %IP.src% %ICMP.type%")
'00:17:df:26:e5:b0 192.168.0.1 echo-reply'
'00:17:df:26:ec:b0 192.168.2.1 echo-reply'
'00:17:df:26:ec:b0 192.168.12.1 echo-reply'
'00:1e:67:80:1c:a1 192.168.13.1 echo-reply'
'00:1e:67:f5:cc:10 192.168.40.1 echo-reply'
'00:17:df:26:ec:b0 192.168.168.1 echo-reply'
'00:17:df:26:ec:b0 192.168.169.1 echo-reply'
'00:25:90:c2:11:de 192.168.173.1 echo-reply'
'00:17:df:26:e5:b0 192.168.200.1 echo-reply'
(Csak a példa kedvéért 192.168.*.1, nyilván nézhetsz más hálókat is meg full /16-ot is végig pingetheted, vagy kitalálhatsz valami kultúráltabb megoldást is.)
Most csak azt sikerült megtudnunk, hogy milyen MAC addressről jöttek (mármint a gateway MAC-jei ezek) a packetek. Ahhoz, hogy tovább tudjunk lépni, először csinálunk egy listát arról hogy a subneten melyik IP-hez milyen MAC tartozik, ez tök egyszerűen ARP kérésekkel megvalósítható. Ebben megtaláljuk hogy a kiboldozott 00:1e:67:f5:cc:10 MAC címmel -mondjuk- az 1.2.3.10 rendelkezik. Az óriáskövetkeztetés hogy az 1.2.3.10 mögött van egy 192.168.40.1 gép egy valamekkora subneten. Majd azt is kiderítjük.
Most már minden infó megvan ahhoz hogy elkezdjük penetrálni a 192.168.40.x -et, úgyhogy nincs más hátra, mint hogy vegyük fel a gépen a route szabályt. miszerint a 192.168.40.0/24 -et a 1.2.3.10 -en keresztül lehet elérni.
# route add -net 192.168.40.0/24 gw 1.2.3.10
Innentől fogva "szabad az út" a 192.168.40.0/24 felé, lehet garázdálkodni.
# nmap -sP 192.168.40.0/24
Starting Nmap 5.00 ( http://nmap.org/ ) at 2013-09-10 17:37 CEST
Host 192.168.40.1 is up (0.00042s latency).
Host 192.168.40.2 is up (0.00042s latency).
Host 192.168.40.3 is up (0.00034s latency).
Nmap done: 256 IP addresses (3 hosts up) scanned in 4.12 seconds
Ennek a postnak most itt a vége, de még így is jobb lovestory mint a Twilight. :) h
P1ngW1n 2013.12.08. 11:27:40
A /24 bitképe ez lesz: 11000000.10101000.00000001 .00000000
Míg a -28-é meg ez: 11000000.10101000.00000001.0000 0000
A különbség egy "szóköz" ami miatt a /28 jobban illeszkedne az eredeti bit képre (11000000.10101000.00000001.0000 0000), tekintve hogy /24nél az a C class határon van nyomban.