How to get around NGAV & EDR - 1/3

How to get around EDR, XDR and all the other Buzzwords and establish a reverse shell. Part 1/3

Intro

Working as part of a Red Team or as Penetration tester, you surely know how awesome it feels to finally get a SYSTEM-Shell on your system of choice. Owning the system despite all the efforts of the defenders is always satisfying. Even better if you were able to get around AV with a 0day or an obfuscated tool. However, too many times the AV is in the way, and you are lacking permissions to kill or suspend the service.

What you need here is a FUD (fully undetectable) exploit or simply something that does not trigger the AV at all. While you can find several of those on GitHub, you would be better off if you could create your own shell/exploit, perfectly suited for the domain in question.

In this blog-series I am trying to take a look at NGAV (Next-Gen-Anti-Virus) and the techniques used to stop exploits from running and most interesting, how to get around NGAVs.

The final goal is to launch a shell and connect back to my attacker machine on a fully patched system with and without a NGAV (Windows Defender / NGAV) The techniques shown here are not new nor is are the code snippets used here. I am simply combining what I learned so far.

NGAV vs AV

I hate all those buzzwords and if you ever had to deal with an AV-Vendor, you’ll know that they like to drown you in buzzwords that sound cool and fancy (“Intercept X Advanced EDR, XDR, MTR”) and will surely confuse and hopefully convince the customer into buying their AV-Solution.

Drained of all the Sales-talk it boils down to added scanning engines on top. NGAVs will in addition to signature detection check heuristics and behavior. While traditional AVs only check the patterns of a file and then decide if it is malicious, NGAVs will also check the timestamp, size, imports, exports and so on (heuristics) and in addition to that, how it behaves when the file is run.

Everything was better/easier in the past

What does this mean for malware authors? A few years ago, it was mostly enough to take a known exploit, rewrite it a few parts and voila…you got yourself a working exploit. Nowadays it got increasingly harder and an exploit that is undetected today may be a red flag tomorrow.

However, that does not mean it is impossible it simply means you need to work harder to hide your payload. There are several ways to do so with new vectors emerging all the time. For example, the relatively new programming language NIM was not on the radar of most AV-Vendors and it was pretty simple to generate FUDs for quite a while (byt3bl33d3r/OffensiveNim)

Techniques

In this series I am going take a look at 2 techniques and how they work under the hood. There are more out there which I may cover later on.

  • API unhooking which is basically unhooking API Hooks of the library you need for your exploit
  • Direct syscalls to avoid using hooked functions such NtCreateFile and so on

API Unhooking

To understand API unhooking we first need to understand API Hooks. Windows (other OS as well of course) offer the system and running programs several APIs to do different tasks. For example, creating, reading or deleting files or opening up a socket or querying the name of the current process will be done through APIs stored in libraries such as user32.dll or ntdll.dll (there are more).

There are certain API-Calls that are common with malware such as VirtualAlloc to allocate memory or VirtualProtect to change the protection of a certain memory region or NtCreateThread to create a thread.

Those API-Calls are monitored by AVs and if triggered will flag the file as potentially malicious or block it right away. The AV itself is able to do so because it injected itself into the code and will scan anything that is supposed to go through that API-Call beforehand.

If our malicious example would call NtCreateThread via ntdll.dll it would first go through the AV (if hooked) and be checked for malicious code and then either get blocked or declared as clear and then routed back to the original API. It should be noted, AVs are also able to intercept kernel related calls and but this will not be part of this series.

What does that mean though? Let me show you on a new W10 machine. One with AV and one with only Windows Defender.

Without going too much into detail we can differentiate hooked or not hooked functions by looking at the disassembled code. We can see here a MOV-instruction on top without another JMP-Instruction before or afterwards.

Compare this to this screenshot here and you’ll notice that there is a jump as first instruction. What happens here is that instead of working on the API-Call, the CPU will jump to the specific memory region, go through the scanning-routine and then return afterwards and continue on working on the API-Call.

Any malicious activity will be easy to spot that way. In this case we can see a “Jump if not zero” Jump. Another indicator is the handles on any running program. Open up powershell.exe and you can see that the AV injected itself into the powershell-process and has several handles open.

So what?

TLDR:

AVs are hooking potentially malicious API-Calls and inject their own code into it. No matter the encryption or obfuscation, when code is in memory and about to run it will be scanned by the AV before it goes through the API-Calls. So…how do we get around it?

There are several different techniques, but it boils down to either avoid the hooked functions somehow or patch them out. It is also possible to directly do syscalls without going through the API which I will cover later on. Another approach is to map a fresh section of ntdl.dll (or another library) and therefore not go through the hooked version of the library.

This means, if your malicious file is able to get around heuristic and signature detection and will NOT go through the runtime detection the AV is basically blind and not looking your way. Therefore, the AV cannot flag anything because it is not going through the scanning-routine.

Direct syscalls

Instead of going through the heavily monitored APIs we can also call those functions directly. If we were able to directly call NtCreateProcess for example instead of going through the monitored ntdll.dll we would avoid the AV-scanner. An interesting example of this is Dumpert were direct syscalls and API unhooking will allow the attacker to run mimikatz on the victim’s system despite EDR and AV installed.

Instead of going through the API itself we do those syscalls ourselves (kernel, 0-ring). This works because we can see what the API is actually doing (example, ZwCreateProcess) and by simply replicating it we could avoid hooked and monitored APIs.

What this means in practice is to dissasemble the actual code (ZwCreateProcess in this case) and taking those instructions (mov eax,B9) and integrate them into our own code. Downside is here, as already mentioned the code itself is not consistent through out each Windows OS and even service packs.

Continued in part 2