Bienvenidos a una nueva entrada de Byte Mind. En este caso vamos a hablar de Covenant, uno de los C2 más potentes disponibles actualmente.
Covenant está desarrollado en C# y se caracteriza por contar con una interfaz web que permite aprovechar todas sus carácterísticas de una forma más visual y sencilla. Al igual que otros C2 está enfocado por completo en tareas de post-explotación de sistemas windows, que veremos en detalle en futuros posts.
Cada uno de los elementos de Covenant cuentan con varios mecanismos interesantes para generar sesiones y stagers en la máquina comprometida de una forma muy similar a la que utiliza Metasploit Framework.
Vamos con la instalación del mismo y después continuaremos explicando las partes de este C2.
Instalación de Covenant
Para la instalación de Covenant hay dos métodos disponibles, instalando DotNet en el sistema donde se ejecutará la herramienta o mediante docker.
Instalación en el sistema
El primer paso será descargar el core de DotNet, el cual puede hacerse desde el siguiente enlace, eso sí, la versión debe ser la 3.1
Posteriormente descargamos el código desde github
1 |
$ git clone --recurse-submodules https://github.com/cobbr/Covenant |
Accedemos al directorio que se acaba de generar
1 |
$ cd Covenant/Covenant |
Y lanzaremos covenant
1 2 3 4 5 |
$ dotnet run warn: Microsoft.EntityFrameworkCore.Model.Validation[10400] Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data, this mode should only be enabled during development. WARNING: Running Covenant non-elevated. You may not have permission to start Listeners on low-numbered ports. Consider running Covenant elevated. Covenant has started! Navigate to https://127.0.0.1:7443 in a browser |
Instalación con docker
Si se opta por utilizar docker, la instalación del mismo es muy sencilla.
Descargaremos el código de github
1 |
$ git clone --recurse-submodules https://github.com/cobbr/Covenant |
Accedemos al directorio que se acaba de generar
1 |
$ cd Covenant/Covenant |
Y construimos nuestro contenedor
1 |
$ docker build -t covenant . |
Como último paso nos quedará arrancar el contenedor sustituyendo la ruta por donde esté nuestro código de github
1 |
$ docker run -it -p 7443:7443 -p 80:80 -p 443:443 --name covenant -v </absolute/path/to/Covenant/Covenant/Data>:/app/Data covenant |
Una vez instalado, ya sea de una forma u otra, el acceso será a través del navegador y elpuerto 7443 y el primer paso será crear un usuario que será el admin.
Listeners
Una vez está el entorno levantado lo primero de todo será crear un Listener, en otras palabras una escucha a la cual deberá conectarse el equipo víctima.
Es vital tener en cuenta que la IP y el puerto seleccionado sean accesibles para el equipo víctima, sino será imposible llevar a cabo el ataque.
Se pueden crear tantos como sean necesarios por lo que no hay ningún tipo de límite en este aspeco, además la gestión de los mismos es muy simple desde su interfaz web. Esto listeners serán utilizados posteriormente por los Launchers, encargados de generar los comandos a ejecutar en el equipo víctima.
Launchers
Los Launchers representan los comandos que se deben ejecutar en el sistema comprometido para recibir una conexión poder controlarlo de forma remota. Como vemos en la sigueinte captura hay varios tipos disponibles, aunque algunos de ellos ya indica que pueden no funcionar correctamente en windows 10 o las últimas versiones de windows server.
Si se accede a algunos de los launchers, es necesario configurar el listener al cual se va a conectar nuestro launcher.
Una vez completado pinchamos en Generate para generar nuestro payload/binario y posteriormente copiar o descargar el mismo para proceder a ejecutarlo en la máquina víctima y conseguir acceso a la misma.
Grunts
Una vez ejecutado el Launcher en la máquina comprometida, dicha instrucción será la encargada de establecer una conexión al listener indicado obteniendo un nuevo Grunt, que en verdad sería el equivalente a un Agent en otras plataformas de C2. En el caso siguiente he creado una vm con un windows 10 home, muy básico, pero suficiente para poder mostrar el potencial de esta herramienta.
Cada grunt dispone de un identificador único y mostrará en una simple tabla algunos detalles básicos como el sistema comprometido, el usuario que lo ha ejecutado o el nivel de integridad obtenido.
Si pinchamos en uno de los grunt existentes veremos 4 pestañas que explicamos a continuación:
- Info -> donde mostrará información del sistema víctima infectado
- Interact -> donde mostrará una consola a través de la cual podremos enviar nuestros comandos al sistema
- Task -> donde se puede ver las tareas disponible a lanzar en el sistema víctima
- Taskings -> donde se pueden observar cada tarea ejecutada y el estado de las mismas
Una de las funcionalidades muy útiles en este C2 es que las tareas se ejecutan de forma asíncrona por lo que podemos lanzar varias tareas a la vez sin necesidad de interrumpir o esperar a que finalice la anterior.
Comprendido el funcionamiento de la herramienta, pasaremos a conocer los principales comandos existentes y como utilizarlos de forma adecuada.
Tasks
Los tasks son una serie de elementos ya preparados en la herramienta para realizar tareas de explotación.
Por defecto la herramienta viene con cerca de 100 tasks diferentes disponibles en la sección de cada grunt.
Si nos fijamos en los mismos, hay comandos muy básicos que se pueden ejecutar en una terminal, pero que la posibilidad de ejecutar varias tareas a la vez ayuda a poder realizar una ataque de forma más eficiente.
En la pestaña de Taskings veremos un histórico de los comandos ejecutados en los diferentes grunt, independientemente de que el grunt se haya eliminado o no.
Ejecución de comandos
Ahora que ya conocemos las diferentes secciones de la herramienta vamos a ejecutar comandos en el equipo víctima que hemos preparado.
Nos vamos al grunt en el cual hemos ejecutado previamente nuestro launcher y desde la pestaña de interact lanzamos, por ejemplo, un whoami para conocer el nombre del usuario a través del cual tenemos acceso.
Además, tal y como hemos comentado anteriormente, en la pestaña de taskings podemos ver todos los comandos lanzados que se van completando de forma asíncrona, por lo que podemos lanzar n tareas a la vez y esperar a que las mismas se vayan completando.
Entre todas las herramientas disponibles hasta el momento hay varias que podríamos destacar como podría ser KeyLogger, Mimikatz, SeatBealt, Rubeus…
Mediante el comando de Help se puede ver un listado de las herramientas disponibles, a las cuales se sumarían posteriormente las diferentes opciones de ejecución disponibles en cada una de ellas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
(ByteMind) > Help Help Show the help menu. PowerShellImport Import a PowerShell script. Connect Connect to a P2P Grunt. Exit Exits the Grunt. Tasks Get active Tasks. TaskKill Kill an active task. Delay Set how long a Grunt should delay between callbacks. Jitter Set the percentage a Grunt should alter it's delay value between each callback. ConnectAttempts Set the maximum number of consecutive unsuccessful attempts a Grunt will make to communicate back to a Listener before giving up and exiting. KillDate Set the date at which a Grunt should exit. Disconnect Disconnect from a ChildGrunt. ScreenShot Takes a screenshot of the currently active desktop, move into a targeted pid for specific desktops Download Download a file. Upload Upload a file. WhoAmI Gets the username of the currently used/impersonated token. GetCurrentDirectory Get the Grunt's Current Working Directory ChangeDirectory Change the current directory. ReadTextFile Read a text file on disk. CreateDirectory Creates all directories and subdirectories in the specified path unless they already exist. Delete Delete a file or directory. Copy Copy a file from one location to another. Kill Kills the process of a given Process ID. SharpShell Execute custom c# code. Rubeus Use a rubeus command. SharpDPAPI Use a SharpDPAPI command. SharpUp Use a SharpUp command. SharpDump Use a SharpDump command. Seatbelt Use a Seatbelt command. SharpWMI Use a SharpWMI command. SharpSC Use a SharpSC command. MakeToken Makes a new token with a specified username and password, and impersonates it to conduct future actions as the specified user. GetSystem Impersonate the SYSTEM user. Equates to ImpersonateUser("NT AUTHORITY\SYSTEM"). ImpersonateProcess Impersonate the token of the specified process. Used to execute subsequent commands as the user associated with the token of the specified process. ImpersonateUser Find a process owned by the specified user and impersonate the token. Used to execute subsequent commands as the specified user. BypassUACGrunt Bypasses UAC through token duplication and executes a Grunt Launcher with high integrity. BypassUACCommand Bypasses UAC through token duplication and executes a command with high integrity. RevertToSelf Ends the impersonation of any token, reverting back to the initial token associated with the current process. Useful in conjuction with functions impersonate a token and do not automatically RevertToSelf, such as ImpersonateUser(), ImpersonateProcess(), GetSystem(), and MakeToken(). LogonPasswords Execute the 'privilege::debug sekurlsa::logonPasswords' Mimikatz command. LsaSecrets Execute the 'privilege::debug lsadump::secrets' Mimikatz command. LsaCache Execute the 'privilege::debug lsadump::cache' Mimikatz command. SamDump Execute the 'privilege::debug lsadump::sam' Mimikatz command. Wdigest Execute the 'sekurlsa::wdigest' Mimikatz command. DCSync Execute the 'lsadump::dcsync Mimikatz command. Mimikatz Execute a mimikatz command. SafetyKatz Use SafetyKatz. GetNetSession Gets a list of `SessionInfo`s from specified remote computer(s). GetNetLoggedOnUser Gets a list of `LoggedOnUser`s from specified remote computer(s). GetNetLocalGroupMember Gets a list of `LocalGroupMember`s from specified remote computer(s). GetNetLocalGroup Gets a list of `LocalGroup`s from specified remote computer(s). GetDomainGroup Gets a list of specified (or all) group `DomainObject`s in the current Domain. GetDomainUser Gets a list of specified (or all) user `DomainObject`s in the current Domain. GetDomainComputer Gets a list of specified (or all) computer `DomainObject`s in the current Domain. Keylogger Monitor the keystrokes for a specified period of time. Kerberoast Perform a "Kerberoast" attack that retrieves crackable service tickets for Domain User's w/ an SPN set. PortScan Perform a TCP port scan. ListDirectory Get a listing of the current directory. ProcessList Get a list of currently running processes. SetRegistryKey Sets a value into the registry. GetRegistryKey Gets a value stored in registry. SetRemoteRegistryKey Sets a value into the registry on a remote system. GetRemoteRegistryKey Gets a value stored in registry on a remote system. BypassAmsi Bypasses AMSI by patching the AmsiScanBuffer function. Shell Execute a Shell command using CreateProcess. ShellCmd Execute a Shell command using CreateProcess with "cmd.exe /c" ShellRunAs Execute a Shell command using CreateProcess as a specified user. ShellCmdRunAs Execute a Shell command using CreateProcess with "cmd.exe /c" as a specified user. CreateProcessWithToken Creates a process with the currently impersonated token. PowerShell Execute a PowerShell command. Assembly Execute a dotnet Assembly EntryPoint. AssemblyReflect Execute a dotnet Assembly method using reflection. ShellCode Executes a specified shellcode byte array by copying it to pinned memory, modifying the memory permissions, and executing. WMIGrunt Execute a Grunt Launcher on a remote system using Win32_Process Create, optionally with alternate credentials. WMICommand Execute a process on a remote system using Win32_Process Create, optionally with alternate credentials. PowerShellRemotingGrunt Execute a Grunt Launcher on a remote system using PowerShell Remoting, optionally with alternate credentials. PowerShellRemotingCommand Execute a PowerShell command on a remote system using PowerShell Remoting, optionally with alternate credentials. DCOMGrunt Execute a Grunt Launcher on a remote system using various DCOM methods. DCOMCommand Execute a process on a remote system using various DCOM methods. PersistStartup Installs a payload into the current users startup folder. Payload: Payload to write to a file. E.g. "powershell -Sta -Nop -Window Hidden -EncodedCommand <blah>". FileName: Name of the file to write. E.g. "startup.bat". PersistCOMHijack Hijacks a CLSID key to execute a payload for persistence. PersistWMI Creates a WMI Event, Consumer and Binding to execute a payload. PersistAutorun Installs an autorun value in HKCU or HKLM to execute a payload. TargetHive: Target hive to install autorun. Specify "CurrentUser" for HKCU and "LocalMachine" for HKLM. Value: Value to set in the registry. E.g. "C:\Example\GruntStager.exe" Name: Name for the registy value.E.g. "Updater". PrivExchange Performs the PrivExchange attack by sending a push notification to EWS. |
Y hasta aquí todo por hoy, espero que les sirva de ayuda en sus ctf, pentesting, etc… y gracias por leernos. Como siempre cualquier duda o aportación es bienvenida en la sección de comentarios.