Přetečení vyrovnávací paměti: příčiny, efektivní metody řešení problému a nezbytná ochrana

Všichni programátoři si jsou vědomi potenciální hrozby přetečení vyrovnávací paměti (buffer) ve svých programech. Existuje mnoho hrozeb souvisejících s ním, v novém i starém softwaru, bez ohledu na počet provedených oprav. Útočníci mohou využít takové chyby vložením kódu speciálně navrženého tak, aby způsobil přetečení počáteční části datové sady a poté zapsal zbývající do adresy paměti sousedící s přeplněnou.

Data mohou obsahovat spustitelný kód, který útočníkům umožní spouštět větší a složitější programy nebo jim umožní přístup do systému. Chyba je velmi obtížné najít a opravit, protože kód se skládá z milionů řádků. Opravy těchto chyb jsou poměrně složité a zase také náchylné k chybám, což komplikuje proces eliminace.

Definice přetečení vyrovnávací paměti

Definice přetečení vyrovnávací paměti

Před hledáním přetečení, potřebujete vědět, co to představuje. Jak název napovídá, tato zranitelnost se týká vyrovnávacích pamětí nebo přidělování paměti v jazycích, které umožňují přímý přístup ke čtení a zápisu na nízké úrovni.

Při použití jazyků C a Assembler čtení nebo zápis takových distribucí neznamená automatickou kontrolu hranic. V souvislosti s tím, pokud je v dané aplikaci detekováno přetečení zásobníku, neexistuje žádná kontrola, zda lze počet bajtů umístit do dané vyrovnávací paměti. V takových případech může program "přetéct" jeho kapacitu. To způsobí, že data zapsaná po naplnění přepíšou obsah následných adres v zásobníku a přečtou další. K přetečení může dojít neúmyslně kvůli chybám uživatele.

Stává se, že je způsobeno škodlivým subjektem, který do programu odešle pečlivě vytvořený škodlivý vstup, který se jej poté pokusí uložit do nedostatečné vyrovnávací paměti. Pokud je v dané aplikaci detekováno přetečení zásobníku vyrovnávací paměti, nadbytečná data se zapíší do sousedního, kde přepíše všechna dostupná data.

Obvykle obsahují návratový ukazatel provozované funkce-adresu, na kterou musí proces pokračovat. Útočník může nastavit nové hodnoty tak, aby ukazovaly na adresu podle výběru. Útočník obvykle nastaví nové hodnoty, aby označil místo, kde je užitečné zatížení umístěno. Tím se změní cesta k provedení procesu a okamžitě se předá správa škodlivého kódu.

Použití přetečení vyrovnávací paměti umožňuje útočníkovi sledovat nebo ukončit proces nebo změnit jeho vnitřní proměnné. Toto porušení se řadí mezi 25 nejnebezpečnějších softwarových chyb na světě (2009 CWE / SANS Top 25 Most Dangerous Programming Errors) a je definováno jako CWE-120 ve slovníku výčtu slabých systémových míst. Přestože jsou dobře prozkoumány, nadále poškozují populární programy.

Jednoduchý vektor použití vyrovnávací paměti

Při práci se zdrojovým kódem musíte věnovat zvláštní pozornost tomu, kde jsou vyrovnávací paměti používány a upravovány. Za zmínku stojí zejména funkce týkající se vstupu poskytnutého uživatelem nebo jiným externím zdrojem, protože poskytují jednoduchý vektor pro použití, když je detekováno přetečení zásobníku vyrovnávací paměti. Například když uživatel položí otázku " ano "nebo " ne", je rozumné uložit data řetězce uživatele do malého bufferu pro řetězec "ano", jak ukazuje následující příklad.

Jednoduchý vektor použití vyrovnávací paměti

Při pohledu na kód je vidět, že kontrola hranic se neprovádí. Pokud uživatel zadá "možná", program se zhroutí a nepožaduje od něj odpověď, která se zapíše do bufferu bez ohledu na jeho délku. V tomto příkladu, protože user answer je jediná deklarovaná proměnná, budou následující hodnoty v zásobníku hodnotou zpáteční adresy nebo místem v paměti, kam se program vrátí po provedení funkce ask Question.

To znamená, že pokud uživatel zadá čtyři bajty dat, což je dostatečné pro přetečení vyrovnávací paměti příkazů klienta, bude následovat platná návratová adresa, která bude změněna. To způsobí, že program opustí funkci v jiném bodě kódu, než se původně předpokládalo, a může způsobit, že se po bude chovat nebezpečným a neúmyslným způsobem.

Pokud je prvním krokem k detekci přetečení vyrovnávací paměti ve zdrojovém kódu pochopení toho, jak fungují, druhým krokem je naučit se externí vstup a manipulaci s vyrovnávací pamětí, pak třetím krokem bude vědět, které funkce jsou touto zranitelností vystaveny a které mohou fungovat jako "červené příznaky". Funkce gets je skvělá pro nahrávání mimo buffer, který jí byl poskytnut. Ve skutečnosti se tato kvalita vztahuje na celou rodinu souvisejících funkcí, včetně strcpy, strcmp a printf/sprintf, kdekoli se používá jedna z těchto funkcí chyby zabezpečení přetečení.

Odstranění z kódové základny

Pokud je ve zdrojovém kódu detekováno přetečení zásobníku vyrovnávací paměti, bude nutné je konzistentně odstranit ze základny. K tomu musíte být obeznámeni s bezpečnými pracovními metodami. Nejjednodušší způsob, jak těmto zranitelnostem zabránit, je použití jazyka, který je neumožňuje. Jazyk C má tyto chyby zabezpečení díky přímému přístupu do paměti a nedostatku přísného psaní objektů. Jazyky, které tyto aspekty nesdílejí, jsou obvykle nezranitelné. Jsou to Java, Python a .NET spolu s dalšími jazyky a platformami, které nevyžadují zvláštní kontroly ani změny.

Samozřejmě není vždy možné zcela změnit vývojový jazyk. V tomto případě se používají bezpečné metody pro provoz s přetečením vyrovnávací paměti příkazů. V případě funkcí zpracování řetězců se hodně diskutovalo o tom, které metody jsou k dispozici, které jsou bezpečné pro použití a kterým je třeba se vyhnout. Funkce strcpy a strcat zkopírují řetězec do vyrovnávací paměti a přidají obsah jednoho do druhého. Tyto dvě metody vykazují nebezpečné chování, protože netestují hranice cílového bufferu a zapisují mimo, pokud k tomu stačí bajty.

Alternativní ochrana

Jednou z často navrhovaných alternativ jsou propojené verze, které zapisují do maximální velikosti cílové vyrovnávací paměti. Na první pohled to vypadá jako perfektní řešení. Tyto funkce bohužel mají malou nuanci, která způsobuje problémy. Když je dosaženo limitu, pokud se koncový znak nevejde do posledního bajtu, dojde k vážnému poruchy při čtení vyrovnávací paměti.

Alternativní ochrana

V tomto zjednodušeném příkladu je vidět nebezpečí řetězců, které nekončí nulou. Když je foo vložen do normal buffer, končí nulou, protože má další prostor. Toto je nejlepší volba pro vývoj událostí. Pokud jsou bajty v přetečení vyrovnávací paměti na zásobníku v jiném znakovém bufferu nebo jiném tisknutelném řádku, funkce tisku pokračovat ve čtení, dokud není dosaženo koncového znaku tohoto řádku.

Nevýhodou je, že jazyk C neposkytuje standardní a bezpečnou alternativu k těmto funkcím. Existuje však pozitivita-dostupnost více implementací pro konkrétní platformu. OpenBSD poskytuje strlcpy a strlcat, které fungují podobně jako funkce strn, kromě zkrácení řetězce o jeden znak dříve, aby se uvolnily místo pro nulový Terminátor.

Podobně společnost Microsoft poskytuje své vlastní zabezpečené implementace běžně používaných funkcí zpracování řetězců: strcpy_s, strcat_s a sprintf_s.

Upřednostňováno je použití bezpečných alternativ uvedených výše. Pokud to není možné, proveďte ruční kontrolu hranic a nulové ukončení při zpracování vyrovnávacích pamětí řetězců.

Chyby kompilace

Chyby kompilace

Pokud nezabezpečená funkce ponechá otevřenou možnost přetečení vyrovnávací paměti C, pak není vše ztraceno. Při spuštění programu kompilátory často vytvářejí náhodné hodnoty známé jako Kanárské ostrovy (Kanárské ostrovy) a vkládají je do zásobníku, takže představují nebezpečí. Kontrola hodnoty kanárku ve vztahu k jeho původní hodnotě může určit, zda došlo k přetečení vyrovnávací paměti systému Windows. Pokud byla hodnota změněna, program se uzavře nebo přejde do chybového stavu, nikoli na potenciálně upravenou zpáteční adresu.

