Ping of death! FreeBSD fixar ett kraschfel i nätverksverktyget PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Ping of death! FreeBSD fixar ett kraschfel i nätverksverktyget

Ett av de första nätverksverktygen på låg nivå som alla datoranvändare lär sig om är det ärevördiga ping verktyg.

Uppkallad efter den självbetitlade ljudeffekten från vilken gammaldags krigsfilmscen som helst som involverar ubåtar, är kommandot ett metaforiskt eko (se vad vi gjorde där?) av undervattensversionen av RADAR känd som SONAR.

Du skickar ut ett ping (mer som ett doinnnng-ljud, in verklighet) in i det saltiga djupet, och genom att mäta hur lång tid det tar för dess kusliga eko att komma tillbaka till dig, och genom att uppskatta ljudhastigheten i det omgivande havet, kan du beräkna avståndet till objektet som producerade ekot.

Spännande nog, med tanke på att du förmodligen har hört förkortningen TCP/IP som används som en generisk beskrivning av protokolllimet som driver internet, ping tekniskt sett använder inte TCP/IP alls.

Faktum är att TCP/IP är en förkortning för överföringskontrollprotokoll över internetprotokollet, och hänvisar till en ganska högnivåmekanism för att skicka data över internet på ett sådant sätt att nätverket självt lägger in mycket av "fungerade det faktiskt korrekt?" ansträngning för dig.

Till exempel, i TCP-anslutningar, garanteras alla bitar av data du skickar antingen att komma intakt i andra änden eller orsaka ett fel så att du vet att de inte klarade det.

Dessutom, även om olika databitar slutar ta olika vägar över internet (till exempel på grund av lastbalansering, tillfälliga avbrott eller andra återställningsbara fel), och även om vissa bitar tar längre tid att komma fram än andra, kommer TCP-data att buffras korrekt. upp och presenteras i rätt ordning i andra änden.

Ping är annorlunda

Smakämnen ping kommandot används dock vanligtvis för att verifiera om en dator du är intresserad av är online överhuvudtaget, särskilt om den inte accepterar den typ av TCP-anslutningar på hög nivå du förväntar dig, som att ta emot e-post eller tillåta SSH-inloggningar.

Detta hjälper dig snabbt att avgöra om ett avbrott sannolikt beror på att nätverket eller själva servern går ner, eller på att enskilda tjänster som körs på den servern inte startar korrekt.

Som ett resultat, ping använder ett mycket lägre protokoll än TCP.

Verkligen, ping använder inte ens TCP:s mer avslappnade kusin UDP, förkortning för användardatagram protokoll, vilket är ett sätt att överföra databitar som är snabbt och enkelt, men som populärt kallas skicka-och-hoppa (eller, om du är en cynisk sort, som spray-and-pray).

UDP själv informerar dig inte om din data har hamnat i andra änden eller inte, och även om den kommer intakt, håller UDP inte reda på i vilken ordning dina paket ursprungligen skickades, så det kan inte ordna om dem kl. andra änden om de kommer dit ur sekvens.

Ping, för vad det är värt, använder ett protokoll på mycket låg nivå, speciellt utformat för felsökning och nätverksomkonfigureringsändamål, känt som ICMP, eller meddelandeprotokoll för internetkontroll.

Vanligtvis hanteras direkt i operativsystemets kärna, så att ICMP/IP-paket nästan säkert kommer igenom även om ingen nätverksprogram på högre nivå har kommit upp korrekt, inkluderar ICMP särskilt två speciella meddelandetyper:

  • Skriv 0x08. Officiellt uppringd ICMP EchoDetta typ av paket kallas vanligtvis en Echo Request. Det är vad ping program skickar ut för att söka efter aktiva datorer i nätverket.
  • Skriv 0x00. Officiellt uppringd ICMP Echo Reply, är denna pakettyp exakt vad det står. En dator som är levande, online och inte konfigurerad för att blockera ICMP Echo-trafik är tänkt att skicka den här typen av paket direkt tillbaka till datorn som begärde det.

Så här:

$ ping -c 3 -p 4E414B45445345435552495459 nakedsecurity.sophos.com MÖNSTER: 0x4e414b45445345435552495459 PING news-sophos.go-vip.192.0.66.227 av 56 av 84 av 64. 192.0.66.227 av 192.0.66.227 av 1. vip. . 53 bytes from 84.0 (64): icmp_seq=192.0.66.227 ttl=192.0.66.227 time=2 ms 53 bytes from 85.1 (64): icmp_seq=192.0.66.227 ttl=192.0.66.227 time=3 ms 53 bytes from 84.8 (3): icmp_seq=3 ttl=0 tid=2004 ms --- news-sophos.go-vip.net pingstatistik --- 84.025 paket överförda, 84.644 mottagna, 85.062% paketförlust, tid 0.446ms rtt min/ avg/max/mdev = XNUMX/XNUMX/XNUMX/XNUMX ms

Att se a ping i aktion på en något lägre nivå kommer vi att använda Lua-koden som du hittar i slutet av artikeln för att konstruera ett eget ICMP Echo-paket och för att läsa svaret som kommer tillbaka, om något:

$ sudo luax ping.lua nakedsecurity.sophos.com Skickar ICMP ECHO-förfrågan till 192.0.66.227 --> 00000000 08 00 03 02 bb 5a 6f 1d 50 69 6e 67 52 65P .. Requ. 71 75 00000010 65 73d 74 4 65 73 73 61 67 65 20 42 42 35 |estMessage BB41A36| 5 6 00000020 46 |F31D | Fick tillbaka--> 44 1 00000000 45 00 f00 af 37 6 00 00 35 01f c94 7 0 e00 |E..42....3.....B.| 7 XX XX XX XX 5 00000010 00b 00 bb 0a 02f 5d 6 1 50e 69 |.........Zo.Ping| 6 67 00000020 52 65 71 75 65 73d 74 4 65 73 73 61 67 65 |RequestMessage B| 20 42 00000030 42 35 41 36 46 |B31A44F5D |

Förresten, vi behövde använda sudo ovan för att köra vårt skript med superanvändarprivilegier, eftersom vi skapade vad som kallas en rå IP-socket – en som kan skapas i vilket underliggande format vi vill, inklusive TCP, UDP och, efter behov här, ICMP.

På många Linux/Unix-system är ping kommandot som tillhandahålls av din distro fungerar utan att uttryckligen ges root-privilegier, vanligtvis för att det är installerat med speciella säkerhetsfunktioner, eller med dess setuid flagguppsättning, vilket betyder att den börjar med att köras under ett annat användarkonto än användaren som körde det.

Väl-designad ping program kommer naturligtvis automatiskt att förkasta sina extra privilegier när de väl har öppnat den råa socket de behöver.

Vi utelämnade den här privilegieavlägsnande koden från vårt exempelskript för korthetens skull. Du kan använda posix.unistd.setpid() funktion för att byta till ett oprivilegierat konto efter att ha skapat socket, men innan du skickar eller tar emot data.

Undersöker svaret

Som du kanske känner igen i datadumpen från vårt skript ovan inkluderar nätverkssocket-funktionen vi använder för att läsa tillbaka data från den svarande servern inte bara ICMP Echo Reply-data, utan även lågnivå-IP (Internet Protocol headers) i det underliggande paketet.

Vi har inte försökt att analysera eller på annat sätt bearbeta denna data, men FreeBSD ping programmet måste göra det för att förstå svaret, inklusive att förstå eventuella felmeddelanden som kommer tillbaka.

Om ping avvisas på något sätt, kommer Echo-svaret vanligtvis inte bara att innehålla sina egna IP-rubriker (som ses ovan) utan också en referenskopia av IP-huvudena och ICMP-data som dök upp i den ursprungliga utgående begäran.

IPv4-pakethuvuden ser vanligtvis ut ungefär som du ser ovan, där IP-huvudena börjar med 45 00 00 37... och fortsätt i 20 byte totalt, upp till och inklusive de byte som visas som ...XX XX XX XX, vilket är IP-adressen till min bärbara dator.

Så här:

00000000 45 00 00 37 f6 af 00 00 35 01 94 7f c0 00 42 e3 |E..7....5.....B.| 00000010 XX XX XX XX |.... | IP-version och rubriklängd: 0x45 (4 = IPv4, 5 = fem 32-bitars ord, dvs 20 byte Servicetyp och överbelastningsdata: 0x00 Total längd på paket: 0x0037 (decimal 55) Sekvensinformation: F6 AF 00 00 Time-to -live (hopp kvar): 0x35 (decimal 53) Protokolltyp: 0x01 (ICMP) Kontrollsumma: 0x947F (decimal 38015) Sändande dators IP-nummer: C0 00 42 E3 (192.0.66.227 = nakens.com) IP-mottagare (mottagares.sofho). bärbar dator): XX XX XX XX (REDAKTERAD = mitt eget IP-nummer)

FreeBSD:s ping programmerare, verkar det som, antog att rubriker av detta slag verkligen alltid skulle vara exakt 20 byte långa, baserat på det rubrikens längdvärde i den första byten av 0x45, betecknar IPv4 (0x4?) med ett 5-DWORD (0x?5), eller 20-byte, rubrik.

Med bara 20 byte att oroa sig för tilldelade programmerarna buffertar med fast storlek på stacken där de kunde behålla en kopia av IP-huvudena i svaret, plus eventuella inbäddade IP-huvuden från den ursprungliga begäran, om det fanns ett feltillstånd att hantera .

Du kan gissa vart detta tar vägen.

Den första byten i IPv4-huvudet kan ha vilket värde som helst från 0x45 (minsta rubrikstorlek på 5 DWORD, eller 20 byte, som visas) upp till 0x4F (betecknar 15 DWORDs, eftersom 0xF är decimal 15, eller totalt 60 byte rubrikdata), vilket på ett snyggt sätt tillåter ytterligare 40 byte med rubrikdata.

Dessa sällsynta, men lagliga, extra rubrikbytes kan användas för olika läckra och ovanliga "funktioner" med konstiga namn som t.ex. Selektiv regisserad sändning, Experimentell flödeskontroll och Uppströms Multicast-paket – saker som vi har hört talas om men aldrig medvetet använt eller ens sett.

Akta dig för cyberbrottslingar som sätter dig på prov

Som du kan föreställa dig, med tanke på att de extra fälten nästan aldrig används, kanske du aldrig ser ett IPv4-paket med något annat än 0x45 i början och med totalt 20 byte headerdata, om du inte har stött på ett gäng cyberkriminella som är redo att sätta dig på prov.

Tyvärr finns det inte mycket som hindrar en angripare från att rigga upp en server som gissar om du använder FreeBSD och medvetet genererar överdimensionerade ICMP/IP Echo Reply-paket för att provocera fram en stack buffertöverskridning inuti din ping programmet.

Om du någon gång kollar för att se om deras server är aktiv (vilket du kanske gör till och med, eller kanske speciellt, om du tycker att det är misstänkt!), kan du bli måltavla med ett snålt svar.

I bästa fall din ping programmet kommer att krascha; i värsta fall, som FreeBSD-säkerhetsrådgivningen generöst medger, "det kan vara möjligt för en skadlig värd att utlösa fjärrkörning av kod i ping."

Lyckligtvis, som FreeBSD-författarna också påpeka, "Pingprocessen körs i en kapacitetssandlåda på alla berörda versioner av FreeBSD och är därför mycket begränsad i hur den kan interagera med resten av systemet vid den punkt där buggen kan uppstå."

Du behöver med andra ord definitivt lappa, men riskerna kan anses vara blygsamma.

Anmärkningsvärt, ping programmet är inte bara låst i en sandlåda, utan körs inte som root när buggykoden nås, vilket bekräftas i säkerhetsrådgivningen: "När ping körs, skapar den den råa socket som behövs för att utföra sitt arbete och återkallar sedan sina förhöjda privilegier."

Som beskrivits ovan krävs superanvändarbefogenheter endast för att skaffa en rå IP-socket från operativsystemet, inte för att använda sendto() och recvfrom() fungerar på det uttaget efteråt.

Denna bugg har fått den officiella identifieraren CVE-2022-23093; det dokumenteras i säkerhetsrådgivningen FreeBSD-SA-22:15.ping.

Vad göra?

  • Om du är en FreeBSD-användare, uppdatera helt enkelt de berörda utgåvorna (FreeBSD 12 och FreeBSD 13) till deras senaste versioner, där denna bugg är åtgärdad.
  • Om du är en nätverksprogrammerare, se alltid till att du har tagit hänsyn till pakethuvuden som kan indikera ovanliga storleksvariationer. Det faktum att du aldrig har sett någon variant själv hindrar dig inte att möta ett paket imorgon som är utöver det vanliga men ändå helt lagligt.
  • Om du är nätverksansvarig, överväg att blockera IPv4-paket med IP-huvuden som inte är 20 byte stora. Om du verkligen verkar behöva tillåta vissa programvaruprodukter att använda ovanliga IPv4-huvudalternativ, överväg att logga dessa ovanliga paket för att ta reda på varför.

Ta hand om dig där ute!


EXEMPEL KOD FÖR ATT DEMONSTRATERA PING-TRAFIK


Tidsstämpel:

Mer från Naken säkerhet