Cobalt Strike "Where Am I?" Beacon Object File
Cobalt Strike Beacon Object File (BOF) that uses handwritten shellcode to return the process Environment strings without touching any DLL's.
This idea was inspired by Matt Eidelberg's DEF CON 29 talk Operation Bypass Catch My Payload If You Can.
- In this talk, Matt shows how EDR heuristics can detect Cobalt Strike beacons based on their behavior.
- Matt uses an example where after the beacon compromises the endpoint, the first thing it does is run the
- This behavior of the host beacon process spawning a new
whoami.exeprocess, triggers the EDR and the beacon is burned!
- I've been doing allot of Windows Internals studying, and this video made a lightbulb go off.
- I thought "Why not just get the
whoami.exeinfo from the process? It's already right there in the beacon processes memory!"
So that's what I did! I created a Beacon Object File that grabs the information we'd want, right there from the beacon process memory!
Since the goal was to make it ninja/OPSEC safe, I figured why not just do it dynamically with Assembly? About halfway through creation, I bit the bullet and burned the extra time to make it into a blog post as well, so here it all is!
This is the walkthrough blog post on how I created this Cobalt Strike Beacon Object File from start to finish:
I discovered that TrustedSec had already created a BOF for this, and of course they did because they are awesome! If you'd like to view their original work you can find it here: trustedsec/CS-Situational-Awareness-BOF/env
Using the WhereAmI BOF from the Cobalt Strike Console
BOF Flow to get the Environment Variables Dynamically in Memory
Below is the high-level flow & WinDBG commands to map our path from the Thread Environment Block (TEB) to the Environment strings we will ultimately display in our Cobalt Strike interactive beacon console.
TEB (GS Register) -->
Environment Block Address &
# TEB Address 0:000> !teb TEB at 00000000002ae000 # PEB Address from TEB 0:000> dt !_TEB 2ae000 +0x060 ProcessEnvironmentBlock : 0x00000000`002ad000 _PEB # ProcessParamters Address from PEB 0:000> dt !_PEB 2ad000 +0x020 ProcessParameters : 0x00000000`007423b0 _RTL_USER_PROCESS_PARAMETERS # Environment Address & Size from ProcessParameters 0:000> dt !_RTL_USER_PROCESS_PARAMETERS 7423b0 +0x080 Environment : 0x00000000`00741130 Void +0x3f0 EnvironmentSize : 0x124e
Using WinDBG to Parse the PEB and View Environment Strings
- We can see that
!pebcommand parses out the PEB structure and displays to us the Loader (Ldr) information, the address & resolved strings of the ProcessParameters struct, as well as the Environment information we are targeting.
x86_64-w64-mingw32-gcc -c whereami.x64.c -o whereami.x64.o -masm=intel
- Matt Eidelberg's DEF CON 29 talk Operation Bypass Catch My Payload If You Can
Sektor7 Courses - Conquer Malware Dev (best courses ever)
Raphael Mudge - Beacon Object Files - Luser Demo
Cobalt Strike - Beacon Object Files
BOF Code References
Implementing ASM in C Code with GCC