Některé moderní operační systémy poskytují dodatečnou ochranu před přetečením vyrovnávací paměti ve formě nevymahatelných zásobníků a randomizace umístění adresního prostoru (ASLR). Nespustitelné zásobníky-prevence spouštění dat (DEP) - označují zásobník a v některých případech jiné struktury jako oblasti, kde kód nebude spuštěn. To znamená, že útočník nemůže vložit exploit kód do zásobníku a očekávat jeho úspěšné provedení.

Před opravou přetečení vyrovnávací paměti rozbalte na počítači ASLR. Byl navržen tak, aby chránil před programováním zaměřeným na návrat jako řešení nevymahatelných zásobníků, kde jsou existující fragmenty kódu zřetězeny na základě zkreslení jejich adres.

Funguje to randomizací paměťových oblastí struktur, takže jejich posuny je obtížnější určit. Pokud by tato obrana existovala koncem osmdesátých let, mohl by být Morrisův červ zabráněn. Důvodem je, že částečně fungoval vyplněním vyrovnávací paměti v protokolu UNIX finger exploitovým kódem a poté ji přetekl, aby změnil zpáteční adresu a ukázal na vyplněnou vyrovnávací paměť.

ASLR A DEP komplikují přesné určení adresy, kterou je třeba určit, provedením této oblasti paměti Zcela nepracující. Někdy zranitelnost proklouzne trhlinami otevřenými útoku přetečení vyrovnávací paměti, přestože má ovládací prvky na vývojové, kompilátorové nebo operační úrovni.

Analýza statického pokrytí

V situaci přetečení bufferu existují dva zásadní problémy. Nejprve je třeba identifikovat chybu zabezpečení a změnit kódovou základnu pro řešení problému. Za druhé, zajistit nahrazení všech verzí kódu chyby zabezpečení přetečení vyrovnávací paměti. V ideálním případě to začne automatickou aktualizací všech systémů připojených k internetu.

Nelze předpokládat, že taková aktualizace poskytne dostatečné pokrytí. Organizace nebo jednotlivci mohou používat software v systémech s omezeným přístupem k internetu, které vyžadují ruční aktualizaci. To znamená, že zprávy o aktualizaci by měly být sdíleny mezi všemi správci, kteří mohou software používat, a oprava by měla být snadno dostupná ke stažení. Vytváření a distribuce oprav se provádí co nejblíže k detekci zranitelnosti, což zajišťuje minimalizaci doby zranitelnosti.

Pomocí bezpečných funkcí zpracování vyrovnávací paměti a příslušných bezpečnostních funkcí kompilátoru a operační systém lze vytvořit spolehlivou ochranu proti přetečení bufferu. S ohledem na tyto kroky je důsledná identifikace nedostatků rozhodujícím krokem k zabránění zneužití.

Kombinace řádků zdrojového kódu při hledání potenciálních hrozeb může být únavná. Kromě toho vždy existuje možnost, že lidské oči mohou vynechat něco důležitého. Nástroje statické analýzy se používají k zajištění kvality kódu, byly vyvinuty speciálně pro detekci zranitelnosti zabezpečení během vývoje.

Statická analýza pokrytí stanoví "červené značky" pro potenciální přetečení buffer. Poté jsou zpracovány a opraveny samostatně, aby nebyly ručně prohledávány v databázi. Tyto nástroje v kombinaci s pravidelnými kontrolami a vědomím, jak eliminovat přetečení, umožňují identifikovat a řešit drtivou většinu nedostatků před dokončením vývoje softwaru.

Spuštění útoku přes root

Chyby kódování jsou obvykle příčinou přetečení bufferu. Běžné chyby při vývoji aplikací, které k tomu mohou vést, patří neschopnost přidělit dostatečně velké vyrovnávací paměti a nedostatek mechanismu pro kontrolu těchto problémů. Takové chyby jsou obzvláště problematické v jazycích C / C++, které nemají vestavěnou ochranu před přetečením a jsou často terčem útoků přetečení vyrovnávací paměti.

V některých případech útočník vloží škodlivý kód do paměti, která byla poškozena přetečením vyrovnávací paměti zásobníku. Jindy jednoduše využívají poškození sousední paměti. Například program, který požaduje heslo uživatele, aby mu umožnil přístup do systému. V níže uvedeném kódu poskytuje správné heslo oprávnění root. Pokud je heslo nesprávné, program neposkytuje uživateli oprávnění.

