0x00 Preface

---

Covenant is a .NET-developed C2 (command and control) framework that utilizes the .NET Core development environment, supporting not only Linux, macOS, and Windows but also Docker containers.

Its most distinctive feature is support for dynamic compilation, enabling the upload of input C# code to the C2 Server, obtaining the compiled file, and loading it from memory using Assembly.Load().

This article solely introduces the details of Covenant and analyzes its characteristics from a technical research perspective.

0x01 Introduction

---

This article will cover the following:

  • Covenant Startup Methods
  • Covenant Feature Introduction
  • Covenant Advantages
  • Covenant Detection

0x02 Covenant Startup Methods

---

1. Windows System

Requires installation of corresponding versions of .NET Core, ASP.NET Core, and SDK

Testing shows Covenant requires .NET Core 2.2.0, ASP.NET Core 2.2.0, and SDK 2.2.101; other versions will cause errors

Download links:

https://dotnet.microsoft.com/download/thank-you/dotnet-sdk-2.2.101-windows-x64-installer

https://dotnet.microsoft.com/download/thank-you/dotnet-runtime-2.2.0-windows-x64-installer

https://dotnet.microsoft.com/download/thank-you/dotnet-runtime-2.2.0-windows-x64-asp.net-core-runtime-installer

Install Git for Windows

https://github.com/git-for-windows/git/releases/download/v2.23.0.windows.1/Git-2.23.0-64-bit.exe

Download and launch:

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

Access https://localhost:7443 to enter the control panel; user registration is required for first-time use

Multiple users can be registered here to enable team collaboration

Note:

Elite is a command-line program for interacting with the Covenant server, which is currently temporarily deprecated. Address:

https://github.com/cobbr/Elite

0x03 Introduction to Covenant Features

---

For the features supported by Covenant, refer to:

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

Here, only the parts considered more important are introduced

1. Listeners

Only HTTP protocol is supported, allowing specification of URLs and communication message formats

Select Listeners->Profiles, which includes two default configuration templates, as shown in the figure below

Alt text

Multiple HttpUrls can be set in the configuration template; Grunt will randomly select from HttpUrls when connecting back

Note:

Grunt is used for deployment to targets as the controlled endpoint

Both HttpRequest and HttpResponse content can be specified

Configuration template corresponds to source file location: .\Covenant\Covenant\Data\Profiles

2. Launchers

Used to launch Grunt, including the following 9 launch methods:

(1) Binary

.NET assembly, formatted as exe file

(2) PowerShell

Launch Grunt via PowerShell in command line

Store .NET assembly in array, load in memory via Assembly.Load()

Code example:

[Reflection.Assembly]::Load(Data).EntryPoint.Invoke(0,$a.ToArray())

(3) MSBuild

Launch Grunt via msbuild in command line

Launch command example:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe GruntStager.xml

Save the .NET assembly in an array and load it in memory via Assembly.Load()

Code example:

System.Reflection.Assembly.Load(oms.ToArray()).EntryPoint.Invoke(0, new object[] { new string[]{ } });

For usage of msbuild, refer to the previous article 'Use MSBuild To Do More'

(4) InstallUtil

Launch Grunt via InstallUtil from the command line

Note:

A bug occurred during my testing here, generating a file named GruntStager.xml containing the base64-encrypted .NET assembly

Based on my understanding of InstallUtil's usage, a .cs file should be generated here

Check the Covenant source code, the template generation source location: .\Covenant\Covenant\Models\Launchers\InstallUtilLauncher.cs

Corresponding link:

https://github.com/cobbr/Covenant/blob/master/Covenant/Models/Launchers/InstallUtilLauncher.cs

The template includes the content of the .cs file, as shown in the figure below

Alt text

Here you can save the content of CodeTemplate as a .cs file, replace "{{GRUNT_IL_BYTE_STRING}}" with a base64-encrypted .NET assembly, and finally save it as test.cs

Example startup command:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /unsafe /out::file.dll test.cs
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U file.dll

(5) Wmic

Example startup command:

wmic os get /format:"file.xsl"

Note:

Covenant indicates here that this method may not work on Windows 10 and Windows Server 2016

Save the .NET assembly in an array and load it in memory via the DotNetToJScript method

Code example:

var o = delegate.DynamicInvoke(array.ToArray()).CreateInstance('Grunt.GruntStager');

For usage of Wmic, refer to the previous article 'Analysis and Utilization of Calling XSL Files via Wmic'

(6) Regsvr32

Example startup command:

regsvr32 /u /s /i:file.sct scrobj.dll

Note:

Covenant notes here that this method may not work on Windows 10 and Windows Server 2016

Save the .NET assembly in an array and load it in memory via the DotNetToJScript method

For usage of Regsvr32, refer to the previous article "Use SCT to Bypass Application Whitelisting Protection"

(7) Mshta

Start command example:

mshta file.hta

Note:

Covenant notes here that this method may not work on Windows 10 and Windows Server 2016

Save the .NET assembly in an array and load it in memory via the DotNetToJScript method

For usage of Mshta, refer to the previous article "Penetration Techniques - Multiple Methods for Downloading Files from GitHub"

(8) Cscript

Start command example:

cscript file.js

DotNetToJScript is utilized here, other content remains the same as above

(9) Wscript

Start command example:

wscript file.js

DotNetToJScript is utilized here, other content remains the same as above

All 9 startup methods above can choose from the following two templates:

(1) GruntHTTP

Communicates with C2 server using HTTP protocol

After execution, establishes reverse connection to C2 server

The following parameters can be set:

  • ValidateCert
  • UseCertPinning
  • Delay
  • JitterPercent
  • ConnectAttempts
  • KillDate
  • DotNetFrameworkVersion

(2)GruntSMB

Uses named pipes, does not communicate directly with the C2 server, but communicates between various Grunts

After execution, creates a named pipe on the local machine, which can be remotely connected to by other Grunts

Here is an additional configuration parameter:

SMBPipeName

Usage example:

GruntSMB is for internal network use and can be activated by other Grunts. Activation method:

Grunt:->Task->Connect

As shown in the figure below

Alt text

3.Grunts

List of all Grunts, control commands can be sent to Grunts

(1)Info

Basic information about Grunt

(2) Interact

Command-line control interface

(3) Task

Features supported by Grunt, with multiple built-in open-source tools:

  • Rubeus
  • Seatbelt
  • SharpDPAPI
  • SharpDump
  • SharpSploit
  • SharpUp
  • SharpWMI

(4) Taskings

Record the execution status of each command

4. Templates

Grunt's template files, which by default include GruntHTTP and GruntSMB

Here you can modify template files or add new ones

5.Tasks

Task template files, as features supported by Grunt, include multiple built-in open-source tools:

  • Rubeus
  • Seatbelt
  • SharpDPAPI
  • SharpDump
  • SharpSploit
  • SharpUp
  • SharpWMI

Here you can modify template files or add new ones

6.Taskings

Records all command execution statuses of Grunts

7.Graph

Graphical page displaying the connection relationships between Grunt and Listener

8.Data

Display valuable information obtained from Grunt

9.Users

Manage logged-in users for team collaboration

0x04 Advantages of Covenant

---

1.C2 Server supports multiple platforms

C2 Server supports not only Linux, macOS, and Windows but also Docker containers

2.High scalability

Customizable communication protocols, startup methods, and functionalities

3.Extended functionalities can be executed directly in memory

Through dynamic compilation, the C2 Server can dynamically compile code and send it to the target, then load it from memory using Assembly.Load()

4.Supports intranet communication with unified traffic egress

Communication between controlled endpoints within the intranet is conducted via named pipes, unifying traffic egress and hiding communication channels

5. Facilitates team collaboration

Supports multiple users, enabling resource sharing

0x05 Covenant Detection

---

1. Detecting .NET assembly execution

Because it requires the Rosyln C# compiler, it references the Microsoft.CodeAnalysis assembly

Here, you can attempt to collect .NET events from specified processes, reference script:

https://gist.github.com/cobbr/1bab9e175ebbc6ff93cc5875c69ecc50

2. Detecting named pipe usage

Detecting traffic from remote connections via named pipes

Remote connections via named pipes generate logs with Event ID 18, reference address:

https://github.com/hunters-forge/OSSEM/blob/master/data_dictionaries/windows/sysmon/event-18.md

3. HTTP communication traffic

The default communication template has identifiable characteristics, as shown in the image below

Alt text

0x06 Summary

---

This article details Covenant, analyzes its features, and highlights its high scalability, making it very convenient for secondary development.