Categorías
Uncategorized

Debugging

¿Qué es el debugging?

Debugging o depuración es el proceso de encontrar bugs o errores en el programa, en este identificamos y aislamos las causas del error. Este puede llevase a cabo de diferentes maneras entre las cuales tenemos software testing, revisión del código o mediante herramientas como debuggers

¿Qué es un debugger?

Un debugger es una herramienta que nos permite depurar un programa en estos podemos ver instrucción por instrucción, alterar el flujo de ejecución, ver los valores de las distintas variables y editarlos, colocar puntos de interrupción o breakpoints. Los depuradores nos permiten ver cómo se comporta el programa mientras es ejecutado

Conociendo las partes de un debugger

En esta parte procederemos a conocer las diferentes partes que puede tener un debugger tomando como ejemplo un debugger muy utilizado llamado x64dbg, el objetivo de esta parte es familiarizarse no solo con este depurador sino entender las diferentes partes para tener un conocimiento general que nos puede servir para cualquier depurador. Algo a tener en cuenta es que algunas de las cosas incluidas en un depurador quizás no estén incluidas en otro, pero hay elementos que son comunes de depurador a depurador

Este es nuestro depurador, lo primero que haremos será cargar un archivo ejecutable para depurarlo, para hacer esto presionamos archivo->abrir

Entre las otras opciones que tenemos están vincular que nos permite depurar un proceso que se encuentra corriendo actualmente, cambiar el comando empleado que nos permite pasarle argumentos al proceso

Una vez cargado nuestro programa en el depurador este para por defecto en el breakpoint del sistema y nos rellenara las diferentes partes con distinta información que procederemos a aclararlos a continuación

Desensamblado

En esta parte se nos muestra el código ensamblador de nuestro ejecutable, en esta parte podemos ver las instrucciones que el programa va ejecutando, podemos colocar breakpoints en la dirección que queramos y también podemos alterar el flujo de ejecución del mismo

Registros

En esta parte podemos ver y modificar los valores de los diferentes registros incluyendo las banderas de estado

Variables Locales

En esta parte nos muestra las variables locales de la función que estamos depurando actualmente y también nos da la opción de seleccionar la convención de llamada de la función

Aclaraciones

En esta parte se nos mostraran aclaraciones como por ejemplo el contenido de un puntero

Volcado de memoria

En esta parte tenemos el volcado de memoria es decir el contenido de la memoria, esta parte la usamos cuando queremos ver el contenido de cierta zona de memoria

Stack

En esta parte tenemos el contenido del stack, que como sabemos es la zona destinada para guardar nuestras variables locales, argumentos, registros salvados entre otra información

En la pestaña breakpoints tenemos todos los breakpoints o puntos de interrupción que hemos colocado, por defecto el depurador nos coloca un breakpoint en el entry point del programa y nos aclara que parará una sola vez

En la pestaña mapa de memoria podemos ver las diferentes secciones del ejecutable, su dirección de inicio y final, así como también las secciones de las diferentes dlls, memoria reservada dinámicamente y los permisos de estas

En la pestaña pila de llamadas tenemos la pila de llamadas es decir las funciones que han sido llamadas para llegar a la función actual, de primero tenemos la función actual y bajando tenemos los callers

Una vez familiarizados con el debugger procederemos a aprender a como depurar nuestros programas, para esto debemos aprender a como tracear, también debemos aprender a colocar puntos de interrupción y los diferentes puntos de interrupción que tenemos a nuestra disposición, además debemos aprender a buscar referencias y otra información que nos puede ser de utilidad.

Con el objetivo de ilustrar esto procederemos a realizar el análisis del crackme de cruehead, en este articulo no veremos la solución del mismo solo lo tomaremos como ejemplo para aprender a usar nuestro depurador

El primer paso será abrir nuestro crackme en el depurador y una vez abierto nos parará por defecto en el breakpoint del sistema

si queremos cambiar este comportamiento lo podemos hacer en opciones->preferencias y en la pestaña eventos podemos seleccionar solamente el breakpoint en el punto de entrada o entry point, esto hará que el programa pare en el entry point

Resaltado en la imagen superior tenemos los comandos que nos permiten, reiniciar el programa, detenerlo, correrlo, pausarlo y tracearlo, procederemos a explicar cada uno a continuación

Reiniciar

Reinicia el proceso que está siendo depurado actualmente

Detener

Detiene el proceso que está siendo depurado actualmente

Ejecutar

Ejecuta el programa hasta que este finaliza o encuentra un breakpoint

Pausar

Pausa la ejecución del programa

Step into

Ejecuta la instrucción entrando a cada uno de los calls

Step over

Ejecuta la instrucción sin entrar a los calls, los calls se ejecutan por completo, pero no se muestra el código dentro de estos

Trace Into y Trace Over

Inicializar el traceado que lo que hace es ejecutar las instrucciones recordándolas y se detiene cuando se cumple determinada condición

Ejecutar hasta el retorno

Ejecuta el contenido de la función actual hasta que llega al fin de esta (el retorno)

Ejecutar hasta el código de usuario

Ejecuta todo el código del sistema y se detiene cuando llega nuevamente al código de usuario

Breakpoints

Los breakpoints o puntos de interrupción los utilizamos cuando queremos parar en determinada instrucción o código que nos interesa, existen varios tipos de breakpoints como lo son de memoria, de hardware y software

Memory Breakpoints

Los breakpoints de memoria nos permiten detener la ejecución del programa cuando se accede a determinada zona de memoria estos pueden parar en acceso ya sea para lectura o escritura, solo en lectura, solo en escritura o en ejecución

Hardware Breakpoints

Los hardware breakpoints son llevados a cabo mediante registros de depuración en el procesador podemos colocar un máximo de 4 breakpoints de este tipo y las condiciones de estos pueden ser de en acceso, en lectura, escritura o ejecución

Software Breakpoints

Este tipo de breakpoint lo colocamos cuando queremos parar en determinada instrucción, cuando colocamos este tipo de breakpoint el depurador cambia la instrucción por un int3 que hace que el programa se detenga ahí pero estos pueden llegar a ser detectados por el programa fácilmente, los breakpoints de software paran en ejecución pero x64dbg soporta breakpoints por software condicionales un ejemplo de esto puede ser parar si determinado registro tiene determinado valor como por ejemplo eax==0x1234

Retomando a el ejemplo del crackme lo primero que hacemos será correr el mismo en el debugger e intentar buscar referencias a cadenas que puedan ser de nuestro interés o también podemos parar en el momento en que se lee nuestro username y serial

Una vez abierto presionamos register

nos abre esta ventanita que nos pide nombre de usuario y serial coloquemos username y 12345

Nos abre esta ventanita que nos indica que fue invalido, tratemos de ver si encontramos referencias a esta string en el debugger y analizar el código en busca de la comparación que decide cuando mostrar o no esta ventanita

Presionamos en el área del desensamblado clic derecho buscar en->módulo actual->referencias a cadena

Vemos que tuvimos suerte y encontramos dos referencias a la cadena “no luck there, mate!” coloquemos un breakpoint en ambas direcciones

Ahí colocamos nuestros breakpoints en las dos referencias, y nos damos cuenta que en una de las referencias esta muy cerca una referencia a la cadena que puede ser nuestro chico bueno, nos ayudamos con un plugin llamado xAnalyzer, una vez instalado el plugin de a cuerdo a las instrucciones de github

Damos clic derecho xAnalyzer analyze module

Este plugin hace un gran trabajo resaltándonos el inicio de las funciones ciclos y demás, vemos que nuestra referencia a nuestra string “no luck there, mate!” es usada por un mensaje box en una función que empieza en 0x401362 y si nos fijamos en la otra referencia

Está dentro de otra función que empieza en 0x40137e esta función hace determinadas comparaciones y ciclos y si no le gusta nos manda al chico malo, ahora busquemos referencias a el código que llama a estas funciones, lo primero que haremos es en el inicio de cada una de estas funciones (me refiero a las funciones que llaman a nuestra cadena)

Posicionados en la dirección que queremos encontrar referencias damos clic derecho->encontrar referencias a-> dirección seleccionada

Nos dirigimos a la dirección y colocamos un breakpoint

Una vez hecho esto con las dos referencias reiniciamos nuestro programa

Colocamos un username y un serial y al dar ok se detiene en nuestro breakpoint

Una vez detenidos podemos ver que va a pasar nuestro username y nuestro serial a dos funciones, la función en la que le pasa el username es la función que realizaba unas comparaciones y bucles y si algo no le gustaba nos mostraba el mensaje de chico malo, al salir de estas funciones en la dirección 0x401241 realiza una comparación que si eax es igual a ebx llama a la función 0x40134d que si nos fijamos cual es

Nos damos cuenta que es la función que nos manda el cartel de felicitaciones, así que lo que haremos es forzar el salto para que siempre nos mande al cartel de felicitaciones a esto se le conoce como parchear

Posicionados sobre el salto decisivo damos clic derecho->ensamblar o presionamos espacio

Cambiaremos el je (salta si es igual) por un jmp (salta siempre)

Nos quedará así ahora presionamos aceptar, ahora para que los cambios se guarden presionamos clic derecho->parches

En la ventana que se nos abre le damos a aplicar el parche

Nos abrirá el explorador de archivos

Guardamos la versión modificada con un nombre cualquiera y procedemos a probarla

Abrimos la versión modificada y colocamos un username y serial cualquiera

Y vemos que al presionar ok ¡nos muestra el mensaje de felicitaciones!

Esto concluye nuestro articulo de hoy en el cual en el nos familiarizamos con el depurador y hemos aprendido como depurar un programa e incluso a modificarlo

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *