fbpx
Wikipedia

Desbordamiento de búfer

En seguridad informática y programación, un desbordamiento de búfer (del inglés buffer overflow o buffer overrun) es un error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un área de memoria reservada a tal efecto (buffer): Si dicha cantidad es superior a la capacidad preasignada, los bytes sobrantes se almacenan en zonas de memoria adyacentes, sobrescribiendo su contenido original, que probablemente pertenecían a datos o código almacenados en memoria. Esto constituye un fallo de programación.[1]

En las arquitecturas comunes de computadoras no existe separación entre las zonas de memoria dedicadas a datos y las dedicadas a programa, por lo que los bytes que desbordan el buffer podrían grabarse donde antes había instrucciones, lo que implicaría la posibilidad de alterar el flujo del programa, llevándole a realizar operaciones imprevistas por el programador original. Esto es lo que se conoce como una vulnerabilidad.

Una vulnerabilidad puede ser aprovechada por un usuario malintencionado para influir en el funcionamiento del sistema. En algunos casos el resultado es la capacidad de conseguir cierto nivel de control saltándose las limitaciones de seguridad habituales. Si el programa con el error en cuestión tiene privilegios especiales constituye en un fallo grave de seguridad.

Se denomina shellcode al código ejecutable especialmente preparado que se copia al host objeto del ataque para obtener los privilegios del programa vulnerable.

La capacidad de los procesadores modernos para marcar zonas de memoria como protegidas puede usarse para aminorar el problema. Si se produce un intento de escritura en una zona de memoria protegida se genera una excepción del sistema de acceso a memoria (segfault), seguido de la terminación del programa. Por desgracia para que esta técnica sea efectiva los programadores han de indicar al sistema operativo las zonas que se necesita proteger, programa a programa y rutina a rutina, lo que supone un problema para todo el código heredado.

Descripción técnica

Un desbordamiento de búfer ocurre cuando los datos que se escriben en un búfer corrompen aquellos datos en direcciones de memoria adyacentes a los destinados para el búfer, debido a una falta de validación de los datos de entrada. Esto se da comúnmente al copiar cadenas de caracteres de un búfer a otro.

Ejemplo básico

En este ejemplo, un programa tiene definidos dos elementos de datos continuos en memoria: un buffer de 8 bytes tipo string, A, y otro de dos bytes tipo entero, B. Al comienzo, A contiene bytes nulos y B contiene el número 3 (cada carácter se representa mediante un byte).

0 0 0 0 0 0 0 0 0 3
Buffer A Buffer B

A continuación, el programa intenta almacenar la cadena de caracteres "demasiado" en el buffer A, seguido de bytes nulos para marcar el fin de string. Al no validarse la longitud de la cadena, se sobrescribe el valor de B:

'd' 'e' 'm' 'a' 's' 'i' 'a' 'd' 'o' 0
Buffer A Buffer B

A pesar de que el programador no quería cambiar el contenido del búfer B, el valor de éste ha sido reemplazado por un número equivalente a parte de la cadena de caracteres. Para este ejemplo, en un sistema big-endian que use ASCII, el carácter 'o' seguido del byte nulo equivale al número 28416.

Si B fuese la única variable aparte de A definida en el programa, la escritura de datos que sobrepasen los límites de B generarían un error como segmentation fault, concluyendo así el programa.


Código fuente de ejemplo

En el siguiente ejemplo se presenta un código fuente en C con un error de programación. Una vez compilado, el programa generará un desbordamiento de buffer si se lo invoca desde la línea de comandos con un argumento lo suficientemente grande, pues este argumento se usa para llenar un buffer, sin validar previamente su longitud.[2]

/* overflow.c - demuestra un desbordamiento de buffer */ #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) {  char buffer[10];  if (argc < 2)  {  fprintf(stderr, "MODO DE USO: %s string\n", argv[0]);  return 1;  }  strcpy(buffer, argv[1]);  return 0; } 

Strings de 9 caracteres o menos no provocarán desbordamiento de buffer. Por el contrario, strings de 10 caracteres o más, sí: Esto siempre es incorrecto, aunque no siempre resultará en un error del programa o segmentation fault.

Este programa puede reescribirse en forma más segura usando la función strncpy de la siguiente manera:[2]

