Problém jménem buffer overflow

Techniku buffer overflow (neboli přetečení zásobníku) využívá řada hackerů k útokům na různá zařízení či apl...


Techniku buffer overflow (neboli přetečení zásobníku) využívá řada hackerů k
útokům na různá zařízení či aplikace.
Buffer je přitom vyrovnávací paměťový prostor sloužící pro přechodné uložení
přesouvaných dat z rychlejšího paměťového média na pomalejší, dále proměnných
programů, mezivýsledků, návratových adres při volání podprogramů apod. Buffer
tak plní roli mezičlánku (např. aby pomalejší médium mělo data stále k
dispozici a rychlejší médium aby nebylo blokováno zdlouhavým přenosem).
Rozlišujeme přitom dva typy přetečení bufferu, a to přetečení na zásobníku
(stack overflow) a přetečení na hromadě (heap overflow). Typicky k přetečení
dochází při zpracování vstupních dat. Buffer overflow nejčastěji vzniká jako
důsledek chyby nebo nevhodného použití programovacího jazyka (zpravidla jako C
nebo C++, které nemají standardně implementovány mechanismy ochrany paměti ty
musejí manuálně vytvářet programátoři, kteří tak mnohdy nečiní nebo činí s
chybami). Jeden z možných důsledků této chyby přitom je, že může dojít k
přepsání nebo poškození korektních dat. Celý problém je o to nebezpečnější, že
nemusí být na první pohled patrný, protože důsledek buffer overflow závisí na
mnoha okolnostech.

Bezpečnostní problém
Hlavní důsledky buffer overflow jsou ale bezpečnostního charakteru. Díky tomuto
problému totiž může dojít ke spuštění kódu v datech, která by měla být
zpracovávána a nikoliv vykonávána. Do těchto dat tedy může hacker umístit svůj
předpřipravený kód, a spustit tak útok vůči systému.
V praxi buffer overflow funguje tak, že při zápisu do bufferu dochází k pokusu
o zápis většího než povoleného objemu dat. Data, která se nacházejí za
vyhrazeným bufferem, jsou pak přepsána a právě sem může útočník pohodlně vložit
svůj programový kód.
Nejoblíbenějším cílem útoků buffer overflow jsou webové servery a další
aplikace. Je to pochopitelné: útok na jedné straně nepotřebuje zásah uživatele,
ale zároveň musí být vykonaný v prostředí, kde se předpokládá vstup uživatele
(např. URL, hlavičky HTTP, tělo HTTP požadavku apod.). Vstup uživatele má pak
podobu vhodně zvolených sekvencí obsahujících kód v assembleru, čímž je
narušena paměť s dalšími důsledky zkolabování serveru nebo právě výše zmíněné
vykonání předpřipraveného kódu. Dávka dat od hackera přesně zaplní buffer a
nahradí data bezprostředně za ním následující.
Správně vytvořené a otestované programy by přitom měly kontrolovat délku
vstupujících dat, a to právě z důvodu, aby nedocházelo k přetečení bufferu.
Jenomže tato skutečnost je často přehlížena.
Jazyky C nebo C++ byly konstruovány s ohledem na rychlost tvorby, a nikoliv na
její bezpečnost. Naproti tomu programovací jazyky jako Java či Lisp řídí
vyčlenění paměti automaticky a používají kombinaci různých technik (run time
checking, static analysis) k tomu, aby nějaký kód měl nepravděpodobnou nebo
zcela vyloučenou možnost buffer overflow. Perl zase nabízí průběžnou změnu
velikosti polí, aby se přetečení zásobníku vyhnul. Přes tyto snahy ale mají i
výše uvedené "bezpečnější" jazyky problémy s buffer overflow, a to díky chybám
v knihovnách.

Nutná prevence
V případě problému buffer overflow je velmi důležité spoléhat hlavně na
prevenci. V prvé řadě je dobré věnovat pozornost použití bezpečných knihoven a
vůbec softwaru. Přetečení zásobníku je mimo jiné bráněno udržováním vysoké
korektnosti kódu (buffer management). Proto dobře napsané a otestované kódy,
které dokáží automaticky provádět buffer management, představují jeden ze
základních pilířů ochrany. Nástroje na detekci chyb v programech přitom mohou
být statické (analyzují zdrojový kód programu bez toho, aby jej prováděly) nebo
dynamické (kód je prováděn a sleduje se jeho chování).
Pak je tu samozřejmě celá řada dalších možných opatření. Třeba použití IDS
(Intrusion Detection Software), neboť tyto programy mají možnost detekovat
pokusy právě o útok buffer overflow. Většina takovýchto útoků totiž obsahuje
dlouhé pole instrukcí, která v korektním kódu chybí. IDS tak mohou blokovat
příchozí pakety obsahující větší počet podobných instrukcí. Nicméně tato
ochrana není úplná, protože příslušná pole mohou být napsána i za použití jiné
syntaxe. Dokonce se lze v poslední době setkat i s alfanumerickými,
polymorfními nebo sebemodifikujícími kódy. Pak jsou to speciální softwarové
nástroje pro ochranu poškození zásobníku, které dokáží detekovat nejobvyklejší
útoky tím, že sledují, zdali nedošlo ke změně zásobníku po návratu funkce.
Pokud k nějaké změně došlo, program je okamžitě ukončen.
Ochrana je možná i na úrovni operačních systémů. Ve Windows najdete několik
možností, které se s problémem dokáží vypořádat. Jedná se například o DEP (Data
Execution Prevention) přítomnou ve verzi XP SP2 nebo W2003 SP1, dále OSsurance
či Anti-Execute. Stejná situace panuje i u Linuxu, kde například knihovna
Libsafe může přesměrovávat volání potenciálně nebezpečných funkcí na sebe,
Openwall Kernel Patch zase doplňuje do jádra systému vlastnosti
"non-executable-stack" a StackGuard zamezuje vzniku přetečení doplněním
kontrolního slova na konec vyrovnávací paměti.



Buffer overflow z historického pohledu
Přetečení zásobníku je typ útoku známý již velmi dlouho a je i velmi hojně
používaný. Ostatně nevznikl právě jako útok, nýbrž jako regulérní
programátorská chyba. A když se pak pátralo po příčinách "padání" programu nebo
jiných kolizí, zjistilo se, že na vině je právě přetečení bufferu. A pak už jen
stačilo, aby si vynalézavá hlava uvědomila, že tuto chybu lze vyvolat uměle a
že ji lze použít k podniknutí útoku.
První větší zneužití chyby buffer overflow byla zaznamenána v roce 1988, a to
ve škodlivém kódu Worm (Červ) Roberta T. Morrise z Cornell University který tak
dal jméno celé kategorii malwaru.
Program Worm měl pouhých 99 řádků kódu, ale dokázal navždy změnit svět. Dokázal
napadnout zhruba šest tisíc počítačů. Podle dnešních měřítek je to samozřejmě
směšně málo, ale je třeba si uvědomit, že tehdy šlo o plných osm procent strojů
připojených do sítě (z hlediska procentuálního zavirování všech připojených
počítačů Worm nezískal už nikdy konkurenta). Robert Morris dostal za svůj
tehdejší "počin" tříletou podmínku, finanční pokuty ve výši několika tisíc
dolarů a také byl vyloučen ze školy.
Ani toto varování však nestačilo. Na problém jménem buffer overflow se na
několik let zapomnělo, znovu jej objevil až v roce 1995 Thomas Lopatic, který
své analýzy zveřejnil v seznamu Bugtraq. Tím nejen varoval IT veřejnost, ale
zároveň ukázal hackerům možnost vstupu do mnoha systémů cestou velmi malého
odporu. Zatímco veřejnost se nepoučila (a testování na odolnost vůči buffer
overflow je dodnes v případě některých programátorů i vývojářských společností
značně nedůsledné), hackeři svoji příležitost rychle rozpoznali.
Svědčí o tom třeba velmi podrobný článek Eliase Levyho (alias Aleph One)
publikovaný v časopise Phrack pod názvem "Smashing the Stack for Fun and
Profit" (Rozbíjení zásobníku pro zábavu i zisk). Ten problém nepojal jako
varování, ale krok za krokem rozebral praktické aspekty zneužití buffer
overflow. Zatímco dosud mohli tyto útoky provádět jen lidé s vysokou úrovní
znalostí problematiky, nyní si mohl buffer overflow vyzkoušet opravdu každý. To
mělo za následek obrovský rozmach útoků v letech následujících.
Za připomenutí také rozhodně stojí událost z roku 2001 CodeRed. První verze
tohoto internetového červa nebyla příliš nebezpečná, protože měl nešťastně
navržený mechanismus šíření. O týden později se ovšem objevila verze druhá, jen
nepatrně modifikovaná, a díky vylepšenému mechanismu šíření bylo celosvětově
napadeno za méně než 14 hodin 359 tisíc počítačů. Způsobené škody byly
vyčísleny na 2,6 miliardy dolarů.
Zatím poslední globální útok zneužívající buffer overflow pak přišel v roce
2003 a měl podobu internetového červa Slammer. Ten se mimochodem stal
nejrychleji se šířícím kódem v historii počítačů. Během deseti minut dokázal
napadnout devadesát procent všech napadnutelných počítačů těch bylo asi 75
tisíc. V průběhu první minuty šíření přitom dokázal zdvojnásobit počet
napadených počítačů během každých 8,5 sekundy. Rychlost Slammeru byla možná
především díky jeho malé velikosti (376 znaků) a také díky tomu, že se šířil
pomocí paketů UDP (ty jsou nesrovnatelně rychlejší než TCP-SY).









Komentáře
K tomuto článku není připojena žádná diskuze, nebo byla zakázána.