Mostrando entradas con la etiqueta Malware. Mostrar todas las entradas
Mostrando entradas con la etiqueta Malware. Mostrar todas las entradas

lunes, 15 de julio de 2013

pype32 - Yet another Python library to manipulate PE/PE+ files

Hace un tiempo, estuve desarrollando una librería en Python para leer y escribir archivos PE/PE+. Comencé por un motivo específico, pensando en hacer algo muy particular para otro trabajo que estaba realizando pero finalmente terminé escribiendo pype32.

Después de tenerla un tiempo guardada, decidí ponerla en github para que todo el mundo pueda usarla.

Digamos que está en un estado alpha porque, más allá de haber realizado bastante pruebas, falta mucho trabajo por hacer para estar a la altura de pefile, por ejemplo.

Por el momento, está el código de la librería y la documentación de las clases y métodos generados con epydoc pero faltaría agregar un pequeño tutorial para demostrar las bondades que tiene.

El que quiera puede comenzar a probarla y darme su opinión.

Seguramente, en los próximos meses continúe el desarrollo de esta y otras librerías.

Saludos.

sábado, 30 de marzo de 2013

Unas notas sobre Yara

Hace un tiempo, tuve la tarea de tratar de identificar determinado patrón dentro de un conjunto de archivos dado. Primero pensé en hacerlo con Python pero no quería hacer lo que seguramente están pensando: string.find(). Entonces, recordé que en un momento, leyendo Malware Analyst's Cookbook, había visto yara.

Qué es Yara?. Desde su web dicen esto:
YARA is a tool aimed at helping malware researchers to identify and classify malware samples. With YARA you can create descriptions of malware families based on textual or binary patterns contained on samples of those families. Each description consists of a set of strings and a Boolean expression which determines its logic.
Para ponerlo en criollo, Yara permite, mediante un conjunto de reglas, clasificar e identificar muestras de malware.

Esto lo vamos a ver mucho más claro con un ejemplo, pero primero, instalemos Yara.

Primero que nada, nos bajamos los sources y los bindings para Python:
nriva@ubuntu:~$ wget http://yara-project.googlecode.com/files/yara-1.7.tar.gz
nriva@ubuntu:~$ wget http://yara-project.googlecode.com/files/yara-python-1.7.tar.gz
Luego, descomprimimos los .tar.gz:
nriva@ubuntu:~$ tar xzf yara-1.7.tar.gz 
nriva@ubuntu:~$ tar xzf yara-python-1.7.tar.gz
Instalamos un par de paquetes que vamos a necesitar para compilar:
nriva@ubuntu:~$ sudo apt-get install python-dev libpcre3 libpcre3-dev
Ahora, nos vamos a la carpeta de los sources de Yara y ejecutamos los siguientes comandos para compilar:
nriva@ubuntu:~$ cd yara-1.7/
nriva@ubuntu:~/yara-1.7$ ./configure
nriva@ubuntu:~/yara-1.7$ make
nriva@ubuntu:~/yara-1.7$ make check
nriva@ubuntu:~/yara-1.7$ sudo make install
Listo, ya tenemos yara funcionando:
nriva@ubuntu:~/yara-1.7$ yara
usage:  yara [OPTION]... [RULEFILE]... FILE | PID
options:
  -t <tag>                  print rules tagged as <tag> and ignore the rest. Can be used more than once.
  -i <identifier>           print rules named <identifier> and ignore the rest. Can be used more than once.
  -n                        print only not satisfied rules (negate).
  -g                        print tags.
  -m                        print metadata.
  -s                        print matching strings.
  -l <number>               abort scanning after a <number> of rules matched.
  -d <identifier>=<value>   define external variable.
  -r                        recursively search directories.
  -f                        fast matching mode.
  -v                        show version information.