Program neposkytuje uživateli oprávnění

V uvedeném příkladu program uděluje uživateli oprávnění root, i když zadal nesprávné heslo. V tomto případě útočník poskytuje vstup, který je delší, než může vyrovnávací paměť pojmout, a vytváří přetečení, které přepíše paměť celého čísla pass. Takže i přes nesprávné heslo se hodnota pass stane nenulovou a útočník získá oprávnění root.

Útok časové oblasti úložiště

Vyrovnávací paměť je dočasná oblast pro ukládání dat. Když program nebo systémový proces umístí více dat než bylo původně přiděleno k ukládání, další přetečení. To způsobí některé prosakování do jiných bufferů, poškození nebo přepsání dat.

Při útoku na přetečení obsahují další data speciální pokyny pro akce určené hackerem nebo škodlivým uživatelem, například vyvolávají odpověď, která poškozuje soubory, mění data nebo odhaluje osobní informace.

Útočník používá zneužití přetečení k využití programu čekajícího na vstup uživatele. Existují dva typy přetečení buffer: na základě zásobníku a haldy. Haldy založené jsou obtížně proveditelné a nejméně běžné, zatímco útočí na aplikaci a vyplňují prostor vyhrazený pro program.

Zásobník-paměťový prostor používaný pro ukládání vlastní instalaci. Takové přetečení je častější u útočníků, kteří používají aplikace.

Moderní kompilátory obvykle poskytují možnost kontroly přetečení při kompilaci / propojení,ale za běhu je docela obtížné tento problém ověřit bez jakéhokoli dalšího mechanismu ochrany zpracování výjimek.

Spuštění útoku přes root

Možnosti programu:

  1. Vstup: 12345678 (8 bajtů), program běží hladce.
  2. Vstup: 123456789( 9 bajtů), zobrazí se zpráva "Chyba segmentace", program se ukončí.

Chyba zabezpečení existuje kvůli přetečení, pokud Uživatelský vstup argv překročí 8 bajtů. Pro 32bitový systém (4 bajty) naplňte paměť dvojím slovem (32 bitů). Velikost znaku je 1 bajt, takže pokud požadujete vyrovnávací paměť s 5 bajty, systém přidělí 2 dvojitá slova (8 bajtů). Proto při zadávání více než 8 bajtů bude Buffer přeplněný.

Podobné standardní funkce, které jsou technicky méně zranitelné, existují. Například strncpy (), strncat ()a memcpy (). Problém s těmito funkcemi je, co odpovědnost pro stanovení velikosti vyrovnávací paměti spočívá na programátorovi, nikoli na kompilátoru.

Každý programátor C / C++ by měl znát problém před zahájením kódování. Mnoho generovaných problémů může být ve většině případů chráněno před přetečením.

Nebezpečí v C / C++

http://blogs.grammatech.com/eliminating-the-danger-of-uninitialized-variables

Uživatelé C by se měli vyhnout použití nebezpečných funkcí, které nekontrolují hranice, pokud si nejsou jisti, že hranice nebudou překročeny. Funkce, kterým je třeba se ve většině případů vyhnout, aby byla zajištěna ochrana, zahrnují funkce strcpy. Měly by být nahrazeny funkcemi jako strncpy. Je třeba se vyhnout použití funkce strlen, pokud je uživatel přesvědčen, že bude nalezen koncový znak NIL. Rodina scanf (): scanf (3), fscanf (3), sscanf (3), vscanf (3), vsscanf (3) a vfscanf ( 3) - nebezpečné pro použití, nepoužívá se k odesílání dat do řetězce bez kontroly maximální délky, "formát% s" je to obzvláště běžné selhání.

Oficiálně snprintf () není standardní funkcí C v klasifikaci ISO 1990. Tyto systémy nechrání před přetečením vyrovnávací paměti, pouze přímo volají sprintf. Je známo, že aktuální verze Linuxu snprintf funguje správně, tj. Návratová hodnota snprintf () se také mění.

