Buffer overflow
A HupWiki-ből...
A buffer overflow (vagy puffer túlcsordulás) akkor következik be, ha egy program saját pointer változója által mutatott bufferében annak méreténél nagyobb mennyiségű adatot próbálnak elhelyezni benne. Ez a legtöbbször biztonsági problémák kapcsán kerül előtérbe.Ez az esemény egyértelműen programozói hibát jelöl.
Tartalomjegyzék |
Hogyan következhet be?
Az ilyen hiba az esetek 99%-ában olyan programnyelveket súlyt, amelyek a memóriamenedzsmentet teljes egészében a programozóra bízzák, tehát neki kell gondoskodni a memóriagazálkodásról. (Például C/C++, assembly, stb...) A hiba oka legtöbbször programozói hanyagság vagy nem kellő szakértelem, figyelmetlenség vagy éppen az emberi határokat meghaladó komplexitású kód. Ha a program ellenőrizetlen bemenetet fogad a külvilágból és azt olyan módon tárolja a memóriában, amelyet a programnyelv maga nem ellenőriz, akkor a program máris buffer overflow-veszélyes.
Példa heap buffer overflow sebezhetőségű kódra
#include <stdio.h> int main() { char* keresztnev; /* Ez egy karaktersorozat C-ben*/ malloc(keresztnev, sizeof(char) *20); /* 20 karakter hosszú helyet foglalunk a memóriában */ printf("Kerlek ird be a neved: "); scanf("%s", keresztnev); /* Beolvassuk a nevet a keresztnev stringbe */ printf("Ez a neved: %s", keresztnev); free(keresztnev); return 0; }
Ez azért veszélyes, mert bár 20 karakternyi helyet foglaltunk a keresztnévnek, de ha én azt írom be a programnak, hogy abcdefghijklmnopqrst, akkor sajnos be fogja olvasni és be fogja tenni a 20 karakternyi memóriába, de nem fogja levágni 20 karakternél. Túlírja az eredetileg 20 hosszúnak szánt stringünket és vakon beleír a bufferünkbe. A probléma ott kezdődik, hogy a bufferben a változóknak egymás után van hely foglalva. Tehát ha túlírom a stringet, akkor bizony a programom más változóiba is képes vagyok adatot csempészni. Ezt a hibát ha egy cracker felfedezi, akkor szerkeszthet egy olyan ügyes kis bemeneti adatot, hogy az a rész, ami már túllógna, olyan értéket kapjon, hogy az egy utána lévő változóban érvényes és neki tetsző adatot tartalmazzon. Tehát átveheti a hatalmat a program felett. Gondoljunk csak bele, hogy hol lehet ez problémás:
#include <stdio.h> #incldue <strings.h> int main() { char* jelszo; /* Ez egy karaktersorozat C-ben*/ char jo_jelszo[] = "pistike123456789qwer"; malloc(jelszo, sizeof(char) *20); /* 20 karakter hosszú helyet foglalunk a memóriában */ printf("Kerlek ird be a jelszavad: "); scanf("%s", jelszo); /* Beolvassuk a nevet a keresztnev stringbe */ if(strcmp(jelszo, jo_jelszo) == 0) { printf("Belepes engedelyezve!"); } else { printf("Belepes MEGTAGADVA!"); free(jelszo); return -1; } free(jelszo); return 0; }
Ha most egy ilyen programnál én azt adom be a programnak, hogy jelszo123456789qwert*jelszo123456789qwert* akkor máris beenged a program, pedig nem is ez a jelszó, nem is tudtam az igazi jelszót. (A csillag karakter helyére igazából ASCII 0 kódú karaktert kell írni mindkét helyre). Mi történik? Tudom, hogy max 20 karater lehetne a jelszó a program vágyai szerint. Beírom az én kis 20 karakteres jelszavam:jelszo123456789qwert ezt követi egy \0 karakter, ami a C-ben a string-eket kötelezően lezárja. és ezek után túlírom a memóriában is (nemcsak a kódban!!!!) a jelszo stringet követő jo_jelszo stringet az én jelszavamra:jelszo123456789qwert majd lezárom egy \0-lal. És amikor a strcmp() összehasonlítja a bevitt értéket a jó jelszóval, akkor már az általam jónak akart stringet találja ott és beenged.
Példa stack buffer overflow sebezhetőségű kódra
Hogyan lehet védekezni?
- ProPolice, PaX, exec-shield, W^X, stb.
- figyelmes kódolás
- A program ellenőrzése Valgrinddel, Splinttel, és más hibakereső eszközökkel
- automatikus memóriamenedzsmentet használó programnyelv
FIXME: hogyan lehet még buffer overflow? Hogyan lehet ellene védekezni? Ennek kifejtése.