Seguridad
Felipe Andres Manzano felipe.andres.manzano@gmail.com
FaMAF - Universidad Nacional de Córdoba - Argentina
Se puede ganar??
i n t main ( ) { i n t c o o k i e ; char b u f [ 8 0 ] ; g e t s ( b u f ) ; i f ( c o o k i e == 0x41424344 ) p r i n t f ( " Gansaste ! \ n " ) ; }Atacante/Ataque/Vulnerabilidad
I Los programas tienen bug/errores
I Vulnerabilidad es un tipo de error que permite un ataque
I Ataque es simplemente una tecnica que utiliza el atacante
I Atacante es es quien intenta ver, modificar o corromper informacion que no deberia (con un fin malicioso)
Ataques de Ingenieria Social
I Caballitos de troya (Ejecutame este programita por favor)
I Login falso
Rootkits (persistencia/ataques del programador)
I Hooking. Interceptar la ejecucion en algun punto y devolver el control al programa/funcion original.
I Cambiar programas de usuario.
I Cambiar codigo fuente
I Cambiar compilador
Atacante externo
I Server side (servicios)
I Client Side (desktop)
Vulnerabilidades en software
I El input es controlado por un atacante
I Bugs + datos mezclados con informacion de control = vulnerabilidades
I Emergen clases de equivalencia
I Inyeccion de comandos I Desbordamiento de enteros I Buffer Overflows
I Format strings I ... etc ..
Inyeccion de comandos
Un programa vulnerable a injeccion de comandos utiliza la entrada del usuario para construir una linea de comando de shell si realizar los checkeos
necesarios. El atacante controla parte de la linea de comandos a ejecutarse por el programa vulnerable y finalmente puede insertar comandos
Inyeccion de comandos - Ejemplo
i n t main ( i n t argc , char ∗∗ argv ) {char b u f f e r [ 6 4 ] = " date " ; p r i n t f ( " B i e n v e n i d o a Megaserver ! \ n \ r " ) ; p r i n t f ( " La hora y fe cha a c t u a l es : " ) ; system ( " date " ) ; p r i n t f ( " Por f a v o r i n g r e s e l a nueva : " ) ; g e t s ( b u f f e r + s t r l e n ( b u f f e r ) ) ; system ( b u f f e r ) ; r e t u r n 0 ; }
Inyeccion de comandos - System
system - ejecuta una orden del interprete de ordenes
SINOPSIS
#include <stdlib.h>
int system(const char *string); DESCRIPCION
system() ejecuta una orden especificada en string llamando a /bin/sh -c string, y regresa despues de que la orden se haya terminado de ejecutar. blah...
Inyeccion de comandos - Demo
Desbordamiento de enteros
# include < s t d i o . h> i n t
main (i n t argc , char ∗ argv [ ] ) { unsigned i n t c o o k i e = 0x12345678 ;
unsigned i n t parameter = a t o i ( argv [ 1 ] ) ; i f ( c o o k i e > c o o k i e +parameter )
p r i n t f ( "NAAAAAAAAAAH ! \ n \ a " ) ; r e t u r n 0 ;
Stack Overflows
I El tipo de vulnerabilidad mas conocido y documentado
I "Smashing the stack for Fun and Profit" (Aleph, One, 1996) (http://www.phrack.org/issues.html?id=
14&issue=49)
Buffers
I Un cacho de memoria. Una porcion memoria continua y limitada
I En C, el buffer mas comun es un arreglo
I Los desbordamientos son posibles porque C/C++ no revisa los limites de los accesos
Leyendo fuera de rango
# include < s t d i o . h> # include < s t r i n g . h> i n t main ( ) { i n t a r r a y [ 5 ] = { 1 , 2 , 3 , 4 , 5 } ; p r i n t f ( "%08x \ n " , a r r a y [ 5 ] ) ; }gcc -O0 -g read5.c -o read5
El compilador no se queja, pero cuando lo ejecutamos imprime un valor "loco"
Escribiendo fuera de rango
i n t main ( ) { i n t a r r a y [ 5 ] ; i n t i ; f o r ( i = 0 ; i < 255; i ++) a r r a y [ i ] = 1 0 ; }gcc -O0 -g write5.c -o write5
El compilador no se queja, pero cuando lo ejecutamos "crashea"
La pila
I estructura de datois LIFO
I sirve para guardar variables automaticas(locales) e informacion de control para la anidacion de funciones
I en INTEL el registro *ESP* apunta al tope de la pila (al ultimo valor usado)
I y *EBP* a la base del marco de activacion actual (no es necesario)
I las intrucciones PUSH and POP usan ESP para acceder a la memoria de la pila
Buffer Overflows - Stack
i n t main ( i n t argc , char ∗ argv [ ] ) { i n t c o o k i e = 0x12345678 ; char b u f f e r [ 4 0 ] ; s t r c p y ( b u f f e r , argv [ 1 ] ) ; i f ( c o o k i e == 0x41424344 ) p r i n t f ( " Ganaste ! \ n \ a " ) ; r e t u r n 0 ; }
Buffer Overflows - Stack
$ gcc -O0 -g stack.c -o stack
Buffer Overflows - Controlando el eip
I EY! Pero ahi tambien esta la direccion de retorno de la funcion
I Intentemos sobreescribirla poniendo mucho mas input
I Vamos a sobreescribir todo el marco de activacion
I La direccion de retorno de la funcion actual es una variable local implicita e *invisible* para el programador
Buffer Overflows - EIP? A donde saltar?
I Hay que decidir donde saltar
I Historicamente se salta nuevamente a la pila
I Podemos elejir un lugar en la funcion main... digamos printf ("Ganaste!\n");
Format strings
SINOPSISint printf(const char *format, ...); DESCRIPCION
Las funciones de la familia printf producen una salida de acuerdo a format.
FORMAT
%d El argumento int se convierte a la notacion decimal con signo.
%n El numero de caracteres escritos hasta ahora se guarda en el entero indicado por el argumento de tipo puntero int * No se convierte ningun argumento. !!!!!!
Format strings - Ejemplo
i n t main ( i n t argc , char ∗ argv [ ] ) { i n t v a l u e = 0 xdeadbeef ; i n t c o o k i e = 0x12345678 ; i n t ∗ value_p = &v a l u e ; i n t ∗ cookie_p = &c o o k i e ; p r i n t f ( " La d i r de c o o k i e :%08x \ n " , cookie_p ) ; p r i n t f ( " La d i r de v a l u e :%08x \ n " , value_p ) ; p r i n t f ( argv [ 1 ] ) ; p r i n t f ( " E l v a l o r de c o o k i e :%08x \ n " , c o o k i e ) ; p r i n t f ( " E l v a l o r de v a l u e :%08x \ n " , v a l u e ) ; i f ( c o o k i e == v a l u e ) p r i n t f ( "NAAAAAAAAAAH ! \ n \ a " ) ; r e t u r n 0 ; }
Format strings - DEMO
Protecciones
I NX/DEP Mapas de memoria no ejecutables son ... ergh.. no executables
I ASLR Aleatorizacion de la posicion base de los mapas de memoria