[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$ft1hZ6TUDwcL6bO-I5-vlfbF_dzGCiEzFbdYeQ05OgoA":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":34,"aiModel":39,"aiConfidence":39,"updatedAt":52,"createdAt":52,"_status":51},822,"What is Covenant and what makes it stand out among C2 frameworks?","Covenant is a .NET-developed C2 framework that runs on Linux, macOS, Windows, and Docker. Its most distinctive feature is support for dynamic compilation, allowing operators to upload C# code to the C2 server, which compiles it and loads the resulting assembly into memory via Assembly.Load(). This enables highly customizable in-memory payloads for defense evasion. Read more about its specifics in [Covenant Utilization Analysis](\u002Fnews\u002Fcovenant-utilization-analysis).","\u003Cp>Covenant is a .NET-developed C2 framework that runs on Linux, macOS, Windows, and Docker. Its most distinctive feature is support for dynamic compilation, allowing operators to upload C# code to the C2 server, which compiles it and loads the resulting assembly into memory via Assembly.Load(). This enables highly customizable in-memory payloads for defense evasion. Read more about its specifics in [Covenant Utilization Analysis](\u002Fnews\u002Fcovenant-utilization-analysis).\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fcovenant-utilization-analysis\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","what-is-covenant-and-what-makes-it-stand-out-among-c2-frameworks-1777481500851","Covenant, C2 framework, dynamic compilation, Assembly.Load, defense evasion",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":30,"cover":31,"author":32,"views":19,"readingTime":33,"status":34,"publishedAt":35,"seo":36,"tags":41,"qaPairs":42,"meta":48,"updatedAt":49,"createdAt":50,"_status":51},202,"Covenant Utilization Analysis","covenant-utilization-analysis","Explore Covenant, a .NET-based C2 framework with dynamic compilation, setup guides for Windows, key features like Listeners and Launchers, and detection insights.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>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.\u003C\u002Fp>\u003Cp>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().\u003C\u002Fp>\u003Cp>This article solely introduces the details of Covenant and analyzes its characteristics from a technical research perspective.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Covenant Startup Methods\u003C\u002Fli>\u003Cli>Covenant Feature Introduction\u003C\u002Fli>\u003Cli>Covenant Advantages\u003C\u002Fli>\u003Cli>Covenant Detection\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Covenant Startup Methods\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Windows System\u003C\u002Fh3>\u003Cp>Requires installation of corresponding versions of .NET Core, ASP.NET Core, and SDK\u003C\u002Fp>\u003Cp>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\u003C\u002Fp>\u003Cp>Download links:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdotnet.microsoft.com\u002Fdownload\u002Fthank-you\u002Fdotnet-sdk-2.2.101-windows-x64-installer\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdotnet.microsoft.com\u002Fdownload\u002Fthank-you\u002Fdotnet-runtime-2.2.0-windows-x64-installer\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdotnet.microsoft.com\u002Fdownload\u002Fthank-you\u002Fdotnet-runtime-2.2.0-windows-x64-asp.net-core-runtime-installer\u003C\u002Fp>\u003Cp>Install Git for Windows\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fgit-for-windows\u002Fgit\u002Freleases\u002Fdownload\u002Fv2.23.0.windows.1\u002FGit-2.23.0-64-bit.exe\u003C\u002Fp>\u003Cp>Download and launch:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>git clone --recurse-submodules https:\u002F\u002Fgithub.com\u002Fcobbr\u002FCovenant\u003Cbr>cd Covenant\u002FCovenant\u003Cbr>dotnet build\u003Cbr>dotnet run\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Access https:\u002F\u002Flocalhost:7443 to enter the control panel; user registration is required for first-time use\u003C\u002Fp>\u003Cp>Multiple users can be registered here to enable team collaboration\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Elite is a command-line program for interacting with the Covenant server, which is currently temporarily deprecated. Address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fcobbr\u002FElite\u003C\u002Fp>\u003Ch2>0x03 Introduction to Covenant Features\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>For the features supported by Covenant, refer to:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fcobbr\u002FCovenant\u002Fwiki\u003C\u002Fp>\u003Cp>Here, only the parts considered more important are introduced\u003C\u002Fp>\u003Ch3>1. Listeners\u003C\u002Fh3>\u003Cp>Only HTTP protocol is supported, allowing specification of URLs and communication message formats\u003C\u002Fp>\u003Cp>Select Listeners-&gt;Profiles, which includes two default configuration templates, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017261117_0_64fa06a51b.jpeg\">\u003C\u002Fp>\u003Cp>Multiple HttpUrls can be set in the configuration template; Grunt will randomly select from HttpUrls when connecting back\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Grunt is used for deployment to targets as the controlled endpoint\u003C\u002Fp>\u003Cp>Both HttpRequest and HttpResponse content can be specified\u003C\u002Fp>\u003Cp>Configuration template corresponds to source file location: .\\Covenant\\Covenant\\Data\\Profiles\u003C\u002Fp>\u003Ch3>2. Launchers\u003C\u002Fh3>\u003Cp>Used to launch Grunt, including the following 9 launch methods:\u003C\u002Fp>\u003Ch4>(1) Binary\u003C\u002Fh4>\u003Cp>.NET assembly, formatted as exe file\u003C\u002Fp>\u003Ch4>(2) PowerShell\u003C\u002Fh4>\u003Cp>Launch Grunt via PowerShell in command line\u003C\u002Fp>\u003Cp>Store .NET assembly in array, load in memory via Assembly.Load()\u003C\u002Fp>\u003Cp>Code example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>[Reflection.Assembly]::Load(Data).EntryPoint.Invoke(0,$a.ToArray())\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>(3) MSBuild\u003C\u002Fh4>\u003Cp>Launch Grunt via msbuild in command line\u003C\u002Fp>\u003Cp>Launch command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\msbuild.exe GruntStager.xml\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Save the .NET assembly in an array and load it in memory via Assembly.Load()\u003C\u002Fp>\u003Cp>Code example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>System.Reflection.Assembly.Load(oms.ToArray()).EntryPoint.Invoke(0, new object[] { new string[]{ } });\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For usage of msbuild, refer to the previous article 'Use MSBuild To Do More'\u003C\u002Fp>\u003Ch4>(4) InstallUtil\u003C\u002Fh4>\u003Cp>Launch Grunt via InstallUtil from the command line\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>A bug occurred during my testing here, generating a file named GruntStager.xml containing the base64-encrypted .NET assembly\u003C\u002Fp>\u003Cp>Based on my understanding of InstallUtil's usage, a .cs file should be generated here\u003C\u002Fp>\u003Cp>Check the Covenant source code, the template generation source location: .\\Covenant\\Covenant\\Models\\Launchers\\InstallUtilLauncher.cs\u003C\u002Fp>\u003Cp>Corresponding link:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fcobbr\u002FCovenant\u002Fblob\u002Fmaster\u002FCovenant\u002FModels\u002FLaunchers\u002FInstallUtilLauncher.cs\u003C\u002Fp>\u003Cp>The template includes the content of the .cs file, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017285977_1_c28bf2e43c.jpeg\">\u003C\u002Fp>\u003Cp>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\u003C\u002Fp>\u003Cp>Example startup command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe \u002Funsafe \u002Fout::file.dll test.cs\u003Cbr>C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\InstallUtil.exe \u002Flogfile= \u002FLogToConsole=false \u002FU file.dll\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>(5) Wmic\u003C\u002Fh4>\u003Cp>Example startup command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic os get \u002Fformat:\"file.xsl\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Covenant indicates here that this method may not work on Windows 10 and Windows Server 2016\u003C\u002Fp>\u003Cp>Save the .NET assembly in an array and load it in memory via the DotNetToJScript method\u003C\u002Fp>\u003Cp>Code example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>var o = delegate.DynamicInvoke(array.ToArray()).CreateInstance('Grunt.GruntStager');\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For usage of Wmic, refer to the previous article 'Analysis and Utilization of Calling XSL Files via Wmic'\u003C\u002Fp>\u003Ch4>(6) Regsvr32\u003C\u002Fh4>\u003Cp>Example startup command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>regsvr32 \u002Fu \u002Fs \u002Fi:file.sct scrobj.dll\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Covenant notes here that this method may not work on Windows 10 and Windows Server 2016\u003C\u002Fp>\u003Cp>Save the .NET assembly in an array and load it in memory via the DotNetToJScript method\u003C\u002Fp>\u003Cp>For usage of Regsvr32, refer to the previous article \"Use SCT to Bypass Application Whitelisting Protection\"\u003C\u002Fp>\u003Ch4>(7) Mshta\u003C\u002Fh4>\u003Cp>Start command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>mshta file.hta\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Covenant notes here that this method may not work on Windows 10 and Windows Server 2016\u003C\u002Fp>\u003Cp>Save the .NET assembly in an array and load it in memory via the DotNetToJScript method\u003C\u002Fp>\u003Cp>For usage of Mshta, refer to the previous article \"Penetration Techniques - Multiple Methods for Downloading Files from GitHub\"\u003C\u002Fp>\u003Ch4>(8) Cscript\u003C\u002Fh4>\u003Cp>Start command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>cscript file.js\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>DotNetToJScript is utilized here, other content remains the same as above\u003C\u002Fp>\u003Ch4>(9) Wscript\u003C\u002Fh4>\u003Cp>Start command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wscript file.js\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>DotNetToJScript is utilized here, other content remains the same as above\u003C\u002Fp>\u003Cp>All 9 startup methods above can choose from the following two templates:\u003C\u002Fp>\u003Ch4>(1) GruntHTTP\u003C\u002Fh4>\u003Cp>Communicates with C2 server using HTTP protocol\u003C\u002Fp>\u003Cp>After execution, establishes reverse connection to C2 server\u003C\u002Fp>\u003Cp>The following parameters can be set:\u003C\u002Fp>\u003Cul>\u003Cli>ValidateCert\u003C\u002Fli>\u003Cli>UseCertPinning\u003C\u002Fli>\u003Cli>Delay\u003C\u002Fli>\u003Cli>JitterPercent\u003C\u002Fli>\u003Cli>ConnectAttempts\u003C\u002Fli>\u003Cli>KillDate\u003C\u002Fli>\u003Cli>DotNetFrameworkVersion\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>(2)GruntSMB\u003C\u002Fh4>\u003Cp>Uses named pipes, does not communicate directly with the C2 server, but communicates between various Grunts\u003C\u002Fp>\u003Cp>After execution, creates a named pipe on the local machine, which can be remotely connected to by other Grunts\u003C\u002Fp>\u003Cp>Here is an additional configuration parameter:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SMBPipeName\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Usage example:\u003C\u002Fp>\u003Cp>GruntSMB is for internal network use and can be activated by other Grunts. Activation method:\u003C\u002Fp>\u003Cp>Grunt:\u003Cid>-&gt;Task-&gt;Connect\u003C\u002Fid>\u003C\u002Fp>\u003Cp>As shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017317153_2_d7a44279f6.jpeg\">\u003C\u002Fp>\u003Ch3>3.Grunts\u003C\u002Fh3>\u003Cp>List of all Grunts, control commands can be sent to Grunts\u003C\u002Fp>\u003Ch4>(1)Info\u003C\u002Fh4>\u003Cp>Basic information about Grunt\u003C\u002Fp>\u003Ch4>(2) Interact\u003C\u002Fh4>\u003Cp>Command-line control interface\u003C\u002Fp>\u003Ch4>(3) Task\u003C\u002Fh4>\u003Cp>Features supported by Grunt, with multiple built-in open-source tools:\u003C\u002Fp>\u003Cul>\u003Cli>Rubeus\u003C\u002Fli>\u003Cli>Seatbelt\u003C\u002Fli>\u003Cli>SharpDPAPI\u003C\u002Fli>\u003Cli>SharpDump\u003C\u002Fli>\u003Cli>SharpSploit\u003C\u002Fli>\u003Cli>SharpUp\u003C\u002Fli>\u003Cli>SharpWMI\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>(4) Taskings\u003C\u002Fh4>\u003Cp>Record the execution status of each command\u003C\u002Fp>\u003Ch3>4. Templates\u003C\u002Fh3>\u003Cp>Grunt's template files, which by default include GruntHTTP and GruntSMB\u003C\u002Fp>\u003Cp>Here you can modify template files or add new ones\u003C\u002Fp>\u003Ch3>5.Tasks\u003C\u002Fh3>\u003Cp>Task template files, as features supported by Grunt, include multiple built-in open-source tools:\u003C\u002Fp>\u003Cul>\u003Cli>Rubeus\u003C\u002Fli>\u003Cli>Seatbelt\u003C\u002Fli>\u003Cli>SharpDPAPI\u003C\u002Fli>\u003Cli>SharpDump\u003C\u002Fli>\u003Cli>SharpSploit\u003C\u002Fli>\u003Cli>SharpUp\u003C\u002Fli>\u003Cli>SharpWMI\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Here you can modify template files or add new ones\u003C\u002Fp>\u003Ch3>6.Taskings\u003C\u002Fh3>\u003Cp>Records all command execution statuses of Grunts\u003C\u002Fp>\u003Ch3>7.Graph\u003C\u002Fh3>\u003Cp>Graphical page displaying the connection relationships between Grunt and Listener\u003C\u002Fp>\u003Ch3>8.Data\u003C\u002Fh3>\u003Cp>Display valuable information obtained from Grunt\u003C\u002Fp>\u003Ch3>9.Users\u003C\u002Fh3>\u003Cp>Manage logged-in users for team collaboration\u003C\u002Fp>\u003Ch2>0x04 Advantages of Covenant\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1.C2 Server supports multiple platforms\u003C\u002Fh3>\u003Cp>C2 Server supports not only Linux, macOS, and Windows but also Docker containers\u003C\u002Fp>\u003Ch3>2.High scalability\u003C\u002Fh3>\u003Cp>Customizable communication protocols, startup methods, and functionalities\u003C\u002Fp>\u003Ch3>3.Extended functionalities can be executed directly in memory\u003C\u002Fh3>\u003Cp>Through dynamic compilation, the C2 Server can dynamically compile code and send it to the target, then load it from memory using Assembly.Load()\u003C\u002Fp>\u003Ch3>4.Supports intranet communication with unified traffic egress\u003C\u002Fh3>\u003Cp>Communication between controlled endpoints within the intranet is conducted via named pipes, unifying traffic egress and hiding communication channels\u003C\u002Fp>\u003Ch3>5. Facilitates team collaboration\u003C\u002Fh3>\u003Cp>Supports multiple users, enabling resource sharing\u003C\u002Fp>\u003Ch2>0x05 Covenant Detection\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Detecting .NET assembly execution\u003C\u002Fh3>\u003Cp>Because it requires the Rosyln C# compiler, it references the Microsoft.CodeAnalysis assembly\u003C\u002Fp>\u003Cp>Here, you can attempt to collect .NET events from specified processes, reference script:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgist.github.com\u002Fcobbr\u002F1bab9e175ebbc6ff93cc5875c69ecc50\u003C\u002Fp>\u003Ch3>2. Detecting named pipe usage\u003C\u002Fh3>\u003Cp>Detecting traffic from remote connections via named pipes\u003C\u002Fp>\u003Cp>Remote connections via named pipes generate logs with Event ID 18, reference address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fhunters-forge\u002FOSSEM\u002Fblob\u002Fmaster\u002Fdata_dictionaries\u002Fwindows\u002Fsysmon\u002Fevent-18.md\u003C\u002Fp>\u003Ch3>3. HTTP communication traffic\u003C\u002Fh3>\u003Cp>The default communication template has identifiable characteristics, as shown in the image below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017360634_3_fbd3a0688b.jpeg\">\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article details Covenant, analyzes its features, and highlights its high scalability, making it very convenient for secondary development.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>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.\u003C\u002Fp>\u003Cp>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().\u003C\u002Fp>\u003Cp>This article solely introduces the details of Covenant and analyzes its characteristics from a technical research perspective.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Covenant Startup Methods\u003C\u002Fli>\u003Cli>Covenant Feature Introduction\u003C\u002Fli>\u003Cli>Covenant Advantages\u003C\u002Fli>\u003Cli>Covenant Detection\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Covenant Startup Methods\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Windows System\u003C\u002Fh3>\u003Cp>Requires installation of corresponding versions of .NET Core, ASP.NET Core, and SDK\u003C\u002Fp>\u003Cp>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\u003C\u002Fp>\u003Cp>Download links:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdotnet.microsoft.com\u002Fdownload\u002Fthank-you\u002Fdotnet-sdk-2.2.101-windows-x64-installer\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdotnet.microsoft.com\u002Fdownload\u002Fthank-you\u002Fdotnet-runtime-2.2.0-windows-x64-installer\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdotnet.microsoft.com\u002Fdownload\u002Fthank-you\u002Fdotnet-runtime-2.2.0-windows-x64-asp.net-core-runtime-installer\u003C\u002Fp>\u003Cp>Install Git for Windows\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fgit-for-windows\u002Fgit\u002Freleases\u002Fdownload\u002Fv2.23.0.windows.1\u002FGit-2.23.0-64-bit.exe\u003C\u002Fp>\u003Cp>Download and launch:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>git clone --recurse-submodules https:\u002F\u002Fgithub.com\u002Fcobbr\u002FCovenant\u003Cbr>cd Covenant\u002FCovenant\u003Cbr>dotnet build\u003Cbr>dotnet run\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Access https:\u002F\u002Flocalhost:7443 to enter the control panel; user registration is required for first-time use\u003C\u002Fp>\u003Cp>Multiple users can be registered here to enable team collaboration\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Elite is a command-line program for interacting with the Covenant server, which is currently temporarily deprecated. Address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fcobbr\u002FElite\u003C\u002Fp>\u003Ch2>0x03 Introduction to Covenant Features\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>For the features supported by Covenant, refer to:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fcobbr\u002FCovenant\u002Fwiki\u003C\u002Fp>\u003Cp>Here, only the parts considered more important are introduced\u003C\u002Fp>\u003Ch3>1. Listeners\u003C\u002Fh3>\u003Cp>Only HTTP protocol is supported, allowing specification of URLs and communication message formats\u003C\u002Fp>\u003Cp>Select Listeners-&gt;Profiles, which includes two default configuration templates, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017261117_0_64fa06a51b-1.jpeg\">\u003C\u002Fp>\u003Cp>Multiple HttpUrls can be set in the configuration template; Grunt will randomly select from HttpUrls when connecting back\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Grunt is used for deployment to targets as the controlled endpoint\u003C\u002Fp>\u003Cp>Both HttpRequest and HttpResponse content can be specified\u003C\u002Fp>\u003Cp>Configuration template corresponds to source file location: .\\Covenant\\Covenant\\Data\\Profiles\u003C\u002Fp>\u003Ch3>2. Launchers\u003C\u002Fh3>\u003Cp>Used to launch Grunt, including the following 9 launch methods:\u003C\u002Fp>\u003Ch4>(1) Binary\u003C\u002Fh4>\u003Cp>.NET assembly, formatted as exe file\u003C\u002Fp>\u003Ch4>(2) PowerShell\u003C\u002Fh4>\u003Cp>Launch Grunt via PowerShell in command line\u003C\u002Fp>\u003Cp>Store .NET assembly in array, load in memory via Assembly.Load()\u003C\u002Fp>\u003Cp>Code example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>[Reflection.Assembly]::Load(Data).EntryPoint.Invoke(0,$a.ToArray())\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>(3) MSBuild\u003C\u002Fh4>\u003Cp>Launch Grunt via msbuild in command line\u003C\u002Fp>\u003Cp>Launch command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\msbuild.exe GruntStager.xml\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Save the .NET assembly in an array and load it in memory via Assembly.Load()\u003C\u002Fp>\u003Cp>Code example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>System.Reflection.Assembly.Load(oms.ToArray()).EntryPoint.Invoke(0, new object[] { new string[]{ } });\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For usage of msbuild, refer to the previous article 'Use MSBuild To Do More'\u003C\u002Fp>\u003Ch4>(4) InstallUtil\u003C\u002Fh4>\u003Cp>Launch Grunt via InstallUtil from the command line\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>A bug occurred during my testing here, generating a file named GruntStager.xml containing the base64-encrypted .NET assembly\u003C\u002Fp>\u003Cp>Based on my understanding of InstallUtil's usage, a .cs file should be generated here\u003C\u002Fp>\u003Cp>Check the Covenant source code, the template generation source location: .\\Covenant\\Covenant\\Models\\Launchers\\InstallUtilLauncher.cs\u003C\u002Fp>\u003Cp>Corresponding link:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fcobbr\u002FCovenant\u002Fblob\u002Fmaster\u002FCovenant\u002FModels\u002FLaunchers\u002FInstallUtilLauncher.cs\u003C\u002Fp>\u003Cp>The template includes the content of the .cs file, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017285977_1_c28bf2e43c-1.jpeg\">\u003C\u002Fp>\u003Cp>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\u003C\u002Fp>\u003Cp>Example startup command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe \u002Funsafe \u002Fout::file.dll test.cs\u003Cbr>C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\InstallUtil.exe \u002Flogfile= \u002FLogToConsole=false \u002FU file.dll\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>(5) Wmic\u003C\u002Fh4>\u003Cp>Example startup command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic os get \u002Fformat:\"file.xsl\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Covenant indicates here that this method may not work on Windows 10 and Windows Server 2016\u003C\u002Fp>\u003Cp>Save the .NET assembly in an array and load it in memory via the DotNetToJScript method\u003C\u002Fp>\u003Cp>Code example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>var o = delegate.DynamicInvoke(array.ToArray()).CreateInstance('Grunt.GruntStager');\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For usage of Wmic, refer to the previous article 'Analysis and Utilization of Calling XSL Files via Wmic'\u003C\u002Fp>\u003Ch4>(6) Regsvr32\u003C\u002Fh4>\u003Cp>Example startup command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>regsvr32 \u002Fu \u002Fs \u002Fi:file.sct scrobj.dll\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Covenant notes here that this method may not work on Windows 10 and Windows Server 2016\u003C\u002Fp>\u003Cp>Save the .NET assembly in an array and load it in memory via the DotNetToJScript method\u003C\u002Fp>\u003Cp>For usage of Regsvr32, refer to the previous article \"Use SCT to Bypass Application Whitelisting Protection\"\u003C\u002Fp>\u003Ch4>(7) Mshta\u003C\u002Fh4>\u003Cp>Start command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>mshta file.hta\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Covenant notes here that this method may not work on Windows 10 and Windows Server 2016\u003C\u002Fp>\u003Cp>Save the .NET assembly in an array and load it in memory via the DotNetToJScript method\u003C\u002Fp>\u003Cp>For usage of Mshta, refer to the previous article \"Penetration Techniques - Multiple Methods for Downloading Files from GitHub\"\u003C\u002Fp>\u003Ch4>(8) Cscript\u003C\u002Fh4>\u003Cp>Start command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>cscript file.js\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>DotNetToJScript is utilized here, other content remains the same as above\u003C\u002Fp>\u003Ch4>(9) Wscript\u003C\u002Fh4>\u003Cp>Start command example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wscript file.js\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>DotNetToJScript is utilized here, other content remains the same as above\u003C\u002Fp>\u003Cp>All 9 startup methods above can choose from the following two templates:\u003C\u002Fp>\u003Ch4>(1) GruntHTTP\u003C\u002Fh4>\u003Cp>Communicates with C2 server using HTTP protocol\u003C\u002Fp>\u003Cp>After execution, establishes reverse connection to C2 server\u003C\u002Fp>\u003Cp>The following parameters can be set:\u003C\u002Fp>\u003Cul>\u003Cli>ValidateCert\u003C\u002Fli>\u003Cli>UseCertPinning\u003C\u002Fli>\u003Cli>Delay\u003C\u002Fli>\u003Cli>JitterPercent\u003C\u002Fli>\u003Cli>ConnectAttempts\u003C\u002Fli>\u003Cli>KillDate\u003C\u002Fli>\u003Cli>DotNetFrameworkVersion\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>(2)GruntSMB\u003C\u002Fh4>\u003Cp>Uses named pipes, does not communicate directly with the C2 server, but communicates between various Grunts\u003C\u002Fp>\u003Cp>After execution, creates a named pipe on the local machine, which can be remotely connected to by other Grunts\u003C\u002Fp>\u003Cp>Here is an additional configuration parameter:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SMBPipeName\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Usage example:\u003C\u002Fp>\u003Cp>GruntSMB is for internal network use and can be activated by other Grunts. Activation method:\u003C\u002Fp>\u003Cp>Grunt:\u003Cid>-&gt;Task-&gt;Connect\u003C\u002Fid>\u003C\u002Fp>\u003Cp>As shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017317153_2_d7a44279f6-1.jpeg\">\u003C\u002Fp>\u003Ch3>3.Grunts\u003C\u002Fh3>\u003Cp>List of all Grunts, control commands can be sent to Grunts\u003C\u002Fp>\u003Ch4>(1)Info\u003C\u002Fh4>\u003Cp>Basic information about Grunt\u003C\u002Fp>\u003Ch4>(2) Interact\u003C\u002Fh4>\u003Cp>Command-line control interface\u003C\u002Fp>\u003Ch4>(3) Task\u003C\u002Fh4>\u003Cp>Features supported by Grunt, with multiple built-in open-source tools:\u003C\u002Fp>\u003Cul>\u003Cli>Rubeus\u003C\u002Fli>\u003Cli>Seatbelt\u003C\u002Fli>\u003Cli>SharpDPAPI\u003C\u002Fli>\u003Cli>SharpDump\u003C\u002Fli>\u003Cli>SharpSploit\u003C\u002Fli>\u003Cli>SharpUp\u003C\u002Fli>\u003Cli>SharpWMI\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>(4) Taskings\u003C\u002Fh4>\u003Cp>Record the execution status of each command\u003C\u002Fp>\u003Ch3>4. Templates\u003C\u002Fh3>\u003Cp>Grunt's template files, which by default include GruntHTTP and GruntSMB\u003C\u002Fp>\u003Cp>Here you can modify template files or add new ones\u003C\u002Fp>\u003Ch3>5.Tasks\u003C\u002Fh3>\u003Cp>Task template files, as features supported by Grunt, include multiple built-in open-source tools:\u003C\u002Fp>\u003Cul>\u003Cli>Rubeus\u003C\u002Fli>\u003Cli>Seatbelt\u003C\u002Fli>\u003Cli>SharpDPAPI\u003C\u002Fli>\u003Cli>SharpDump\u003C\u002Fli>\u003Cli>SharpSploit\u003C\u002Fli>\u003Cli>SharpUp\u003C\u002Fli>\u003Cli>SharpWMI\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Here you can modify template files or add new ones\u003C\u002Fp>\u003Ch3>6.Taskings\u003C\u002Fh3>\u003Cp>Records all command execution statuses of Grunts\u003C\u002Fp>\u003Ch3>7.Graph\u003C\u002Fh3>\u003Cp>Graphical page displaying the connection relationships between Grunt and Listener\u003C\u002Fp>\u003Ch3>8.Data\u003C\u002Fh3>\u003Cp>Display valuable information obtained from Grunt\u003C\u002Fp>\u003Ch3>9.Users\u003C\u002Fh3>\u003Cp>Manage logged-in users for team collaboration\u003C\u002Fp>\u003Ch2>0x04 Advantages of Covenant\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1.C2 Server supports multiple platforms\u003C\u002Fh3>\u003Cp>C2 Server supports not only Linux, macOS, and Windows but also Docker containers\u003C\u002Fp>\u003Ch3>2.High scalability\u003C\u002Fh3>\u003Cp>Customizable communication protocols, startup methods, and functionalities\u003C\u002Fp>\u003Ch3>3.Extended functionalities can be executed directly in memory\u003C\u002Fh3>\u003Cp>Through dynamic compilation, the C2 Server can dynamically compile code and send it to the target, then load it from memory using Assembly.Load()\u003C\u002Fp>\u003Ch3>4.Supports intranet communication with unified traffic egress\u003C\u002Fh3>\u003Cp>Communication between controlled endpoints within the intranet is conducted via named pipes, unifying traffic egress and hiding communication channels\u003C\u002Fp>\u003Ch3>5. Facilitates team collaboration\u003C\u002Fh3>\u003Cp>Supports multiple users, enabling resource sharing\u003C\u002Fp>\u003Ch2>0x05 Covenant Detection\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Detecting .NET assembly execution\u003C\u002Fh3>\u003Cp>Because it requires the Rosyln C# compiler, it references the Microsoft.CodeAnalysis assembly\u003C\u002Fp>\u003Cp>Here, you can attempt to collect .NET events from specified processes, reference script:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgist.github.com\u002Fcobbr\u002F1bab9e175ebbc6ff93cc5875c69ecc50\u003C\u002Fp>\u003Ch3>2. Detecting named pipe usage\u003C\u002Fh3>\u003Cp>Detecting traffic from remote connections via named pipes\u003C\u002Fp>\u003Cp>Remote connections via named pipes generate logs with Event ID 18, reference address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fhunters-forge\u002FOSSEM\u002Fblob\u002Fmaster\u002Fdata_dictionaries\u002Fwindows\u002Fsysmon\u002Fevent-18.md\u003C\u002Fp>\u003Ch3>3. HTTP communication traffic\u003C\u002Fh3>\u003Cp>The default communication template has identifiable characteristics, as shown in the image below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017360634_3_fbd3a0688b-1.jpeg\">\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article details Covenant, analyzes its features, and highlights its high scalability, making it very convenient for secondary development.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>",749,"Onedaysec",5,"published","2026-02-02T07:38:21.197Z",{"title":37,"description":14,"keywords":38,"ogImage":39,"canonicalUrl":39,"noIndex":40},"Covenant C2 Framework: Setup, Features, and Detection Analysis","Covenant C2, .NET Core, command and control, Grunt, Listeners, Launchers, cybersecurity, red team",null,false,[],{"docs":43,"hasNextPage":40},[44,45,46,47,4],826,825,824,823,{"title":39,"description":39,"image":39},"2026-07-24T15:37:11.346Z","2026-07-23T16:02:08.796Z","draft","2026-07-23T16:14:57.271Z"]