Ce este Buffer Overflow? În securitatea calculatoarelor si programare, un buffer overflow, sau buffer overrun, este o anomalie în cazul în care stocheaz? datele unui proces într-un buffer de memorie în afara programatorului retrase din circuitul pentru el. De date suplimentare suprascrie memorie adiacente, care ar putea con?ine alte date, inclusiv variabilele de program ?i programul de control al fluxului de date. Acest lucru poate duce la comportament programul neregulat, inclusiv erori de memorie de acces, rezultate incorecte, de terminare program (un accident), sau o înc?lcare a securit??ii sistemului. Buffer overflow poate fi declan?at de factori de produc?ie care sunt concepute pentru a executa cod, sau modifica modul în care func?ioneaz? programul. Ei sunt astfel, în func?ie de vulnerabilit??ilor software-ului de multe ?i pot fi exploatate cu rea inten?ie. Verificarea Bounds poate preveni deversari buffer. Limbaje de programare frecvent asociate cu buffer overflow includ C ?i C + +, care nu furniza nici built-in protec?ia împotriva accesarea sau suprascrie date în orice parte a memoriei ?i nu în mod automat a verifica faptul c? datele scrise la un array (buffer built-in de tip) se afl? în limitele pe care matrice. Mai multe informatii pe Buffer overflow - Wikipedia, the free encyclopedia Generalit??i Cele mai multe dintre exploiturile sunt pe baza buffer overflow are ca scop for?area de executarea de cod mali?ios, în principal,pentru a oferi un shell root pentru utilizator. Principiul este destul de simplu: instruc?iuni de virusare sunt stocate întrun buffer, care este overflow pentru a permite o utilizare nea?teptat? a procesului, prin modificarea de memorie diverse sec?iuni. Astfel, ne va introduce în acest document modul în care un proces este mapat? în memoria de ma?ini, dup? cum precum ?i a bufferr no?iunea, apoi ne vom concentra pe dou? tipuri de exploituri bazate pe buffer overflow:stack overflow ?i heap overflow. 1.1 Procesul de memorie 1.1.1 organiza?ie global? Când un program este executat, elemente de diferitele sale (instruc?iuni, variabile …) sunt mapate în memorie, în -un mod structurat. Cele mai mari zone con?in procesul de mediul înconjur?tor, precum ?i argumentele sale: siruri de caractere env, arg siruri de caractere, indica?ii env . Urm?toarea parte a memoriei const? în dou? sec?iuni, stiv? ?i zona de lucru, care sunt alocate la timpului de func?ionare. Stack este utilizat pentru a stoca argumente func?iei, variabile locale, sau a unor informa?ii care s? permit? pentru a prelua stack-ul de stat în fa?a unui apel func?ia de … Aceast stack se bazeaz? pe un LIFO (uLast In, First Out), ?i cre?te fa?? de adresele de memorie redus?. Variabile alocate dinamic se g?sesc în zona de lucru, de obicei, un indicator se refer? la o adres? de gr?mad?, în cazul în care acesta este returnat de un apel la func?ia malloc. . BSS ?i. Sec?iuni de date sunt dedicate variabile globale, ?i sunt alocate la timpul de compilare. . Sec?iunea de date con?ine date ini?ializate statice, în timp ce datele neinitializata pot fi g?site în BSS. sec?iune. Memoria ultima sec?iune,. De text, con?ine instruc?iuni (de exemplu, codul de program) ?i pot include read-only de date. Exemple scurte pot fi într-adev?r utile pentru o mai bun? în?elegere, s? vedem în cazul în care fiecare tip de variabil? este depozitat: heap int main(){ char * tata = malloc(3); ... } tata points to an address wich is in the heap. .bss char global; int main (){ ... } int main(){ static int bss_var; ... } global and bss_var will be in .bss .data char global = 'a'; int main(){ ... } int main(){ static char data_var = 'a'; ... } global and data_var will be in .data. 1.1.2 apeluri de func?ii Vom lua în considerare acum cum apeluri de func?ii sunt reprezentate în memorie (în stack de a fi mai exact), ?i încerc?m s? în?elegem mecanismele implicate. Pe un sistem Unix, un apel func?ie poate fi împr??tiat în trei etape: 1. prolog: pointer actual cadru este salvat. Un cadru poate fi privit ca o unitate logic? a stack-ului, ?i con?ine toate elementele legate de o sum? function.Numarul de memorie, care este necesar? pentru func?ia este rezervat. 2. de apel: parametrii func?iei sunt stocate în stiv? ?i indicatorul de instruc?iuni este salvat, în scopul de s? ?tie care se face instruirea trebuie s? fie luate în considerare atunci când se întoarce func?ie. 3. return (sau epilog): The Old Stack de stat este restabilit?. O ilustrare simplu ajut? pentru a vedea cum toate aceste lucr?ri, ?i ne va permite o mai bun? în?elegere a cel mai frecvent utilizate tehnici implicate în buffer overflow exploituri. S? ne ia în considerare acest cod: toto int (int a, b int, int c) ( int i = 4; return (a + i); ) int main (int argc, char ** argv) ( toto (0, 1, 2); return 0; ) Avem acum s? dezasambleze gdb binar utilizarea, în scopul de a ob?ine mai multe detalii despre aceste trei etape. Doua registre sunt enumera?i aici: puncte de EBP la cadrul actual (indicatorul frame), si ESP la partea de sus de stack. În primul rând, func?ia principal?: (gdb) demonta principalele Dump de cod de asamblare pentru func?ia principal?: 0×80483e4 <main>: push %ebp 0×80483e5 <main+1>: mov %esp,%ebp 0×80483e7 <main+3>: sub $0×8,%esp Aceasta este prologul principal? func?ie. Pentru mai multe detalii despre un prolog func?ie, a se vedea în continuare ( toto () caz). 0×80483ea <main+6>: add $0xfffffffc,%esp 0×80483ed <main+9>: push $0×2 0×80483ef <main+11>: push $0×1 0×80483f1 <main+13>: push $0×0 0×80483f3 <main+15>: call 0×80483c0 <toto> Toto () func?ia de apel se face prin aceste patru instruc?iuni: parametrii acestuia sunt ingramadite (în ordine invers?) ?i func?ia este invocat?. 0×80483f8 <main+20>: add $0×10,%esp Aceast? instruire reprezint? toto () func?ie de returnare, în principal, () func?ie: stack indicatorul pentru a adresa expeditorului, a?a c? trebuie s? se cre?te la punct înainte de parametrii func?iei (stack-ul creste spre adrese mici!). Astfel, ne intoarcem la mediu ini?ial, a?a cum a fost înainte de toto () a fost chemat. 0×80483fb <main+23>: xor %eax,%eax 0×80483fd <main+25>: jmp 0×8048400 <main+28> 0×80483ff <main+27>: nop 0×8048400 <main+28>: leave 0×8048401 <main+29>: ret End of assembler dump. Ultimele dou? instruc?iuni sunt principalele functii main() , pas de returnare. Acum haide?i s? arunc?m o privire la functia toto() (gdb) demonta?i toto Dump de cod de asamblare pentru func?ia de toto: 0×80483c0 <toto>: push %ebp 0×80483c1 <toto+1>: mov %esp,%ebp 0×80483c3 <toto+3>: sub $0×18,%esp Acest lucru este un prolog nostru func?ie:% EBP ini?ial de puncte pentru mediu; este pufos (pentru a salva aceast? curente de mediu), precum ?i instruirea face dou? puncte% EBP la partea de sus a stivei, care con?ine acum adresa ini?ial? de mediu. Rezerva a treia instruc?iune suficient? memorie pentru func?ie (locale variabile). 0×80483c6 <toto+6>: movl $0×4,0xfffffffc(%ebp) 0×80483cd <toto+13>: mov 0×8(%ebp),%eax 0×80483d0 <toto+16>: mov 0xfffffffc(%ebp),%ecx 0×80483d3 <toto+19>: lea (%ecx,%eax,1),%edx 0×80483d6 <toto+22>: mov %edx,%eax 0×80483d8 <toto+24>: jmp 0×80483e0 <toto+32> 0×80483da <toto+26>: lea 0×0(%esi),%esi Acestea sunt instruc?iunile de func?ia de … 0×80483e0 <toto+32>: leave 0×80483e1 <toto+33>: ret End of assembler dump. (gdb) Primul pas a reveni (cel ar faza s?u intern) se face cu aceste dou? instruc?iuni. Primul care face EBP%, iar indicii% ESP prelua valoarea pe care au avut înainte de prolog (dar nu înainte de apelul func?iei, ca stiva pointer înc? de puncte la o adresa, care este mai mic? decât în zona de memorie unde gasim parametrul functiei toto () , ?i am v?zut c? acesta preia valoarea sa ini?ial?, în principal, () func?ia). se ocup? de instruire al doilea registru de instruc?iuni, care este vizitat o dat? din nou în func?ia de apel, s? ?tie care se face instruirea trebuie s? fie executat. Acest exemplu scurt arat? ca stack-ul atunci când organizeaza func?ii sunt numite. Mai departe în acest tutorial, ne vom concentra pe rezervarea de memorie. În cazul în care aceast? sec?iune de memorie nu este gestionat cu aten?ie, acesta poate prevedea oportunit??i pentru un atacator s? perturbe acest stack de organizare, precum ?i pentru a executa un cod pe nea?teptate. Aceasta este posibil, deoarece, atunci când o întoarce func?ia, instruc?iunea urm?toarea adres? este copiat de la stack-ul la indicatorul EIP (acesta a fost sc?mos implicit de instruc?iuni de apel). Deoarece aceast? adres? este stocat în stack, în cazul în care este posibil s? se corupa stack-ul pentru a accesa aceast? zon? ?i de a scrie o nou? valoare acolo, este posibil pentru a specifica o nou? adres? de instruire, care corespunde unei zone de memorie care con?ine codul de malefice. Ne vom ocupa acum cubuffers, care sunt utilizate în mod curent pentru astfel de atacuri stack. 1.2 Buffers, ?i modul în care acestea pot fi vulnerabili În limbajul C, siruri de caractere, sau buffers, sunt reprezentate de un pointer la adresa de byte, ?i Noi consider?m am ajuns la sfâr?itul buffer când vom vedea un byte null. Acest lucru înseamn? c? nu exist? este nici o modalitate de a stabili exact cantitatea de memorie rezervate pentru un buffer, totul depinde de num?rul de de caractere. Acum, s? ne-au o privire mai atent? la modul în care buffer-ele sunt organizate în memorie. În primul rând, problema m?rimea face limitarea de memorie alocate uneibuffer, pentru a preveni orice peste overflow, destul de dificila. Acesta este motivul pentru unele probleme, poate fi observat, de exemplu atunci când strcpy este folosit f?r? îngrijire, care permite unui utilizator s? copieze un buffer în altele mai mici! Aici este o ilustrare a acestei organiza?ii de memorie: de exemplu de stocare a buffer-ului, al doilea este de depozitare de dou? ERS consecutive buffer, wxy ?i apoi abcde. Re?ine?i c?, în cazul partea dreapta, avem doi byte neutilizatu, deoarece cuvintele (patru sec?iuni byte) sunt utilizate pentru a stoca date. Astfel, un buffer are nevoie de dou? cuvinte, sau bytes în?l?ime, în memorie. Buffer vulnerabilty este prezentat în acest program: #include <stdio.h> int main(int argc, char **argv){ char jayce[4]=”Oum”; char herc[8]=”Gillian”; strcpy(herc, “BrookFlora”); printf(”%s\n”, jayce); return 0; } Dou? buffere sunt stocate în stack doar a?a cum se arat? pe figura de mai jos. În cazul în care zece caractere sunt copiate într-un buffer, care se presupune a fi doar opt byte lung,primul buffer este modificat. Acest lucru provoac? o copie buffer overflow, ?i aici este organizarea de memorie înainte ?i dup? apelul de strcpy: Aici este ceea ce vom vedea când vom rula programul nostru, cum era de a?teptat: alfred@atlantis:~$ gcc jayce.c alfred@atlantis:~$ ./a.out ra alfred@atlantis:~$ Acesta este genul de vulnerabilitate utilizate în exploiturile buffer overflow. Cam asta ar fi prima parte,intr-o saptamana,maxim doua vine si partea a 2 a.