Verze 2 SPECIFIKACE Unix (SUS) a standard C99 se liší tím, že vrací snprintf (). Některé verze snprintf don ` t zajišťují, že řetězec skončí v NIL, a pokud je řetězec příliš dlouhý, nebude vůbec obsahovat NIL. Knihovna glib má g_snprintf () se sekvenční návratovou sémantikou, vždy končí NIL a co je nejdůležitější, vždy bere v úvahu délku vyrovnávací paměti.

Přetečení vyrovnávací paměti komunikačního portu

Přetečení vyrovnávací paměti komunikačního portu

Sériový port někdy hlásí přetečení bufferu. Tento problém může být způsoben několika faktory. Patří mezi ně rychlost počítače, rychlost přenosu použitých dat, velikost sériového portu FIFO a velikost zařízení FIFO, které přenáší data na sériový port.

Řízení toku bude čekat, až se ve vyrovnávací paměti objeví určitý počet bajtů, než procesor odešle zprávu nebo signál jinému zařízení, aby zastavil přenos. Při vyšších přenosových rychlostech bude sériový port přijímat více bajtů od dosažení úrovně řízení toku vyrovnávací paměti a zastavení přenosu zařízení.

Tyto další bajty budou větší, pokud proces s vysokou prioritou řídí cílový procesor v reálném čase. Protože proces přetečení vyrovnávací paměti komunikačního portu má vyšší prioritu než přerušení VISA, procesor nepřijme žádnou akci, dokud nebude tento proces dokončen v reálném čase.

Výchozí nastavení VISA a Windows pro 16BAJTOVÝ FIFO je 14 bajtů, takže 2 bajty ve FIFO, když se zařízení pokusí odeslat zprávu ze zdroje. Při vyšších přenosových rychlostech na pomalých počítačích je možné získat více než 4 bajty v okamžiku, kdy sériový port požaduje procesor a vysílá signál, který zastaví přenos.

Chcete-li problém vyřešit, když je v systému Windows 10 detekováno přetečení zásobníku, musíte otevřít Správce zařízení. Poté najděte port COM, pro který se změní nastavení, a otevřete vlastnosti. Dále klikněte na kartu "Upřesnit", zobrazí se posuvník, který změní velikost přetečení schránky tak, aby UART rychleji povolil řízení toku.

Výchozí hodnota je většinou dostatečná. Pokud však dojde k chybě přetečení vyrovnávací paměti, hodnota se sníží. To způsobí odeslání většího počtu přerušení procesoru se zpomalením bajtů do UART.

Metody bezpečného vývoje

Metody bezpečného vývoje

Metody bezpečného vývoje zahrnují pravidelné testování k detekci a odstranění přetečení. Nejspolehlivější způsob, jak se tomu vyhnout nebo mu zabránit, je použití automatické ochrany na úrovni jazyka. Další opravou je kontrola hranic za běhu, která zabraňuje přetečení automatickým ověřením, že data zapsaná do vyrovnávací paměti jsou v platných mezích.

Cloudová služba Veracode identifikuje chyby zabezpečení kódu, jako je přetečení bufferu, takže je vývojáři před zneužitím opraví. Technologie Veracode, jedinečná v oboru, Patentovaná technologie testování zabezpečení binárních statických aplikací (SAST), ji analyzuje, včetně komponent open source a třetích stran, aniž by k ní bylo nutné přistupovat.

SAST doplňuje modelování hrozeb a kontroly kódu prováděné vývojáři rychleji as nižšími náklady detekováním chyb a opomenutí v kódu automatizací. Obvykle se spouští v raných fázích životního cyklu vývoje softwaru, protože je snazší a levnější řešit problémy před zahájením výrobního nasazení.

SAST identifikuje kritická zranitelnost, jako je injekce SQL, skriptování mezi weby( XSS), chyba přetečení vyrovnávací paměti, stavy nezpracovaných chyb a potenciální zákoutí. Binární technologie SAST navíc poskytuje užitečné informace, které upřednostňují závažnost a poskytují podrobné pokyny na opravu.

Chyba přetečení bufferu existuje téměř 3 desetiletí, ale stále je zatěžující. Hackeři po celém světě ji nadále považují za výchozí taktiku kvůli obrovskému množství citlivých webových aplikací. Vývojáři a programátoři vynakládají obrovské úsilí na boj s tímto zlem IT technologií a přicházejí s novými a novými způsoby.

Základní myšlenkou posledně uvedeného přístupu je implementace opravného nástroje, který vytvoří více kopií návratových adres v zásobníku a poté kromě počtu randomizuje umístění všech kopií. Všechny duplikáty jsou aktualizovány a kontrolovány paralelně, takže jakýkoli nesoulad mezi nimi naznačuje možný pokus o útok a vyvolá výjimku.

Články na téma