Přetečení na zásobníku: Porovnání verzí

Smazaný obsah Přidaný obsah
m →‎Vizualizace útoku v paměti: Vizualizace by měla odpovídat kódu
Formulace, opravy chyb
Řádek 1:
'''Přetečení zásobníku''' ({{Vjazyce2|en|'''buffer overflow'''}}) je v [[Informatika (počítačová věda)|informatice]] technika napadení [[Počítačový program|programu]] nebo [[Operační systém|operačního sytému]], která využívá přetečení [[Zásobník (datová struktura)|zásobníku]] ke spuštění libovolného [[Strojový kód|strojového kódu]], například přepsáním návratové adresy pro návrat z podprogramu.
 
== Příklad útoku ==
 
=== Zdrojový kód ===
TypickýKód, kódkterý je náchylný k útoku, typicky obsahuje část, kde se manipuluje s datovou strukturou, jejižjejíž velikost je pevně stanovenástanovena. Problém nastane ve chvíli, kdy se při vkládání dat do proměnné nekontroluje a neošetřuje, zda se data do této proměnné vejdou.
 
<source lang="c">
void functionkopiruj (char *str) {
char buffer[8];
strcpy (buffer, str);
}
int main () {
char *str = "excessive\0";
function (str);
}
Řádek 17 ⟶ 18:
 
=== Vizualizace útoku v paměti===
* ''SP - Stack Pointer - ukazatel na vrchol zásobníku''
* ''RET - Návratovánávratová adresa z funkce ''kopiruj'' do hlavního programu
* ''ARG - Argument - parametr funkce''
 
{| class="wikitable" style="width:30em; text-align:center; white-space:nowrap;"
!
! style="white-space:nowrap;" |
! colspan="8" style="background:#ddf;" | 8-bitový8bajtový buffer
! colspan="2" style="background:#fdd;" | SP
! colspan="2"|- style="background:#fddddf;" | RET
! hodnota
|- style="background:#ddf; font-family:monospace;"
| colspan="8" | žádný obsah
! style="font-family:sans;" | hodnota
| colspan="82" style="font-sizebackground:smaller; font-family:sans#fdd;" | žádný obsahRET
| colspan="2"- style="font-size:smaller; font-family:sans;background:#fddddf;" | 7911
! HEX
! colspan="2" style="font-size:smaller; font-family:sans;background:#fdd;" | 6828
|- style="background:#ddf; font-family:monospace;"
! style="font-family:sans;" | HEX
| 00 || 00 || 00 || 00 || 00 || 00 || 00 || 00
| style="background:#fdd;" | 1E |
| style="background:#fdd;" | E7
! style="background:#fdd;" | 1A || style="background:#fdd;" | AC
|}
 
Pokud zapíšeme na zásobník řetězec delší než 8 bajtů, dojde k přetečení vyhrazeného bufferu (zde ve formě lokální proměnné, která je umístěna na zásobníku). Zapisovaný řetězec "excessive" je dle zvyklostí zakončen znakem <code>\0</code> (tj. binárně nula). Po jeho zápisu do proměnné ''buffer'' bude situace v paměti vypadat tak, jak je znázorněno v následující tabulce:
Pokud se nyní pokusíme zapsat na zásobník např. string delší než 8 bitů, dojde k jeho přetečení. Pokusíme se zapsat "excessive\0"
 
{| class="wikitable" style="width:30em; text-align:center; white-space:nowrap;"
!
! style="white-space:nowrap;" |
! colspan="8" style="background:#ddf;" | 8-bitový8bajtový buffer
! colspan="2" style="background:#fdd;" | SP
! colspan="2"|- style="background:#fddddf;" | RET
! hodnota
|- style="background:#ddf; font-family:monospace;"
!| colspan="8" style="font-familybackground:sans#ddf;" | hodnotaexcessiv
| colspan="82" style="font-size:smaller; font-family:sans;background:#ddffdd;" | excessive\0
| colspan="2"- style="font-size:smaller; font-family:sans;background:#fddddf;" | e\0
! HEX
! colspan="2" style="font-size:smaller; font-family:sans;background:#fdd;" | 0028
|- style="background:#ddf; font-family:monospace;"
! style="font-family:sans;" | HEX
| 65 || 78 || 63 || 65 || 73 || 73 || 69 || 76
| style="background:#fdd;" | 65 |
| style="background:#fdd;" | 00
! style="background:#fdd;" | 1A || style="background:#fdd;" | AC
|}
 
