2024. április 28., vasárnap

Gyorskeresés

Mr Dini 'nagy' Cloudflare törése

Írta: | Kulcsszavak: Cloudflare . bug . bounty . warp . wireguard . ipv6

[ ÚJ BEJEGYZÉS ]

Idén két éve friss munkanélküliként, több helyről visszautasítva, kétségbeesetten kerestem a helyem a világban. Az egyetlen számítógéphez köthető örömforrásom - ha egyáltalán lehet így nevezni - a chatbotok írása volt, amivel a saját hobbijaim megkönnyítése volt a cél. Azonban ezeket hosztolni is kellett valahol, ami pénzbe került. Szerettem volna a meglévő költségeimen spórolni és így fedeztem fel véletlenül egy jelentős hibát a Cloudflare ökoszisztémában. Álljon hát itt a történet, ami majdnem gyökeresen megváltoztatta az életem, de aztán mégsem tette. Illetve ami egy emailhez vezetett, amit minden akkori CF felhasználó megkapott! :)

Tehát Chatbotok! Hogyan, s miért keveredtem én ide?

Bár nem tudom fejből oda-vissza a vi szerkesztő összes létező billentyű kombinációját, nagy rabja vagyok a billentyűzetnek. Ha tehetem nem nyúlok az egérhez és nem ívelem át azt a kicsi kis kurzort az egész képernyőn egyetlen kattintás kedvéért. Éppen ezért volt számomra egy teljesen új világ a desktop Windowsról egy minimál Linuxra váltás, mivel valahogy a PowerShell-t sose voltam képes elsajátítani eléggé, linuxon viszont elkerülhetetlen volt a terminál felkapása és hála a rengeteg leírásnak, viszonylag hamar rájöttem, hogy milyen optimális terminálból csinálni a tömeges procedúrákat. Ez a felfedezés végül olyan szintű toxikussághoz vezetett, hogy a végén direkt kerestem magamnak feladatokat, amire szkripteket, automatizációkat tudtam gyártani és ha tehettem, csak a böngészés kedvéért hagytam el a CLI-t. :D

Ezek mellett nagy fórumos voltam, de sose volt szimpatikus az, hogy felvetődik egy érdekes téma, aztán napokig kell várni, hogy kibontakozzon, mivel az emberek többsége nem az oldal folyamatos újratöltésével tölti az idejét, hanem naponta párszor néz csak fel, hogy jött-e reakció. Szóval az azonnali értesítések hiánya aggasztott. Igaz, hogy voltak valósidejű, illetve majdnem valósidejűvé tehető alternatívák, mint az IRC, viszont nagyon kevés ismerőst sikerült rávenni a használatára, illetve a chat history hiánya sem volt pozitív élmény. Igaz, hogy a legtöbb kliens rendelkezett mentés funkcióval, de ha épp nem volt neted, vagy áramszüneted volt, vagy egyéb okból nem ment a géped, akkor lemaradtál az összes üzenetről. Sokáig persze elvoltam a fórumokon, ha IT témában szerettem volna öntovábbképzést tartani, de aztán valahogy rátaláltam a Discordra, ami egyből szimpatikus lett, mivel pofonegyszerű volt a használata, akkoriban rohamosan fejlődött és az emberek is szívesen használták. Nomeg gyerekjáték volt tematikus chatszobákat létrehozni.

Eleinte persze csak IT-s csoportok követésére használtam az alkalmazást, aztán ahogy fejlődött a platform, elkezdtek megjelenni a bot userek. Ez a koncepció nem volt új számomra, hiszen IRC alatt is létezett megannyi hasznos bot, de a Discordos API nagyon hamar megfogott, mert megláttam benne azt, amit egy terminálban. Gyakorlatilag itt is tudok parancsokat beírni és erre majdnem azonnal kapok is választ. Meg tudom osztani másokkal a history-t, ők is be tudnak csatlakozni, van lehetőség a terminált akciógombokkal (reakciók) kiegészíteni, képeket küldeni, programok kimenetét összegyűjteni, sőt hangot lejátszani is.

Készítettem tehát egy privát botot, amibe beépítettem a sokat használt kódjaim. Tudott a bot IP, whois és DNS kereséstől a Google keresésig, képtől a hangszerkesztésig, optikai karakterfelismeréstől a diktált szöveg írássá alakításáig mindent, amire gyakran szükségem volt. Sőt, akkoriban az AI-jal bontogattam a szárnyaim, így ez a bot lett az interfésze a generált képek, szövegek demonstrálásának is.

Igen ám, de ahogy nőtt a funkcionalitás, úgy nőtt az erőforrásigény is. Eredetileg egy ZyXEL NAS-on futott, aminek egyetlen ARMv5 CPU magja volt 256 MiB RAM-mal az egész rendszerrel. Majd kénytelen voltam egy komolyabb hosztingba beruházni. Eredetileg otthonról szerettem volna futtatni, de kiszámoltam, hogy nem érné meg az áramszámlával, a netköltséggel és az alkatrészek folyamatos cseréjével a home hoszting, mikor $3-$5-ért kapott az ember akkoriban egy használható VPS-t, amit ráadásul bármikor bővíthetett. A latency is jobb volt sokkal, mint otthoni netről futtatva. :)

