DRAFT - Beating EDR Detections
Anti-virus products used to search for static Indicators of Compromise (IOC), which typically took the form of an MD5 checksum, a url, or a filename. Well, referencing the “Pyramid of Pain” of IOCs, we can see that these are trivial for adversaries to change. It’s not unknown for APTs to change attack infrastructure in the middle of a campaign in order to foil any attempt at detecting their static IOCs.
Enter EDR. Endpoint Detection and Response (EDR) software is the next-generation of anti-virus products. They look at the behavior of programs and what they do instead of what they are. For instance, instead of looking for files named
Malicious Document.docx, they can instead see that when Word opens
Malicious Document.docx, a macro runs that launches
Powershell.exe with a Base-64 encoded command-line argument.
I recently read a blog post by Christophe Tafani-Dereeper, “Building an Office macro to spoof parent processes and command line arguments”. The post shows research from Didier Stevens and Casey Smith on modifying process memory/data structures in order to spoof not only the command-line arguments, which has been a fairly standard procedure, but also the parent process, which I think is pretty cool.
However, in my own research of this technique I found something else: the a parameter of the process filepath of the new process spawned. As noted below, this didn’t pan out, though if someone finds a way to modify this, let me know!
The Technical Stuff
The magic lies in two data structures: the
STARTUPINFOEXA.lpAttributeList which is of type
LPPROC_THREAD_ATTRIBUTE_LIST, and the
PEB (Process Environment Block).
LPPROC_THREAD_ATTRIBUTE_LIST type contains attribute data for process and thread creation. Typically when you use
CreateProcess, you’d set the
STARTUPINFOEXA variable to
NULL and not worry really worry about it (other than one size attribute). However, looking at the
UpdateProcThreadAttribute, there’s clearly a plethora of attributes that can be modified before creation of the process, most notably,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS. Modifiying that specific attribute to a
DWORD value of a valid PID will make it appear as if the new process was spawned by that parent.
PEB data structure contains a member called
ProcessParameters of type
_RTL_USER_PROCESS_PARAMETERS, which in turn contains
CommandLine. Modifying this Unicode string while the process is suspended upon creation will allow you to modify what appears to be the command-line arguments without actually affecting how the process is started. Interestingly enough, there is another member there titled
ImagePathName. Unfortunately, after looking into it, I couldn’t find a way to successfully modify this value.
Adding it All Together
The original blog post had all the code, but I wanted to make it into a sort of kit so cybersecurity professionals could easily use this as a test in their own environment and see what the outcome is. You can find the code here.