Unholy Unhooking: byoDLL
Using our own copy of ntdll.dll, our implant will clear AV hooks and execute a malicious payload.
Last updated
Using our own copy of ntdll.dll, our implant will clear AV hooks and execute a malicious payload.
Last updated
If you've been paying attention to some of the recent news in malware development, then you've probably noticed that the death of Halo's Gate is coming.
In short, Microsoft has implemented a new syscall numbering system on WOW64 that effectively breaks the underlying assumptions about syscall numbers that Halo's Gate uses to unhook executables. Because the latest Windows builds do not have directly incrementing numbers, Halo's gate will fail and exploits on these newer systems will become detectable.
There's a couple of remaining tricks that resolve this issue, Perun's Fart and a modified Hell's Gate could do the trick, but Perun's Fart relies on creating a sacrificial suspended process and then accessing that process' memory in order to get a clean copy of ntdll. Creating suspended processes is an OPSEC expensive operation, and modifying Hell's Gate may work for the near future, but future changes to the numbering could kill that methodology as well.
Thanks to @woolgatherer99 for pointing out that the new syscall numbering only applies to WOW64
The classic unhooking methodology is to load a clean copy of ntdll from disk, and thereby clear the hooks from our hooked dll. In this write up, we're going to explore a deviation of that process. Instead of loading a clean copy of ntdll.dll from disk, we're going to bring our own dll (byoDLL) to our target system, load it during execution, and then execute some malicious code.
This variation of the classic unhooking methodology allows attackers to deploy small probing malware that determines the Windows build version, download a copy of ntdll.dll from a control server, deploy it in the target environment, and finally load the main malware. We're going to simulate some of this workflow by simply hardcoding our copy of ntdll into our implant, but this is just a proof of concept (PoC) for the proposed methodology above. More advanced techniques are up to you.
Rather than calling LoadLibrary, we're going to open the file, map the contents, and then use the contents to overwrite the .text section of our hooked .dll. In essence this is the same as the classic methodology, with the added step of writing your dll to disk with the "FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN" flags which should help retain OPSEC.
The entire code can be found on my Github, but the most interesting bits are below.
[Intentionally Left Blank]
Hooked NtCreateThreadEx:
Unhooked NtCreateThreadEx:
Hitting NtCreateThreadEx in execution:
Result: