Zephyrnet-logo

Thuisrouters met NetUSB-ondersteuning kunnen een kritiek kernelgat hebben

Datum:

Nu er een patch is verspreid onder leveranciers, hebben onderzoekers van Sentinel One vrijgegeven details van een zorgwekkende bug in een IoT-softwarestuurprogramma genaamd NetUSB.

Het product is afkomstig van een Taiwanese hardware- en softwaremaker genaamd K-codes, die zichzelf als volgt omschrijft:

[A] toonaangevende leverancier en ontwikkelaar van producten met USB over IP-technologie. Tegenwoordig is meer dan 20% van de wereldwijde netwerkapparaten ingebed in de KCodes-oplossing.

Het idee is leuk: NetUSB is een virtuele connector voor USB-hardware, zodat u een reeks verschillende USB-apparaten rechtstreeks op uw router kunt aansluiten en ze vervolgens op afstand kunt openen vanaf sommige, veel of alle andere apparaten in uw netwerk .

In plaats van een USB-apparaat zoals een diskdrive, een printer of een tv-tuner te delen door deze beurtelings op uw verschillende laptops, desktops en mobiele telefoons aan te sluiten, sluit u het USB-apparaat permanent aan op het virtuele centrum van uw netwerk door het aan te sluiten naar uw router.

Vervolgens deel je het met een "virtuele USB-kabel" die de USB-gegevens over je draadloze netwerk schuift in plaats van over een fysieke kabel - op vrijwel dezelfde manier waarop Windows je stationsletters, mappen en bestanden over het netwerk laat omleiden met de NET USE opdracht.

Kernelstuurprogramma open voor internetverkeer

Sentinel One-onderzoeker Max van Amerongen dacht dat er misschien code is die het waard is om in te duiken wanneer hij onderzocht een NetGear-router in 2021 en vond een kernelstuurprogramma dat luisterde naar netwerkverbindingen op TCP-poort 20005.

Het is veelbetekenend dat de bestuurder op de netwerkinterface luisterde 0.0.0.0, wat een afkorting is voor "alle interfaces", dus dekt localhost, het interne LAN en de extern aangesloten WAN-interface.

De netwerkinterface die wordt gebruikt voor: localhost is alleen toegankelijk voor programma's die rechtstreeks op de router zelf draaien - inderdaad, de "netwerkkaart" voor deze interface is volledig in software geïmplementeerd en krijgt meestal het IP-nummer 127.0.0.1 op IPv4-netwerken.

Het interne LAN heeft meestal een zogenaamd "privé" IP-nummer, meestal 192.168.x.x or 10.x.x.x, die alleen geldig is op het LAN zelf en daarom standaard niet toegankelijk is voor de buitenwereld.

Maar uw WAN-interface, waar WAN een afkorting is voor wide-area netwerk, en betekent losjes "het internet in zijn geheel", heeft meestal een openbaar IP-nummer, vaak automatisch uitgegeven door uw ISP telkens wanneer uw router opstart.

U moet ervan uitgaan dat uw WAN-interface zowel zichtbaar als toegankelijk is van overal ter wereld.

Met andere woorden, TCP-netwerkservices die expliciet luisteren op de WAN-poort, of impliciet door een catchall IP-nummer van 0.0.0.0, worden over het algemeen blootgesteld aan, kunnen door bijna iedereen worden onderzocht en (indien buggy) door bijna iedereen worden uitgebuit.

Erger nog, de meeste computers die luisteren naar verbindingen van de buitenwereld - of ze nu per ongeluk of ontwerp luisteren - zullen automatisch, regelmatig en herhaaldelijk worden gevonden en gepord.

Zelfs als u niet openlijk adverteert voor bezoekers, zoals u zou doen als u uw eigen webserver of blogsite zou hebben, zullen zowel onderzoekers als oplichters u vinden, zonder echt te proberen, meestal binnen enkele minuten nadat uw router is opgestart.

Het IPv4-netwerk kan ongeveer 4 miljard verschillende gelijktijdig verbonden en uniek identificeerbare apparaten ondersteunen (dat komt omdat een 32-bits netwerknummer maximaal 232 verschillende waarden, en 232 = 4,294,967,296)…

…maar bij hedendaagse netwerksnelheden kan zelfs een relatief bescheiden commerciële internetverbinding alle mogelijke IP-nummers uitproberen – miljarden! – in uren of zelfs minuten.

Simpel gezegd, iemand die uw kwetsbare router wil vinden, kan en zal dit doen, zonder u in het bijzonder te hoeven targeten, omdat het verrassend eenvoudig is om te targeten iedereen door letterlijk te proberen iedereen.

Bufferoverloop

Het duurde niet lang voordat Van Amerongen een probleem ontdekte in de code die inkomende netwerkgegevens verwerkte in het Kcodes NetUSB-stuurprogramma.

Zoals bij veel TCP-protocollen, is de eerste stap het inlezen en identificeren van de opdracht die de gebruiker wil uitvoeren.

Als je ooit met HTTP hebt gewerkt, weet je dat inkomende opdrachten worden gespecificeerd in de eerste paar bytes van het eerste netwerkpakket, met behulp van door mensen leesbare bytereeksen zoals GET, HEAD, POST en OPTIONS.

In NetUSB worden opdrachten gespecificeerd met numerieke codes, niet met tekststrings, en van Amerongen ontdekte er een met het nummer 0x805F (32,863), die werd verwerkt door een C-functie genaamd SoftwareBus_dispatchNormalEPMsgOut.

(We weten niet wat een EP bericht betekent in deze context, maar dat doet er niet toe, want het is niet het commando zelf dat het gat maakt, het is de voorbereiding voor het verwerken van het commando.)

Na te zijn geselecteerd op nummer, leest deze functie vervolgens een 32-bits waarde in die de grootte aangeeft van het bericht dat de gebruiker wil verzenden, en wijst voldoende kernelgeheugen toe om vast te houden wat er gaat komen.

Alleen is dat niet helemaal hoe de code werkt, omdat het eigenlijk vraagt ​​om "zoveel geheugen als de gebruiker heeft gevraagd, plus 17 extra bytes die we zullen gebruiken tijdens de verwerking".

Die extra 17 bytes zijn wat het beveiligingslek introduceert.

In pseudocode doet de driver dit:

 U32 size = read(socket,4); // get 32-bit size from network void* buff = kernel_alloc(size+17); // allocate the needed memory, plus 17 additional bytes if (buff == NULL) { error(...); } // make sure there was enough memory [... accept data into buff...]

Later leest de code gegevens van de andere kant in - tot, maar niet noodzakelijkerwijs, size bytes' waard - en kopieert vervolgens alle gegevens die het heeft ontvangen naar het toegewezen geheugengebied buff.

Je hebt waarschijnlijk het probleem opgemerkt.

Als de gebruiker de bestuurder vraagt ​​om een ​​enorme hoeveelheid RAM toe te wijzen door in te stellen size naar, laten we zeggen, een waarde van 3 miljard (wat in 32 bits past – zie hierboven), de kernel_alloc() zal vrijwel zeker mislukken en de functie zal gracieus falen.

Maar als de gebruiker vraagt ​​om bijna, maar niet helemaal, 232 bytes RAM, dan komt het daadwerkelijk gevraagde bedrag bijvoorbeeld uit op (0xFFFFFFFF + 17).

Behalve dat met slechts 32 bits om mee te spelen, de hierboven getoonde som een ​​"millenniumbug" -probleem vertoont, omdat (0xFFFFFFFF + 17) = 0x10000010, wat 33 bits lang is.

Dus de som loopt over en wordt terug "geplet" in 32 bits als slechts 0x10 (16), op precies dezelfde manier waarop AD1999+1 terug zou gaan naar het jaar AD1900 vanwege de Y2K-bug als je maar twee cijfers beschikbaar had om het jaar vertegenwoordigen.

Met andere woorden, een aanvaller kan vragen om 232-1 bytes aan gegevens (0xFFFFFFFF); zou ten onrechte een buffer van slechts 16 bytes ontvangen; en konden vervolgens zoveel gegevens verzenden als ze wilden, of dat nu 100 bytes, 1000 bytes of, inderdaad, elk bedrag tot 0xFFFFFFFF bytes was ...

... maar alle bytes vanaf de 17e zouden een bufferoverloop veroorzaken.

Sentinel One ging niet verder met deze aanval, aangezien het "moeilijk is om een ​​exploit voor deze kwetsbaarheid te schrijven", hoewel Van Amerongen wijselijk opmerkte dat:

We zijn van mening dat het niet onmogelijk is en daarom moeten mensen met wifi-routers mogelijk op zoek naar firmware-updates voor hun router.

Wat te doen?

  • Als je een router hebt die NetUSB biedt voor het koppelen van apparaten via het netwerk, controleer dan op een update. Merk op dat alleen controleren of uw router luistert naar TCP-verbindingen op poort 20005 (bijv Nmap) is op zichzelf niet voldoende, maar het is een nuttige hint dat u een probleem zou kunnen hebben als u weet hoe u poorten moet scannen.
  • Luister niet standaard op alle netwerkinterfaces, tenzij het echt nodig is. Als u code schrijft om inkomende netwerkverbindingen te accepteren en te verwerken, neem dan zo min mogelijk privileges en stel uw connectiviteit zo min mogelijk open.
  • Als u code schrijft die geheugen toewijst op verzoek van een onbetrouwbare buitenstaander, controleer dan altijd of er redelijke limieten zijn. Zelfs als deze bufferoverloop niet mogelijk zou zijn, kunnen we ons niet voorstellen waarom de SoftwareBus_dispatchNormalEPMsgOut functie zou ooit in de buurt van 4 GB aan RAM moeten toewijzen. (Volgens Sentinel One was de patch van NetGear bedoeld om de limiet op te beperken) size tot slechts 16 MByte.)
  • Controleer altijd op over- en onderstroom van gehele getallen bij het berekenen met niet-vertrouwde invoer. Overloop is waar positieve getallen te groot worden en rondlopen naar het begin van het bereik, zoals in dit geval; en onderstroom is waar getallen onder nul eindigen, en in plaats daarvan rond het einde van het bereik lopen.

Underflow klinkt in het begin misschien verwarrend, maar als u ondertekende en niet-ondertekende nummers door elkaar haalt, onderstroom leidt meestal tot enorme overloop.

Je kunt dit visualiseren door je een old-school auto-kilometerteller voor te stellen die aangeeft dat 00001 2 km wordt omgekeerd: na de eerste kilometer zou hij correct terugdraaien naar 00000, maar na de tweede kilometer zou hij blijkbaar naar voren springen om 99999 te lezen.

De kilometerteller heeft geen enkele manier om negatieve waarden aan te duiden, waardoor 00000 en 99999 naast elkaar worden geplaatst in zijn numerieke cyclus, met als resultaat dat hij zijn eigen "klok"-rekenstijl heeft waarin 99999 + 2 1 geeft en 1 – 2 geeft 99999


Bron: https://nakedsecurity.sophos.com/2022/01/11/home-routers-with-netusb-support-could-have-critical-kernel-hole/

spot_img

Laatste intelligentie

spot_img

Chat met ons

Hallo daar! Hoe kan ik u helpen?