Extending The Covenant

Several new tasks for Covenant that have proven to be helpful to us.

This is the second part of a series of blog posts about my recent work with the open source C2 framework Covenant.

After working with other C2s and seeing their capabilities, I wanted to add some new tasks to Covenant. They focus mostly on enumeration of processes and their modules or threads. This can be useful when injecting into those processes or when trying to find out more about EDRs and their functionalities. Full disclosure, the tasks are heavily inspired by commands from the impressive closed source command and control Brute Ratel (BRc4, command documentation is here).

All the new tasks can be found on our GitHub page: Covenant-Additions

I have also modified some tasks to better suit our needs, but they are currently not ready to be open sourced. When I fixed the different bugs and flaws, I will add them to the repo too.


Enumerate through all running processes to find those that have a CLR loaded. When injecting a .NET assembly into another process, I prefer to use a process that already has a CLR loaded for increased stealth. Otherwise, a process that usually does not load a CLR now suddenly does, which could trigger some alerts or suspicions.


The modules of all processes are searched for the string "clr.dll". Since it does not have to be an exact match, coreclr.dll is also found. Check the module name to see if it fits your needs.



Enumerate through all running processes to find those that have the required DLL loaded. This is also helpful when trying to find processes to inject into. FindCLRProcess is the exact same functionality, just with "clr.dll" as a fixed argument. With this function, it is possible to search processes that usually communicate over the internet (winhttp.dll) or have some other functionality that we would like to use.




List all the exports of a DLL loaded in the current process. Useful for patching or just learning more about a DLL, such as a userland EDR DLL and its exported functions.




Enumerates the loaded modules of a specified process. Again, similar to FindProcessWithDll and FindCLRProcess, but this task shows all loaded modules of the process with the specified PID. The base address and the file name of the module are also returned.




Enumerates threads and their states in a specified process. If the thread is in a waiting state, the wait reason will be appended to the output. This can be helpful in finding threads that are in an alertable state. These can be used to hijack and inject code into other processes. Other, non-alertable threads could also be used, but would have to be set into an alertable state first (e.g. suspended), which again could raise suspicion.



These are our new tasks that are now available on GitHub. I have some future work planned, where I want to check if an exported method of a DLL is hooked by an EDR. As far as I know, if the EDR does not hook the IAT, it "inline hooks" the exported methods of DLLs in the process, so it points to a different location. This is detectable, in fact Brute Ratel offers this functionality (detect_hooks) with a lot more tracing and enumeration. Let's see if I can do something similar in C#. Any input is welcome!

Thanks for reading! As always, feel free to send any questions or remarks to or contact me in the BloodHoundGang slack (user @jannlemm0913).

Similar posts