Modificando el funcionamiento de ejecutables

Iniciado por andergedon, Febrero 07, 2018, 09:53:57 PM

Tema anterior - Siguiente tema

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



Que tal colegas. Hoy les enseñaré a aprovecharse del flujo de un programa para modificar determinadas partes de su funcionamiento.
Es recomendado tener al menos conocimiento básico sobre ingeniería inversa, ollydbg, y algo de lenguaje ensamblador.

El ejecutable que estaré utilizando en el ejemplo, es un programa sencillo que hice hace mucho tiempo mientras practicaba las GUI de C++. Lo he encontrado entre la basura de mis carpetas y vi que se prestaba para lo que quiero demostrar, Lo pueden descargar No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, dicho esto, empecemos  ;D

El programa simplemente genera 4 colores aleatorios creando así una paleta de colores, la app tiene una opción que permite buscar imagenes en el navegador que contengan los colores de la paleta generada.

   

Lo que vamos a hacer es modificar esa URL que genera el programa y colocar la que nosotros deseemos.
Manos a la obra 8)

Primero buscaré todas las strings relevantes en relación al botón que llama la función para abrir el navegador. Empezaré con la string "Search image with this colors!" y presionamos F2 para poner un BreakPoint. También localizaré la string "labs.tineye.com" que es la URL que abre el navegador al momento de pulsar el botón, podemos asumir que en algún momento se pasará como argumento a una función. Por ahora colocaré un BreakPoint ahí también.


Bien, una vez hecho esto intentemos comenzar la depuración del ejecutable y esperar que se tope con alguno de nuestros BreakPoints antes colocados.
Presionamos el botón que nos interesa, el que llama a la función para buscar las imagenes. Nos topamos con uno de los BreakPoints, el de la URL y vemos que la instrucción  manipula esa string a partir de la posición 00A4CC4C


A partir de este punto avanzaré hasta encontrar el punto en donde se abre nuestro navegador para tener puntos de inicio/final. Luego de ir paso a paso hallamos ese punto final en 00405158.

Ya que sabemos donde está nuestro punto final podemos analizar el flujo del programa con más calma. Si volvemos a ejecutar el programa y vamos de nuevo instrucción por instrucción notamos que en 0040512B la dirección de nuestra URL completa es almacenada en el registro EAX


La dirección que almacena nuestra string con la URL es entonces 0028F6F2

Lo que voy a hacer acontinuación es cambiar el contenido de la memoria donde es almacenada la URL, lo haré antes de que sea copiado al registro EAX, pues parece que el registro es utilizado para mover el string y utilizarlo dentro de la función que llama al navegador. Para hacer esto tenemos que "inyectar" un par de instrucciones en el programa.
Lo primero que vamos a hacer es buscar un espacio "nulo", es decir, un espacio en la memoria bastante alejada en donde no haya ninguna instrucción, byte, etc. Normalmente se idetifican por una serie bastante larga de NOP o DB 00 Yo elegiré la 00A3C34F. A partir de aquí es donde empezaremos a colocar las instrucciones "inyectadas" con el fin de modificar la URL

Tenemos que hacer que nuestro programa salte en algún punto hasta nuestra dirección alejada, para esto buscaremos una instrucción "inofensiva" o una instrucción que no sea tan importante. Elegiré 0040511E   MOV EAX,16. Pues no hace más que copiar 16 al registro EAX. Reemplazaremos esa instrucción por JMP 00A3C34F para que de un salto incondicional hasta nuestra dirección alejada.

Una vez dado el salto empezaremos a modificar la dirección de memoria de la URL.

La url que inyectaré será: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta (El link acortado al foro de underc0de) Luego de convertirlo a hexadecimal, quedaría así:
Código: php
676f6f2e 676c2f43 714d4d32 6e00


Y luego de invertirlo para pasarlo mediante el registro quedaría de esta forma:
Código: php
2E6F6F67 432F6C67 324D4D71 006e


Ahora empezaremos a copiar todos esos caracteres mediante EAX a nuestra memoria donde se encuentra la URL. Las instrucciones quedarían algo así

Código: asm
MOV EAX, 2E6F6F67
MOV [0028F6F2], EAX
MOV EAX, 432F6C67
MOV [0028F6F6],EAX
MOV EAX, 324D4D71
MOV [0028F6FA], EAX
MOV EAX, 006e
MOV [0028F6FE], EAX
MOV EAX, 16
JMP 00405123



Estas instrucciones son las que colocaremos en nuestra dirección alejada (00A3C34F). Si ejecutamos un poco estas instrucciones podemos ver como nuestra URL va cambiando.


Una vez terminada la modificación de la memoria hay que "dejar todo como estaba y fingir que nada pasó" por eso colocamos ese 16 en EAX y volvemos con un salto al punto justo después de donde aplicamos el primer salto. Esto para que el programa siga su curso "normalmente"

Ejecutamos nuestro programa dentro del depurador para comprobar y...


Búm! Hemos conseguido que el programa nos envíe a un sitio totalmente diferente al que conducía originalmente.
Para guardar los cambios damos en click derecho> copy to executable > All modifications.

¡Y listo!


Esto fue todo por hoy, espero que también hayan aprendido algo. ¡Nos leemos!.
\x11\x12\x13

Buen post compañero, muy interesante, en verdad.

Ahora tengo 2 dudas.

La primera. ¿Por qué inviertes el hexadecimal obtenido, digo no se puede insertar directamente al registro de esa forma?

La segunda que puede ser un poco primitiva... ¿Estos valores al ser guardados en el registro EAX, son más grandes de 32 bits, cómo no se sobrecarga este registro? :)
"Cuando se nace pobre, estudiar es el mayor acto de rebeldía contra el sistema. El saber rompe las cadenas de la esclavitud" -Tomas Bulat.

Hola @No tienes permitido ver los links. Registrarse o Entrar a mi cuenta gracias por tu comentario

Citar¿Por qué inviertes el hexadecimal obtenido, digo no se puede insertar directamente al registro de esa forma?

Se invierte el hexadecimal debido al formato No tienes permitido ver los links. Registrarse o Entrar a mi cuenta que poseen los procesadores más comunes. De este modo se hace más intuitivo el acceso a datos, porque se efectúa fácilmente de manera incremental de menos relevante a más relevante.

Citar¿Estos valores al ser guardados en el registro EAX, son más grandes de 32 bits, cómo no se sobrecarga este registro?

Los valores estan dentro del rango de los 32bits.
El máximo valor que puede tomar el registro es: 7fffffff=2147483647, y el valor más grande que almacenado en esas instrucciones es  432F6C67=1127181415
1127181415<2147483647   



Saludos!
\x11\x12\x13