Desbordament del buffer

Visualització d'un desbordament de memòria intermèdia de programari. Les dades s'escriuen a A, però són massa grans per cabre dins d'A, de manera que es desborden a B.

En programació i seguretat de la informació, un desbordament de memòria intermèdia o desbordament de la memòria intermèdia és una anomalia per la qual un programa escriu dades en una memòria intermèdia més enllà de la memòria assignada a la memòria intermèdia, sobreescrivint les ubicacions de memòria adjacents.[1]

Els buffers són àrees de memòria reservades per contenir dades, sovint mentre es mouen d'una secció d'un programa a una altra, o entre programes. Els desbordaments de memòria intermèdia sovint es poden desencadenar per entrades mal formades; si hom suposa que totes les entrades seran més petites que una determinada mida i la memòria intermèdia es crea per tenir aquesta mida, aleshores una transacció anòmala que produeixi més dades podria fer que escrigui més enllà del final de la memòria intermèdia. Si això sobreescriu les dades adjacents o el codi executable, això pot provocar un comportament erràtic del programa, com ara errors d'accés a la memòria, resultats incorrectes i bloquejos.[2]

L'explotació del comportament d'un desbordament de memòria intermèdia és una explotació de seguretat ben coneguda. En molts sistemes, la disposició de memòria d'un programa, o del sistema en conjunt, està ben definit. Mitjançant l'enviament de dades dissenyades per provocar un desbordament de memòria intermèdia, és possible escriure en àrees conegudes que contenen codi executable i substituir-lo per codi maliciós o sobreescriure selectivament les dades relatives a l'estat del programa, provocant, per tant, un comportament que no estava previst pel programador original. Els buffers estan molt estesos en el codi del sistema operatiu (SO), de manera que és possible fer atacs que realitzen una escalada de privilegis i obtenir accés il·limitat als recursos de l'ordinador. El famós cuc Morris el 1988 va utilitzar això com una de les seves tècniques d'atac.[3]

Els llenguatges de programació habitualment associats als desbordaments de memòria intermèdia són C i C++, que no proporcionen cap protecció integrada contra l'accés o la sobreescriptura de dades en cap part de la memòria i no comproven automàticament que les dades escrites en una matriu (el tipus de memòria intermèdia integrada) estiguin dins els límits d'aquesta matriu. La comprovació de límits pot evitar desbordaments de memòria intermèdia, però requereix codi i temps de processament addicionals. Els sistemes operatius moderns utilitzen una varietat de tècniques per combatre els desbordaments de memòria intermèdia maliciosos, sobretot mitjançant l'aleatorització de la disposició de la memòria o deixant deliberadament espai entre les memòries intermèdies i cercant accions que escriguin en aquestes àrees ("canaris").

Descripció tècnica

[modifica]

Es produeix un desbordament de la memòria intermèdia quan les dades escrites en una memòria intermèdia també corrompen els valors de les dades de les adreces de memòria adjacents a la memòria intermèdia de destinació a causa d'una comprovació insuficient de límits. Això pot passar quan es copien dades d'una memòria intermèdia a una altra sense comprovar abans que les dades s'ajustin a la memòria intermèdia de destinació.[4]

Exemple

[modifica]

En l'exemple següent expressat en C, un programa té dues variables adjacents a la memòria: un buffer de cadena de 8 bytes de llargada, A, i un nombre enter big-endian de dos bytes, B.

char A[8] = "";
unsigned short B = 1979;

Inicialment, A no conté més que zero bytes, i B conté el número 1979.

nom de la variable A B
valor [ cadena nul·la ] 1979
valor hexadecimal 00 00 00 00 00 00 00 00 07 BB

Ara, el programa intenta emmagatzemar la cadena "excessive" amb codificació ASCII al buffer A.

strcpy(A, "excessive");

La cadena "excessive" és de 9 caràcters; incloent el bit buit que requereix al final (null terminator) per tal d'indicar el final de la cadena, ocupa un total de 10 bytes. Recordem, però, que A només pot contenir 8 bytes. En no comprovar la longitud de la cadena, també sobreescriu el valor de B:

nom de la variable A B
valor 'e' 'x' 'c' 'e' 's' 's' 'i' 'v' 25856
hexadecimal 65 78 63 65 73 73 69 76 65 00

El valor de B ara s'ha substituït inadvertidament per un nombre format a partir d'una part de la cadena de caràcters. En aquest exemple, "e" seguida d'un byte zero es convertiria en 25856.

De vegades, el sistema operatiu pot detectar l'escriptura de dades més enllà del final de la memòria assignada, i genera un error de segmentació que acaba el procés.

Per evitar que es produeixi el desbordament de la memòria intermèdia en aquest exemple, el call a strcpy es podria substituir per strlcpy, que pren la capacitat màxima de A (incloent el caràcter de terminació nul·la) com a paràmetre addicional i garanteix que no s'excedeix aquesta quantitat de dades:

strlcpy(A, "excessive", sizeof(A));

Quan està disponible, es prefereix la funció de biblioteca strlcpy sobre strncpy, que no acaba amb nul·la la memòria intermèdia de destinació si la longitud de la cadena d'origen és superior o igual a la mida de la memòria intermèdia (el tercer argument passat a la funció).

Referències

[modifica]
  1. «What is buffer overflow?» (en anglès). https://www.cloudflare.com.+[Consulta: 10 setembre 2023].
  2. «What Is Buffer Overflow? Attacks, Types & Vulnerabilities» (en anglès). [Consulta: 10 setembre 2023].
  3. «Buffer Overflow | OWASP Foundation» (en anglès). [Consulta: 10 setembre 2023].
  4. «What is a Buffer Overflow | Attack Types and Prevention Methods | Imperva» (en anglès americà). [Consulta: 10 setembre 2023].