Estos últimos días he estado investigando sobre como ejecutar shellcodes en los sistemas actuales. Me he encontrado con varios problemas como el expuesto por c1c4tr1z hace unos días.
Las protecciones añadidas están disponibles en GCC >= 4.1 (libc 2.4) pero no siempre son obligatorias. Por ejemplo en ubuntu las protecciones están activadas por defecto. Esto va a empezar a ser una constante y todos los sistemas van a llevar esto tipo de protecciones.
Las protecciones son las siguientes:
1. Reorders local variables so that buffers are placed after pointers
2. Copies pointers in function arguments to an area before local buffers
3. omits instrumentation code from functions to reduce overhead
4. adds a call to __stack_chk_fail() in the epilog
La protección 1 a mi me parece una vulnerabilidad. Fijaos en este ejemplo.
Código
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_authentication(char *password) {
[b] char password_buffer[16];
int auth_flag = 0; [/b]
strcpy(password_buffer, password);
if(strcmp(password_buffer, "planadecu") == 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);
}
if(check_authentication(argv[1])) {
printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
printf(" Access Granted.\n");
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
} else {
printf("\nAccess Denied.\n");
}
}
Como esta ordenado el código en teoría se pondría auth_flag, y luego password_buffer. Debido a la protección 1 esto es al revés. Primero se pone password_buffer y luego auth_flag.
Que pasa cuando pasamos un parametro de 17 caracteres? Obtenemos acceso.
Código
planadecu@pdux:~/hacking$ gcc auth_overflow2.c -o auth_overflow -fno-stack-protector
planadecu@pdux:~/hacking$ ./auth_overflow $(perl -e 'print "A"x16')
Access Denied.
planadecu@pdux:~/hacking$ ./auth_overflow planadecu
-=-=-=-=-=-=-=-=-=-=-=-=-=-
Access Granted.
-=-=-=-=-=-=-=-=-=-=-=-=-=-
planadecu@pdux:~/hacking$ ./auth_overflow $(perl -e 'print "A"x17')
-=-=-=-=-=-=-=-=-=-=-=-=-=-
Access Granted.
-=-=-=-=-=-=-=-=-=-=-=-=-=-
A tener en cuenta que he desactivado el stack protector. Vamos a tratar este tema en seguida.
¿Que pasa al activar o desactivar el flag -fno-stack-protector?
Vamos a tomar el siguiente codigo y compilarlo en las dos versiones.
Código
planadecu@pdux:~/hacking/$ gcc auth_overflow2.c -o auth_overflow2_sin_prot -fno-stack-protector
planadecu@pdux:~/hacking/$ gcc auth_overflow2.c -o auth_overflow2_con_prot -fstack-protector
planadecu@pdux:~/hacking/$ objdump -d auth_overflow2_sin_prot > auth_overflow2_sin_prot.s
planadecu@pdux:~/hacking/$ objdump -d auth_overflow2_con_prot > auth_overflow2_con_prot.s
Comparando ambos ficheros sin tener en cuenta las direcciones he observado las siguientes diferencias:
Sin protección
Código
08048494 <check_authentication>:
8048494: 55 push %ebp
8048495: 89 e5 mov %esp,%ebp
;####
8048497: 83 ec 28 sub $0x28,%esp ;16+4 buffer y int + 8 frame pointer
;####
804849a: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
80484a1: 8b 45 08 mov 0x8(%ebp),%eax
80484a4: 89 44 24 04 mov %eax,0x4(%esp)
80484a8: 8d 45 ec lea -0x14(%ebp),%eax
80484ab: 89 04 24 mov %eax,(%esp)
80484ae: e8 d5 fe ff ff call 8048388 <strcpy@plt>
80484b3: c7 44 24 04 50 86 04 movl $0x8048650,0x4(%esp)
80484ba: 08
80484bb: 8d 45 ec lea -0x14(%ebp),%eax
80484be: 89 04 24 mov %eax,(%esp)
80484c1: e8 f2 fe ff ff call 80483b8 <strcmp@plt>
80484c6: 85 c0 test %eax,%eax
80484c8: 75 07 jne 80484d1 <check_authentication+0x3d>
80484ca: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
80484d1: c7 44 24 04 58 86 04 movl $0x8048658,0x4(%esp)
80484d8: 08
80484d9: 8d 45 ec lea -0x14(%ebp),%eax
80484dc: 89 04 24 mov %eax,(%esp)
80484df: e8 d4 fe ff ff call 80483b8 <strcmp@plt>
80484e4: 85 c0 test %eax,%eax
80484e6: 75 07 jne 80484ef <check_authentication+0x5b>
80484e8: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
80484ef: 8b 45 fc mov -0x4(%ebp),%eax
80484f2: c9 leave
80484f3: c3 ret
Con protección
Código
080484e4 <check_authentication>:
80484e4: 55 push %ebp
80484e5: 89 e5 mov %esp,%ebp
;####
80484e7: 83 ec 38 sub $0x38,%esp ;10 bytes mas
;#### Inicio trozo insertado
80484ea: 8b 45 08 mov 0x8(%ebp),%eax
80484ed: 89 45 dc mov %eax,-0x24(%ebp)
80484f0: 65 a1 14 00 00 00 mov %gs:0x14,%eax
80484f6: 89 45 fc mov %eax,-0x4(%ebp)
80484f9: 31 c0 xor %eax,%eax
;#### Fin trozo insertado
80484fb: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp)
8048502: 8b 45 dc mov -0x24(%ebp),%eax
8048505: 89 44 24 04 mov %eax,0x4(%esp)
8048509: 8d 45 ec lea -0x14(%ebp),%eax
804850c: 89 04 24 mov %eax,(%esp)
804850f: e8 bc fe ff ff call 80483d0 <strcpy@plt>
8048514: c7 44 24 04 c0 86 04 movl $0x80486c0,0x4(%esp)
804851b: 08
804851c: 8d 45 ec lea -0x14(%ebp),%eax
804851f: 89 04 24 mov %eax,(%esp)
8048522: e8 e9 fe ff ff call 8048410 <strcmp@plt>
8048527: 85 c0 test %eax,%eax
8048529: 75 07 jne 8048532 <check_authentication+0x4e>
804852b: c7 45 e8 01 00 00 00 movl $0x1,-0x18(%ebp)
8048532: c7 44 24 04 c8 86 04 movl $0x80486c8,0x4(%esp)
8048539: 08
804853a: 8d 45 ec lea -0x14(%ebp),%eax
804853d: 89 04 24 mov %eax,(%esp)
8048540: e8 cb fe ff ff call 8048410 <strcmp@plt>
8048545: 85 c0 test %eax,%eax
8048547: 75 07 jne 8048550 <check_authentication+0x6c>
;#### Inicio trozo insertado
8048549: c7 45 e8 01 00 00 00 movl $0x1,-0x18(%ebp)
8048550: 8b 45 e8 mov -0x18(%ebp),%eax
8048553: 8b 55 fc mov -0x4(%ebp),%edx
8048556: 65 33 15 14 00 00 00 xor %gs:0x14,%edx
804855d: 74 05 je 8048564 <check_authentication+0x80>
804855f: e8 8c fe ff ff call 80483f0 <__stack_chk_fail@plt>
;#### Fin trozo insertado
8048564: c9 leave
8048565: c3 ret
Más tarde continuo con la explicación. Dejo que penseis un poco.
Seria intersante ver como saltarse esta protección. Este es mi goal.
Saludos!










Autor



En línea
