Securitate acces la memorie

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 28 iunie 2021; verificările necesită 6 modificări .

Securitatea accesului la memorie  este un concept în dezvoltarea de software care urmărește evitarea erorilor care duc la vulnerabilități legate de accesarea memoriei RAM a unui computer , cum ar fi depășirile de buffer și pointerii suspendați .

Limbajele de programare cu un nivel scăzut de abstractizare, cum ar fi C și C++ , care acceptă acces direct la memoria computerului (aritmetică arbitrară pointerului , alocare și dealocare a memoriei ) și tip casting , dar nu au verificare automată a limitelor matricei sigure . în ceea ce privește accesul la memorie [1] [2] . C și C++, totuși, oferă instrumente (cum ar fi indicatori inteligente ) pentru a îmbunătăți securitatea accesului la memorie. Tehnicile de gestionare a memoriei servesc aceluiași scop [3] . Cu toate acestea, evitarea erorilor de acces la memorie, în special în sistemele complexe, nu este adesea posibilă [4] .

Vulnerabilitati de acces la memorie

Una dintre cele mai comune clase de vulnerabilități software sunt problemele de securitate a memoriei [5] [6] . Acest tip de vulnerabilitate este cunoscut de peste 30 de ani [7] . Securitatea memoriei înseamnă prevenirea încercărilor de utilizare sau modificare a datelor cu excepția cazului în care aceasta a fost permisă în mod intenționat de către programator la crearea produsului software [8] .

Multe programe critice pentru performanță sunt implementate în limbaje de programare cu un nivel scăzut de abstractizare ( C și C++ ), care sunt predispuse la acest tip de vulnerabilitate. Lipsa de securitate a acestor limbaje de programare permite atacatorilor să obțină controlul deplin asupra programului, să schimbe fluxul de control și să aibă acces neautorizat la informații confidențiale [9] . În acest moment, au fost propuse diverse soluții la problemele legate de accesul la memorie. Mecanismele de protecție trebuie să fie eficiente atât din punct de vedere al securității, cât și al performanței [10] .

Erorile de memorie au fost făcute publice pentru prima dată în 1972 [11] . Și apoi au fost problema multor produse software, un instrument care vă permite să utilizați exploit -uri . De exemplu, viermele Morris a folosit multe vulnerabilități, dintre care unele erau legate de erori de memorie [12] .

Tipuri de erori de memorie

Există mai multe tipuri de erori de memorie (vulnerabilități) care pot apărea în unele limbaje de programare: [13] [14] [15]

Detectarea erorilor

Posibilele erori de lucru cu memorie pot fi detectate atât în ​​timpul compilării programului, cât și în timpul execuției ( depanare ).

Pe lângă avertismentele de la compilator, analizoarele de cod statice sunt utilizate pentru a detecta erorile înainte ca programul să fie construit . Acestea vă permit să acoperiți o parte semnificativă a situațiilor periculoase prin examinarea codului sursă mai detaliat decât o analiză superficială a compilatorului. Analizoarele statice pot detecta: [44] [45] [46] [47]

În timpul depanării programului, pot fi utilizați manageri speciali de memorie. În acest caz, zonele de memorie „moarte” sunt create în jurul obiectelor alocate în heap, iar atunci când depanatorul intră în ele, poate detecta erori [48] . O alternativă sunt mașinile virtuale specializate care verifică accesul la memorie ( Valgrind ). Detectarea erorilor este ajutată de sistemele de instrumentare a codului , inclusiv cele furnizate de compilator (Sanitizer [49] ).

Metode de securitate

Majoritatea limbajelor de nivel înalt rezolvă aceste probleme prin eliminarea aritmeticii pointerului din limbaj, limitând capacitatea de a arunca și introducând colectarea gunoiului ca singura schemă de gestionare a memoriei [50] . Spre deosebire de limbajele de nivel scăzut , unde viteza este importantă, limbajele de nivel înalt efectuează în mare parte verificări suplimentare [51] , cum ar fi verificarea limitelor atunci când accesează matrice și obiecte [52] .

Pentru a evita scurgerile de memorie și resurse și pentru a asigura siguranța excepțiilor, C++ modern folosește pointeri inteligente . De obicei, acestea sunt o clasă care imită interfața unui pointer obișnuit și adaugă funcționalitate suplimentară [53] , cum ar fi verificarea limitelor matricelor și obiectelor, gestionând automat alocarea și dealocarea memoriei pentru obiectul utilizat. Ele ajută la implementarea idiomului de programare Resource Acquisition is Initialization (RAII), în care achiziția unui obiect este indisolubil legată de inițializarea acestuia, iar eliberarea este indisolubil legată de distrugerea sa [54] .

Când utilizați funcții de bibliotecă, ar trebui să acordați atenție valorilor returnate ale acestora pentru a detecta posibile încălcări în funcționarea lor [55] . Funcțiile de lucru cu memoria dinamică în C semnalează o eroare (lipsa memoriei libere de dimensiunea cerută) prin returnarea unui pointer nul în locul unui pointer către un bloc de memorie [56] ; C++ folosește excepții [57] . Tratarea corectă a acestor situații vă permite să evitați terminarea incorectă (anormală) a programului [58] .

Verificările limitelor când se folosesc pointeri îmbunătățesc securitatea. Astfel de verificări sunt adăugate în timpul compilării și pot încetini programele; Au fost dezvoltate extensii hardware speciale (de exemplu, Intel MPX [59] ) pentru a le accelera .

La nivelurile inferioare de abstractizare , există sisteme speciale care asigură securitatea memoriei. La nivel de sistem de operare, acesta este un manager de memorie virtuală care separă zonele de memorie disponibile pentru procesele individuale ( suport multitasking ) și facilități de sincronizare pentru a suporta multithreading [60] . Stratul hardware tinde, de asemenea, să includă unele mecanisme precum inele de protecție [61] .

Note

  1. Erik Poll. Note de curs despre securitatea bazată pe limbă . - Universitatea Radboud Nijmegen, 2016. - 21 ianuarie. / „Funcțiile de limbă care distrug siguranța memoriei includ...”
  2. Laszlo Szekeres, Mathias Payer, Dawn Song. SoK: Războiul etern în memorie . — 2013 IEEE Symposium on Security and Privacy, 2013. / „Erorile de corupție a memoriei în software-ul scris în limbaje de nivel scăzut precum C sau C++ sunt una dintre cele mai vechi probleme în securitatea computerelor.”
  3. Fundația ISO Standard C++. Întrebări frecvente C++: Gestionarea memoriei  . isocpp.org . Preluat la 10 februarie 2022. Arhivat din original la 10 septembrie 2018.
  4. Fundația ISO Standard C++. Întrebări frecvente C++: Gestionarea memoriei  . isocpp.org . Preluat la 10 februarie 2022. Arhivat din original la 10 septembrie 2018. / „În mod clar, dacă codul tău are operații noi, operații de ștergere și aritmetică a indicatorului peste tot, vei da greșelii undeva și vei obține scurgeri, indicatori rătăciți etc.” Acest lucru este adevărat, indiferent de cât de conștiincios ești cu alocările tale: în cele din urmă, complexitatea codului va depăși timpul și efortul pe care ți-l poți permite.”
  5. Victor van der Veen, Nitish dutt-Sharma, Lorenzo Cavallaro, Herbert Bos. Erori de memorie: trecutul, prezentul și viitorul . — RAID'12; Amsterdam, Olanda, 2012. - 12-14 septembrie. / „… și încă se clasează printre primele 3 erori de software cele mai periculoase.”
  6. Cântecul zorilor. Siguranța memoriei - Atacuri și apărări . - Berkeley CS161 Computer Security, 2015. - Primăvara. / „De fapt, după erorile de configurare, erorile de implementare sunt probabil cea mai mare clasă de erori de securitate exploatate în practică.”
  7. Laszlo Szekeres, Mathias Payer, Dawn Song. SoK: Războiul etern în memorie . — 2013 IEEE Symposium on Security and Privacy, 2013. / „Această problemă există de mai bine de 30 de ani...”
  8. Cântecul zorilor. Siguranța memoriei - Atacuri și apărări . - Berkeley CS161 Computer Security, 2015. - Primăvara. / "... împiedicând atacatorii să citească sau să scrie în alte locații de memorie decât cele intenționate de programator."
  9. Laszlo Szekeres, Mathias Payer, Dawn Song. SoK: Războiul etern în memorie . — 2013 IEEE Symposium on Security and Privacy, 2013. / Aplicațiile scrise în limbaje de nivel scăzut precum C sau C++ sunt predispuse la aceste tipuri de erori. Lipsa siguranței memoriei... permite atacatorilor să exploateze erorile de memorie modificând cu răutate comportamentul programului sau chiar luând controlul deplin asupra fluxului de control.”
  10. Laszlo Szekeres, Mathias Payer, Dawn Song. SoK: Războiul etern în memorie . — 2013 IEEE Symposium on Security and Privacy, 2013 .
  11. Victor van der Veen, Nitish dutt-Sharma, Lorenzo Cavallaro, Herbert Bos. Erori de memorie: trecutul, prezentul și viitorul . — RAID'12; Amsterdam, Olanda, 2012. - 12-14 septembrie. / „Erorile de memorie au fost discutate public pentru prima dată în 1972 de către Panelul de studiu de planificare a tehnologiei securității computerelor”.
  12. Victor van der Veen, Nitish dutt-Sharma, Lorenzo Cavallaro, Herbert Bos. Erori de memorie: trecutul, prezentul și viitorul . — RAID'12; Amsterdam, Olanda, 2012. - 12-14 septembrie. / „Viermele Internet a exploatat o serie de vulnerabilități, inclusiv cele legate de erori de memorie.”
  13. Laszlo Szekeres, Mathias Payer, Dawn Song. SoK: Războiul etern în memorie . — 2013 Simpozionul IEEE privind securitatea și confidențialitatea, 2013.
  14. Cântecul zorilor. Siguranța memoriei - Atacuri și apărări . - Berkeley CS161 Computer Security, 2015. - Primăvara.
  15. Katrina Tsipenyuk, Brian Chess, Gary McGraw. Șapte regate pernicioase: o taxonomie a erorilor de securitate software . - Atelierul NIST privind instrumentele, tehnicile și valorile de asigurare a securității software, Long Beach, CA, 2005. - noiembrie.
  16. Edsger W. Dijkstra. De ce numerotarea ar trebui să înceapă de la zero (EWD 831) . - Plataanstraat 5, 5671 AL NUENEN, Olanda, 1982. - 11 august. / „... folosirea celorlalte trei convenții a fost o sursă constantă de stângăcie și greșeli...”
  17. Richard Jones și Paul Kelly. Verificarea limitelor pentru C . - Imperial College, 1995. - iulie. / „Un răspuns la această analiză este renunțarea la C, deoarece această lipsă de verificare eficientă este responsabilă pentru multe defecțiuni ale software-ului.”
  18. John Erickson. Hacking. Arta exploatării . - Sankt Petersburg. : Simbol-Plus, 2010. - S.  139 . — ISBN 978-5-93286-158-5 .
  19. John Erickson. Hacking. Arta exploatării . - Sankt Petersburg. : Simbol-Plus, 2010. - S.  142 . — ISBN 978-5-93286-158-5 .
  20. David A. Wheeler. HOWTO pentru programare sigură . — Publicat v3.72. — 2015. / „Depășirile de tampon sunt o defecțiune de securitate extrem de comună și periculoasă…”
  21. Enumerarea punctelor slabe comune. CWE-126: Buffer Over-read (08 decembrie 2015). Consultat la 24 noiembrie 2016. Arhivat din original la 27 septembrie 2016. / „Acest lucru se întâmplă de obicei când indicatorul sau indexul său este incrementat la o poziție dincolo de limitele tamponului...”
  22. Steve Christey. 2011 CWE/SANS Top 25 cele mai periculoase erori de software . MITRE (13 septembrie 2011). Consultat la 24 noiembrie 2016. Arhivat din original la 12 aprilie 2018.
  23. Guy Keren. Gestionarea memoriei Unix și C/C++ pentru programatori (link indisponibil) (2001-2002). Consultat la 24 noiembrie 2016. Arhivat din original la 27 septembrie 2016.   / "Mediul de rulare definește nu numai modul în care memoria este alocată și eliberată..."
  24. Robert C. Seacord. Codare sigură în C și C++ . — Addison-Wesley, 2013. — P.  162 . - ISBN 978-0-321-82213-0 .
  25. Jonathan Afek, Adi Sharabani. Indicator suspendat. Distruge indicatorul pentru distracție și profit . — Watchfire Corporation, 2007.
  26. Ziar de calculator. Un link către nicăieri sau un indicator rupt . Preluat la 24 noiembrie 2016. Arhivat din original la 22 iunie 2018. / "... vulnerabilități care pot fi cauzate de utilizarea greșită a indicatorilor și referințelor."
  27. Enumerarea punctelor slabe comune. CWE-416: Utilizați după gratuit (08 decembrie 2015). Consultat la 24 noiembrie 2016. Arhivat din original la 18 iulie 2019. / „Referirea la memorie după ce aceasta a fost eliberată poate cauza blocarea unui program, utilizarea unor valori neașteptate sau executarea codului.”
  28. Juan Caballero, Gustavo Grieco, Mark Marron, Antonio Nappa. Undangle: detectarea timpurie a indicatoarelor atârnate în vulnerabilități de utilizare după liber și dublu liber . — Institutul de software IMDEA; Madrid, Spania. / „Vulnerabilitățile „Use-after-free” cresc rapid în popularitate, în special pentru exploatarea browserelor web.”
  29. comp.lang.c. Întrebarea 5.1 . Consultat la 24 noiembrie 2016. Arhivat din original la 27 septembrie 2016. / „Definiția limbajului afirmă că pentru fiecare tip de indicator, există o valoare specială...”
  30. Oracol. Platforma Java, specificația API Standard Edition 7 . Consultat la 24 noiembrie 2016. Arhivat din original la 23 aprilie 2018. / „Aruns atunci când o aplicație încearcă să folosească null într-un caz în care este necesar un obiect.”
  31. Enumerarea punctelor slabe comune. CWE-415: Dublu gratuit (08 decembrie 2015). Consultat la 24 noiembrie 2016. Arhivat din original la 27 septembrie 2016. / "Când un program apelează free() de două ori cu același argument..."
  32. Yan Huang. Debordări de grămezi și atacuri dublu libere . Consultat la 24 noiembrie 2016. Arhivat din original la 17 aprilie 2018. / "Dacă free(p) a fost deja apelat înainte, apare un comportament nedefinit."
  33. Andrei Alexandrescu. Design modern C++: programare generică și modele de proiectare aplicate . - Addison Wesley, 2001.  (link indisponibil) / „... este de obicei implementat ca un înveliș subțire în jurul alocatorului C heap...”
  34. Guy Keren. Gestionarea memoriei Unix și C/C++ pentru programatori (link indisponibil) (2001-2002). Consultat la 25 noiembrie 2016. Arhivat din original la 27 septembrie 2016.   / "De exemplu, noul operator al compilatorului GNU C++ invocă de fapt funcția C runtime malloc()."
  35. Managementul memoriei . Consultat la 25 noiembrie 2016. Arhivat din original la 10 septembrie 2018. / "Operatorii C++ noi și ștergeți garantează construcția și distrugerea corespunzătoare... Funcțiile în stil C... nu asigură asta."
  36. OWASP. scurgere de memorie . Consultat la 25 noiembrie 2016. Arhivat din original pe 23 noiembrie 2016.
  37. Probleme legate de pointeri . Data accesului: 25 noiembrie 2016. Arhivat din original pe 26 februarie 2013. / „Nimic nu este mai deranjant decât indicatoarele „sălbatice”!”
  38. Halvar Flake. Atacurile asupra variabilelor locale neinițializate (2006). Consultat la 25 noiembrie 2016. Arhivat din original la 3 iunie 2016. / "Ne uităm la următoarea situație atunci..."
  39. Enumerarea punctelor slabe comune. CWE-457: Utilizarea variabilei neinițializate (08 decembrie 2015). Consultat la 25 noiembrie 2016. Arhivat din original la 2 octombrie 2016. / „Un atacator poate uneori să controleze sau să citească aceste conținuturi.”
  40. Utilizarea și portarea GNU Fortran . James Craig, Burley (1 iunie 1991). Data accesului: 25 noiembrie 2016. Arhivat din original pe 5 octombrie 2012.
  41. Danny Kalev. Înțelegerea depășirii stivei (5 septembrie 2000). Data accesului: 25 noiembrie 2016. Arhivat din original pe 5 octombrie 2012. / „Cele două cauze cele mai frecvente pentru o depășire a stivei...”
  42. John Boyland. Document de poziție: Gestionarea erorilor „Memorie lipsită” . — Universitatea din Wisconsin-Milwaukee, SUA. Arhivat din original pe 22 martie 2016. / „O eroare „memorie lipsită” poate fi catastrofală pentru un program, în special pentru unul scris într-un limbaj precum Java care utilizează frecvent alocarea memoriei.”
  43. Mulyadi Santosa. Când Linux rămâne fără memorie (30.11.2006). Consultat la 15 noiembrie 2016. Arhivat din original la 14 aprilie 2018. / "... nu mai puteți aloca mai multă memorie și nucleul oprește o sarcină (de obicei cea care rulează curent)."
  44. Anders Moller și Michael I. Schwartzbach. Analiza Programului Static . - Departamentul de Informatică, Universitatea Aarhus, 2015. - Mai.
  45. Cppcheck - Un instrument pentru analiza statică a codului C/C++ . Consultat la 25 noiembrie 2016. Arhivat din original la 18 ianuarie 2016. / "Detectați diferite tipuri de erori în codul dvs...."
  46. Proiecte semantice. Analiza siguranței memoriei cu CheckPointer . Consultat la 25 noiembrie 2016. Arhivat din original la 18 aprilie 2018. / „Programele cu pointeri pot comite o varietate de erori în accesarea memoriei...”
  47. PVS-Studio. Analiza codului static (25.03.2015). Consultat la 25 noiembrie 2016. Arhivat din original la 25 ianuarie 2018.
  48. Emery D. Berger, Benjamin G. Zorn. DieHard: Siguranța probabilistică a memoriei pentru limbile nesigure . — PLDI'06; Ottawa, Ontario, Canada, 2006. 11-14 iunie.
  49. Konstantin Serebryani, Dmitri Vyukov. Găsirea curselor și erorilor de memorie cu instrumente de compilare . GNU Tools Cauldron (10 iulie 2012). Consultat la 25 noiembrie 2016. Arhivat din original la 12 martie 2016.
  50. Erik Poll. Securitate bazată pe limbaj: limbaje de programare „sigure” (downlink) . Universitatea Radboud din Nijmegen . Consultat la 25 noiembrie 2016. Arhivat din original pe 5 noiembrie 2016.   / „Gestionarea manuală a memoriei poate fi evitată prin...”
  51. Dinakar Dhurjati și Vikram Adve. Verificarea limitelor matricei compatibile cu versiunea inversă pentru C cu supraîncărcare foarte scăzută . — Departamentul de Informatică Universitatea Illinois din Urbana-Champaign. / „... o problemă nerezolvată, în ciuda unui istoric îndelungat de muncă privind detectarea încălcărilor limitelor matricei sau a depășirilor de buffer, deoarece cele mai bune soluții existente până în prezent sunt fie mult prea scumpe pentru a fi utilizate în codul de producție implementat...”
  52. Bruce Eckel. Gândirea în Java. Ediția a patra . / „Atât matricele, cât și containerele garantează că nu puteți abuza de ele. Indiferent dacă utilizați o matrice sau un container, veți obține o excepție RuntimeException dacă depășiți limitele, indicând o eroare a programatorului."
  53. David Kieras. Folosind indicatori inteligenti C++11 . - Departamentul EECS, Universitatea din Michigan, 2016. - Iunie. / „Indicatoarele inteligente sunt obiecte de clasă care se comportă ca indicatori încorporați, dar gestionează și obiectele pe care le creați...”
  54. Microsoft Developer Network. Indicatori inteligente (C++ modern) . Consultat la 25 noiembrie 2016. Arhivat din original la 5 decembrie 2017. / „Sunt extrem de importante pentru limbajul de programare RAII sau Achiziția resurselor este inițializarea...”
  55. Enumerarea punctelor slabe comune. CWE-252: Valoare de returnare neverificată (08 decembrie 2015). Consultat la 25 noiembrie 2016. Arhivat din original la 18 iulie 2019. / „Software-ul nu verifică valoarea returnată de la o metodă sau o funcție, ceea ce o poate împiedica să detecteze stări și condiții neașteptate.”
  56. Microsoft Developer Network. malloc . Consultat la 25 noiembrie 2016. Arhivat din original la 5 octombrie 2016. / "malloc returnează un pointer netipizat către zona de memorie alocată sau NULL dacă nu este suficientă memorie disponibilă."
  57. operator nou, operator nou[ ] . Consultat la 25 noiembrie 2016. Arhivat din original la 29 martie 2018. / "aruncă std::bad_alloc sau o altă excepție derivată din std::bad_alloc (din C++11) la eșecul alocării memoriei"
  58. Paul și Harvey Deitel. C: cum se programează .
  59. Zona pentru dezvoltatori Intel. Introducere în Intel® Memory Protection Extensions (16 iulie 2013). Consultat la 25 noiembrie 2016. Arhivat din original la 5 mai 2019.
  60. Sarah Diesburg. Protecția memoriei: kernel și spații de adrese utilizator . Consultat la 25 noiembrie 2016. Arhivat din original la 9 august 2017.
  61. Michael D. Schroeder și Jerome H. Saltzer. O arhitectură hardware pentru implementarea inelelor de protecție . - Al treilea simpozion ACM privind principiile sistemelor de operare, Palo Alto, California, 1971. - 18-20 octombrie.

Literatură

Link -uri

Publicatii generale

Publicații tematice