So we'll start really slow with some basic concepts,
like to use Covenant, you need to install Covenant.
So unlike some other projects,
the installation of Covenant is pretty well documented.
Browsing to the GitHub for the project located here,
there is a wiki for the installation.
The wiki covers two different options for installation.
One benefit of using .NET Core is that this collaborative server
can run on any platform that you need it to,
and the instructions for building the .NET project are included under Option 1.
Option 2, and arguably the easier of the two options to spin up quickly,
is to build and use a Docker container,
and that's exactly what I'm going to walk you through in this demo.
I'm going to show you the installation of Kali Linux here,
and this is kind of a standard for red team'rs,
though I'm not specifically tied to it.
I'm more of a fan of creating your own builds once you know what tools you like,
but Kali Linux is pretty ubiquitous in this space and kind of the go‑to for
something where I want you to be able to follow along with me.
It is a Debian‑based Linux and settings you use on Kali
Linux will apply across other Debian builds,
like Ubuntu, as well.
Of course,
the first step for this is to make sure that you have Docker installed.
If not, the name of the project is actually docker.io within the repositories,
and it can be installed with apt‑get install docker.io.
And if you don't use the io, it will install a completely different service,
which can get confusing.
Following the instructions for installation at the terminal,
run the git command, including the settings for the recursive modules.
This is going to download and initialize the sub‑modules required for
the operation of the project into the data folder.
Change directories into the inner Covenant folder,
or the second level of the Covenant, if you will.
It's two directories deep and the contents look like this.
More importantly, you can see the Dockerfile is here,
and that is what you will be using to build the Docker image.
Once there,
run the docker build command using ‑t for the name, and if the
working directory you're in is in fact the same directory that has
the Dockerfile in it, just use the period character here to
indicate the path to the Dockerfile.
Don't forget to use sudo and go ahead and execute the build of the image.
This build process wraps up the Covenant project code and
all the required libraries and environment setup for the
.NET project all into one image.
And once it's complete, you are ready to run a container based on this image.
The command in the documentation works great,
but first make sure that you understand the flags that are being
used so you can modify it to work best in your environment, or
later for different types of listeners,
The ‑p flag is used to tie ports on the localhost to ports exposed in the
Docker container that is running the Covenant application.
Port 7443 is required because it's the access to the
admin portal for the Covenant.
However,
80 and 443 are just the default for callbacks from implants, called grunts in
this context. If you want to call back to a different port,
maybe 53 to simulate DNS or 22 for SSH,
you need to expose those ports with a separate ‑p flag. The ‑v command
will bind the files and folders inside the container to the files and
folders on the host. For the Covenant container to run properly, you have
to share the data folder located on the host with the internal app/Data
folder for the application.
If you have an error that mentions the sub‑modules,
either this folder is not referenced correctly,
and I recommend using the full path here, or the
modules that were indeed not initialized.
With proper execution of the container in interactive mode,
it will show you the application is listening on port 7443
that was exposed in the run command.
And that's that for the installation.
Now, open up a browser and browse to that portal at
that address for the first time.
Remember, it is going to be hosted on HTTPS,
so type accordingly and you'll reach the screen asking
for the registration of the first user.
Enter a username and password, keeping in mind that this is only
going to happen for the first user. After this,
the users will need to be created by an existing
administrator. If you check out the dashboard,
you'll see that it's empty and you have a lot of work
to do to get some connections going.
Grunts will be displayed here after the appropriate code is executed on the
exploited machines and calls back to an active listener.
There are currently no listeners, so even if you had grunts calling back,
it wouldn't matter.
Tasks, as the name implies,
shows any current taskings out to the grunts. To quickly
go over the panel to the left, the whole process starts
with having listeners set up.
Then you need launchers to execute on the exploited devices
that create the implant called grunts that call back and
connect in through the listeners.
If you are familiar with other C2 frameworks like PoshC2,
PowerShell Empire or Cobalt Strike,
these concepts with this workflow are essentially the same.
Templates provide a baseline for implants that can be used with
different types of listeners and provide you the capability to
create your own, as well as view and edit the code that's used for
each one of the included templates.
When grunts are connected,
you can execute different tasks through that connection.
The Tasks panel provides a transparent look at exactly what
each one of those tasks does and how, and it allows you to modify them.
This level of customization allows you to change your footprint to
evade detections, or in the case of emulation,
simulate a specific group's tactics. The Taskings show currently queued
tasks, and Graph shows the connections between the listeners,
HTTP connections, and subsequent pivots through SMB. And the Data view will
populate as you collect data from compromised systems.
So that's enough of an overview for me. And you can't see two systems
with sweet APT tactics unless you first compromise a system and gain
the ability to remotely execute code.
So, I'll give you a few moments to knock that out.
And if this is your own network,
then you can simply just execute the command with a legitimate login.
Okay, time's up.
I'm sure that was plenty of time to gather vulnerability information, develop
an exploit, and successfully gain a shell into a system that you're working
on as a red team, or you simply wrote an email and you're going to use one of
those launchers as an attachment.
And that's fine, too.
We all know that no one can resist the early access
to Baby Yoda plush doll link.
Well played you cyber phishing mastermind.
But before you click send,
you need to set up a listener. In the Listeners pane, notice the Profiles tab.
All listeners will use profiles,
and if you have used or heard of Malleable C2, this is the same idea,
and each profile can be customized or you can create your
own. Covenant supports two bridge types.
The first is the native, currently supported HTTP Bridge,
which also supports SSL connections.
And the second bridge listener is a custom encrypted TCP connection.
These are the connections from the grunts inside the
network back out to the Covenant server,
and it does not apply to the SMB connections between grunts.
A quick look at the HTTP custom profile, and you can see that you can change
nearly every behavior that could be used for detection.
The URLs, the way it transforms messages for transmission, the user agents,
response headers, and post and get responses as well.
The TCP bridges are just as customizable,
but simply with less variables to change in the first place because it's just
a simple TCP connection. To create a listener, click the Create button and
choose the listener type that you want to use.
I'm using the HTTP listener for this course, but I highly recommend using a
valid SSL certificate to turn this into an HTTPS connection and ensuring
that you have a registered domain that's not going to be on any sort of
block list for production operations.
The other options that you may have identified some
specific custom traffic that you can blend in with and use
the TCP bridge for that purpose.
There's two things to remember.
The first is that unless you can change the message transformation,
the messages between the server and the grunt will be Base64
encoded and easily decoded by defenders.
Second is that when you are setting the bind ports
while using the Covenant within Docker,
you have to make sure that you added these ports within the docker
run command when you originally ran the container. The bind address
in the port is used to reference the specific interface in the port
the C2 bridge will connect to.
The connect address and port is the location that the grunts will
call back to when they are launched on an exploited system. Because
I ran the Docker container with binds to port 80, I'm using the 80
port as the connect port,
and I will be changing the connect address to the address of the host and
sticking with the default HTTP bridge profile. For production, instead of
using the IP, you would change this to the domain name URL as long as it
resolves through DNS within the environment.
Next,
we need to create a grunt launcher that is tied to the listener. In
the Launchers pane, you have various options.
Note that the binary option is the only option that does not require the use
of system binaries available on the compromised system.
You can generate various types of scripts,
including VBA and JScript,
to embed in the documents, use PowerShell and WMIC or
various built‑in Microsoft binaries. All great, known ways
to get around endpoint protections.
I'm simply going to use the binary file here,
but highly recommend looking through each of the other options for ways to evade
protections. Like anything from an offensive perspective, you want to avoid
signature detection, and the best way to do that is to customize these launchers
yourself. Inside the Binary Launcher menu, I'm going to choose the listener that
I'm creating the launcher for,
and each listener is going to require a different grunt to be created.
Now, you have a weaponized payload that will reach back out to
your Covenant C2 server. All you have to do is get some
schmuck user to click it, and boom,
you get your first grunt callback. And this is generally where you're going to
spend most of your time, interacting and managing each grunt,
spreading your creep, and pulling down creds in data. Diving into
the context of your first HTTP grunt callback.
You get all the info from the device it is running on that you would expect,
and most importantly, the username and context under which it's running.
You can interact directly with the grunt to send commands like
who am I that will execute a task and provide the output back to
you, like so. Or you can just choose a task from many in the
drop‑down to get information,
execute Kerberos‑based attacks on authentication or
attempt to execute grunts on other devices.
The list is long,
so you're going to have to explore all of that yourself, but
many of the SharpSploit and other tools that have been ported
to .NET execution are included.
No reason to start leaving PowerShell traces everywhere now. This is where
you really get to show off your OpSec chops and restraint.
Every action here has a consequence that could get you caught
depending on your environment, so task responsibly.
So what now?
Well, for me,
I always like to draw things out to get a graphical idea of where I am in the
space and what I want to do next, and the Graph view does just that. The
listeners are red and you have one HTTP grunt connected.
The common practice would be to use one or two HTTP, DNS or HTTPS connectors to
connect out to your C2 server and then pivot to other devices internally through
those HTTP connected machines using SMB pipes, and that's exactly what you're
going to do here. Back in Launchers, you create an SMB launcher in any form that
will work for the environment.
Then, you can use one of the various remoting capabilities through the
HTTP listener to execute the SMB grunt payload. Once that's complete,
within the desired HTTP pivot grunt, select the Connect task. Here, you're
going to supply the IP of the machine on which the SMB grunt launcher was
executed and use the name pipe that was specified in the creation of the
launcher to connect.
Once this is executed,
you can move back to the Grunt pane and watch the new grunt
connect back and progress through the stages,
finalizing in an active C#,
dynamically compiled grunt, in memory of the system with all
the same capabilities as the HTTP listener.
From an emulation perspective,
this is the activity that you're going to want to generate throughout your
environment and then test the internal detection capability.
And you can see the connections and the way that you spread
through a network back in the Graph view.
Now it wouldn't be a proper red team engagement if you didn't at
least run some version of Mimikatz on the system.
And yes,
that is one of the tasks. In the SMB grunt, you can assign the Mimikatz task,
then check in the Taskings pane for the output of the command.
And sure enough,
you get the familiar LSA dump that we've all seen. A little
sparse on creds, but a few floating around in there. But to see
the loot in a more organized way, you can now look through the Data pane.
Here, you're going to find stolen credentials organized by type,
including the NTLM hash of my Microsoft demo account, which no,
you don't get to see that.
Wouldn't that be great?
The security guy was giving you the NTLM hash of the Microsoft login account.
Well, not today you evildoers.
I thwarted you using an excellent technique called fuzzy
pixelation. With all that moving around,
you certainly have some tracks defined on the systems and in the network
traffic, and the Indicators tab keeps track of those indicators,
including computer names,
network addresses used, and files ran as part of the red team operation,
which is perfect for training a blue team or testing a detection
capability, as well as just having an understanding of your footprint as
the Red Team Operator. The dashboard that was once empty is now completely
full and gives you the heads up information,
including the active grunts, listeners, and tasks.
The real power in a collaborative platform like this is the collaboration, so
you can imagine how helpful all this information and data collection
capability is when you have more than one operator all working off the same
platform with the same information in real time.