Buffer Overflow (koncept)

Co je buffer overflow?

Buffer overflow (přetečení bufferu) je zranitelnost, ke které dochází, když program zapisuje více dat do paměťového bufferu, než kolik je pro něj alokováno.

Vizualizace

Představ si buffer o velikosti 8 bytů:

[ A A A A A A A A ]

Program ale zapíše 12 bytů:

[ A A A A A A A A | B B B B ]

Tyto extra hodnoty (B) přepíšou další data v paměti.

Proč je to problém?

Paměť programu není izolovaná po „logických blocích“, ale je lineární. To znamená, že:

  • vedle bufferu mohou být důležité hodnoty
  • může dojít k přepsání proměnných
  • v některých případech i návratové adresy funkce

To umožňuje útočníkovi ovlivnit chování programu.

Typické příklady v C

V praxi buffer overflow často vzniká při práci s funkcemi, které nekontrolují délku vstupu, nebo jsou použity nesprávně.

gets

char buffer[8];
gets(buffer);

Funkce gets vůbec nekontroluje délku vstupu, a proto je z principu nebezpečná.

fgets se špatnou velikostí

char buffer[8];
fgets(buffer, 64, stdin);

fgets je sama o sobě bezpečnější, ale pouze tehdy, pokud je předaná správná velikost bufferu. Zde program tvrdí, že může číst až 64 bytů do bufferu o velikosti 8 bytů.

strcpy

char buffer[8];
strcpy(buffer, "AAAAAAAAAAAAAAAA");

strcpy kopíruje data až do konce řetězce a neověřuje, zda se vejdou do cílového bufferu.

strcat

char buffer[8] = "ABC";
strcat(buffer, "DEFGHIJK");

strcat připojuje další data na konec existujícího řetězce. Pokud není v bufferu dostatek místa, dojde k přetečení.

sprintf

char buffer[8];
sprintf(buffer, "%s", "AAAAAAAAAAAA");

sprintf zapisuje formátovaný výstup bez omezení délky. Pokud výstup přesáhne velikost bufferu, dojde k přepisu paměti.

read

char buffer[8];
read(0, buffer, 32);

Nízkourovňové funkce jako read dávají programátorovi plnou kontrolu nad počtem čtených bytů. Pokud tento počet neodpovídá velikosti bufferu, vzniká overflow.

scanf bez omezení délky

char buffer[8];
scanf("%s", buffer);

Formát %s čte vstup až do whitespace, ale bez omezení délky. Bez specifikace maximální šířky je tak použití potenciálně nebezpečné.

memcpy

char buffer[8];
char src[32] = {0};
memcpy(buffer, src, 32);

memcpy kopíruje přesně zadaný počet bytů. Pokud programátor předá větší délku, než jakou má cílový buffer, dojde k přetečení.

Tyto funkce nejsou vždy samy o sobě „špatné“, ale při nesprávném použití velmi snadno vedou ke vzniku zranitelnosti.

Co lze přepsat?

V závislosti na kontextu může overflow ovlivnit například:

  • sousední proměnné
  • ukazatele
  • struktury
  • řídicí data (např. návratová adresa)

Stack vs Heap

Buffer overflow se může objevit na různých místech:

  • stack overflow – přetečení lokální proměnné ve funkci
  • heap overflow – přetečení dynamicky alokované paměti

Důležité poznámky

  • Ne každý overflow je exploitatelný
  • Moderní systémy mají ochrany (ASLR, NX, stack canary)
  • Přesto jde o jednu z nejdůležitějších tříd zranitelností

Shrnutí

Buffer overflow je situace, kdy program zapíše více dat, než kolik buffer pojme, a tím přepíše sousední paměť. To může vést k chybám programu nebo k jeho plnému ovládnutí.