Understanding Buffer Overruns....Comprensión de búfer sobrecostos

Typically, buffer overrun attacks are aimed at programs that implement network functions, such as Web servers and mail servers.

The goal of every hacker is to get the target system to do something you don't want it to do, a primary example is to reveal sensitive files such as /etc/passwd and /etc/shadow (which store the user names and encrypted passwords of your users.) Once these are in his or her hands, it is possible to use a "dictionary" attack on the passwords, alternatively they can have your system FTP over an infected file and run it, which can be as bad or worse.
In order to do this, they need to get a "trusted" program to execute commands they specify. Usually, this is done by a "buffer overrun" attack.

A famous attack was aimed at the Sendmail Simple Mail Transfer Protocol (SMTP) mail server.
These programs listen for incoming network connections and process the requests. Some, like SMTP, use plain-english conversations that look like

Code:
220 secure.hostname.com ESMTP Sendmail 8.11.2/8.11.2; Thu, 4 Sep 2003 13:18:30
HELLO mail.otherhost.com
250 secure.hostname.com Hello skinny [127.0.0.1], pleased to meet you
So essentially the program is reading lines of text, interpretting them, and doing actions based on them.
A convenient feature that these "network daemons" take advantage of is that they can communicate with the client computer using "standard input" and "standard output", which for a normal program would be the keyboard and display of the person running the program.
But in this case it is reading and writing to another program (such as Microsoft Outlook) running on another computer, to understand how a buffer overrun works, you need to look at the very small C program below


Code:
#include
main() {
char *name;
char *dangerous_system_command;
name = (char *) malloc(10);
dangerous_system_command = (char *) malloc(128);
printf("Address of name is %d\n", name);
printf("Address of command is %d\n", dangerous_system_command);
sprintf(dangerous_system_command, "echo %s", "Hello world!");
printf("What's your name?");
gets(name);
system(dangerous_system_command);
}

If you're not a C coder don't worry i'll walk you through it, this program is designed to be run by a user on a console, but it illustrated the trouble that a poorly written network daemon can cause, the first thing the program does is to declare two string variables, and assign memory to them.
The "name" variable is given 10 bytes of memory (which will allow it to hold a 10 character string.
The "dangerous_system_command" variable is given 128 bytes.
The thing you have to understand is that in C, the memory chunks given to these variable will be located directly next to each other in the virtual memory space given to the program.
If you run the program with a short name, you can see how things are supposed to work

Code:
[jturner@secure jturner]$ ./overrun
Address of name is 134518696
Address of command is 134518712
What's your name?Jhoseff
Hello world!
[jturner@secure jturner]$
As you can see, the address given to the "dangerous_system_command" variable is 16 bytes from the start of the "name" variable.
The extra 6 bytes are overhead used by the "malloc" system call to allow the memory to be returned to general usage when it is freed.

After allocating the memory and printing the memory locations of the two variables, the program generates a command which will later be sent to the "system" call, which causes it to be excuted as if it had been typed at a keyboard.
In this case, all it does is print "Hello world!".
Then, we prompt the user for their name and read it using the "gets" system call. In a real network daemon, this might be printing a prompt and awaiting a command from the client program such as a web site address or mail address.

The important thing to know is that "gets", which reads a string from standard input to the specified memory location, DOES NOT have a "length" specification.
This means it will read as many characters as it takes to get to the end of the line, even if it overruns the end of the memory allocated.
Knowing this, a wiley hacker can overrun the "name" memory into the "dangerous_system_command" memory, and run whatever command they wish, for example


Code:
[jturner@secure jturner]$ ./overrun
Address of name is 134518696
Address of command is 134518712
What's your name?0123456789123456cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail

By padding out the response to the name query to 16 character and then adding a system command, the system command overwrites "echo Hello World!" with "cat /etc/passwd".
As you can see, this causes that command to be run instead of the appropriate one.

So what can be done to prevent this? For one, using the fgets system call, which specifies a maximum length, will eliminate the possibility altogether by changing the 'gets' call to

Code:
fgets(name, 10, stdin);

Code:
[jturner@secure jturner]$ ./overrun
Address of name is 134518768
Address of command is 134518784
What's your name?01234567890123456cat /etc/passwd
Hello world!
[jturner@secure jturner]$

But since many sites run software that they don't have source code to (commericial databases, for example), you can't protect yourself from all buffer overruns.
The other important step you need to take is to turn off any network services you don't use, and only run the ones you do use at a permission level that meets the needs of the program.
For example, don't run a database as root, give it its own user and group. That way, if it is exploited, it can't be used to take over the system.

Buffer overruns are one of those things that every first-year programming student should be taught to avoid.
That it still is used with such frequency by hackers is an indication of how far we have to go in the quest for truly reliable and secure software.
.................................................................................

Normalmente, los ataques de desbordamiento de búfer se dirigen a programas que implementan funciones de red, tales como servidores Web y servidores de correo.
El objetivo de todos los hackers es conseguir que el sistema objetivo de hacer algo que no lo quieren hacer, un ejemplo de ello es primordial para revelar archivos tales como / etc / passwd y / etc / shadow (que almacenan los nombres de usuario y cifrado las contraseñas de sus usuarios.)
Una vez que estos están en las manos, es posible utilizar un "diccionario" ataque a las contraseñas, en su defecto que puede tener su sistema de FTP más de un archivo infectado y ejecutar, lo que puede ser tan malo o peor.
Para ello, necesitan obtener una "confianza" del programa para ejecutar comandos que especifique. Normalmente, esto se hace por un "desbordamiento de búfer" ataque.

Un famoso ataque estaba destinado a la Sendmail el Simple Mail Transfer Protocol (SMTP). Estos programas para escuchar las conexiones de red y el proceso de las solicitudes. Algunos, como SMTP, uso sencillo Inglés conversaciones que parecen

Código:
220 secure.hostname.com ESMTP Sendmail 8.11.2/8.11.2; Thu, 4 Sep 2003 13:18:30
HELLO mail.otherhost.com
Hola flaco secure.hostname.com 250 [127.0.0.1], el placer de conocerte
Así que básicamente es el programa de lectura de líneas de texto, interpretting ellos, y haciendo las acciones basadas en ellos.
Una característica conveniente que estos "demonios de red" de aprovechar es que pueden comunicarse con el equipo cliente utilizando "la entrada estándar" y "salida estándar", que para un programa normal sería el teclado y la pantalla de la persona que ejecuta el programa.
Pero en este caso es la lectura y la escritura a otro programa (como Microsoft Outlook) que se ejecutan en otro equipo, para entender cómo funciona un desbordamiento de búfer, tiene que ver el muy pequeño programa C por debajo de


Código:
# include
main () (
char * nombre;
char * dangerous_system_command;
nombre = (char *) malloc (10);
dangerous_system_command = (char *) malloc (128);
printf ( "Dirección de nombre es% d \ n", nombre);
printf ( "Dirección de mando es% d \ n", dangerous_system_command);
sprintf (dangerous_system_command, "echo% s", "Hola Mundo!");
printf ( "¿Cuál es tu nombre?");
gets (nombre);
sistema (dangerous_system_command);
)

Si no eres un codificador C no te preocupes que voy a caminar a través de él, este programa está diseñado para ser ejecutado por un usuario en una consola, pero ilustra los problemas que un mal escrita puede hacer que el demonio de red, la primera cosa que el programa hace es declarar dos variables de cadena, y asignar la memoria para ellos.
La variable "name" es de 10 bytes de memoria (lo que le permitirá mantener una cadena de 10 caracteres.
El "dangerous_system_command" variable se da 128 bytes.
La cosa que tienes que entender es que en C, la memoria a estos pedazos variable se encuentra directamente junto a la otra en el espacio de memoria virtual para el programa.
Si se ejecuta el programa con un nombre corto, puede ver cómo las cosas se supone que el trabajo


Código:
[@ jturner seguro jturner] $. / rebasamiento
Dirección del nombre es 134518696
Dirección de mando es 134518712
¿Cuál es tu nombre? Jhoseff
Hola Mundo!
[@ jturner seguro jturner] $

Como puede ver, la dirección que figura a la "dangerous_system_command" variable es de 16 bytes desde el comienzo de la variable "name".
Los extras son 6 bytes generales utilizados por el "malloc" llamada al sistema para permitir que la memoria para ser devueltos al uso general cuando es liberado.

Después de la asignación de la memoria y la impresión de la memoria de las dos variables, el programa genera un comando que luego se enviará a la "sistema" de llamada, lo que provoca que se excuted como si hubiera sido escrito en un teclado. En este caso, todo lo que hace es imprimir "Hola Mundo!".
Entonces, preguntará al usuario por su nombre y leer a través del "se" llamada al sistema.
En una verdadera red demonio, este podría ser la impresión de una rápida y en espera de un comando del programa cliente, como un sitio web o dirección de correo electrónico.

Lo importante a saber es que "recibe", que dice una cadena desde la entrada estándar a la ubicación especificada de memoria, no tiene una "duración" pliego de condiciones.
Esto significa que diga lo que muchos personajes que se necesita para llegar a la final de la línea, incluso si los sobrecostos de la final de la memoria asignada. Sabiendo esto, un hacker puede Wiley rebasado el "nombre" en la memoria "dangerous_system_command" memoria y ejecutar cualquier comando que desea, por ejemplo

Código:
[@ jturner seguro jturner] $. / rebasamiento
Dirección del nombre es 134518696
Dirección de mando es 134518712
¿Cuál es tu nombre? 0123456789123456cat / etc / passwd
root: x: 0:0: root: / root: / bin / bash
bin: x: 1:1: bin: / bin:
demonio: x: 2:2: demonio: / sbin:
adm: x: 3:4: adm: / var / adm:
lp: x: 4:7: lp: / var / spool / lpd:
sincronización: x: 5:0: sincronización: / sbin: / bin / sincronización
shutdown: x: 6:0: shutdown: / sbin: / sbin / shutdown
detener: x: 7:0: detener: / sbin: / sbin / detener
mail: x: 8:12: mail: / var / spool / mail

Por relleno de la respuesta a la consulta de nombre de 16 caracteres y, a continuación, añadir un sistema de comando, el sistema de comandos sobreescribe "echo Hola Mundo!" con "cat / etc / passwd". Como puede ver, este comando hace que se ejecute en lugar de la apropiada.

Entonces, ¿qué se puede hacer para evitar esto? Por un lado, utilizando la llamada al sistema fgets, que especifica una longitud máxima, se eliminará por completo la posibilidad de cambiar la 'toma' llamada a la

Código:
fgets (nombre, 10, stdin);

Código:
[@ jturner seguro jturner] $. / rebasamiento
Dirección del nombre es 134518768
Dirección de mando es 134518784
¿Cuál es tu nombre? 01234567890123456cat / etc / passwd
Hola Mundo!
[@ jturner seguro jturner] $

Pero dado que muchos sitios para ejecutar los programas que no tienen código fuente (las bases de datos comerciales, por ejemplo), no puede protegerse de todos los excesos de amortiguación.
El otro paso importante que tiene que tomar es desactivar cualquier red de servicios que no utilizan, y sólo son las que hacen uso en un nivel de permiso que satisfaga las necesidades del programa.
Por ejemplo, no van en una base de datos como root, darle su propio usuario y de grupo. De esta forma, si se explota, no se puede utilizar para hacerse cargo del sistema.

Buffer sobrecostos son una de esas cosas que todos los de primer año de programación de estudiantes se les debe enseñar a evitar.
Que aún se utiliza con tanta frecuencia por los piratas informáticos es un indicio de hasta qué punto tenemos que ir en la búsqueda de la verdad de software fiable y seguro.

No hay comentarios:

Protected by Copyscape Original Article Checker