
Beacon Object File для Cobalt Strike, который выполняет .NET сборки в beacon с техниками обхода защиты.
Beacon Object File для Cobalt Strike, выполняющий .NET сборки в beacon с техниками обхода.
┌──────────────────────────────────────────────────────────────────────────────┐
│ Beacon Cobalt Strike │
│ (родительский процесс) │
└──────────────────────────────────┬───────────────────────────────────────────┘
│
│ beacon_inline_execute()
│ - Распарсить упакованные аргументы
│ - Вызвать go()
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ BOF Execute-Assembly Вход (go) │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Разбор конфигурации │ │
│ │ • ProxyMethod (None/Draugr/Timer/RegWait) │ │
│ │ • AmsiEvasion (None/Patch/HWBP) │ │
│ │ • EtwEvasion (None/Patch) │ │
│ │ • PipeName, AppDomainName, байты сборки, аргументы │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Инициализация фреймворка │ │
│ │ • InitVxTable() - Разрешить номера системных вызовов │ │
│ │ └-> NtProtectVirtualMemory, NtContinue, NtCreateEvent, │ │
│ │ NtSetEvent, NtWaitForSingleObject, NtClose │ │
│ │ • DraugrInit() - Настроить синтетические кадры стека │ │
│ │ └-> Найти RtlUserThreadStart, BaseThreadInitThunk │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Загрузка DLL (ProxyLoadLibraryA) │ │
│ │ • amsi.dll, OleAut32.dll, mscoree.dll, User32.dll │ │
│ │ │ │
│ │ PROXY_NONE: LoadLibraryA() напрямую │ │
│ │ PROXY_DRAUGR: DRAUGR_API(LoadLibraryA) - поддельный стек │ │
│ │ PROXY_TIMER: CreateTimerQueue → обратный вызов таймера │ │
│ │ PROXY_REGWAIT: RegisterWaitForSingleObject → обратный вызов события │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Настройка обхода AMSI │ │
│ │ │ │
│ │ AMSI_PATCH: AMSI_HWBP: │ │
│ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │
│ │ │ 1. Сохранить 4 байта │ │ 1. Добавить VEH обработчик │ │ │
│ │ │ 2. NtProtectVirtualMem │ │ 2. RtlCaptureContext │ │ │
│ │ │ (RW) │ │ 3. Установить DR0 = AmsiScanBuffer│ │ │
│ │ │ 3. Записать: │ │ 4. Включить точку остановы DR7│ │ │
│ │ │ 48 31 C0 xor rax,rax│ │ 5. NtContinue (применить контекст)│ │ │
│ │ │ C3 ret │ │ │ │ │
│ │ │ 4. NtProtectVirtualMem │ │ При вызове AmsiScanBuffer: │ │ │
│ │ │ (восстановить) │ │ → #BP Исключение │ │ │
│ │ └─────────────────────────┘ │ → VEH перенаправляет на RET│ │ │
│ │ │ → RAX = 0 │ │ │
│ │ └──────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Обход ETW (если включён) │ │
│ │ • NtProtectVirtualMemory(NtTraceEvent, RW) │ │
│ │ • Сохранить 4 байта │ │
│ │ • Записать: 48 31 C0 C3 (xor rax,rax; ret) │ │
│ │ • NtProtectVirtualMemory(восстановить защиту) │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Настройка перенаправления вывода │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. CreateNamedPipeW(\\.\pipe\{CustomName}) → hPipe │ │ │
│ │ │ 2. CreateFileW(путь канала) → hFile │ │ │
│ │ │ 3. AllocConsole() + ShowWindow(SW_HIDE) → Скрытая консоль │ │ │
│ │ │ │ │ │
│ │ │ 4. Манипуляция PEB: │ │ │
│ │ │ • Резервная копия: hCurrentStdOut = PEB->ProcessParameters->StdOut│ │ │
│ │ │ • Резервная копия: hCurrentStdErr = PEB->ProcessParameters->StdErr│ │ │
│ │ │ • Перенаправление: PEB->StdOut = hFile │ │ │
│ │ │ • Перенаправление: PEB->StdErr = hFile │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Хостинг CLR и выполнение сборки (ExecuteAssembly) │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. Определение версии CLR │ │ │
│ │ │ • Сканировать байты сборки на "v2.0.50727" или "v4.0.30319" │ │ │
│ │ │ │ │ │
│ │ │ 2. Инициализация CLR │ │ │
│ │ │ • CLRCreateInstance → ICLRMetaHost │ │ │
│ │ │ • GetRuntime(v2/v4) → ICLRRuntimeInfo │ │ │
│ │ │ • GetInterface → ICorRuntimeHost │ │ │
│ │ │ • Start() │ │ │
│ │ │ │ │ │
│ │ │ 3. Управление AppDomain │ │ │
│ │ │ • GetDefaultDomain() → Default AppDomain │ │ │
│ │ │ • CreateDomain(CustomName) → Изолированный AppDomain │ │ │
│ │ │ │ │ │
│ │ │ 4. Загрузка сборки │ │ │
│ │ │ • Создать SAFEARRAY (VT_UI1) с байтами сборки │ │ │
│ │ │ • SafeArrayAccessData → Скопировать сборку в безопасный массив│ │ │