Indirect Waffles: Shellcode Loader to Evade EDRs

A shellcode loader with advanced techniques such as HellHall's indirect syscalls, Early Bird APC injection, and more, to evade EDR detection.

Hero image for Indirect Waffles: Shellcode Loader to Evade EDRs
Posted 13 Oct 2024 By André Oliveira
Share

While preparing for CRTO 2 and learning from Maldev Academy, I wanted to put everything I had learned into practice. That’s when I created Indirect Waffles, a custom shellcode loader designed for EDR evasion and enhanced by many of the advanced techniques I’ve been studying.

Demo

Key Features

  • Enumeration: Uses NtQuerySystemInformation to enumerate processes for PPID spoofing and NtOpenProcess syscall to obtain process handles.
  • Custom Dynamic HTTP/s Payload Staging
    • Check it out on my GitHub.
  • Shellcode Decryption: RC4 with runtime key brute-forcing.
  • Process Creation with NtCreateUserProcess and the following enhancements:
    • Suspended process creation for APC Injection.
    • Parent Process ID (PPID) spoofing.
    • Block DLL injection policy, preventing third-party DLLs (non-Microsoft signed) from being injected, mitigating some EDR hooking techniques.
  • Injection: Remote Mapped Injection via syscalls with RX (Read Execute) permissions for improved evasion from memory scanners.
  • Execution: Early Bird APC Injection using syscalls to queue the payload for execution before the target thread resumes execution.
  • Resumes process via NtResumeThread syscall.
  • Extra Enhancements:
    • Custom string literal obfuscation: Works on both normal and wide strings.
      • fc5156f67325c8e5433bf4fb4bcfa641.png
    • Compile-time IAT API hashing using MurmurHash to evade static API detection techniques.
    • HellHalls’ Indirect Syscall implementation with compile-time hashing via MurmurHash.
      • 93ee3d54f3f8cac2476da7ad12280d00.png
  • Anti-Debugging:
    • Checks the PEB flag for the IsDebugged flag to detect the presence of a debugger.
    • Anti-debug loop (30 seconds total):
      • 3-second sleep intervals using NtWaitForSingleObject.
      • API hammering to make the sleep appear more benign.
    • Uses QueryPerformanceCounter to measure total loop time; if it exceeds 35 seconds, it is likely being debugged.
  • Spoofed Binary Metadata:
    • .DLL: Spoofed as Notepad++’s libcurls.dll.
    • .EXE: Spoofed as Notepad++’s gup.exe.

Learn how to spoof a binary’s metadata here


Share