Covenant Task 101 - PPID Spoof Example

Covenant is a great C2 tool for red teaming. I use it on most engagements as its in C# and easily extensible. This post was inspired by Rasta Mouse's Covenant 101 where he nicely described how to modify Covenant source to add a task. The purpose of this post is to leverage Rasta's post to further simplify the process especially for those new to Covenant.

Ryan Cobbr, the main author of Covenant has already done a great job by adding a "Tasks" menu where an admin user can lists all tasks and modify their configurations. I will be be showing how I leveraged this in a recent engagement to bypass certain EDRs and AV behavioural signatures.

Story Time

Once upon a time, I was contracted to do a red teaming engagement for one of the World's leading pharmaceutical firms. Fast forward to when I crafted and had sent a neat phishing mail (embedded with a link to a malicious Word doc). Within 10 mins, about 9 users had clicked, and I had 9 grunts, however, the grunts were running as Word doc processes.

I knew they had a spectacular EDR that logged everything and alerted on anything that was an anomaly. So issuing commands like "shellcmd whoami" or "powershell whoami" will definitely get me caught as these commands executes by spawning the command prompt from the WINWORD process which will definitely trigger. There were two options that came to mind (there might be better ones):

  1. Injection into another process
  2. Spoof the parent process Id (PPID) of any spawned command prompt.
I couldn't do (1) as I know that EDR enforces Attack Surface Rules (ASR) and doesn't allow injection from Office applications to other processes. However, in my lab testing with same EDR, it allows injection from Word to Excel and some other office applications, but doing that doesn't improve my situation.

Covenant by default doesn't not have any existing task that could enable me do (2). I already had a working code (C sharp file) that could do Parent PID spoofing, all I needed to do was modify to be compatible with Covenant. I used Visual Studio (cos of its great features). I always try to make all code fit into one .cs file.

Like Rasta's points out and also looking at existing tasks' configuration, you would notice that a Task need to have a Task class, an Execute method which should always return a String. Lets take ListDirectory task as an example.


For our PPID spoofing, I decided I need two parameters, (1) the ID to spoof, (2) the command to run. Click on "+ Create" at the bottom to start the task creation process.


As long as my task did not depend on external libraries, I lazily select all ReferenceAssemblies, I don't actually need all, just wanted to be quick with it. These defined parameters need to be embedded into the code as shown below, then the Program class and Main method modified to Task and Execute respectively. The parameter names defined graphically should also be same within the Execute method.


Modify other return values within UnmanagedExecute Class (CreateProcess method) to ensure they are String values.

The final code (ppid.cs) along with other tasks in yaml format is here, you just can just paste (or import the yaml) this within your task code. Make sure you click on "Edit" to save.

This is an example showing powershell execution for ipconfig under another powershell process.





There are certain tasks you might want to add that depend on external libraries. I haven't personally tried it, but I guess you can add them under "Embedded Resources" just like it was done for SafetyKatz task. There is also an article here that talks about it using SharpHound as example.

I hope this is helpful to someone.

References:




Comments

  1. Awesome blog very impressive idea on this topic, Looking forward for more update soon. NFFI

    ReplyDelete

Post a Comment

Popular posts from this blog

Red Teaming with Covenant and Donut

Pentesting Android applications