💀
0xTriboulet
  • Introduction
  • Achieving Access
    • achieving access: implantv1
    • achieving access: implantv2
    • achieving access: implantv3
  • Deceiving Defender
    • Deceiving Defender: Making nc.exe viable again
    • Deceiving Defender: Classic Bypass
    • Deceiving Defender: Name Bypass
    • Deceiving Defender: The Texas Two Step
    • Deceiving Defender: The Big Stack Bypass
      • Making Meterpreter Viable Again
    • Deceiving Defender: Meterpreter
  • Making Malware
    • making malware #0
    • making malware #1
    • making malware #2
  • Just Malicious
    • Advanced String Obfuscation
    • From C, with inline assembly, to shellcode
    • Thnks4RWX
  • TTPs
    • TTPs: Embedding Payloads with MSFVenom (x86)
    • TTPs: Embedding Payloads with MSFVenom (x64)
    • TTPs: Rust vs C++
    • TTPs: JmpNoCall
    • TTPs: BadAsm
    • TTPs: BadStrings
  • Unholy Unhooking
    • Unholy Unhooking: byoDLL
    • Unholy Unhooking: FrByoDLL
    • Unholy Unhooking: Rusty Fart
  • Weird Windows
    • Command Hijacking with .COM
    • Non-Existent File Paths
  • ZeroTotal
    • ZeroTotal: Msfvenom Calc
    • ZeroTotal: Self-Injecting Calc
    • ZeroTotal: Rusty Calc
  • Disclaimers
Powered by GitBook
On this page
  • Part One: Introduction
  • Part Two: Bringing Back the Classics
  • Part Three: tHe cod3
  • Part Four: ????
  • Part Five: Profit
  • Part Six: Conclusion
  • References
  1. Unholy Unhooking

Unholy Unhooking: FrByoDLL

Using pe2shc, we'll load a clean copy of ntdll.dll in memory, unhook our program, and execute our malicious payload.

PreviousUnholy Unhooking: byoDLLNextUnholy Unhooking: Rusty Fart

Last updated 1 year ago

Part One: Introduction

Last time we talked about loading a DLL from our implant in order to unhook our process from EDR. But there was a problem, we had to create and write to a file.

Sure, technically in some instances the operating system decides not to put anything on disk if there's enough cache, but that takes a lot of control out of the attacker's hands and leaves the possibility that someone will detect what we're doing (EDR might detect a copy of ntdll in a weird place).

Part Two: Bringing Back the Classics

Reflective DLL injection (RDI) has been around for a long time in malware development. But recently some really cool tools have been released that give open source malware developers a new edge. In this write up we'll be using pe2shc by @hasherezade to turn our copy of ntdll into a reflective DLL, load it into a sacrificial thread, then copy it over the hooked copy of ntdll and thereby unhook our process.

Part Three: tHe cod3

Turning ntdll into a reflective dll is pretty straight forward with pe2shc.

The file paths make the screenshot look a little cluttered, but you just point pe2shc to your copy of ntdll and out comes a shellcode.

Once again the entire C++ code can be found on my Github, but the interesting bit is below.

//Make executable memory
exec_mem = VirtualAlloc_p(NULL, raw_ntdll_len, MEM_COMMIT, PAGE_READWRITE);
RtlMoveMemory_p(exec_mem, raw_ntdll, raw_ntdll_len);
VirtualProtect_p(exec_mem, raw_ntdll_len, PAGE_EXECUTE_READWRITE, &oldprotect);

//Create Sacrificial Thread
hFile = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
WaitForSingleObject(hFile, -1);

printf("Remove hooks?\n");
getchar();

//UnhookNtdll
UnhookNtdll(GetModuleHandle((LPCSTR) sNtdll), exec_mem);

Part Four: ????

[Intentionally Left Blank]

Part Five: Profit

Hooked NtCreateThreadEx:

Unhooked NtCreateThreadEx:

Result:

Part Six: Conclusion

This method has some benefits to previously documented methods. Firstly, this method does not require starting a process in a suspended state or access to the memory of another process. These are two of the most OPSEC expensive operations, and we can bypass the need for them by leveraging pe2shc to load and overwrite our hooked ntdll.

Unfortunately, this solution is not perfect, at present time the presence of an extra ntdll in memory is not flagged, but this future development would break this methodology. Additionally, leveraging pe2shc in this way creates a detectable pattern for defenders due to pe2shc's bootstrap stubs. These stubs are (nearly) identical in every shellcode generated by pe2shc and could easily be signatured and result in detection.

References

SEKTOR7 Research
Page cover image
Red_Team_Code_Snippets/Cpp/BYOdll/version3 at main · 0xTriboulet/Red_Team_Code_SnippetsGitHub
Logo
pe_to_shellcode/pe2shc at master · hasherezade/pe_to_shellcodeGitHub
Logo