Report bugs to: <vmalvarez@virustotal.com>
Ahora, compilemos los bindings para Python:
nriva@ubuntu:~$ cd yara-python-1.7/
nriva@ubuntu:~/yara-python-1.7$ python setup.py build
nriva@ubuntu:~/yara-python-1.7$ sudo python setup.py install
Probemos a ver si funciona:
nriva@ubuntu:~/yara-python-1.7$ python
Python 2.7.2+ (default, Jul 20 2012, 22:15:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import yara
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: libyara.so.0: cannot open shared object file: No such file or directory
>>>
Tenemos un error. Buscando en Google, damos con la solución:
nriva@ubuntu:~/yara-python-1.7$ sudo su
root@ubuntu:/home/nriva/yara-python-1.7# echo "/usr/local/lib" >> /etc/ld.so.conf
root@ubuntu:/home/nriva/yara-python-1.7# ldconfig
root@ubuntu:/home/nriva/yara-python-1.7# exit
exit
nriva@ubuntu:~/yara-python-1.7$ python
Python 2.7.2+ (default, Jul 20 2012, 22:15:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import yara
>>> dir(yara)
['CALLBACK_ABORT', 'CALLBACK_CONTINUE', 'Error', 'SyntaxError', '__doc__', '__file__', '__name__', '__package__', 'compile']
>>> 
Ya tenemos todo funcionando. Por un lado, la versión standalone que ejecutaremos desde una terminal y por el otro los módulos para poder utilizar Yara desde Python.

Es hora de que comencemos a escribir nuestra primer regla, pero les aconsejo que miren la documentación de Yara para tener mucha más información al respecto. 

Las reglas en Yara van simplemente en un archivo .txt aunque por conveniencia se le coloca la extensión .yara.

La estructura de cada regla es la siguiente:

rule NombreDeLaRegla : keyword1 keyword2
{
     meta:
        description = "Metadata. Un simple párrafo que explica que hace la regla."
     
     strings:
        $pattern1 = "MiStringAMatchear1"
        $pattern2 = "MiStringAMatchear2"
        $regex1 = "MiRegex"

     condition:
        if $pattern1 and $pattern2 or regex1
}
Vayamos por partes.

Para comenzar, tenemos la palabra reservada "rule" para indicar que es una regla. Seguido va el nombre que queremos darle a la regla y separado por dos puntos ":" van los keywords o tags para dicha regla.

Entre llaves "{}" va a ir todo el "código" de la regla. Primero, tenemos una sección de metadata indicada con la palabra "meta". En "description" es donde colocaremos un pequeño párrafo describiendo para que sirve la regla, como funciona, etc.

Luego, tenemos dos partes importantes que son,  básicamente, el esqueleto principal de cada regla.

Primeramente, "strings" sirve para declarar los patrones a buscar y matchear. Estos patrones pueden ser bytes, strings ASCII, strings wide, tanto case sensitive como case insensitive y hasta expresiones regulares.

A continuación, tenemos "condition". En esta sección vamos a colocar todas las condiciones que deben de cumplirse para matchear. Estas son expresiones lógicas como las que pusimos en el ejemplo.

Para seguir aclarando las cosas un poco más, escribamos una regla que nos diga si un archivo esta empacado con UPX:
rule upx : checkupx
{
    meta:
        description = "Esta regla comprueba si un archivo dado esta o no empacado con UPX."
       
    strings:
        /*
        -----> UPX 3.09
        807C24 08 01  CMP BYTE PTR SS:[ESP+8],1
        0F85 E2010000 JNZ iisproxy.10091E5D
        60            PUSHAD
        BE 00800510   MOV ESI,iisproxy.10058000
        8DBE 0090FAFF LEA EDI,DWORD PTR DS:[ESI+FFFA9000]
        57            PUSH EDI
        EB 10         JMP SHORT
        */
        $entrypoint_signature = { 80 7C 24 08 01 0F 85 ?? ?? ?? ?? 60 BE ?? ?? ?? ?? 8D BE ?? ?? ?? ?? 57 EB 10 }
       
    condition:
        $entrypoint_signature at entrypoint
}
Si se fijan, en la condición estoy utilizando una palabra reservada más "entrypoint". De esta manera, le digo que solo busque el signature en el EntryPoint de un archivo PE. En caso de que el archivo no sea PE, esta regla nunca resultará en True.

Voy a probar esta regla contra un archivo empacado con UPX 3.09. Vamos a hacerlo desde una terminal:
nriva@fastix:~/Desktop$ yara -s -t checkupx checkupx.yara iisproxy.dll
upx iisproxy.dll
0x3a070:$entrypoint_signature: 80 7C 24 08 01 0F 85 E2 01 00 00 60 BE 00 80 05 10 8D BE 00 90 FA FF 57 EB 10
Como vemos, la detección fue exitosa. Al invocar a Yara, le he pasado un par de parámetros:
  • -s: con este parámetro le indico que me muestre los patrones que han matcheado.
  • -t <tag>: con este parámetro le indico que quiero que solo me matchee la regla marcada con el keyword <tag>.
Esto lo prodríamos haber hecho desde Python también pero eso queda como tarea para el lector :)

Sin dudas, es una gran herramienta que nos puede ser de mucha utilidad.

Hasta acá con Yara. Espero que les haya sido útil. Hasta la próxima.

Referencias:

miércoles, 9 de noviembre de 2011

ARTeam Tutorial - Analyzing an Adobe Flash Malware CVE-2011-2110

Hola!,

acá pueden encontrar un nuevo tutorial que escribí, esta vez, para la gente de ARTeam.

El tutorial es sobre un bug de hace un par de meses en Adobe Flash. Van a poder encontrar, entre otras cosas:

- Anáisis del bug
- Análisis del malware que explota el bug
- Análisis del exploit utilizado para explotar el bug
- Como desarrollar una pequeña herramienta utilizando Pin

Antes de despedirme, quiero agradecer a marciano, que fue con quien estuve analizando este bug, a Nacho_dj por el feedback sobre el tutorial y a Shub por editarlo y publicarlo. Gracias a todos ellos!.

El tutorial fue escrito en Inglés y Español, para que nadie se quede afuera :P

Espero que sea de su agrado!.

Cualquier comentario acerca del tutorial es bienvenido :)

Hasta pronto!.

sábado, 13 de noviembre de 2010

Nuevo plugin para Ollydbg - aadp4olly v0.1

Hola!,

esta vez queria presentarles un nuevo proyecto en el cual he estado trabajando estas ultimas tres o 4 semanas en mis ratos libres. Se trata de un nuevo plugin para Ollydbg, aadp4olly o Anti-Anti-Debugger Plugin for Ollydbg.

Este nuevo plugin sirve para ocultar a Ollydbg de los trucos anti-dbg mas comunes como IsDebuggerPresent, NtGlobalFlags, etc; si bien ya hay plugins de este estilo para Ollydbg desde hace mucho tiempo, queria hacer mi propia version para incluir todos los trucos que necesito en mis sesiones de debugging con packers.

En esta primera version pueden encontrar trucos anti IsDebuggerPresent, NtGlobalFlags, HeapFlags, ZwSetInformationThread, OutputDebugString, ZwQueryInformationProcess y GetTickCount, por el momento, todos desde ring3.

En proximas versiones voy a continuar agregando mas trucos y posiblemente no solo en ring3 sino en ring0.

Cualquier comentario, sugerencia, pedido para agregar algo, etc, no duden en comentar aqui o escribirme directamente.

Obviamente, el proyecto es Open Source, como todo lo que he hecho hasta ahora.

Sin mucho mas que decirles, les dejo la pagina del proyecto: aadp

La descarga directa del plugin es: aadp4olly

Espero que les sea util!.

Aca les dejo un screenshot:


Hasta pronto!.

UPDATE (14/11/2010): aadp4olly ha sido actualizado a la version 0.1.1. Se fixeo un pequeño bug cuando se cerraba la ventana del plugin (reportado por marciano).
UPDATE (18/11/2010): aadp4olly ha sido actualizado a la version 0.1.2. Se incluye un fix para XP SP0 que permite que las opciones para hookear las funciones "Zw" funcionen en dicho OS (reportado por LCF-AT).
UPDATE (21/11/2010): aadp4olly ha sido actualizado a la version 0.1.3. Se incluye un nuevo fix para las funciones Zw reportado por LCF-AT.

viernes, 16 de julio de 2010

New FUU Plugin - deExeFog!

Hola!,
quienes me conocen, saben que continuamente estoy intentando hacer algo, escribiendo algun tutorial, programando alguna toolcita, etc; ahora, quiero hacer una cosa: por cada nuevo plugin de FUU que haga voy a escribir un post comentando un poco los trucos que utiliza el packer para poder facilmente identificar las zonas importantes a la hora de desempacar.
En este primer post, vamos a hablar de un packer sencillo, exeFog, mas particularmente, nos centraremos en exeFog v1.x, desconozco si existe alguna version 2.x, si alguno tiene un exe, dll, ocx o lo que sea packeado con alguna otra version de exeFog, no tiene mas que enviarla para que la pueda estudiarla y agregarle soporte al correspondiente plugin.

La idea de este y los siguientes post no es la de realizar un analisis detallado sobre el packer como suelo realizar en los tutoriales, sino que veremos las partes importantes nada mas como para vencerlo y que son utilizadas luego en el plugin.

Voy a basarme en este crackme: http://www.tuts4you.com/request.php?1093

Por ejemplo, si cargamos el programa packeado en Olly (sin plugins) y le damos a F9 (Run), veremos que Olly se detiene en una exception, mas especificamente, un DIVISION_BY_ZERO:


Esto se debe a un viejo y conocido truco anti-debug conocido como IsDebuggerPresent pero en este caso, el truco no invocando explicitamente a la API IsDebuggerPresent, sino realizando un inline de esta funcion.

Si comenzamos a tracear, veremos que primeramente, llegamos a un loop en el cual se desexorea codigo, este codigo no es mas que otra parte del stub de desempacado del programa:


Como vemos, primero coloca en EBX un puntero a una zona un poco mas abajo de la instruccion "loopd", coloca en ECX un offset, en este caso "0x3c8" y en AL la key para xorear, en este caso "0x8c", luego, solo va indexando en EBX+ECX y xoreando cada byte, luego, vuelve a tomar otro byte en AL y a repetir la operacion.

Una vez que pasamos esto, si llegamos a la zona del inline IsDebuggerPresent:


Como pueden observar, solo esta accediendo al flag "BeingDebugged" que se encuentra en la PEB:
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
BYTE Reserved4[104];
PVOID Reserved5[52];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved6[128];
PVOID Reserved7[1];
ULONG SessionId;
} PEB, *PPEB;
Se encuentra en el campo [2] de la PEB del proceso (movzx eax, byte ptr ds:[eax+2]).

Como vemos, a ese byte, primero le aplica un NOT y luego un AND con 1, con lo cual, si ese byte esta en 1 (quiere decir que el proceso esta siendo debuggeado), el resultado de esas dos operaciones sera 0 y si el byte esta en 0 (quiere decir que el proceso no esta siendo debuggeado) pues el resultado de esas dos operaciones dara 1.

Cual es el truco en todo esto? pues que este valor es utilizado como divisor y dividendo en una division un poco mas adelante:


Como vimos, el resultado del NOT y AND lo colocaba en EBX pero a su vez quedaba en EAX tambien, con lo cual si el resultado del NOT y AND es 0 pues sera 0 / 0 = ERROR!!!.

Para solucionar esto, simplemente debemos de setear ese byte a 0 para que el resultado del NOT y AND sea 1. Podemos hacerlo de varias maneras, la mas rapida es: cuando estemos en el EP (EntryPoint) del packer, simplemente hacemos CTRL+G y ponemos "EBX" y cambiamos el valor del segundo byte a 0. Por que asi? pues porque EBX siempre apunta a la PEB cuando estamos parados en el EP:


Luego, tenemos dos partes importantes mas:

1) Donde resuelve los imports.
2) Donde salta al OEP (Original Entry Point)

Ambas zonas son facil de encontrar, miremos un poco el codigo y vamos a ver que aqui resuelve las dlls importadas por el programa:


Si miramos los registros en este momento, podremos ver que EBX contiene un puntero al string de la dll importada:


Luego, en esta zona, veremos que resuelve las funciones importadas por cada dll:


y si miramos los registros, veremos que EAX contiene el puntero al string de la funcion importada y EDI el puntero al lugar en la IAT donde esa funcion deberia de encontrarse en el programa original:


Ah, antes de continuar, queria comentarles que ademas, exeFog, realiza comprobaciones en los primeros bytes de las APIs a las cuales va a llamar para ver si hay un breakpoint colocado ahi:


Ahi pueden ver un ejemplo de como, luego de resolver la funcion y colocar el puntero en EAX, verifica que el primer byte de esa funcion no contenga un breakpoint (0xCC). Con colocar hardware breakpoints o colocar los breakpoints por software en la segunda instruccion de la API (o en el RET) bastara para bypassear la comprobacion.

Bien, finalmente, el lugar en el cual se salta al OEP es este:


Llegado al "ADD", ESP contiene el offset al EP y EBP la ImageBase del programa, con lo cual, al sumarlo dara como resultado el OEP y al tomar el RET quedaremos parados ahi:



Para realizar el plugin, los pasos que realice fueron los siguientes:

1) Buscar el patron del loop que desexorea el codigo.
2) Pasar el loop anterior y realizar una busqueda de los patrones de codigo que resuelven la IAT, nos dan el salto al OEP y realizan la verificacion de BeingDebugged. Esto lo hago seteando callbacks para cada una de las tareas.
3) Cuando salta el callback en el truco anti-dbg lo unico que hago es colocar EAX en 1 luego el AND y antes del MOV EBX, EAX, con eso me aseguro de que EAX siempre es 1.
2) Cuando salta el callback de LoadLibraryA solo tomo el valor de EAX y lo voy agregando a la IAT.
4) Cuando salta el callback de GetProcAddress simplemente tomo los valores de EAX y EDI y los agrego en la IAT.

La el plugin (dll) lo pueden conseguir aca: http://tinyurl.com/2arrnct

El source code del plugin lo pueden conseguir aca: http://tinyurl.com/2wz5bty

Hasta el proximo post!.

miércoles, 7 de julio de 2010

FUU v0.1.1 Beta - Minor Release


Hola!,

bueno, luego de un tiempo sin actualizaciones al final sacamos una nueva version de FUU. Esta nueva version es mas que nada un minor release para corregir un par de cosas que habian quedado muy feas en la primera version.

Alguna de las cosas que se corrigieron son la funcion de "Refresh" en la GUI y un par de errores logicos en el codigo, tanto de la GUI como de los plugins. Ademas, se agrego la posibilidad de poder guardar el dumpeado resultante del proceso de unpacking en el lugar que uno elija.

Tengo que agradecer a toda la gente que se acerco a darme una mano con el proyecto, como GUAN, Eddy, Marciano, Mario Vilas y Erisoft. Todos ellos estuvieron ayudandome tanto para testear la herramienta y reportar bugs, como para colaborar con codigo e ideas para futuras versiones como con samples para poder realizar pruebas "particulares".

Un amigo, GUAN de Dio, se ha sumado al proyecto como colaborador migrando la version de 32 bits a 64 bits. Lamentablemente, en este release no pudimos incluirla porque estamos teniendo problemas con el SDK TitanEngine y su soporte para 64 bits con MASM y VS (Visual Studio), pero esperamos prontamente poder solucionar esto y lanzar finalmente una version de 64 bits.

Quisiera ademas aprovechar un poco para aclarar algunas cosas. He visto por al red algunos comentarios de algunas personas diciendo cosas del estilo: "Para que usar FUU si PEiD con plugins va mejor". Bueno, primero que nada quisiera aclarar que la idea principal de FUU es la de un proyecto OpenSource donde todo el mundo pueda colaborar. PEiD en cambio es un proyecto No-OpenSource. Ademas, agregar que la palabra "Universal" en FUU no significa un unpacker generico sino que con esa palabra intentamos describir lo que en un futuro FUU puede llegar a ser: al ser un proyecto OpenSource en el cual todo el mundo interesado puede colaborar con sus plugins y unpackers, entonces, podriamos desarrollar un unpacker para cada proteccion conocida hasta el momento, eso es lo que quiero decir cuando digo que FUU es "Universal Unpacker".

En fin, cualquier sugerencia, reporte de bugs, aporte para el proyecto es bienvenido y solo tienen que sumarse a nuestra lista de correo o enviarme un mail (en el caso de respoderle a una persona en particular de manera privada hace que el proyecto deje de tener sentido, la idea es que todos discutamos en la lista las ideas y aportes para FUU).

Nuevamente, agradecer a todos aquellos que colaboraron con el proyecto!!!.

Las ideas aportadas fueron muy buenas y sin dudas las vamos a ir agregando de a poco en los posteriores releases.

Ah, antes de que me olvide, prometo actualizar de manera algo mas periodica que hasta ahora la seccion de plugins, subiendo nuevos sources de nuevos plugins (siempre y cuando el tiempo me lo permita).

Web del proyecto: FUU

FUU v0.1.1 Beta Download link: FUUv0.1.1b

Disfruten!.

Hasta el proximo release!.