2025-12-07

Evasive C2: The Final Polish

EvasionBOFSleep ObfuscationEkko

We've built a functional C2. Now we need to make it invisible. In this final post, we'll explore two advanced topics: Beacon Object Files (BOFs) and Sleep Obfuscation.

Beacon Object Files (BOFs): The Scalpel

Using .NET is great, but it's heavy. It loads the CLR, which is a massive indicator. Sometimes you want to be surgical.

What is a BOF? Introduced by Raphael Mudge for Cobalt Strike in 2020, a BOF is just a C program that has been compiled but not linked. It's an .o file (Object File).

Normally, when you compile a program, the "Linker" connects all the function calls (like printf) to the libraries that contain them. A BOF leaves these disconnected. It's a bag of code with a table of "Relocations" (To-Do notes).

The BOF Loader Our agent acts as the Linker. When we send a BOF:

  1. Allocate: We carve out a small chunk of memory (RWX or RX).
  2. Resolve Symbols: The BOF calls functions like kernel32$VirtualAlloc. We parse these strings, load the library, find the function address, and patch the call site.
  3. Apply Relocations: The code assumes it lives at address 0. We update all memory references to match the actual allocated address.
  4. Execute: We jump to the entry point.

Why is this stealthy?

  • No Process Creation: It runs inside our own process (unlike Fork & Run).
  • No New DLLs: It uses what's already there.
  • Tiny Footprint: A BOF to list processes might be 2KB.

We can now use the massive ecosystem of community BOFs (like TrustedSec's CS-Situational-Awareness-BOF) directly in our custom agent.

Ekko: Sleeping with One Eye Open

The most dangerous time for malware is when it's doing nothing. Most agents spend 99% of their time Sleep()ing. While sleeping, the agent is just a sitting duck in memory. EDRs can scan memory looking for strings or byte signatures.

The Solution: Sleep Obfuscation We want to encrypt our own memory while we sleep, and decrypt it only when we wake up. But we can't just write a loop to do this, because if you encrypt your own code, the CPU can't execute the next instruction!

We implemented Ekko, a technique originally published by C5pider (based on concepts from Peter Winter-Smith at MDSec).

The ROP Chain Trick

We use Return Oriented Programming (ROP). We don't run our own code; we borrow snippets of code from Windows DLLs.

We use the Windows Timer Queue API (CreateTimerQueueTimer) to schedule a series of API calls to happen in the future. We are effectively programming the OS to protect us.

The Chain:

  1. EventSet(StartEvent): Signals that the timer has fired.
  2. VirtualProtect(RW): Marks our own code section as Read-Write. This is critical. If we leave it Executable, the EDR might catch us modifying it. By making it RW, we hide it from "Executable Memory" scans.
  3. SystemFunction032(Encrypt): We use this undocumented function (part of advapi32.dll) to encrypt our memory image using RC4.
  4. WaitForSingleObject(Sleep): The actual delay. The thread pauses here.
  5. SystemFunction032(Decrypt): We decrypt our memory.
  6. VirtualProtect(RX): We restore Read-Execute permissions so we can run again.
  7. EventSet(EndEvent): We wake up the main thread.

Stack Spoofing

Ekko also handles Call Stack Spoofing. When the thread is sleeping at step 4, an analyst looking at the call stack will see a legitimate chain of Windows Timer functions, originating from ntdll.dll. They won't see MyMalware.exe -> Sleep.

// spoof.cpp
CtxSpoof.Rsp -= sizeof(PVOID); // Adjust stack pointer
SetThreadContext(Thread, &CtxSpoof);

Conclusion

Building C24U has been a journey from "Hello World" to a usable evasive C2.

  • Polymorphic Network Layer: HTTP/DNS/SMB (WinINet & Custom DNS Tunneling).
  • Evasion: Indirect Syscalls with Custom Hashing & Junk Assembly.
  • Weaponization: Named Pipe Redirectors for PPID Spoofing.
  • Post-Ex: In-Memory .NET & BOF Loader.
  • Stealth: Ekko Sleep Obfuscation.

This is it. Thats all for now, but I plan to continue working on this project and add more features in the future. Huge Thanks to Maldev Academy for a lot of the resources and inspiration. Building this was a blast.