Pulverizarea în grămada în securitatea informațiilor este un atac care utilizează erori în lucrul cu memoria aplicației . Atacând cu pulverizare în grămada, un hacker forțează o aplicație să aloce memorie pentru un număr mare de obiecte care conțin cod rău intenționat . Acest lucru crește rata de succes a unui exploit care mută firul de execuție într-o anumită poziție din heap . Este important să înțelegeți că, fără un exploit care vă permite să schimbați fluxul de execuție, pulverizarea în grămada nu va cauza niciun rău. Atacul se bazează pe predictibilitatea poziției heap-ului în spațiul de adrese al procesului. În plus, alocarea memoriei pe heap este o operație deterministă, care face posibilă aplicarea cu succes a acestei tehnici. Pulverizarea în grămada este eficientă în special în browsere , unde un hacker poate aloca memorie folosind mai multe linii de JavaScript pe o pagină web . Un rol important îl joacă asemănarea alocării memoriei în diferite sisteme de operare , ceea ce face ca acest atac să fie multiplatformă. Ca rezultat, este posibil să se insereze o anumită secvență de octeți (de exemplu, o instrucțiune de mașină) într-o adresă pre-previzată în memoria procesului țintă [1] .
Când un proces este creat în sistemul de operare , este alocat un spațiu de adresă [2] [3] [4] pentru nevoile acestuia , care conține date utilizator, cod executabil și unele informații de sistem care depind de sistemul de operare specific. Datele utilizatorului sunt distribuite între heap și stivă în funcție de modul în care este alocată memoria pentru aceștia [5] . De exemplu, segmentul de stivă stochează variabile cu o clasă de alocare automată, precum și informații care sunt salvate de fiecare dată când o funcție este apelată, cum ar fi adresa de retur. Heap-ul este o zonă de memorie dinamică , adică atunci când memoria este alocată dinamic, spațiul este alocat pe heap. În mod tradițional, grămada și stiva cresc unul spre celălalt [2] [3] [4] .
Pulverizarea în grămada nu este o vulnerabilitate în sine . Cu toate acestea, poate fi folosit pentru a livra cod rău intenționat în zona de memorie executabilă a unui proces . Această tehnică exploatează determinismul operațiunii de alocare a memoriei a sistemului . Aceasta înseamnă că o cantitate mare de memorie este adesea localizată la același offset în spațiul de adrese ale procesului . Cu toate acestea, această tehnică nu este capabilă să creeze o breșă în sistemul de securitate în sine. Prin urmare, utilizarea lui necesită o vulnerabilitate care vă permite să schimbați ordinea de execuție a comenzilor (instrucțiuni de mașină) [6] .
Este dificil de utilizat această tehnică deoarece numărul de factori care afectează execuția procesului (din punctul de vedere al unui hacker) este foarte mare. Cu toate acestea, folosind pulverizarea în grămada, puteți executa un număr mare de instrucțiuni, care compensează parțial această dificultate și vă permite să creșteți probabilitatea unei fisuri reușite [7] .
Pulverizarea în grămada poate fi implementată pentru majoritatea sistemelor de operare și arhitecturii . Principala dificultate este găsirea unei vulnerabilități care vă permite să redirecționați fluxul de execuție . Alocarea dinamică a unei cantități mari de memorie, așa cum am menționat mai devreme, este o operație care vă permite să preziceți poziția heap-ului în memorie (la momentul mapării memoriei virtuale la memoria fizică ) [8] . De fiecare dată când se efectuează aceeași secvență de accesări la memorie, heap-ul va ajunge cel mai probabil în același loc [6] [7] .
Totuși, pentru a crește această probabilitate, este necesar ca dimensiunea unei bucăți de memorie alocată să fie comparabilă cu dimensiunea unui segment sau a unei pagini , în funcție de modul în care este organizată memoria [7] .
Principala problemă a acestui atac este schimbarea fluxului de execuție . Fără capacitatea de a intercepta execuția, acest tip de atac nu are sens. Unele funcții pot stoca adresa de retur pe heap, caz în care un hacker ar putea încerca să le schimbe. În acest caz, la întoarcerea de la o astfel de funcție, se va muta într-o locație de memorie care este convenabilă pentru un hacker și, ca urmare, codul rău intenționat va începe să se execute . Orice funcție care citește o adresă din heap poate fi exploatată ca o vulnerabilitate. Un hacker poate înlocui această adresă cu adresa unei bucăți de memorie pe care a modificat-o. Acest lucru poate duce la redirecționarea firului de execuție către cod rău intenționat. Totuși, acest lucru nu este atât de ușor pe cât pare [1] [8] .
Corectitudinea adresei (dimensiunea acesteia, offset față de începutul paginii) utilizată pentru înlocuire depinde în mare măsură de arhitectură. Prin urmare, în practică, se folosesc blocuri, constând în principal din NOP - uri, adăugând codul necesar la sfârșit. Această tehnică vă permite să nu vă faceți griji cu privire la acuratețea calculului adresei și să direcționați fluxul de execuție către o locație aproximativă din spațiul de adrese [1] .
Pași pentru implementarea pulverizării în grămada:
Acest tip de atac este foarte eficient în browsere . Majoritatea browserelor acceptă execuția de scripturi . Un hacker poate aloca memoria necesară folosind câteva rânduri de JavaScript sau ActionScript pe o pagină web. Un rol important îl joacă asemănarea alocării memoriei în diferite sisteme de operare , ceea ce face ca acest atac să fie multiplatformă. Mai mult, adresele la care trebuie să sari vor fi similare [9] .
Pulverizarea în grămada a fost folosită pentru prima dată în 2001 și s-a răspândit în vara lui 2005. De atunci, un număr mare de vulnerabilități au fost găsite în Internet Explorer [10] [11] . Explorările erau foarte asemănătoare între ele. Fiecare astfel de exploatare a constat în pulverizarea în grămada, a cărei metodă de implementare nu s-a schimbat și transferul contorului programului în locația necesară din memorie . Prin urmare, o nouă exploatare a fost obținută prin schimbarea câtorva linii de HTML și trecerea la o nouă vulnerabilitate [1] .
Cel mai simplu mod de a aloca spațiu în memoria browserului este să declarați o variabilă șir și să o inițializați [1] .
Exemple de alocare de memorie în JavaScript [9] :
var myvar = "CORELAN!" ; var myvar2 = new String ( "CORELAN!" ); var myvar3 = myvar + myvar2 ; var myvar4 = myvar3 . subșir ( 0 , 8 );Acestea sunt exemple foarte simple, deoarece liniile evidențiate sunt mici. O bucată de shellcode este mult mai mare, dar mai mică decât o întreagă pagină de memorie .
În mod ipotetic, este posibil să scriem codul shell necesar de mai multe ori în fiecare bloc pe care îl alocăm, dar apoi atacatorul va trebui să țină evidența la ce adresă specifică merge pointerul, deoarece nu ar trebui să cadă în mijlocul codului executabil . De obicei acţionează diferit - selectează piese care conţin multe NOP -uri, iar la final prescriu comenzile necesare. Apoi, datorită aranjamentului liniar al blocurilor în heap, este mai ușor de observat liniaritatea execuției codului și nu este nevoie să vă faceți griji cu privire la acuratețea lovirii începutului unei bucăți de memorie [9] .
Cu alegerea corectă a dimensiunii, bucățile de memorie alocate ar trebui să fie foarte apropiate de dimensiunea elementului heap. Dacă memoria alocată este mai mică, atunci spațiul rămas va fi liber. Managerul de memorie va lăsa, în cel mai bun caz, gunoiul sistemului în acest „spațiu nealocat” și, în cel mai rău caz, va pune un obiect de dimensiunea potrivită. În orice caz, aceasta va avea ca rezultat o eroare atunci când încercați să executați această locație de memorie [1] [9] .
Astfel, scriptul folosit de atacatori arată astfel [9] :
< html > < script > var shellcode = unescape ( '%u\4141%u\4141' ); // aceasta este eticheta CORELAN var bigblock = unescape ( '%u\9090%u\9090' ); //90 este codul NOP var headersize = 20 ; var slackspace = headersize + shellcode . lungime ; // dimensiunea inițială a fragmentului nostru: cod util + dimensiune antet while ( bigblock . length < slackspace ) bigblock += bigblock ; //umplere cu NOP -uri var fillblock = bigblock . subșir ( 0 , slackspace ); //cod util - umplutură var block = bigblock . subșir ( 0 , bigblock . lungime - slackspace ); //doar NOPs while ( block . length + slackspace < 0x40000 ) block = block + block + fillblock ; //umpleți până la dimensiunea elementului heap - în acest caz este 0x40000 var memorie = new Array (); pentru ( i = 0 ; i < 500 ; i ++ ){ memorie [ i ] = bloc + cod shell } // selectează mai multe astfel de elemente. </ script > </ html >unescape()este o funcție care vă permite să puneți octeții exact în ordinea specificată în argumentul [1] .
VBScript este folosit în Internet Explorer pentru a crea șiruri cu string. Conceptual la fel ca implementarea JavaScript , doar numele funcțiilor se schimbă [6] .
În iulie 2009, au fost găsite exploit -uri care permit utilizarea ActionScript pentru a implementa pulverizarea în grămada în Adobe Flash [1] .
În septembrie 2012, la EuSecWest 2012 a fost prezentată o nouă implementare [12] . Federico Muttis și Anibal Sacco au arătat că pulverizarea în grămadă foarte granulară poate fi implementată folosind tehnologii HTML5 . Ei au folosit interfața bitmap de nivel scăzut oferită de API-ul canvas .
Există metode care folosesc încărcarea imaginii. Imaginea este compusă din NOP și apoi se procedează ca în cazurile precedente [1] [9] .
Ca și în cazul tuturor depășirilor de buffer , există trei apărări principale. [1] Este adesea mai ușor să preveniți o modificare a fluxului de execuție decât utilizarea efectivă a tamponului. Sistemele de operare moderne folosesc toate următoarele metode:
Proiecte legate de acest tip de atac: