google translator

lunes, 19 de septiembre de 2011

Creando un plugin para immunity debugger

Muchas veces, cuando estamos depurando una aplicación con el immunity debugger, siempre pensamos que hay algo que debería tener pero que no tiene. Incluso perdemos el tiempo repitiendo tareas que podríamos evitar tener que hacer mil veces si hubiera un plugin que lo hiciese. Pues bien, en este post voy a hacer una pequeña introducción a como realizar un plugin para el immunity, para que os sirva de introducción, y podáis haceros luego vuestros propios plugins.

El plugin que vamos a realizar es muy sencillo, simplemente buscará unas instrucciones en ensamblador por todo el programa que estemos depurando (incluso sus librerías), y nos mostrará por pantalla donde se encuentra dichas instrucciones. Para realizarlo, lo vamos a hacer con Python, un lenguaje que se lleva muy bien con Immunity y con el que además vamos a programar el plugin muy rápido.

Todas los plugins de immunity se encuentran en el directorio "PyCommands" del directorio de instalación de Immunity (No confundir con el directorio "PyPlugins"). Con lo cual vamos a crear un fichero en esa carpeta llamado "buscador.py". Para hacer una prueba y ver como funciona esto de los plugins, vamos a hacer primero el típico "hola mundo". Para ello abrimos el fichero "buscador.py" y escribimos lo siguiente:

def main(args):
	return "Hola mundo!"

Una vez guardado, abrimos el immunity cargando cualquier programa (yo he cargado en notepad) y en la parte inferior de la ventana tecleamos lo siguiente:

!hola 

Después de eso veremos con se muestra justo debajo de donde hemos escrito el mensaje "hola mundo!", como podemos ver en la imagen.



Con esto ya nos podemos hacer un poco a la idea de como van los plugins de immunity. Así que ahora vamos a explicar como hacer más cosas.

La librería que nos trae immunity para hacer plugins se llama "immlib", y es en lo que nos vamos a basar para hacer cualquier plugin ya que con esta libreria podemos hacer casi de todo con immunity. El propio immunity trae en el menú una parte dedicada a "immlib" y si extendemos el menú veremos que tenemos ayuda sobre immlib y su API. Aunque la mejor ayuda esta en el directorio "documentation/ref" del la carpeta principal de immunity. Si hacemos doble click sobre index.html veremos la documentación completa de immlib y esta sí que es muy buena, si perdemos un poco de tiempo echándole un vistazo podemos hacer cosas bastante chulas (hooks, breakpoints, etc..)

Para hacer el plugin vamos a utilizar alguna de las funciones que nos ofrece immlib. Para ello lo primero que deberemos de hacer es importar "immlib" e instanciar la clase "debugger" que es la que vamos a usar en nuestro plugin. Los métodos que vamos a usar para el plugin van a ser solo tres:
  • log - Con el cual vamos a escribir en la ventana de log.
  • searchCommands - El cual buscará las instrucciones en ensamblador que le pasemos.
  • getMemoryPageByAddress - Como el nombre indica devuelve una página de memoria, desde una dirección que devuelve "searchCommands"
Buenos ahora que ya sabemos los tres comandos que vamos a necesitar voy a mostrar el código completo del plugin y lo vamos comentando:

from immlib import *

def main(args):

  imm = Debugger()
  if not args:
     imm.log("!prueba [asm]")
     imm.log("Ejemplo: !prueba pop r32|pop r32|ret")
     return "[*] No se ha usado correctamente. Vea la ventana de logs"

  codigo = " ".join(args).replace("|","\n")
  res = imm.searchCommands(codigo.upper())

  for aux in res:
    memoria = imm.getMemoryPageByAddress( aux[0] )
    permisos = memoria.getAccess(human = True)
    if "execute" in permisos.lower():
      imm.log("[*] Coincidencia: %s (0x%08x) en %s" % (codigo.replace("\n","|"),aux[0], aux[2]))
 

  return "[*] Ejecutado sin errores. Consulte la ventana de logs para ver los resultados"

Como se puede ver el código no es complicado, en las primeras lineas lo único que hago es instanciar la clase Debugger, y si el usuario introduce mal los argumentos mostrarle como debe hacerlo.

En la segunda parte, sustituyo las tuberías (que hago que el usuario introduzca para separar comandos) por un salto de linea (necesario para que "searchCommands" funcione correctamente) y hago que "searchCommands" busque las instrucciones.

En la ultima parte, con cada resultado devuelto, uso getMemoryPageByAddress para saber que permisos tiene dicha región de memoria, y en el caso de que esa región sea ejecutable la muestro por pantalla. Muchos os preguntareis, ¿Por qué ejecutable? Pues bien, este plugin lo hice con la intención de buscar pop/pop/ret para los exploits, por lo cual necesitaba que la región donde se encuentren estas instrucciones fuera ejecutable. Así que si no os interesa esta parte simplemente la podéis comentar y solo mostrar los resultados de la busqueda con "searchCommands", o si os vale con que la memoria sea de lectura pues podéis poner "read", esto ya os lo dejo a vuestra imaginación.

Si queréis probar el plugin, ya sabéis como hacerlo, copiáis el codigo en un fichero (para los vagos os lo podéis bajar de aquí) y luego lo ponéis en la carpeta "PyCommands". Abrir el immunity debugger con alguna aplicación y en la parte baja de la ventana, el nombre que le hayáis puesto al fichero más la cadena a buscar. Por ejemplo, si al fichero lo habéis llamado buscador y queréis buscar la famosa cadena pop/pop/ret, podéis poner lo siguiente:

!buscador pop eax|pop ebx|ret 



y buscará todas las instrucciones que se correspondan con esa cadena y las mostrará en la ventana de logs. Sencillo, no?

No hay comentarios:

Publicar un comentario