Felköltöztem tehát a "felhőbe". Minden igényemet ki is szolgálta szépen a szolgáltatás. Aztán bekövetkezett az, hogy megcsappantak a bevételeim, illetve ezzel párhuzamosan kezdték átszabni a hoszting árakat a szolgáltatók arra hivatkozva, hogy az IPv4 címek rohamos fogyatkozásával kénytelenek borsos (értsd. $1-$2 :D) bérleti díjakat kiszabni a felhasználókra.

A jövő: IPv6! Vagy mégsem?

Ahogy átfutottam a friss árakat feltűnt, hogy sok szolgáltatónál megjelent egy 'IPv6 Only' címke általában a legkisebb VPS-en, vagy kifejezetten fizetős extraként lehetett v4-es címet kérni. Találtam is egy nagyon bíztató árfekvésű VPS-t havi 2.5 dollárért, ami gyakorlatilag az akkori kiadásaim felét jelentette. 2.5 dollár ezek szerint csak az IPv4 cím miatt lett kiszabva rám. Elgondolkoztam, hogy kell-e nekem a v4 egyáltalán, hiszen én nem hosztolok semmit közvetlenül, a programom kliensként csatlakozik egy távoli szerverhez, aminek bizonyára van IPv6 címe 2021-ben, ha már ilyen jelentős felhasználói táborral rendelkezik. Ugye Discord? Ugye...? :U

Nézzük!

[steve@todo ~]$ dig discord.com a +short
162.159.135.232
162.159.138.232
162.159.136.232
162.159.137.232
162.159.128.233
[steve@todo ~]$ dig discord.com aaaa +short
[steve@todo ~]$

Itt bizony az látszik, hogy még a cikk írásának pillanatában, 2023-ban sincs IPv6 elérhetősége az oldalnak. Külön érdekes, hogy a Discord köztudottan Cloudflare-t használ, akiknél jobban kevés internetes cég promotálta az IPv6 terjesztését jobban (tucatnyi blogposztjuk is van a témában: [link]) és az összes Cloudflare mögé bekötött oldal alapból elérhetővé válik IPv6-on is, hiszen a Cloudflare így a felhasználó és a Discord szerverei közé ékelődik és rajta keresztül folyik át az összes forgalom.


[+] Béna ábra a Cloudflare és Discord kapcsolatát szemléltetve

Oké, de mi értelme bevonni egy külső céget a két fél közé?

Valamikor a kezdetek kezdetén a Discord nem volt Cloudflare mögött. Ígéretes startup volt ugyan, de nem éppen a stabil elérhetőségéről volt híres. Feltételezem, hogy a hirtelen jött népszerűség sok DDoSser figyelmét is magára vonta és bizony volt, hogy rendesen köhögött az API időnként. Ilyenkor chatelni se lehetett rendesen. Ennek következményeképp köthették Cloudflare mögé az oldalt, amely egyik pozitív velejárója volt, hogy a felhasználók közvetlenül nem, csupán a Cloudflare szerver networkjén keresztül érhették el az oldalt, tehát a különböző támadások elleni védekezések nagy részét már Cloudflare oldalon meg lehetett fogni. Nem kellett közvetlenül a Discordnak invesztálni saját szerverekbe a világ minden táján. Illetve mivel a forgalom felkerült így a Cloudflare hálózatára, sok esetben stabilabb lett az elérés is, hiszen a kliens felcsatlakozott a hozzá legközelebbi Cloudflare szerverre, ami a forgalmat igyekezett a Cloudflare belső hálózatán elvinni olyan közel, ahogy csak lehetséges a tényleges hosztingot biztosító szerverig, majd csak ott hagyta el a hálózatukat a forgalom, ahol optimálisnak tűnt. Persze sok más előnye van, de a cikk szempontjából nagyjából ennyit elég tudni.

Az előnye ugyanakkor a hátránya is. Sokan nem bíznak meg egy mamut cégben, aki mára az internet jelentős részének forgalmába 'belelát'. Hatalmas monopóliumot épített ki mára a Cloudflare és a sok ingyenes, illetve olcsó szolgáltatásával nehezen tudnak versenyezni a versenytársak. Már ott tartunk, hogy politikai szavazások folynak Cloudflare szervereken keresztül és a usernek nincs alternatívája. Vagy eléri az oldalt CF-en keresztül, vagy nem éri el az oldalt egyáltalán.

Node ennyit az unalmas bevezetésről! Ott tartottunk, hogy a Discord IPv6-on nem elérhető, még úgy sem, hogy a CF alapértelmezetten ajánl IPv6 elérést is. Kivéve akkor, ha azt a Cloudflare fiókban külön letiltja valaki:

Nem működhetett az tehát, hogy veszek egy v6 only VPS-t és arról csatlakozom a Discordra.

Nincs v6 Discord elérés, van v6 elérés

Nyilván nem hagyott nyugodni, hogy egyetlen apró technikai akadály miatt fizetem a dupláját annak, amit kéne, így elkezdtek forogni a fogaskerekek, hogy milyen módon tudnék IPv4-en át csatlakozni a Discordhoz, ha nincs IPv4 címem.

Első gondolatom az lett volna, hogy egy VPN-en át hazahozom a discord forgalmát, hiszen a lakossági előfizetésemen van v4 és v6 is. Ez működött is egy darabig, azonban egy szolgáltatói baki következtében hónapokig nem volt v6 címem, így alternatíva után kellett néznem.

Maradtam a VPN-es ötletnél, de most dedikált VPN szolgáltatásokat néztem, ahol pár dollárért kapsz tetszőleges országban hosztolt szervereken át internetet. Ez szimpatikusnak tűnt, azonban a legtöbb VPN kiszolgáló $5-nál nem adott olcsóbban elérést, ezzel tehát drágábban jöttem volna ki, mint egy nem v6 only VPS-sel. Illetve benne volt az is így, hogy a VPN IP-t nem csak én használom és elképzelhető, hogy más pont a VPN IP-ről áll neki támadni a Discordot, ami aztán tiltja az IP-t és az elérésemet is. Nomeg ha több bot fut azonos IP-ről, akkor a rate limiteket is hamarabb elértük volna közösen. Hamar elvetettem ezt az ötletet.

Még mindig a VPN vonalon maradva eszembe jutott a Cloudflare Warp, ami szintén egy Cloudflare szolgáltatás. Akkoriban nehezen volt megfogható, hogy pontosan mi a céljuk vele, de a marketing kampányukból nekem az jött le, hogy a projekt célja a user internetforgalmának biztonságosabbá tétele. Hogyan? Béna példa, de ezt egy értelmes use-case-nek képzelem el:

Adott Bob. Bob szeret egzotikus országokba repülni, ezért órákat vár két átszállás között a helyi reptéren. Mivel a mobilnete véges és kecsegtető, hogy van ingyen wifi biztosítva a reptéren, Bob ezt használva kezd el böngészgetni. Bár 2021-ben már ritka az, hogy a webes forgalom titkosítatlanul történjen, még mindig sok adatot tud begyűjteni Bob forgalmáról a legtöbb wifis kliens körülötte, hiszen a DNS még ma is népszerű titkosítatlanul, vagy HTTPS forgalom esetén az SNI elárulhatja, hogy milyen domainek irányába megy a forgalmunk. Mivel a levegő egy nyílt közeg, nem szerencsés Bobnak csak úgy csatlakoznia. Ilyenkor jöhet jól egy VPN, ami az összes forgalmat az eszközről titkosítja, majd egy távoli szerverre viszi. Így a reptéren hallgatózó kíváncsi felek csupán titkosított csomagokat látnak a VPN szerver felé és felől.

A Warp is egy ilyen VPN, sőt a hivatalos alkalmazásuk az ismert Wireguard protokollt használja. Gyakorlatilag az alkalmazásukat futtatva és elindítva az eszköz teljes forgalma Wireguardon át a Cloudflare szerverekre lesz irányítva.

Eddigi ábránk tehát bonyolódik:

És hogy miért jó ez nekem? Mivel tudok kapcsolódni v6-on a warp szerverre, ami pedig rendelkezik v4-es címmel is:

[steve@todo ~]$ dig engage.cloudflareclient.com +short
162.159.192.1
[steve@todo ~]$ dig engage.cloudflareclient.com +short aaaa
2606:4700:d0::a29f:c001

Pontosan ez kell nekem. Egy ingyenes 'VPN', amin keresztül elérhetem a v4 címeket is. A gond csak az, hogy 2021-et írunk és nincs linuxos kliensük. Van azonban egy lelkes harmadik féltől származó projekt, a wgcf, melynek segítségével tudunk generálni szabványos wireguard konfigokat hozzá, amit utána az összes wireguard kliens támogatni fog.

Az elmélet tehát összeállt. Egy dologról viszont nem esett szó, amiben a Warp nagyon speciális volt még 2021-ben is, a többi VPN szolgáltatóhoz képest. Ha valamilyen VPN-en át meglátogattam a whatismyip oldalt, akkor a whatismyip logikusan a VPN IP-t jelenítette meg, hiszen innen kezdeményezték az oldalletöltést. Arról a whatismyip-nek fogalma sincs, hogy a VPN előtt még volt az én eszközöm is. Ez a Warp esetében sincs másképp, ha olyan oldalra csatlakozol, ami nincs bekötve Cloudflare mögé. Hiszen a TCP/IP protokoll nem támogatja az eredeti forrás IP leközlését. Nem is lenne sok értelme, hiszen lehetne bármit hazudni akkor. Tehát ha a google.com-ot megnyitod, míg a warp aktív, akkor a Google a Cloudflare VPN IP-t fogja hozzád csatolni. Viszont ha a meglátogatni kívánt oldal is Cloudflare-t használ, mint a Discord, akkor a Cloudflare tudja módosítani a forrás IP-t és a Discord nem azt fogja látni, hogy a Cloudflare VPN IP csatlakozott hozzá, hanem a Cloudflare készségesen továbbítja a szolgáltatásnak azt az IP címet, amivel te a Warpra csatlakoztál. Jelen esetben a VPS IP címem.

Ez eddig tiszta sor. Node mi történik abban a speciális esetben, ha IPv6-on keresztül csatlakozik a szerverem a Warp VPN-hez és meg akarom látogatni a discord.com-ot, ami viszont csak v4-en elérhető és Cloudflare mögül van hosztolva? Vajon milyen forrás IP címet fog kapni? Továbbküldi a v6 címünk? Vagy ilyen esetben meghagyja a Cloudflare IP-t? Netalántán más fog történni?

Ezek a gondolatok jártak a fejemben, amikor elkezdtem felépíteni a tesztkörnyezetet.

Lássuk a medvét! Indulhat az éles tesztelés!

Volt egy olyan csúnya szokásom, hogy minden ilyen abszurd hálózatos módosítást éles VPS-eken próbáltam ki, mert ez tűnt a legegyszerűbb megoldásnak. Nem is jelentett volna nagy problémát, ha a VPS-emen kísérletezem, hiszen a legrosszabb, ami történhet, hogy kiesik a hálózat a szerveremről, a bot elérhetetlen lesz és egy újraindítás után minden újra a régi. De szerettem volna most másképp csinálni és tanulni valami újat. Így bukkantam rá a network namespace-re, amit a linux kernel régóta támogat, sőt a docker, podman stb konténerizációs platformok előszeretettel használják.

Kiválónak bizonyult arra, hogy elkülönítsem a hoszt hálózatától a környezetem. Azt is elhatároztam, hogy nem a VPS-en fogok kísérletezni, hanem az otthoni gépemen, ahol nem volt IPv6 címem, tehát első körben ezt kellett megoldani.

Szerencsére van egy pár ingyenes tunnelbroker szolgáltatás a mai napig, akik biztosítanak számodra egy IPv6 blokkot, amit szabadon tudsz használni olyan helyeken, ahol amúgy nem lenne elérhető a v6, viszont van v4-es címed. Hátránya viszont, hogy az összes v6 forgalmat az ő szervereiken keresztül kell küldened, illetve hogy nem lakossági v6 címet kapsz, tehát Netflix és társai felejtősek ezeken az IP-ken. Nekem viszont tökéletes volt. Regisztráltam tehát az egyik ilyen oldalra, a tunnelbroker.net-re. Ez a Hurricane Electric tulajdonában van és egész sok országban van szerverük, köztük Budapesten is. Így erre kértem a /64-es IPv6 blokkom. Csupán annyi kell, hogy az IPv4 címünk legyen pingelhető.

Miután kész a tunnel, a weboldalon látni fogunk egy Example configurations fület, majd azon belül a listában egy Linux-route2 opciót. Én ezt választottam és a következő parancsokat tárta elém az oldal:

modprobe ipv6
ip tunnel add he-ipv6 mode sit remote 216.66.80.30 local 1.2.3.4 ttl 255
ip link set he-ipv6 up
ip addr add 2001:470:1f0a:1394::2/64 dev he-ipv6
ip route add ::/0 dev he-ipv6
ip -f inet6 addr

Itt a 216.66.80.30 a frankfurti szerverük címe, amihez majd kapcsolódunk, viszont a local cím hiába 1.2.3.4 esetemben, mivel a gépem rá van kötve egy NAT-olt belső hálózatra, így az 1.2.3.4 helyére a gépem belső IP címét kell majd írnom, ami esetemben 192.168.1.30.

Ne adjuk ki a parancsokat, hiszen ez a legalapabb setuphoz lenne jó és az egész hoszt gép IPv6 forgalmát átküldené a tunnelen. Helyette csináljunk egy network namespace-t test néven:

[steve@todo ~]$ sudo ip netns add test
[steve@todo ~]$

Hozzuk létre a tunnelbroker tunneljét a hoszton:

[steve@todo ~]$ sudo ip tunnel add he-ipv6 mode sit remote 216.66.87.14 local 192.168.1.30 ttl 255
[steve@todo ~]$

Adjuk át a network namespacenek:

[steve@todo ~]$ sudo ip link set he-ipv6 netns test
[steve@todo ~]$

Állítsunk DNS-t a namespacenek:

sudo mkdir -p /etc/netns/test/
sudo echo 'nameserver 2606:4700:4700::1111' > /etc/netns/test/resolv.conf

Lépjünk be a namespacebe:

[steve@todo ~]$ sudo ip netns exec test bash
[root@todo ~]# export PS1="netns> "
netns>

Itt, ha kiadjuk, hogy ip a, akkor csak az általunk hozzáadott interfészt fogjuk látni, egy localhost interface-t, illetve a sit tunnel interface-t:

netns> ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
6: he-ipv6@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/sit 192.168.1.30 peer 216.66.80.30 link-netnsid 0

Végezetül adjuk ki azt a pár parancsot, amit a példából kimásoltunk. Ez ad IP-t az interfésznek, beállítja a default routeot IPv6-on erre a tunnelre és teszteljük, hogy van-e net:

netns> ip link set he-ipv6 up
netns> ip addr add 2001:470:27:34f::2/64 dev he-ipv6
netns> ip route add ::/0 dev he-ipv6
netns> ping google.com
PING google.com(fra15s17-in-x0e.1e100.net (2a00:1450:4001:81c::200e)) 56 data bytes
64 bytes from fra15s17-in-x0e.1e100.net (2a00:1450:4001:81c::200e): icmp_seq=1 ttl=116 time=43.8 ms
64 bytes from lcfraa-aa-in-x0e.1e100.net (2a00:1450:4001:81c::200e): icmp_seq=2 ttl=116 time=43.8 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 43.761/43.765/43.769/0.004 ms
netns> curl ifconfig.co/json
{
"ip": "2001:470:27:34f::2",
"ip_decimal": 42540578165215622696195063661031587842,
"country": "Russia",
"country_iso": "RU",
"country_eu": false,
"region_name": "St.-Petersburg",
"region_code": "SPE",
"zip_code": "190817",
"city": "St Petersburg",
"latitude": 59.8944,
"longitude": 30.2642,
"time_zone": "Europe/Moscow",
"asn": "AS6939",
"asn_org": "HURRICANE",
"hostname": "tunnel624930-pt.tunnel.tserv24.sto1.ipv6.he.net",
"user_agent": {
"product": "curl",
"version": "7.71.1",
"raw_value": "curl/7.71.1"
}
}netns>

v4 címünk pedig a netns-en belül nincsen:

netns> ping 1.1.1.1
ping: connect: Network is unreachable
netns>

Előállt pontosan az az állapot, ami az IPv6 only VPS-en lenne. :C

Most töltsük le a legfrissebb verziót a wgcf binárisból és futtassuk, hogy kapjunk egy wireguard kulcsot a warphoz:

netns> cd /tmp/
netns> mkdir warp-test
netns> cd warp-test
netns> wget https://github.com/ViRb3/wgcf/releases/download/v2.2.18/wgcf_2.2.18_linux_amd64
--2023-07-27 14:34:05-- https://github.com/ViRb3/wgcf/releases/download/v2.2.18/wgcf_2.2.18_linux_amd64
Resolving github.com (github.com)... 140.82.121.3
Connecting to github.com (github.com)|140.82.121.3|:443... failed: Network is unreachable.
netns>

Enyhe irónia, de a githubnak sincsen IPv6 címe ezek szerint. Semmi baj, az exit parancs kiléptet a netns-ből és a hosztról le tudjuk tölteni a binárist, majd a sudo ip netns exec test bash visszavisz minket.

netns> ls
wgcf_2.2.18_linux_amd64
netns> chmod +x wgcf_2.2.18_linux_amd64
netns> ./wgcf_2.2.18_linux_amd64 register
2023/07/27 14:37:43 Using config file: wgcf-account.toml
This project is in no way affiliated with Cloudflare
Cloudflare's Terms of Service: https://www.cloudflare.com/application/terms/
✔ Yes
2023/07/27 14:37:47 =======================================
2023/07/27 14:37:47 Device name : <kiszedtem érthető okokból>
2023/07/27 14:37:47 Device model : PC
2023/07/27 14:37:47 Device active : true
2023/07/27 14:37:47 Account type : free
2023/07/27 14:37:47 Role : child
2023/07/27 14:37:47 Premium data : 0.00 B
2023/07/27 14:37:47 Quota : 0.00 B
2023/07/27 14:37:47 =======================================
2023/07/27 14:37:47 Successfully created Cloudflare Warp account
netns> ./wgcf_2.2.18_linux_amd64 generate
2023/07/27 14:37:50 Using config file: wgcf-account.toml
2023/07/27 14:37:50 =======================================
2023/07/27 14:37:50 Device name : <kiszedtem érthető okokból>
2023/07/27 14:37:50 Device model : PC
2023/07/27 14:37:50 Device active : true
2023/07/27 14:37:50 Account type : free
2023/07/27 14:37:50 Role : child
2023/07/27 14:37:50 Premium data : 0.00 B
2023/07/27 14:37:50 Quota : 0.00 B
2023/07/27 14:37:50 =======================================
2023/07/27 14:37:50 Successfully generated WireGuard profile: wgcf-profile.conf
netns> cat wgcf-profile.conf
[Interface]
PrivateKey = QK9+<kiszedtem érthető okokból>=
Address = 172.16.0.2/32
Address = 2606:<kiszedtem érthető okokból>/128
#DNS = 1.1.1.1
MTU = 1280
[Peer]
PublicKey = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=
AllowedIPs = 0.0.0.0/0
#AllowedIPs = ::/0
Endpoint = engage.cloudflareclient.com:2408
netns>

Itt az AllowedIPs IPv6-os részét szándékosan kommenteltem ki, hiszen a wg-quick berakna egy default routeot warpra is. Ezt én nem szeretném, nekem elég, ha a v4-es forgalom lesz warpon keresztül irányítva.

A DNS-hez meg a wg-quick használna resolvectl-t, ami nincs fent a gépemen és nem is szeretném telepíteni. Majd kézzel hozzáírom a DNS-t.

Ideje elindítani a VPN-t: sudo wg-quick up ./wgcf-profile.conf

Teszteljük, hogy tudunk-e IPv4-et pingelni:

netns> ping discord.com
PING discord.com (162.159.128.233) 56(84) bytes of data.
64 bytes from 162.159.128.233 (162.159.128.233): icmp_seq=1 ttl=64 time=17.1 ms
64 bytes from 162.159.128.233 (162.159.128.233): icmp_seq=2 ttl=64 time=16.1 ms
64 bytes from 162.159.128.233 (162.159.128.233): icmp_seq=3 ttl=64 time=15.9 ms
64 bytes from 162.159.128.233 (162.159.128.233): icmp_seq=4 ttl=64 time=15.9 ms
^C
--- discord.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 15.854/16.240/17.058/0.480 ms
netns>

Node végre valahára elérkezett a várva várt pillanat!

Az összes Cloudflare mögötti oldal esetében működik, hogy a /cdn-cgi/trace linket lekérve kapunk egy adag hasznos infót, hogy a cloudflare edge minek látta az IP címünk, hogyan csatlakoztunk pontosan stb. De elég a kertelésből. Mindenkinek javaslom, hogy tegye meg a tippjét, mi fog következni, ha lekérem a discordapp.com/cdn-cgi/trace URL-t.

netns> curl https://discordapp.com/cdn-cgi/trace
fl=71f499
h=discordapp.com
ip=127.0.0.1
ts=1616532985.758
visit_scheme=https
uag=curl/7.71.1
colo=FRA
http=http/2
loc=XX
tls=TLSv1.3
sni=plaintext
warp=on
gateway=off
netns> curl https://discordapp.com/cdn-cgi/trace
fl=71f499
h=discordapp.com
ip=2001:470:27:34f::2
ts=1616532988.233
visit_scheme=https
uag=curl/7.71.1
colo=FRA
http=http/2
loc=DE
tls=TLSv1.3
sni=plaintext
warp=on
gateway=off

Mikor ezt megláttam, a szívem megállt egy pillanatra. Nem akartam hinni a szememnek. Eggyé váltam a Cloudflare-rel egy pillanatra. Bejött a tipped? :D Ekkor már kezdtem érezni, hogy valami bugot sikerült felfedezni egészen véletlenül.

Node hogy lehet, hogy csak egyszer sikerült? Szétkapcsoltam az egészet, majd vártam pár órát, megismételtem a warp kapcsolódást és ismét az első kérés localhost volt.

Arra tippeltem tehát, hogy ha a backenden nincs gyorsítótárazva a címem, akkor az első lekérés Cloudflare domainekre mind 127.0.0.1 lesz. Amint cachelt viszont minden rendeltetésszerűen kezd működni, ami nekem az exploit szempontjából nem szerencsés.

Gondolkoztam tehát, hogy hogy tudnék örökre localhost lenni. Egyből beugrott, hogy a tunnelbroker bizony egy /64-es IPv6 tartományt adott. Egy /64 pedig 18 446 744 073 709 551 616 IP címből áll, ami jó pár nem gyorsítótárazott IP címet jelent. Sőt, tunnelbrokernél lehet /48-at kérni, ha ez nem lenne elég. A Wireguardról pedig azt érdemes tudni, hogy nem érdekli a forrás IP/port. Ha kap egy csomagot és tudja decryptelni, akkor kezd vele valamit, ha nem tudja, akkor eldobja és mintha mise' történt volna. Magyarul ha útközben lecserélem a saját IP-m, nem lesz probléma.

Írtam tehát egy PoC-ot rustban, ami ezt kihasználva minden kapcsolatnak új tunnelbroker IP-t sorsolt, így biztosítva az állandó localhost kapcsolatom. Egy egyszerű HTTP proxy-t csinált helyben, amit pedig tudtam használni a további kutatásra. Az eredmény ténylegesen az lett, hogy bárhova csatlakoztam, az 127.0.0.1-nek látott.

Maradt még azonban egy nyitott kérdés bennem. Fentebb jól látható, hogy a második kérésnél már a tényleges kapcsolódó IPv6 címet ismerte fel a Cloudflare edge. Node a Discord mit kaphatott vajon az ő webszervereire, ha le volt tiltva a v6 náluk? Ha a v6-ot küldi el, akkor az nagyon rossz lenne, mivel a discord IP parsere nincs felkészítve a v6-os címekre. Éppen ezért felkerestem a Discord akkori lead developerjét és infra leadjét, majd megkérdeztem, hogy rá tudna-e nekem nézni a logokra. Illetve megkérdeztem, hogy miért nincs engedélyezve a v6 és azt a választ kaptam, hogy mivel a Google Cloud Platform load balancerjei nem ismerik a v6-ot, így le lett tiltva.

Közben megnézte a logokat és lehet tippelni, hogy mi látszódott az ő oldalukon. Igen, helyes. Az első kérés 127.0.0.1-től jött. A második? No az egy IPv4-es cím volt. Tipp? Annyit segítek, hogy eddig nem láttuk sehol. Bizony! Egy Class E cím. Mint kiderült ez egy teljesen várt viselkedés, még blogposzt is született róla: [link]

Itt elgondolkoztam, hogy mégis mit tudnék csinálni az exploittal. Nem scannelhetem csak úgy végig a Cloudflare belső hálózatát, hiszen azzal minden bizonnyal életfogytigLAN-ra ítélném magam, így csak arra tudtam gondolni, hogy geo bypassre fogom használni. Kipróbáltam, hogy a saját weboldalamon beállítottam egy szűrést. Csak az angol IP címeket engedje megtekinteni, minden mást blokkoljon. Végül pedig küldtem egy kérést és localhostról pillanatok alatt visszadobta a csak angliából elérhető tartalmat.

Ezekután megkérdeztem a discordos fejlesztőt, hogy van-e valami teszt környezet, aminek tudnék jogszerűen spammelni, mert arra gondoltam, hogyha kellő mennyiségű API spamet küldök egy IP-ről, akkor a discord automatikusan felveszi egy Cloudflare feketelistába az IP címem és bannolja azt napokra. Sikeresen elértem így, hogy bannolja a 127.0.0.1-et a discord és ezzel valahogy egy újabb bugnak köszönhetően nem volt többé elérhető az oldal. Jelentettem a hibát, majd kicsivel később a hiba javítva is lett.

Aztán nekiálltam kutatni, hogy hogyan tudom bejelenteni a hibát és mit kaphatok érte. Találtam egy hackerone projektet, de nem volt sehol részletezve, hogy mik a program keretei csak nagyon nagy vonalakban. Konkrétan a Warp sem volt létrehozva, mint kategória. Találtam egy régi fórum posztot viszont, ahol azt írták, hogy egy Cloudflare pólót adtak bug bountyra.

Nekem több se kellett, gondoltam mindenképp bejelentem, de így, hogy kaphatok egy CF pólót, mégjobban motivált lettem. Leírtam a reprodukálás lépéseit, a lehetséges impactokat, majd beküldtem és a torkomban a pulzusommal vártam, hogy mi történik majd vele. Közben a Discord fejlesztőt is informáltam, hogy bejelentettem a bugot, aki elkérte az issue ID-t és írt a Cloudflarenek, mint jelentős customer, akit szintén negatívan érint a jelenség, hogy azonnal nézzenek rá.

Először 0.2-es értékelést kapott, majd amint visszaírtak, hirtelen felugrott 9.8-as Criticalra. Illetve azonnal átrakták a ticketet egy privát programba, ahol viszont már részletesebb infók voltak. Először nem tudták reprodukálni a hibát, aztán egy rövid üzenetváltás keretében megértették miről van szó, megerősítették és informáltak, hogy a következő security meetingjük fő témája lesz, megkezdik a javítást, de hosszabb időbe is beletelhet.

Kiírtak $1000-t bountynak. Ez volt akkor a legnagyobb összeg, amit kaphattál tőlük. Megkérdeztem, hogy nem-e kaphatnék pólót helyette, amire sajnos nemleges választ kaptam. Illetve megkérdeztem, hogy van-e lehetőségem írni egy posztot a hibáról, amint befoltozták. Őszintén szólva nem hittem abban, hogy megengedik, hiszen az egész program szigorúan hangsúlyozta, hogy semmit nem publikálhatok. Legnagyobb meglepetésemre azonban azt válaszolták, hogy természetesen, sőt lektorálásra is szívesen jelentkeznének. :)

Közben az is kiderült, hogy kiírnak egy extra $500-at, mivel a Cloudflare Teams csoportba tartozó termékek hónapja volt...

Ezzel párhuzamosan pedig tudatta velem a Discord fejlesztő, hogy az IPv6-os Warp-os Class E-s trükköt is eliminálták, mostantól nem lehet majd az API-hoz kapcsolódni ilyen formán. De azt válaszolta, hogy a bounty bevételből jó pár év IPv4-es hoszting kitelik majd.

Végül 8.9-es high score-ral zárult, a pénzt odaadták és megköszönték a részletes leírásomat. Ebből 10%-ot félre tettem bot hosztingra, a maradékot pedig kis kutatómunka után megkapta egy megbízható, gyermekek étkeztetésével foglalkozó alapítvány.

Viszont a bug még egy hónap múlva is létezett. Már már azt hittem, hogy sosem lesz befoltozva, amikoris kaptam egy emailt:

Igen, ezt minden Cloudflare felhasználó megkapta. :)

Az lett tehát a megoldásuk, hogy a Class E címek helyett erre a különleges esetre a publikus IP tartományukból különítenek el egy szeletet. A localhost címes bugot pedig megoldották valahogy, már nem tudtam reprodukálni.

Sokáig félretettem a dolgot, megelégedtem azzal, hogy a fix létezik és remekül működik. Aztán karácsony környékén valahogy elkezdtem merengeni és eszembe jutott a következő trükk. Mi van abban az esetben, ha v6-tal csatlakozom a warphoz, mint eddig és azon belül csatlakozom egy warp szerverhez? Tehát a warpon belül kapok egy Cloudflare iP-t, majd erről csatlakozom a warpra ismét. Gyorsan kipróbáltam a fentebb leírtakhoz hasonló módon, éééés: ismét localhost voltam. ;] A láncmese folytatódik...

Egy szó, mint száz, ez a bug is be lett foltozva, aztán 2022-ben bejelentették, hogy mostantól nem próbálja meg a saját IP címed kiadni az oldalaknak, hanem megpróbál egy olyan Cloudflare IP-t használni, ami fizikailag nagyjából ugyanahhoz a városhoz van rendelve, mint a te IP címed. Ennél kicsit összetettebb a megoldás, de írtak róla egy blogposztot is: [link]

Ezenkívül kaptam egy állásajánlatot (ugye a sors iróniája), ami okozott pár inszomniás éjszakát, hiszen biztosan sokat tanulhattam volna egy ilyen hatalmas cégnél és jól esett, hogy gondoltak rám. De aztán belegondoltam, hogy ők csupán annyit láttak belőlem, amit bejelentettem és sok közöm nincs a hálózatokhoz. Ez is csupán véletlenek és hosszú hetek kutatómunkájának sorozata volt. Szerencsém volt. :) Nem sokat tudnék hozzátenni a céghez. Nem engem keresnek. Nomeg az állás mindenképpen hibrid lett volna, ha Magyarországon szeretnék maradni, amit nem szerettem volna bevállalni.

Ezek után önző módon játszottam a gondolattal, hogy írok egy catchy medium cikket és megvárom, amíg valaki küld pár állásajánlatot, de erről az ötletről is hamar lebeszéltem magam, mert ez nem én vagyok. Nem bántam meg. Sokkal jobb érzés bulvár helyett nyugodt fejjel leírni ide a történelmet annak a pár embernek, aki eljut ezen írás végére, mint a címlapokon okoskodni. Én pedig büszkén hordozom a történet emlékét.

Hát így esett, hogy majdnem megváltozott az életem, aztán mégsem. :) Hatalmas élmény volt! Azóta duplán felnézek a bughunterekre, mivel erős szívizom kellhet egy-egy ilyen triageolási folyamat levezényléséhez.

Hozzászólások

(#1) Mr Dini


Mr Dini
addikt
LOGOUT blog

Elnézést a logout floodért, nem terveztem két írást is kiadni, de így alakult! :B Nem lesz rendszeres.

Ez most kicsit más jellegű írás lett, kíváncsi vagyok még a véleményekre. Vannak még a tarsolyomban hasonló történetek... Mit gondoltok, van értelme írni róluk?

Hogy hívják az éhes horgászt? Gyere Pista, kész a kaja!

(#2) PSti


PSti
tag

Szép munka, gratulálok! :R

És nem baj, hogy hosszan írtál róla, érdekes volt elolvasni!

(#3) sonar


sonar
addikt

Jó olvasni a bejegyzéseidet :R Azontúl motiváló és inspiráló is.
Twitteren vagy máshol esetleg szoktál post-olni?

A tudást mástól kapjuk, a siker a mi tehetségünk - Remember: Your life – Your choices!

(#4) Mr Dini válasza sonar (#3) üzenetére


Mr Dini
addikt
LOGOUT blog

Nem igazán élek social mediaval. :B

Matrix, email, telegram, discord. Ezeken a platformokon és ebben a preferencia sorrendben vagyok elérhető.

Egy mediumon gondolkoztam, meg angolul írni, de még nem vettem rá magam. :D

Hogy hívják az éhes horgászt? Gyere Pista, kész a kaja!

(#5) joghurt


joghurt
addikt

:R

A bountyból pedig akár egy cloudflare-es pólót is nyomathatsz magadnak. :DDD

A tej élet, erő, egészség.

(#6) hcl


hcl
félisten
LOGOUT blog

Nagyon komoly újfent :R Ilyennel floodolhatsz :)

Mutogatni való hater díszpinty

(#7) Ceree


Ceree
senior tag

Respect! Jo volt olvasni, bar sajnos a technikai reszt kevesse ertettem... 😅

Másolat_eredetije

(#8) Salamander válasza Mr Dini (#1) üzenetére


Salamander
junior tag

Van értelme. :)

iPhone 13 Mini + SE3 + SE1 + 7 + 4S | #StopPutin

(#9) Lenry


Lenry
félisten

szép munka :R
jó volt olvasni :K

Gvella Glan! | There are two types of people: Those who can extrapolate from incomplete data

(#10) sh4d0w


sh4d0w
nagyúr
LOGOUT blog (1)

Bravo, szep munka!

Azt azert felvetem, mint otletet: mi van, ha nem halozatos embert kerestek, hanem security-st? :)

[ Szerkesztve ]

https://www.coreinfinity.tech

További hozzászólások megtekintése...
Copyright © 2000-2024 PROHARDVER Informatikai Kft.