BOF_RunPE
BOF RunPE — это Beacon Object File для Cobalt Strike, который выполняет PE-файлы полностью в памяти внутри процесса beacon. В отличие от традиционного fork&run, не создается дочерний процесс, не создается консоль и не используется канал (pipe) — весь вывод захватывается через перехват IAT и перенаправляется в консоль beacon.
Архитектура: только x64
Обзор
┌──────────────────────────────────────────────────────────────┐
│ Cobalt Strike Beacon │
│ (Current Process) │
└────────────────────────┬─────────────────────────────────────┘
│
│ beacon_inline_execute()
│
▼
┌──────────────────────────────────────────────────────────────┐
│ BOF RunPE │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ VxTable + Draugr Initialization │ │
│ │ (Syscall Resolution + Stack Spoofing) │ │
│ └──────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼─────────────────────────────────┐ │
│ │ PE Mapping │ │
│ │ - Section Copy - IAT Patching (with hooks) │ │
│ │ - Relocations - Memory Protection │ │
│ └──────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼─────────────────────────────────┐ │
│ │ Thread Execution │ │
│ │ - Spoofed Start Address │ │
│ │ - RIP Hijacking to Entry Point │ │
│ │ - Output Redirection via Hooks │ │
│ └────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Ключевые возможности
- Нет создания процесса: PE выполняется внутри процесса beacon
- Нет консоли/канала: Вывод захватывается через перехват
printf/WriteConsole
- Несколько методов выделения памяти: Heap, VirtualAlloc, Module Stomping
- Прокси-загрузка: Timer Queue, RegisterWait или прямые вызовы
- Снятие перехвата ntdll: Опционально свежая копия с диска
- RWX: Опционально выделять память как RWX
- Спуфинг стартового адреса потока: Легитимный стартовый адрес с перехватом RIP
Параметры конфигурации
Поведение BOF можно настроить в Additionals postex -> RunPe Config

Методы прокси
| Метод | Описание |
|---|
None | Прямые вызовы API |
Draugr | Вызовы API со спуфингом стека |
Regwait |
Методы выделения памяти
| Метод | Описание |
|---|
Heap | Приватная куча через RtlCreateHeap с Draugr |
VirtualAlloc | NtAllocateVirtualMemory с Draugr |
Module stomping | Перезапись секции .text легитимной DLL |
Общие опции
Спуфинг потока
| Опция | Описание |
|---|
ModuleName | Легитимный модуль для стартового адреса (например, Kernel32.dll) |
ProcedureName | Имя функции внутри модуля (например, ) |
Захват вывода
Весь вывод PE перенаправляется в консоль beacon через перехваты IAT. Не создается ни окно консоли, ни именованный канал.
Техники обхода
Векторы обнаружения
Телеметрия ядра (ETW-TI)
NtGetContextThread / NtSetContextThread:
- Манипуляция контекстом потока на приостановленных потоках с последующим возобновлением
Операции с памятью:
- NtAllocateMemory — выделение, может быть в RWX (зависит от конфигурации)
- NtProtectVirtualMemory — переходы (RW → RX)
- Исполняемая память в областях кучи подозрительна (зависит от конфигурации)
- Module stomping обнаруживается через несоответствие хэша секции (зависит от конфигурации)
Поведенческие индикаторы
- Создан приостановленный поток, получен контекст, затем изменено значение RIP
- Память кучи помечена как исполняемая (если распределитель памяти — куча)
- DLL загружена с флагом
DONT_RESOLVE_DLL_REFERENCES (если распределитель памяти — module stomping)
- Секция .text ntdll изменена (если включено снятие перехвата)
Использование
Загрузка скрипта
Cobalt Strike → Script Manager → Load → BOF_RunPe.cna
Команды Aggressor
beacon> runpe /path/to/binary.exe --arg1 value1


Компиляция
Требуется GCC 13 (mingw-w64). Используйте предоставленный Dockerfile:
sudo docker build -t ubuntu-gcc-13 .
sudo docker run --rm -it -v "$PWD":/work -w /work ubuntu-gcc-13:latest make
Результат: Bin/runpe.o
Ограничения
| Ограничение | Описание |
|---|
| CET | Технология Control-flow Enforcement может блокировать синтетические кадры стека |
|
Благодарности / Использованные ресурсы для разработки
Репозитории/статьи в блогах
Книги
Windows Native API Programming — Pavel Yosifovich
Windows Internals, Part 1 — Pavel Yosifovich
Windows Internals, Part 2 — Andrea Allievi