PoPři zapsánízápisu došlo k přetečenípřepsání vrcholu zásobníku hodnotou "e\0". mimoPři zásobníkpokusu ao knávrat přepsánído SP.hlavního Tímprogramu pádem(instrukcí ukazatelRET) zásobníkudojde nyní můžek ukazovatodskoku na teoreticky libovolné místo v paměti. Pokud vhodně zvolíme přetečenou hodnotu a případně přepíšeme i následující paměťový prostor (typicky vlastním strojovým kódem), podařídojde sek námjeho relativněspuštění. snadnoÚtok spustitje nebezpečný zejména v případě, kdy data přepisující zásobník přicházejí z (nekontrolovatelného) vnějšku počítače (tzv. libovolný[[Exploit|remote kódexploit]]).
 
== Obrana proti útoku ==
Obrana proti přetečení zásobníku je možná několika způsoby:
 
=== Z pohledu programátora ===
* pokud to není nutné nepoužívat jazyky, které používají přímý přístup k paměti (typicky C, C++)
Řádek 66 ⟶ 63:
* používání tříd a funkcí, které manipulují s pamětí bezpečně
* použití automatizovaných nástrojů v součinnosti s kompilátorem
====Fungování automatických nástrojů====
Většina automatických nástrojů, které se snaží tomuto způsobu zneužití zabránit používají tzv. kanárky (pojmenováno podle kanárků, kteří se používali v dolech na odhalení nebezpečných plynů). Jedná se o specifická data, která se umístí do paměti za nadefinované proměnné. Ve chvíli, kdy dojde k přetečení zásobníku, tak je přepsána i hodnota kanárka a přetečení je odhaleno. Kanárků se používá několik druhů - statický, náhodný nebo také XOR.
* '''Statický kanárek''' je snadný na implementaci, ale neposkytuje příliš efektivní ochranu, neboť ve chvíli, kdy je hodnota kanárka vyzrazena, může útočník upravit vstupní data, tak aby nezměnili hodnotu kanárka a přetečení zůstane neodhaleno.
* '''Náhodý kanárek''' je podobný a jeho účinnost je závislá na kvalitě generátoru náhodných čísel.
* '''XOR kanárek''' je hodnota, která je výsledkem operace XOR nad náhodnou hodnotou kanárka a výsledkem funkce nad nadefinovanými proměnnými. Tím přidává další úroveň složitosti do případného útoku, protože je třeba zjistit jak náhodnou hodnotu, tak funkci, tak odpovídající vstupní hodnoty funkce (tedy obsah andefinovaných proměnných).
 
====Fungování Využití automatických nástrojů ====
Mimo využití kanárků tyto nástroje také přeskupují pozice proměnných v paměti tak, aby struktury náchylné na přetečení byly na začátku paměťového prostoru. Tato změna způsobí jednak to, že přepsáním dalších proměnných dojde pravděpodobně k chybě v programu, takže přetečení bude odhaleno. A také proto, že se zvětší šance, že vstupní data nebudou dostatečně dlouhá na přetečení mimo vyhrazený prostor.
Většina automatických nástrojů, které se snaží tomuto způsobu zneužití zabránit, používají tzv. kanárky (pojmenováno podle kanárků, kteří se používali v dolech na odhalení nebezpečných plynů). Jedná se o specifická data, která se umístí do paměti za nadefinované proměnné. Ve chvíli, kdy dojde k přetečení zásobníku, tak je přepsána i hodnota kanárka a přetečení jemůže být odhaleno. Kanárků se používá několik druhů - statický, náhodný nebo také XOR.
====Přehled funkcí a jejich "bezpečnějších" ekvivalentů====
 
Pro většinu C/C++ funkcí existuje ekvivalentní ''"n" funkce''[http://stackoverflow.com/questions/1253053/cs-bad-functions-vs-their-good-alternatives], v případě <code>strcpy</code> i ''"l" funkce''. ''"n" funkce'' kontrolují délku stringu, ''"l" funkce'' ho ořežou a doplní ''\0''.
*;Statický kanárek: '''Statický kanárek''' je snadný na implementaci, ale neposkytuje příliš efektivní ochranu, neboť ve chvíli, kdy je hodnota kanárka vyzrazena, může útočník upravit vstupní data, tak aby nezměnili hodnotu kanárka a přetečení zůstane neodhaleno.
*;Náhodný '''Náhodýkanárek: Náhodný kanárek''' je podobný a jeho účinnost je závislá na kvalitě generátoru náhodných čísel.
*;XOR kanárek: '''XOR kanárek''' jepoužívá hodnotahodnotu, která je výsledkem operace XOR nad náhodnou hodnotou kanárka a výsledkem funkce nad nadefinovanými proměnnými. Tím přidává další úroveň složitosti do případného útoku, protože je třeba zjistit jak náhodnou hodnotu, tak funkci, tak odpovídající vstupní hodnoty funkce (tedy obsah andefinovanýchnadefinovaných proměnných).
 
MimoDalší využitímožností kanárkůje tyto nástroje také přeskupujípřeskupení pozice proměnných v paměti tak, aby struktury náchylné na přetečení byly na začátku paměťového prostoru. Tato změnaZměna způsobí jednak to, že přepsáním dalších proměnných dojde pravděpodobně k chybě v programu, takže přetečení bude odhaleno. AKromě také proto, žetoho se zvětší šance, že vstupní data nebudou dostatečně dlouhá naa k přetečení dojde mimo vyhrazenýúčinný prostor.
 
==== Použití bezpečnějších ekvivalentů funkcí ====
Pro většinu C/C++ funkcí existuje ekvivalentní ''"n" funkce''[.<ref>http://stackoverflow.com/questions/1253053/cs-bad-functions-vs-their-good-alternatives],</ref> vV případě funkce <code>strcpy</code> itéž ''"l" funkce''. ''"n" funkce'' kontrolujínezapíší délkuvíce, stringunež stanovenou délku, ''"l" funkce'' honavíc ořežou a doplnídoplňují ''\0''.
 
strcpy → strncpy → strlcpy
strlen → strnlen
Řádek 85 ⟶ 86:
 
=== Z pohledu uživatele ===
Uživatel se může pouze omezit následky takového útoku tím, že nebude spouštět nedůvěryhodné programy s právy privilegovaného uživatele, případně se mu vyhnout použitím aktualizovaných verzí programů. Stoprocentní obrana však neexistuje. I v současnosti přes široké povědomí o tomto typu útoku se objevují programy, které jsou na tento typ útoku náchylné. Chyby tohoto typu se objevují např. i v OS[[Kernel|jádře operačního systému]]<ref>http://www.debian.org/security/2010/dsa-1998]</ref> a dalších kritických programech. Zde je nespornou výhodou použití [[opensource]] programů, neboť u nich díky podpoře komunity dochází k velmi rychlému vydání opravných balíčků.
 
=== Hardwarová ochrana ===
Dalším ze způsobů ochrany je [[NX bit]] (hardwarová ochrana paměti implementovaná v procesoru) který zabráníumožňuje zabránit spuštění kódu v datové části paměti, což je jeden ze způsobů, jak využítkterý buffer overflow zranitelnostivyužívá.
 
== Reference ==
<references />
 
== Související články ==
Dalším ze způsobů ochrany je [[NX bit]] (hardwarová ochrana paměti implementovaná v procesoru) který zabrání spuštění kódu v datové části paměti, což je jeden ze způsobů jak využít buffer overflow zranitelnosti.
== Související ==
* [[Zásobník (datová struktura)]]
* [[Počítačová bezpečnost]]