Tienda Wifi

Tienda Wifi
CiudadWireless es la tienda Wifi recomendada por elhacker.NET

Entradas Mensuales

Síguenos en:

Canal Oficial Telegram de elhacker.NET Grupo Facebook elhacker.NET Twitter elhacker.NET Canal Youtube elhacker.NET Comunidad Steam: Grupo elhacker.NET

Suscripción

¿Quieres recibir las últimas novedades del blog en tu correo?

¡Suscríbete al feed!

Entradas populares

PostHeaderIcon Introducción y Herramientas de Ingeniería Inversa




Primeros pasos en el mundo de la ingeniería inversa. Es un "arte" complejo, considerado por muchos como avanzado, que requiere muchísimas horas de práctica y estudio. Definiciones, conceptos y herramientas como OllyDbg, Radare, Immunity Debugger, Ida Pro (y Free) o GNU Debugger (GDB), Windbg, X64dbg, Ghidra.




Ingeniería Inversa

Definición por pancake aka trufae

La ingeniería inversa sirve para obtener información de un producto, cómo ha sido construido o cómo funciona por dentro.

El objetivo de la ingeniería inversa es obtener información o un diseño a partir de un producto accesible al público, con el fin de determinar de qué está hecho, qué lo hace funcionar y cómo fue fabricado. Hoy en día los productos más comúnmente sometidos a ingeniería inversa son los programas.

Sirve para:

  • Clasificar Malware
  • Liberar drivers/hardware
  • Analizar vulnerabilidades
  • Hacker crackmes/ctf (Capture the Flag)
  • Contailidad con software
  • Espionaje industrial


  • ¿Qué tipos de ejecutables existen? ¿Todos se depuran de la misma forma?
  • ¿Por qué los ejecutables tienen un encabezado? ¿Qué información hay en ese encabezado (header en inglés)?
  • ¿Cómo se analiza un virus y qué modifica?
  • ¿Cómo se modifica un programa?
  • ¿Cómo puedo depurar mi programa para buscar errores?
  • Una vez que he aprendido a depurar, ¿cómo puedo mejorar la protección de mi software?

Del Código Máquina al Lenguaje Ensamblador


Cuando nos encontramos frente a una variante de algún código malicioso en un sistema y nos disponemos a analizarlo tenemos el archivo binario y debemos utilizar un desensamblador para generar el código en assembler con el objetivo de analizarlo. Ensamblador (assembler) es en realidad una clase de lenguaje de programación. Cada variante de ensamblador corresponde a una familia particular de microprocesadores tales como x86, x64, SPARC, PowerPC, MIPS o ARM. Dentro de todas estas familias la más habitual dentro las arquitecturas de procesadores es la x86, aunque con el pasar de los años vemos más y más procesadores x64.

  • Data: La sección de datos de un programa hace referencia a una región específica de memoria. Contiene lo que se conoce como las variables estáticas que no cambian con la ejecución del programa. También en esta sección se encuentran las variables globales, que están disponibles desde cualquier parte del programa.
  • Code: En esta región de memoria se almacena el código que se ejecuta del programa donde se alojan todas las instrucciones que se van a ejecutar.
  • Heap: El heap es una región de memoria que se utiliza para alocar nuevos valores durante la ejecución del programa como así también para eliminarlos una vez que se dejaron de utilizar. El heap es una memoría dinámica y su contenido varía a medida que se ejecuta el programa
  • Stack (Pila): La pila se utiliza para alojar las variables locales, parámetros y valores de retorno de una función como así también contiene las direcciones de retorno entre una llamada a una función y otra, siendo muy útil para controlar el flujo de ejecución del programa.


Cualquier software se ejecuta de forma secuencial, es decir una instrucción detrás de otra, la siguiente instrucción a ejecutar se almacena en un registro llamado IP, mediante programación se puede desviar esa ejecución hacia funciones que realicen tareas concretas, el programa en un principio ejecutará el flujo normal hasta que llega a una llamada a una función, en ese momento guarda en RAM el registro IP, ejecuta la función y retorna al flujo principal del programa porque fué capaz de leer el valor almacenado en RAM del registro IP.

 Registros


Un registro es, de forma simplificada, un pequeño almacén en la CPU y es, evidentemente, la forma más rápida que tiene la CPU de acceder a datos. En la arquitectura x86 de Intel existen ocho registros de propósito general: EAX, EDX, ECX, ESI, EDI, EBP, ESP y EBX (cambiar E por R en arquitecturas de 64 bits).

Son utilizados para facilitar la tarea en el procesado de las instrucciones, cómo para almacenar datos que se utilizaran posteriormente por las mismas.
  • El registro EAX (RAX)
  • El registro EDX (RDX)
  • El registro ECX (RCX)
  • Los registros ESI (XSI) y EDI (RDI)
  • Los registros ESP (RSP) y EBP (RBP)
  • El registro EBX (RBX)
  • Registro especial EIP (RIP)

 Estos son alguno de los registros básicos que existen:

  • - EAX (Accumulator register): Utilizado tanto para realizar cálculos, cómo para el almacenamiento de valores de retorno en "calls".
  • - EDX (Data register): Extensión de EAX, utilizada para el almacenamiento de datos en cálculos más complejos.
  • - ECX (Count register): Utilizado en funciones que necesiten de contadores, como por ejemplo bucles.
  • - EBX (Base register): Se suele utilizar para apuntar a datos situados en la memoria.
  • - ESI (Source index): Utilizado para la lectura de datos.
  • - EDI (Destination index): Utilizado para la escritura de datos.
  • - ESP (Stack pointer): Apunta a la cima de la pila “stack”.
  • - EBP (Base pointer: Apunta a la base de la pila “stack”.

Instrucciones

Son acciones predefinidas en el lenguaje ensamblador. Algunas de las más habituales de ver son:

  • - PUSH: Guarda el valor en la pila.
  • - POP: Recupera valor de la pila.
  • - MOV (dst, src): Copia el operador “src” en el operador “dst”.
  • - LEA (reg, src): Copia una dirección de memoria en el registro destino (ej: EAX).
  • - ADD (o1, o2): Suma los dos operadores y los almacena en el operador uno.
  • - SUB (o1, o2): Resta el valor del segundo operador sobre el primero y lo almacena en el primer operador.
  • - INC: Incrementa en 1 el valor del operador indicado.
  • - DEC: Decrementa en 1 el valor del operador indicado.
  • - AND: El resultado es 1 si los dos operadores son iguales, y 0 en cualquier otro caso.
  • - OR: El resultado es 1 si uno o los dos operadores es 1, y 0 en cualquier otro caso.
  • - CMP: Compara dos operadores.
  • - JMP Salta a la dirección indicada.
  • - CALL: Llama/Salta a la dirección/función indicada.
  • - NOP: Not Operation.

Estructura de la pila (Stack)


La pila es una estructura FILO (First In, Last Out) donde los argumentos son apilados en la cima de la misma cuando se invoca una función y retirados cuando la función finaliza. El registro ESP se usa para seguir la pista a la parte más alta del marco de la pila y el registro EBP para seguirle la pista a la parte baja (aunque ya vimos que ciertos compiladores pueden decidir no usar ebp para eso).

La PILA o Stack es un conjunto de direcciones de memoria encargadas de almacena información de llamadas a funciones, variables locales, direcciones de retorno a funciones anteriores, entre otras tareas. La PILA es dinámica, por lo que va cambiando su tamaño dependiendo de la función a la cual se encuentre asociada, dispone de una estructura “First In, Last Out”, por lo que lo último que entra será lo primero en salir, delimitada siempre por su cima (ESP) y por su base (EBP).

Puntos de Interrupción (Breakpoints)


La habilidad de parar un proceso que está siendo depurado se consigue mediante el fijado de puntos de interrupción o breakpoints. Al parar el proceso podemos inspeccionar el valor de las variables, los argumentos de la pila, y las direcciones de memoria sin que el proceso modifique estos valores hasta que no se lo indicas de esa forma al depurador.


Los puntos de interrupción son la herramienta principal proporcionada por los depuradores. Los puntos de interrupción le permiten interrumpir la ejecución del programa en un lugar específico. Hay dos tipos de puntos de interrupción:

  • Puntos de interrupción de software
  • Puntos de interrupción de hardware


Es muy difícil realizar ingeniería inversa de software sin puntos de interrupción. Las tácticas populares de ingeniería anti-reversa se basan en la detección de puntos de interrupción, proporcionando una serie de métodos anti-depuración correspondientes.

Cómo omitir una verificación de punto de interrupción de software

No existe un enfoque universal para evitar una verificación de punto de interrupción de software. Para evitar esta protección, debes encontrar el código que calcula la suma de verificación y sustituir el valor devuelto con una constante, así como los valores de todas las variables que almacenan sumas de verificación de funciones.

Puntos de interrupción de hardware

  • DR0-DR3 – breakpoint registers -“Debug Address Registers” or “Address-Breakpoint Registers”
  • DR4 & DR5 – reserved - “Reserved Debug Registers”
  • DR6 – debug status - "Debug Status Register”
  • DR7 – debug control -“Debug Control Register”


SEH (Structured Exception Handling)



El manejo estructurado de excepciones es un mecanismo proporcionado por el sistema operativo a una aplicación que le permite recibir notificaciones sobre situaciones excepcionales como la división por cero, la referencia a un puntero inexistente o la ejecución de una instrucción restringida. Este mecanismo le permite manejar excepciones dentro de una aplicación, sin la participación del sistema operativo. Si no se maneja una excepción, dará como resultado la finalización anormal del programa. Los desarrolladores suelen ubicar punteros a SEH en la pila, que se denominan marcos SEH. La dirección de trama SEH actual se encuentra en el desplazamiento 0 en relación con el selector FS (o el selector GS para los sistemas x64).

VEH (Vectored Exception Handler)


VEH se introdujo en Windows XP y es una variación de SEH. VEH y SEH no dependen el uno del otro y funcionan simultáneamente. Cuando se agrega un nuevo "manejador" VEH, la cadena SEH no se ve afectada ya que la lista de manejadores VEH se almacena en la variable no exportada ntdll! LdrpVectorHandlerList. Los mecanismos VEH y SEH son bastante similares, la única diferencia es que las funciones documentadas se utilizan para configurar y eliminar un controlador VEH.

Exploiting sobre Linux-x86

La porción de RAM utilizada por un programa cuando se llama a una función es comunmente llamada pila o stack, debemos tener en cuenta que la pila crece de arriba a abajo, como podemos ver hay una parte de la ram que almacena la copia del registro IP(EIP) en el momento de realizar la llamada a la función, en el programa no se tiene en cuenta que el dato introducido sea de una longitud concreta, se realiza la copia a ciegas a la variable nombre, aprovechando este descuido podemos hacer crecer la variable nombre hasta llegar a ocupar la dirección de retorno EIP haciendo así que el software termine retornando a otra posición de memoria y no la que se guardó al realizar la llamada a la función func.

¿Qué es una Shellcode?


Una shellcode no es mas que el conjunto de opcodes (instrucciones en hexadecimal) que ejecutará el procesador para realizar un acción en concreto, las shellcodes suelen estar escritas en ensamblador ya que nos permite un control total sobre el proceso de ejecución además de un tamaño inferior de la shellcode.

Definición Buffer

Un espacio de memoria de cierto tamaño que se reserva para guardar datos, y manejar los mismos.

Un ejemplo básico es una lata de 20 litros que tengo vacía para guardar allí un contenido, el mismo podrá ser menor o igual a 20 litros, el cual es el tamaño máximo que puedo guardar en este buffer de 20 litros,  si quisiera guardar más en un solo depósito debería buscar la forma de tener un buffer más grande, sino, al tratar de guardar por ejemplo 40 litros en una lata de 20 litros se desbordaría.

Un buffer overflow ocurre cuando un programa informático excede el uso de cantidad de memoria reservado para ello , escribiendo en el bloque de memoria contiguo.

  • En verdad, un buffer overflow se produce en una aplicación informática cuando no cuenta con los chequeos de seguridad necesarios en su código de programación, como por ejemplo medir la cantidad de datos que se copiara a un buffer y que no exceda el tamaño del mismo.
  • Los tipos más comunes de buffer overflows son los stack buffer overflows y los heap buffer overflows.

Bueno aqui vemos la definición de buffer overflow, y en nuestro ejemplo anterior si trato de guardar 40 litros en una lata de 20 litros se desbordara como vimos, ese desborde que se produce es el buffer overflow, o sea el desbordamiento de mi depósito al sobrepasar la máxima capacidad del mismo.


Stack y heap overflow

Ahora una idea acerca de la diferencia entre stack y heap:

  • STACK : El stack se utiliza para guardar las variables locales de una función que sólo necesitan durar tanto como la ejecución de la función. En la mayoría de los lenguajes de programación es fundamental que sepamos en tiempo de compilación qué tan grande es una variable si queremos almacenarla en el stack.
  • HEAP: El heap se utiliza para reservar memoria dinámica, cuya vida útil no se sabe muy bien por adelantado, pero se espera que duren un tiempo. Si no sabemos su tamaño o el mismo se decide en tiempo de ejecución se deberá calcular y reservar en el heap.

Stack Buffer Overflow


In software, a stack buffer overflow occurs when a program writes to a memory address on the program's call stack outside of the intended data structure; usually a fixed length buffer.

Es decir, la vulnerabilidad Stack Buffer Overflow ocurre cuando una aplicación no controla correctamente el número de bytes que son almacenados en una dirección de memoria previamente reservada, de forma que la cantidad de bytes que se van a almacenar son superiores a los reservados.

Nuestro principal objetivo es llegar a sobrescribir la dirección de retorno (almacenada en la PILA) con un valor que apunte a nuestra shellcode.

  • Registro EIP (Extended Instruction Pointer): Este registro apunta a la siguiente dirección de memoria que el procesador va a ejecutar.
  • Instrucción RETN: Es la instrucción encargada de recoger el valor de ESP y almacenarlo en el registro EIP, de este modo el valor de ESP será la próxima dirección de memoria que el
    procesador va a ejecutar.
  • Dirección de retorno: Es el valor exacto que nos indica la dirección de memoria donde habíamos dejado la aplicación ante de entrar en una subfunción, para así cuando esta termine volver a la posición exacta donde nos quedamos. Este valor se encontrará almacenado en la siguiente dirección de memoria del EBP de la subfunción

Anti-sandboxing y Anti-debugging

Debuggers como OllyDbg, WindDbg, Radare o IDA ya sabréis que se requieren conocimientos sobre lenguaje ensamblador y estructuras internas de ficheros.

Una técnica anti-debugging muy fácil de implementar, pero también muy fácil de evadir, es la función “IsDebuggerPresent”. PEB (Process Environment Block)

  • Los códigos de espagueti y basura hacen que las herramientas de análisis comunes sean ineficaces

El primer problema de ofuscación que requiere una solución es la eliminación de las instrucciones basura y el "código de espagueti", que es una técnica que pretende confundir los programas de desamblado El código de espagueti hace que el programa fluya de forma difícil de leer al agregar saltos continuos de código, de ahí el nombre.

Este problema no es nuevo, y en situaciones comunes se conocen complementos de reversing que pueden ayudar en esta tarea. Sin embargo, a veces no podemos encontrar un buen complemento de desensamblador interactivo (IDA) que pueda normalizar el flujo de código.

VM detection


  • hardware IDs are VmBus in case of HyperV
  • VEN_15AD in case of VMware


Debugger detection 

  • IsDebuggerPresent
  • ThreadHideFromDebugger
  • ProcessDebugPort
  • ProcessDebugObjectHandle
  • ProcessDebugFlags
  • CheckRemoteDebuggerPresent
  • NtQueryInformationProcess
  • ProcessBasicInformation

Debuggers - Dissamblers - Depurador

Immunity Debugger



Immunity Debugger is a powerful new way to write exploits, analyze malware, and reverse engineer binary files. It builds on a solid user interface with function graphing, the industry’s first heap analysis tool built specifically for heap creation, and a large and well supported Python API for easy extensibility.



OllyDbg



OllyDbg, creado por Oleh Yuschuk, es un depurador a nivel de aplicación. La interfaz OllyDbg muestra el código ensamblador, volcado hexadecimal, la pila y registros de la CPU. OllyDbg también soporta rastreo, puntos de interrupción condicionales, visión de cabecera PE, edición hexadecimal.

OllyDbg es un depurador a nivel de aplicación. La interfaz OllyDbg muestra el código ensamblador, volcado hexadecimal, la pila y registros de la CPU. OllyDbg también soporta rastreo, puntos de interrupción condicionales, visión de cabecera PE, edición hexadecimal, y plug-in de soporte.

En la primera puesta en marcha, OllyDbg pide configurar el directorio de datos del usuario (UDD) y el directorio de plug-ins. UDD se utiliza para guardar información específica de la aplicación como puntos de interrupción. Ofrece amplias opciones de depuración como la configuración de breakpoints en la carga de nuevos módulos, la creación de threads, la forma de procesar las excepciones, etc. OllyDbg soporta el establecimiento de puntos de interrupción de hardware, puntos de interrupción de software, puntos de interrupción de memoria e incluso puntos de interrupción condicionales.

GNU Debugger (GDB)



GDB o GNU Debugger es el depurador estándar para el sistema operativo GNU. Es un depurador portable que se puede utilizar en varias plataformas Unix y funciona para varios lenguajes de programación como C, C++ y Fortran. GDB fue escrito por Richard Stallman en 1988. GDB es software libre distribuido bajo la licencia GPL.


IDA Pro


Al igual que OllyDbg, IDA Pro es un depurador / desensamblador a nivel de aplicación que nos ayudará enormemente en seguir la pista de la ejecución del programa. Cuenta con una versión de demo y una versión freeware más antigua, que es gratuita solo para uso no comercial.


Radare (radare2, r2)


RA-DA-RE significa RAw DAta REcovery. Empezó como un programa para recuperar ficheros del disco duro y poco a poco se fueron añadiendo funcionalidades para que pudiera desensamblar y depurar. Radaré nació como una herramienta editor hexadecimal, debugger, assembler/disassembler, bajo la línea de comandos. Radare2 fue re-escrito de nuevo y poco a poco ha ido alcanzando el nivel del radare original.  

Una de las principales solicitudes de r2 ha sido siempre una interfaz gráfica de usuario (GUI) Radare2 ahora tiene una interfaz web que debe sentir familiar a los usuarios de desensambladores comerciales. El API r2pipe también se puede utilizar desde Python, NodeJS o navegadores web, y ofrece una potente interfaz para automatizar tareas o interactuar con el núcleo radare2.

radare - RAw DAta REcovery

Posteriormente se ha convertido en una suite de herramientas que te dan una shell completa para la ingeniería inversa y que esta formada por varias utilidades:



 



  • radare editor hexadecimal en linea de comando con varios plugins que le permite ampliar
    sus posibilidades.
     
  • rabin obtiene información de archivos ELF / MZ / PE / CLASS archivos
  • radiff ofrece diferentes funcionalidades para comparar binarios.
  • rasc generador de shellcodes.
  • rasm ensamblador y desensamblador en linea de comando.
  • xrefs encuentra referencias cruzadas en archivos raw en, ppc, arm y x86.
  • rahash calcula algoritmos de encriptación en archivo, bloque de datos e incluso en flujo de
    datos.
  • rsc es el lenguaje de script de radare.
  • javasm minimalista ensamblador / desensamblador / classdumper de java.
  • armasm minimalista ensamblador de arm.
  • rax convierte números en diferentes bases.

Radare2 (r2)

Actualmente radare2  es un framework para la ingeniería inversa y el análisis de binarios.

r2 es una reescritura desde cero de radare el fin de proporcionar un conjunto de bibliotecas y herramientas para trabajar con archivos binarios. Proporciona un marco con un conjunto de bibliotecas y programas para trabajar con datos binarios.

El poryecto Radare comenzó como una herramienta forense, un editor hexadecimal en línea de comandos capaz de abrir archivos de disco, para después permitir analizar los binarios, desmontaje código, depuración de programas, conectarse a servidores remotos gdb, .. 



radare2 es portable y soporta los tipos de ficheros tipo bios, dex, elf, elf64, filesystem, java, fatmach0, mach0, mach0-64, MZ, PE, PE+, TE, COFF, plan9, bios, dyldcache, Gameboy  y Nintendo DS ROMs

  • radare2: Editor hexadecimal y debugger
  • rabin2: Extractor de info de los ejecutables binarios
  • rasm2: Ensamblador, desensamblador desde la CLI
  • rahash2: Generador de hashes
  • radiff2: Utilidad para buscar diferencias utilizando varios algoritmos
  • rafind2: Buscador de patrones en un fichero
  • ragg2: Compilador de binarios
  • rarun2: Nos permite correr el programa en diferentes entornos, variables de entorno, argumentos, directorios...
Radare también dispone de una interfaz gráfica basada en viz.js.

Desde el 2014 cuenta con una nueva interfaz web (GUI) que corre sobre un servidor web:

$ r2 -c=H /bin/ls






O el Visual mode (v)




p
  • hex, the hexadecimal view
  • disasm, the disassembly listing
  • debug, the debugger
  • words, the word-hexidecimal view
  • buf, the C-formatted buffer
  • annotated, the annotated hexdump.
También existen dos GUI para radare que son:


Fuentes:
http://www.alfaexploit.com/ficheros_web/leer.php?id=168
http://www.karmany.net/ingenieria-inversa/19-ingenieria-inversa-novatos/300-como-crackear-mi-primer-programa-legalmente-parte-i
http://www.genbetadev.com/cc/como-funciona-un-depurador-de-c-c-parte-i
http://www.unlearningsecurity.com/2012/04/documento-explotacion-de.html

0 comentarios :

Publicar un comentario

Los comentarios pueden ser revisados en cualquier momento por los moderadores.

Serán publicados aquellos que cumplan las siguientes condiciones:
- Comentario acorde al contenido del post.
- Prohibido mensajes de tipo SPAM.
- Evite incluir links innecesarios en su comentario.
- Contenidos ofensivos, amenazas e insultos no serán permitidos.

Debe saber que los comentarios de los lectores no reflejan necesariamente la opinión del STAFF.