/* mejor.c - demuestra un método de resolver el problema */ #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) {  char buffer[10];  if (argc < 2)  {  fprintf(stderr, "MODO DE USO: %s string\n", argv[0]);  return 1;  }  strncpy(buffer, argv[1], sizeof(buffer));  buffer[sizeof(buffer) - 1] = '\0';  return 0; } 

Historia de abusos

Uno de los primeros aprovechamientos de los que hay registro de desbordamiento de búferes fue en 1988. Fue uno de los muchos que usó el gusano Morris para propagarse en Internet. El programa abusado fue un servicio de Unix llamado fingerd.[3]

Más tarde, en 1995, Thomas Lopatic redescubrió en forma independiente el desbordamiento de búfer y publicó sus descubrimientos en la lista de correo sobre seguridad Bugtraq.[4]​ Un año después, en 1996, Elias Levy (conocido también como Aleph One) publicó en la revista Phrack su artículo "Smashing the Stack for Fun and Profit",[5]​ una introducción paso a paso para aprovecharse de vulnerabilidades de desbordamientos de búfer basados en la pila.

Desde entonces, por lo menos dos de los gusanos más importantes de Internet se han aprovechado de los desbordamientos de búfer para comprometer un gran número de sistemas. En 2001, el gusano Code Red se aprovechó de un desbordamiento de búfer en el Internet Information Services (IIS) 5.0 de Microsoft[6]​ y en 2003 el gusano SQL Slammer comprometió máquinas corriendo Microsoft SQL Server 2000.[7]

Stack smashing

El pisado de pila o stack smashing es un tipo de desbordamiento de buffer que es aprovechado por algunos virus y otros programas maliciosos para tomar control sobre una aplicación, o provocar su terminación. Esto sucede cuando, por algún error imprevisto, se ingresa a la pila de la aplicación más datos que los que ésta puede contener, lo que provoca que esta se "desborde" y algunos datos se sobreescriban. Para evitar que suceda esto, los compiladores se mejoran cada día dejándole tiempo al programador para pensar en lo que realmente importa.

La siguiente sería una explicación de qué es, cómo se hace y cómo se previene el desbordamiento de pila, con el valor agregado de posibilitar una nueva herramienta que ayudará a explicar errores comunes de programación. El siguiente ejemplo está inspirado en la funcionalidad incluida en el nuevo compilador por defecto de la distribución Debian (en su versión inestable):

Este es un ejemplo común de un programa C vulnerable:

#include <stdio.h> #include <string.h> int main( int argc, char *argv[] ) {  // Buffer estático en la pila.  char buffer[1024];  if ( argc != 2 )  {  printf("Uso: %s argumento\n", argv[0] );  return( -1 );  }  // Copiado de cadenas sin control.  strcpy( buffer, argv[1]);  printf( "Argumento copiado\n" );  return(0); } 

Este programa simple acepta un argumento y lo copia a un buffer estático. Este es un error de programación clásico, si este programa fuese compilado a un ejecutable setuid/setgid (ejecutable por cualquiera como si fuese el dueño) permitiría a un atacante ganar permisos fácilmente.

Como se van a demostrar las nuevas funciones del nuevo compilador, hay que asegurarse de compilar el ejemplo anterior con gcc-3.3 de la siguiente forma:

user@pc:/tmp$ gcc-3.3 -o buggy buggy.c

Antes de determinar si se puede romper, se deben ejecutar dos pruebas:

user@pc:/tmp$ /tmp/buggy Uso: /tmp/buggy argumento user@pc:/tmp$ /tmp/buggy test Argumento copiado 

Ambas funcionan como se espera. Ahora, se ejecuta la prueba pasando un argumento más largo para determinar si se desborda el buffer estático:

user@pc:/tmp$ ./buggy `perl -e 'print "X"x2048'` Argumento copiado Violación de segmento

Como se observa, la prueba fue exitosa: el buffer se desbordó con un argumento de más de 2000 caracteres, resultando en una violación de segmento. Ahora, un archivo de núcleo puede permitir depurarlo para identificar las direcciones de memoria utilizadas por el proceso:

user@pc:/tmp$ ulimit -c 09999999 user@pc:/tmp$ ./buggy `perl -e 'print "X"x3333'` Argumento copiado Violación de segmento (con archivo de núcleo) 

