Buffer-överflöde

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 6 januari 2017; kontroller kräver 22 redigeringar .

Ett  buffertspill är ett fenomen som uppstår när ett datorprogram skriver data utanför en buffert som är allokerad i minnet .

Buffertspill beror vanligtvis på felaktig hantering av externt mottagen data och minne, i avsaknad av starka skydd från programmeringsundersystemet ( kompilator eller tolk ) och operativsystemet . Som ett resultat av ett spill kan data som finns efter bufferten (eller före den) [1] skadas .

Buffertspill är ett av de mest populära sätten att hacka datorsystem [2] , eftersom de flesta högnivåspråk använder stack frame -teknologi  - placera data på processstacken , blanda programdata med kontrolldata (inklusive startadressen för stackram och returadressen från den körbara funktionen).

Ett buffertspill kan göra att ett program kraschar eller hänger sig, vilket leder till ett överbelastningsskydd ( DoS ). Vissa typer av överflöden, till exempel stackframe-overflow, tillåter en angripare att ladda och exekvera godtycklig maskinkod på uppdrag av programmet och med rättigheterna för kontot som det körs från [3] .

Exempel är kända när buffertspill medvetet används av systemprogram för att kringgå begränsningar i befintlig programvara eller fast programvara. Till exempel använde operativsystemet iS-DOS (för ZX Spectrum-datorer ) buffertspillfunktionen i den inbyggda TR-DOS för att starta sin bootloader i maskinkoder (vilket är omöjligt att göra med vanliga TR-DOS-verktyg).

Säkerhet

Ett program som använder en sårbarhet för att bryta skyddet för ett annat program kallas en exploatering . De farligaste är exploateringar utformade för att få tillgång till superanvändarnivån , eller med andra ord, privilegieskalering . Buffertspillningsutnyttjandet uppnår detta genom att skicka specialgjorda indata till programmet. Sådan data svämmar över den tilldelade bufferten och ändrar data som följer efter bufferten i minnet . [fyra]

Föreställ dig ett hypotetiskt systemadministrationsprogram som körs med superanvändarbehörigheter – till exempel att ändra användarlösenord . Om programmet inte kontrollerar längden på det angivna nya lösenordet, kommer all data som överstiger storleken på bufferten som tilldelats för deras lagring helt enkelt att skrivas över det som var efter bufferten. En angripare kan infoga maskinspråksinstruktioner i detta minnesområde , till exempel skalkod , utföra valfri åtgärd med superanvändarprivilegier - lägga till och ta bort användarkonton, ändra lösenord, ändra eller ta bort filer etc. Om den körs i detta minnesområde tillåts och i i framtiden kommer programmet att överföra kontrollen till det, kommer systemet att köra angriparens maskinkod som finns där.

Välskrivna program bör kontrollera längden på indata för att säkerställa att den inte är större än den tilldelade databufferten. Men programmerare glömmer det ofta. Om bufferten är placerad på stacken och stacken "växer ner" (till exempel i x86- arkitekturen ), kan du med hjälp av ett buffertspill ändra returadressen för den körda funktionen , eftersom returadressen är placerad efter buffert tilldelad av den exekverade funktionen. Således är det möjligt att exekvera en godtycklig sektion av maskinkod i processens adressutrymme. Det är möjligt att använda ett buffertspill för att korrumpera returadressen även om stacken "växer upp" (i vilket fall är returadressen vanligtvis före bufferten). [5]

Även erfarna programmerare har svårt att avgöra om ett givet buffertspill kan vara en sårbarhet. Detta kräver djup kunskap om datorarkitekturen och målprogrammet. Det har visat sig att även så små spill som att skriva en enda byte ur bufferten kan representera sårbarheter. [6]

Buffertspill är vanliga i program som är skrivna på relativt lågnivåprogrammeringsspråk som assemblerspråk , C och C++ , som kräver att programmeraren kontrollerar storleken på det tilldelade minnet. Felsökning av buffertspill är fortfarande en dåligt automatiserad process. Formella programverifieringssystem är inte särskilt effektiva med moderna programmeringsspråk. [7]

Många programmeringsspråk, som Perl , Python , Java och Ada , hanterar minnesallokering automatiskt, vilket gör buffertspillfel osannolika eller omöjliga. [8] Perl tillhandahåller automatisk storleksändring av arrayer för att undvika buffertspill . Körtidssystem och bibliotek för sådana språk kan dock fortfarande vara känsliga för buffertspill på grund av möjliga interna buggar i implementeringen av dessa valideringssystem. Flera mjukvaru- och firmwarelösningar finns tillgängliga på Windows som förhindrar att kod exekveras utanför en spillbuffert om ett sådant spill inträffar. Dessa lösningar inkluderar DEP i Windows XP SP2 , [9] OSsurance och Anti-Execute .

I Harvard-arkitekturen hålls den körbara koden åtskild från data, vilket gör sådana attacker nästan omöjliga. [tio]

Kort teknisk sammanfattning

Exempel

Tänk på ett exempel på ett sårbart C- program :

#include <string.h> int main ( int argc , char * argv []) { charbuf [ 100 ] ; strcpy ( buf , argv [ 1 ]); returnera 0 ; }

Den använder den osäkra strcpy- funktionen , som låter dig skriva mer data än vad som får plats i den array som är tilldelad för dem. Om du kör detta program på ett Windows- system med ett argument som är längre än 100 byte kommer programmet med största sannolikhet att krascha och användaren får ett felmeddelande.

Följande program påverkas inte av denna sårbarhet:

#include <string.h> int main ( int argc , char * argv []) { charbuf [ 100 ] ; strncpy ( buf , argv [ 1 ], sizeof ( buf )); returnera 0 ; }

Här har strcpy ersatts med strncpy , där det maximala antalet tecken som ska kopieras begränsas av storleken på bufferten. [elva]

Beskrivning

Diagrammen nedan visar hur ett sårbart program kan skada stackstrukturen .

Illustration av att skriva olika data till en buffert tilldelad på stacken

I x86- arkitekturen växer stacken från större adresser till mindre, det vill säga nya data placeras före de som redan finns på stacken.

Genom att skriva data till bufferten kan du skriva utanför dess gränser och ändra data där, i synnerhet ändra returadressen .

Om programmet har speciella privilegier (som att köra som root ) kan en angripare ändra returadressen till en skalkodsadress , vilket gör att han kan utföra kommandon på målsystemet med förhöjda privilegier . [12]

Exploatering

Buffertspilltekniker varierar beroende på arkitektur, operativsystem och minnesområde. Till exempel skiljer sig fallet med ett buffertspill på högen (används för dynamisk minnesallokering) väsentligt från det på anropsstacken .

Stackexploatering

Även känd som Stack smashing . En tekniskt kunnig användare kan använda ett stackbuffertspill för att manipulera programmet till sin fördel på följande sätt:

  • skriva över en lokal variabel som finns i minnet bredvid bufferten, vilket ändrar programmets beteende till dess fördel.
  • skriva över returadressen i stackramen . Så snart funktionen avslutas överförs kontrollen till den adress som angriparen angett, vanligtvis till minnesområdet som han hade tillgång till att ändra.
  • skriva över en funktionspekare [13] eller en undantagshanterare som senare kommer att ta kontroll.
  • skriva över parametern från en annan stackram, eller en icke-lokal adress som pekas på i det aktuella sammanhanget. [fjorton]

Om adressen till användardata är okänd, men den är lagrad i ett register,  kan trampolinmetoden användas   : returadressen kan skrivas över med adressen till opkoden , som kommer att överföra kontrollen till minnesområdet med användardata. Om adressen är lagrad i R-registret, kommer att hoppa till ett kommando som överför kontroll till den adressen (till exempel anrop R) att få den användarspecificerade koden att exekveras. Adresser till lämpliga opkoder eller minnesbytes kan hittas i DLL : n eller i själva den körbara filen. Adresser kan dock vanligtvis inte innehålla nolltecken, och placeringen av dessa opkoder varierar beroende på applikation och operativsystem. Metasploit-projektet upprätthöll till exempel en databas med lämpliga opkoder för Windows-system (som för närvarande inte är tillgänglig). [femton]

Ett buffertspill på stapeln ska inte förväxlas med ett stackspill .

Det är också värt att notera att sådana sårbarheter vanligtvis hittas med hjälp av fuzzing testtekniken .

Högexploatering

Ett buffertspill i ett heapdataområde kallas ett heapoverflow och utnyttjas på ett annat sätt än ett buffertspill i stacken. Högminne allokeras dynamiskt av en applikation vid körning och innehåller vanligtvis programdata. Utnyttjande görs genom att korrumpera denna data på speciella sätt för att tvinga applikationen att skriva över interna strukturer som pekare i länkade listor. En vanlig utnyttjandeteknik för heapbuffertspill är att skriva över dynamiska minnesreferenser ( som malloc - funktionsmetadata ) och använda den resulterande modifierade pekaren för att skriva över programfunktionspekaren.

En sårbarhet i Microsofts GDI+ -produkt i hanteringen av JPEG- bilder  är ett exempel på faran som ett heapbuffertspill kan utgöra. [16]

Svårigheter att använda

Att manipulera bufferten innan du läser eller kör den kan förhindra framgångsrikt utnyttjande av sårbarheten. De kan minska hotet om en framgångsrik attack, men inte helt eliminera det. Åtgärder kan innefatta att konvertera en sträng till versaler eller gemener, ta bort specialtecken eller filtrera bort alla utom alfanumeriska tecken. Det finns dock knep för att kringgå dessa åtgärder: alfanumeriska skalkoder, [17] polymorfa koder , [ 18 ] självförändrande koder och bibliotekets returattack . [19] Samma tekniker kan användas för att gömma sig från system för intrångsdetektering . I vissa fall, inklusive fall av konvertering av tecken till Unicode , misstas sårbarheten för att tillåta en DoS-attack , när det faktiskt är möjligt att fjärrexekvera godtycklig kod. [tjugo]

Förebyggande

Olika knep används för att göra buffertspill mindre sannolika.

Intrångsdetekteringssystem

Intrångsdetekteringssystem (IDS) kan upptäcka och förhindra försök att på distans utnyttja buffertspill. Eftersom data som är avsedda för ett buffertspill i de flesta fall innehåller långa arrayer av No Operation ( eller ) instruktioner , blockerar IDS helt enkelt alla inkommande paket som innehåller ett stort antal på varandra följande NOP:er. Denna metod är i allmänhet ineffektiv, eftersom sådana arrayer kan skrivas med hjälp av en mängd olika instruktioner för assemblerspråk . På senare tid har crackers börjat använda skalkoder med kryptering , självmodifierande kod , polymorf kod och alfanumerisk kod , såväl som reservattacker till standardbiblioteket för att penetrera IDS. [21]NOPNOOP

Stack korruptionsskydd

Stackkorruptionsskydd används för att upptäcka de vanligaste buffertspillfelen. Detta kontrollerar att anropsstacken inte har modifierats innan den återgår från funktionen. Om det har ändrats, avslutas programmet med ett segmenteringsfel .

Det finns två system, StackGuard och Stack-Smashing Protector (tidigare ProPolice), båda förlängningar av gcc- kompilatorn . Sedan gcc-4.1- stage2 har SSP integrerats i huvudkompilatordistributionen . Gentoo Linux och OpenBSD inkluderar SSP med sina gcc-distributioner. [22]

Att placera returadressen på datastacken gör det lättare att implementera ett buffertspill som leder till exekvering av godtycklig kod. Teoretiskt kan ändringar göras i gcc för att tillåta att adressen placeras på en speciell returstack som är helt skild från datastacken, liknande hur den är implementerad i Forth-språket . Detta är dock inte en komplett lösning på buffertspillproblemet, eftersom även annan stackdata måste skyddas.

Kodutrymmesskydd för UNIX -liknande system

Att skydda utrymmet för körbar kod kan mildra effekterna av buffertspill, vilket gör de flesta skadliga åtgärder omöjliga. Detta uppnås genom adressutrymmesrandomisering ( ASLR ) och/eller förbud mot samtidig minnesåtkomst för skrivning och exekvering. Den icke-körbara stacken förhindrar de flesta skalkodsexploater .

Det finns två Linux- kärnkorrigeringar som ger detta skydd - PaX och exec-shield . Ingen av dessa är ännu inkluderade i huvudkärndistributionen. OpenBSD sedan version 3.3 har inkluderat ett system som heter W^X som också ger körtidskontroll.

Observera att den här skyddsmetoden inte förhindrar stackkorruption. Men det förhindrar ofta att utnyttjandet "nyttolasten" kan köras framgångsrikt. Programmet kommer inte att kunna infoga skalkod i skrivskyddat minne, såsom befintliga segment av körbar kod. Det kommer inte heller att vara möjligt att köra instruktioner på icke-körbart minne såsom stacken eller heapen .

ASLR gör det svårt för en angripare att bestämma adresserna till funktioner i ett programs kod med vilka han kan utföra en framgångsrik attack, och gör attacker som ret2libc mycket svåra, även om de fortfarande är möjliga i en kontrollerad miljö, eller om angriparen är korrekt gissar rätt adress.

Vissa processorer , som Suns Sparc , Transmetas Efficeon och de senaste 64-bitarsprocessorerna från AMD och Intel , förhindrar exekvering av kod som finns i minnesområden som är markerade med den speciella NX-biten . AMD kallar sin lösning NX (från engelska No eXecute ), och Intel kallar sin XD (från engelska eXecute Disabled ). [23]  

Skydd för körningskodutrymme för Windows

Det finns nu flera olika lösningar tillgängliga för att skydda körbar kod på Windows -system , både från Microsoft och tredje part.

Microsoft erbjöd sin lösning, kallad DEP (från engelska.  Data Execution Prevention  - "data execution prevention"), inklusive den i servicepack för Windows XP och Windows Server 2003 . DEP drar fördel av nyare Intel- och AMD - processorer som designades för att övervinna gränsen för adresserbart minne på 4 GB för 32-bitarsprocessorer. För dessa ändamål har vissa tjänstestrukturer utökats. Dessa strukturer innehåller nu den reserverade NX-biten. DEP använder denna bit för att förhindra attacker som innebär att adressen till en undantagshanterare ändras (den så kallade SEH-exploateringen ). DEP ger endast skydd mot SEH- exploateringen, det skyddar inte minnessidor med körbar kod. [9]

Dessutom har Microsoft utvecklat en stackskyddsmekanism designad för Windows Server. Stacken markeras med hjälp av de så kallade "informanterna" ( engelska  kanariefågen ), vars integritet sedan kontrolleras. Om "informatören" har ändrats är stacken skadad. [24]

Det finns även tredjepartslösningar som förhindrar exekvering av kod som finns i minnesområden avsedda för data eller implementering av ASLR-mekanismen.

Använda säkra bibliotek

Problemet med buffertspill är vanligt för programmeringsspråken C och C++ eftersom de inte döljer detaljerna i lågnivårepresentationen av buffertar som behållare för datatyper . För att undvika buffertöverskridanden måste en hög nivå av kontroll över skapandet och modifieringen av koden som hanterar buffertar upprätthållas. Användningen av abstrakta datatypbibliotek som utför centraliserad automatisk bufferthantering och inkluderar spillkontroll är ett tekniskt tillvägagångssätt för att förhindra buffertspill. [25]

De två huvuddatatyperna som tillåter buffertspill på dessa språk är strängar och matriser . Således undviker användningen av bibliotek för strängar och listdatastrukturer som har utvecklats för att förhindra och/eller upptäcka buffertspill många sårbarheter. Priset för sådana lösningar är en minskning av prestanda på grund av onödiga kontroller och andra åtgärder som utförs av bibliotekskoden, eftersom den är skriven "för alla tillfällen", och i varje specifikt fall kan vissa av de åtgärder den utför vara överflödiga.

Historik

Buffertspillet förstods och dokumenterades delvis redan 1972 i Computer Security Technology Planning Study. [26] Den tidigaste dokumenterade skadliga användningen av ett buffertspill inträffade 1988. Den baserades på en av flera bedrifter som Morris-masken använde för att självföröka sig över Internet. Programmet utnyttjade en sårbarhet i Unix fingertjänst . [27] Senare, 1995, återupptäckte Thomas Lopatik självständigt buffertspillet och listade fynden på Bagtrak- listan . [28] Ett år senare publicerade Elias Levy en steg-för-steg-introduktion till att använda buffertspill med stacken, Smashing the Stack for Fun and Profit, i Phrack magazine . [12]

Sedan dess har minst två kända nätverksmaskar använt buffertspill för att infektera ett stort antal system. År 2001 utnyttjade Code Red -masken denna sårbarhet i Microsofts Internet Information Services (IIS) 5.0 - produkt [29] och 2003 infekterade SQL Slammer maskiner som kör Microsoft SQL Server 2000 . [trettio]

2003 tillät utnyttjandet av ett buffertspill i licensierade Xbox -spel olicensierad programvara att köras på konsolen utan hårdvarumodifiering med så kallade modchips . [31] PS2 Independence Exploit använde också ett buffertspill för att uppnå samma resultat för PlayStation 2 . En liknande exploatering för Wii Twilight utnyttjade denna sårbarhet i The Legend of Zelda: Twilight Princess .

Se även

Anteckningar

  1. Erickson, 2010 , 0x320 Buffer Overflow, sid. 139.
  2. Wheeler, 2004 , 6. Undvik buffertspill, sid. 71.
  3. Erickson, 2010 , 0x321 Stack Buffer Overflow, sid. 142.
  4. Erickson, 2010 , 0x300 Exploits, sid. 135-139.
  5. ↑ "HP-UX (PA-RISC 1.1) Overflows" av Zhodiac  . Phrack . Hämtad 8 december 2014. Arkiverad från originalet 3 december 2014.
  6. ↑ "The Frame Pointer Overwrite" av klog  . Phrack . Hämtad 8 december 2014. Arkiverad från originalet 3 december 2014.
  7. Wheeler, 2004 , 6.1. Faror i C/C++, sid. 71.
  8. Wheeler, 2004 , 6.4. Andra språk, sid. 80.
  9. ↑ 1 2 Data Execution Prevention (DEP  ) . vlaurie.com. Hämtad 8 december 2014. Arkiverad från originalet 18 december 2008.
  10. Hacka Windows CE  . Phrack . Datum för åtkomst: 14 december 2014. Arkiverad från originalet 3 december 2014.
  11. DIY Buffer Overflow #2 . Xakep tidningen. Datum för åtkomst: 8 december 2014. Arkiverad från originalet 11 december 2014.
  12. ↑ 1 2 "Smashing the Stack för skojs skull och vinst" av Aleph One  . Phrack . Datum för åtkomst: 8 december 2014. Arkiverad från originalet 6 februari 2013.
  13. ↑ CORE-2007-0219: OpenBSD :s IPv6 mbufs fjärrkärna buffertspill  . securityfocus.com. Datum för åtkomst: 8 december 2014. Arkiverad från originalet 12 februari 2012.
  14. Moderna  spillmål . Paketstorm. Hämtad 8 december 2014. Arkiverad från originalet 23 oktober 2016.
  15. Metasploit Opcode Database  . Metasploit . Hämtad 15 maj 2007. Arkiverad från originalet 12 maj 2007.
  16. Microsoft Technet Security Bulletin MS04-028  (engelska)  (länk ej tillgänglig) . Microsoft . Hämtad 8 december 2014. Arkiverad från originalet 4 augusti 2011.
  17. Skriva ia32 alfanumeriska  skalkoder . Phrack . Hämtad 14 december 2014. Arkiverad från originalet 10 mars 2014.
  18. Polymorphic Shellcode  Engine . Phrack . Datum för åtkomst: 14 december 2014. Arkiverad från originalet 11 december 2014.
  19. Det avancerade return-into-lib(c) utnyttjar  . Phrack . Datum för åtkomst: 14 december 2014. Arkiverad från originalet 14 december 2014.
  20. Skapa godtycklig skalkod i Unicode Expanded Strings  (engelska) (PDF). Hjälp Net Security. Hämtad 8 december 2014. Arkiverad från originalet 5 januari 2006.
  21. Dag, DJ; Sch. of Comput., Univ. från Derby, Derby, Storbritannien; Zhengxu Zhao; Minhua Ma. Upptäcka återgång-till-libc buffertspillattacker med nätverksintrångsdetekteringssystem   // IEEE . - 2010. - S. 172-177 . - ISBN 978-1-4244-5805-9 . - doi : 10.1109/ICDS.2010.37 .
  22. Wheeler, 2004 , 6.3. Sammanställningslösningar i C/C++, sid. 79.
  23. Funktioner  . _ Ubuntu . Hämtad 9 december 2014. Arkiverad från originalet 8 augusti 2019.
  24. Perla, Oldani, 2011 , KAPITEL 6 Windows.
  25. Wheeler, 2004 , 6.2. Bibliotekslösningar i C/C++, sid. 73.
  26. Planeringsstudie för datorsäkerhetsteknik  (engelska) (PDF)  (länk ej tillgänglig) . Computer Security Resource Center (CSRC). Datum för åtkomst: 8 december 2014. Arkiverad från originalet 21 juli 2011.
  27. "A Tour of The Worm" av Donn Seeley, University of  Utah . world.std.com. Hämtad 3 juni 2007. Arkiverad från originalet 20 maj 2007.
  28. ↑ Arkiv för e- postlista  för Bugtraq säkerhet . www.security-express.com. Hämtad 3 juni 2007. Arkiverad från originalet 1 september 2007.
  29. eEye Digital Security  . eEye digital säkerhet. Hämtad 3 juni 2007. Arkiverad från originalet 25 juni 2007.
  30. Microsoft Technet Security Bulletin MS02-039  (engelska)  (länk ej tillgänglig) . Microsoft . Hämtad 8 december 2014. Arkiverad från originalet 7 mars 2008.
  31. Hacker bryter Xbox-skyddet utan mod-  chip . gamesindustry.biz Hämtad 3 juni 2007. Arkiverad från originalet 27 september 2007.

Litteratur

  • James Foster, Mike Price. Hackskydd: sockets, exploits, shellcode = Sockets, Shellcode, Porting & Coding. - M . : Publishing House DMK-press, 2006. - S. 35, 532. - 784 sid. - ISBN 5-9706-0019-9 .
  • John Eriksson. 0x320 Buffer Overflow // Hacking : The Art of Exploitation. — 2:a upplagan. - St Petersburg. : Symbol-Plus, 2010. - S.  139 . — 512 sid. — ISBN 978-5-93286-158-5 .
  • David A. Wheeler. Kapitel 6. Undvik buffertspill // Säker programmering för Linux och Unix HOWTO . - 2004. - S. 71. - 188 sid.
  • Enrico Perla, Massimiliano Oldani. KAPITEL 6 Windows // En guide till kärnexploatering: Att attackera kärnan. - 2011. - S. 334. - 442 sid. — ISBN 978-1-59749-486-1 .

Länkar

Bibliotek och andra skydd