Al correr el depurador gdb se puede ver el programa:

user@pc:/tmp$ gdb ./buggy core GNU gdb 6.4.90-debian ... El programa finalizó con señal 11, Violación de segmento #0 0x58585858 in ?? () (gdb) info registers eip eip 0x58585858 0x58585858 

Se puede observar que EIP muestra la dirección de memoria de la siguiente instrucción que será ejecutada (0×58585858). Esto significa que efectivamente se tomó el control del ejecutable con el script malicioso.

El explotar el ejecutable para correr una línea de comandos habiendo hecho esto es trivial y, por lo general, puede ser automatizado:

user@pc:~/cmd-overflow$ make gcc-3.3 -o cmd-overflow -Wall -ggdb cmd-overflow.c gcc-3.3 -o cmd-vuln -Wall -ggdb cmd-vuln.c user@pc:~/cmd-overflow$ ./cmd-overflow --target=/tmp/buggy --args='%' --size=2048 Argumento copiado shell-3.1$ id uid=1000(user) gid=1000(user) groups=29(audio), 44(video), 46(plugdev), 100(users), 1000(user) shell-3.1$ exit exit 

Se utiliza aquí un programa simple para crear un argumento de 2048 bytes de longitud que contiene el código requerido para correr una línea de comandos, y luego se ejecuta el programa defectuoso con este argumento construido a medida.

Se produjo el desbordamiento del buffer al correr este código, lo cual resultó en la ejecución de una línea de comandos. Si el programa se hubiese sido ejecutado en Linux con el flag setuid por un super-usuario se hubieran ganado los privilegios del super-usuario.

Referencias

  1. «Buffer Overflow | OWASP». owasp.org (en inglés). Consultado el 13 de septiembre de 2021. 
  2. Safer C: Developing Software for High-integrity and Safety-critical Systems (ISBN 0-07-707640-0)
  3. "Tour del gusano" por Donn Seeley, Universidad de Utah
  4. Bugtraq security mailing list [2] el 1 de septiembre de 2007 en Wayback Machine.
  5. "Smashing the Stack for Fun and Profit" by Aleph One
  6. eEye Digital Security [4]
  7. Microsft Technet Security Bulletin MS02-039 [5]

Véase también

  •   Datos: Q19423

desbordamiento, búfer, seguridad, informática, programación, desbordamiento, búfer, inglés, buffer, overflow, buffer, overrun, error, software, produce, cuando, programa, controla, adecuadamente, cantidad, datos, copian, sobre, área, memoria, reservada, efecto. En seguridad informatica y programacion un desbordamiento de bufer del ingles buffer overflow o buffer overrun es un error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un area de memoria reservada a tal efecto buffer Si dicha cantidad es superior a la capacidad preasignada los bytes sobrantes se almacenan en zonas de memoria adyacentes sobrescribiendo su contenido original que probablemente pertenecian a datos o codigo almacenados en memoria Esto constituye un fallo de programacion 1 En las arquitecturas comunes de computadoras no existe separacion entre las zonas de memoria dedicadas a datos y las dedicadas a programa por lo que los bytes que desbordan el buffer podrian grabarse donde antes habia instrucciones lo que implicaria la posibilidad de alterar el flujo del programa llevandole a realizar operaciones imprevistas por el programador original Esto es lo que se conoce como una vulnerabilidad Una vulnerabilidad puede ser aprovechada por un usuario malintencionado para influir en el funcionamiento del sistema En algunos casos el resultado es la capacidad de conseguir cierto nivel de control saltandose las limitaciones de seguridad habituales Si el programa con el error en cuestion tiene privilegios especiales constituye en un fallo grave de seguridad Se denomina shellcode al codigo ejecutable especialmente preparado que se copia al host objeto del ataque para obtener los privilegios del programa vulnerable La capacidad de los procesadores modernos para marcar zonas de memoria como protegidas puede usarse para aminorar el problema Si se produce un intento de escritura en una zona de memoria protegida se genera una excepcion del sistema de acceso a memoria segfault seguido de la terminacion del programa Por desgracia para que esta tecnica sea efectiva los programadores han de indicar al sistema operativo las zonas que se necesita proteger programa a programa y rutina a rutina lo que supone un problema para todo el codigo heredado Indice 1 Descripcion tecnica 1 1 Ejemplo basico 1 2 Codigo fuente de ejemplo 2 Historia de abusos 3 Stack smashing 4 Referencias 5 Vease tambienDescripcion tecnica EditarUn desbordamiento de bufer ocurre cuando los datos que se escriben en un bufer corrompen aquellos datos en direcciones de memoria adyacentes a los destinados para el bufer debido a una falta de validacion de los datos de entrada Esto se da comunmente al copiar cadenas de caracteres de un bufer a otro Ejemplo basico Editar En este ejemplo un programa tiene definidos dos elementos de datos continuos en memoria un buffer de 8 bytes tipo string A y otro de dos bytes tipo entero B Al comienzo A contiene bytes nulos y B contiene el numero 3 cada caracter se representa mediante un byte 0 0 0 0 0 0 0 0 0 3Buffer A Buffer BA continuacion el programa intenta almacenar la cadena de caracteres demasiado en el buffer A seguido de bytes nulos para marcar el fin de string Al no validarse la longitud de la cadena se sobrescribe el valor de B d e m a s i a d o 0Buffer A Buffer BA pesar de que el programador no queria cambiar el contenido del bufer B el valor de este ha sido reemplazado por un numero equivalente a parte de la cadena de caracteres Para este ejemplo en un sistema big endian que use ASCII el caracter o seguido del byte nulo equivale al numero 28416 Si B fuese la unica variable aparte de A definida en el programa la escritura de datos que sobrepasen los limites de B generarian un error como segmentation fault concluyendo asi el programa Codigo fuente de ejemplo Editar En el siguiente ejemplo se presenta un codigo fuente en C con un error de programacion Una vez compilado el programa generara un desbordamiento de buffer si se lo invoca desde la linea de comandos con un argumento lo suficientemente grande pues este argumento se usa para llenar un buffer sin validar previamente su longitud 2 overflow c demuestra un desbordamiento de buffer include lt stdio h gt include lt string h gt int main int argc char argv char buffer 10 if argc lt 2 fprintf stderr MODO DE USO s string n argv 0 return 1 strcpy buffer argv 1 return 0 Strings de 9 caracteres o menos no provocaran desbordamiento de buffer Por el contrario strings de 10 caracteres o mas si Esto siempre es incorrecto aunque no siempre resultara en un error del programa o segmentation fault Este programa puede reescribirse en forma mas segura usando la funcion strncpy de la siguiente manera 2 mejor c demuestra un metodo de resolver el problema include lt stdio h gt include lt string h gt int main int argc char argv char buffer 10 if argc lt 2 fprintf stderr MODO DE USO s string n argv 0 return 1 strncpy buffer argv 1 sizeof buffer buffer sizeof buffer 1 0 return 0 Historia de abusos EditarUno de los primeros aprovechamientos de los que hay registro de desbordamiento de buferes fue en 1988 Fue uno de los muchos que uso el gusano Morris para propagarse en Internet El programa abusado fue un servicio de Unix llamado fingerd 3 Mas tarde en 1995 Thomas Lopatic redescubrio en forma independiente el desbordamiento de bufer y publico sus descubrimientos en la lista de correo sobre seguridad Bugtraq 4 Un ano despues en 1996 Elias Levy conocido tambien como Aleph One publico en la revista Phrack su articulo Smashing the Stack for Fun and Profit 5 una introduccion paso a paso para aprovecharse de vulnerabilidades de desbordamientos de bufer basados en la pila Desde entonces por lo menos dos de los gusanos mas importantes de Internet se han aprovechado de los desbordamientos de bufer para comprometer un gran numero de sistemas En 2001 el gusano Code Red se aprovecho de un desbordamiento de bufer en el Internet Information Services IIS 5 0 de Microsoft 6 y en 2003 el gusano SQL Slammer comprometio maquinas corriendo Microsoft SQL Server 2000 7 Stack smashing EditarEl pisado de pila o stack smashing es un tipo de desbordamiento de buffer que es aprovechado por algunos virus y otros programas maliciosos para tomar control sobre una aplicacion o provocar su terminacion Esto sucede cuando por algun error imprevisto se ingresa a la pila de la aplicacion mas datos que los que esta puede contener lo que provoca que esta se desborde y algunos datos se sobreescriban Para evitar que suceda esto los compiladores se mejoran cada dia dejandole tiempo al programador para pensar en lo que realmente importa La siguiente seria una explicacion de que es como se hace y como se previene el desbordamiento de pila con el valor agregado de posibilitar una nueva herramienta que ayudara a explicar errores comunes de programacion El siguiente ejemplo esta inspirado en la funcionalidad incluida en el nuevo compilador por defecto de la distribucion Debian en su version inestable Este es un ejemplo comun de un programa C vulnerable include lt stdio h gt include lt string h gt int main int argc char argv Buffer estatico en la pila char buffer 1024 if argc 2 printf Uso s argumento n argv 0 return 1 Copiado de cadenas sin control strcpy buffer argv 1 printf Argumento copiado n return 0 Este programa simple acepta un argumento y lo copia a un buffer estatico Este es un error de programacion clasico si este programa fuese compilado a un ejecutable setuid setgid ejecutable por cualquiera como si fuese el dueno permitiria a un atacante ganar permisos facilmente Como se van a demostrar las nuevas funciones del nuevo compilador hay que asegurarse de compilar el ejemplo anterior con gcc 3 3 de la siguiente forma user pc tmp gcc 3 3 o buggy buggy c Antes de determinar si se puede romper se deben ejecutar dos pruebas user pc tmp tmp buggy Uso tmp buggy argumento user pc tmp tmp buggy test Argumento copiado Ambas funcionan como se espera Ahora se ejecuta la prueba pasando un argumento mas largo para determinar si se desborda el buffer estatico user pc tmp buggy perl e print X x2048 Argumento copiado Violacion de segmento Como se observa la prueba fue exitosa el buffer se desbordo con un argumento de mas de 2000 caracteres resultando en una violacion de segmento Ahora un archivo de nucleo puede permitir depurarlo para identificar las direcciones de memoria utilizadas por el proceso user pc tmp ulimit c 09999999 user pc tmp buggy perl e print X x3333 Argumento copiado Violacion de segmento con archivo de nucleo Al correr el depurador gdb se puede ver el programa user pc tmp gdb buggy core GNU gdb 6 4 90 debian El programa finalizo con senal 11 Violacion de segmento 0 0x58585858 in gdb info registers eip eip 0x58585858 0x58585858 Se puede observar que EIP muestra la direccion de memoria de la siguiente instruccion que sera ejecutada 0 58585858 Esto significa que efectivamente se tomo el control del ejecutable con el script malicioso El explotar el ejecutable para correr una linea de comandos habiendo hecho esto es trivial y por lo general puede ser automatizado user pc cmd overflow make gcc 3 3 o cmd overflow Wall ggdb cmd overflow c gcc 3 3 o cmd vuln Wall ggdb cmd vuln c user pc cmd overflow cmd overflow target tmp buggy args size 2048 Argumento copiado shell 3 1 id uid 1000 user gid 1000 user groups 29 audio 44 video 46 plugdev 100 users 1000 user shell 3 1 exit exit Se utiliza aqui un programa simple para crear un argumento de 2048 bytes de longitud que contiene el codigo requerido para correr una linea de comandos y luego se ejecuta el programa defectuoso con este argumento construido a medida Se produjo el desbordamiento del buffer al correr este codigo lo cual resulto en la ejecucion de una linea de comandos Si el programa se hubiese sido ejecutado en Linux con el flag setuid por un super usuario se hubieran ganado los privilegios del super usuario Referencias Editar Buffer Overflow OWASP owasp org en ingles Consultado el 13 de septiembre de 2021 a b Safer C Developing Software for High integrity and Safety critical Systems ISBN 0 07 707640 0 Tour del gusano por Donn Seeley Universidad de Utah 1 Bugtraq security mailing list 2 Archivado el 1 de septiembre de 2007 en Wayback Machine Smashing the Stack for Fun and Profit by Aleph One 3 eEye Digital Security 4 Microsft Technet Security Bulletin MS02 039 5 Vease tambien EditarSeguridad informatica Inseguridad informatica Desbordamiento de pila HoF Ping de la muerte Exploit Bug Subdesbordamiento de bufer Datos Q19423 Obtenido de https es wikipedia org w index php title Desbordamiento de bufer amp oldid 138325613, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos