
Archivo de objeto Beacon para Cobalt Strike que ejecuta ensamblados .NET en beacon con técnicas de evasión.
Beacon Object File para Cobalt Strike que ejecuta ensamblados .NET en beacon con técnicas de evasión.
┌──────────────────────────────────────────────────────────────────────────────┐
│ Cobalt Strike Beacon │
│ (Proceso Padre) │
└──────────────────────────────────┬───────────────────────────────────────────┘
│
│ beacon_inline_execute()
│ - Parsear argumentos empaquetados
│ - Llamar a go()
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ BOF Execute-Assembly Entry (go) │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Análisis de Configuración │ │
│ │ • ProxyMethod (None/Draugr/Timer/RegWait) │ │
│ │ • AmsiEvasion (None/Patch/HWBP) │ │
│ │ • EtwEvasion (None/Patch) │ │
│ │ • PipeName, AppDomainName, bytes del ensamblado, Argumentos │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Inicialización del Framework │ │
│ │ • InitVxTable() - Resolver números de syscall │ │
│ │ └─> NtProtectVirtualMemory, NtContinue, NtCreateEvent, │ │
│ │ NtSetEvent, NtWaitForSingleObject, NtClose │ │
│ │ • DraugrInit() - Configurar marcos de pila sintéticos │ │
│ │ └─> Localizar RtlUserThreadStart, BaseThreadInitThunk │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Carga de DLL (ProxyLoadLibraryA) │ │
│ │ • amsi.dll, OleAut32.dll, mscoree.dll, User32.dll │ │
│ │ │ │
│ │ PROXY_NONE: LoadLibraryA() directamente │ │
│ │ PROXY_DRAUGR: DRAUGR_API(LoadLibraryA) - pila falseada │ │
│ │ PROXY_TIMER: CreateTimerQueue → devolución de llamada del Timer │ │
│ │ PROXY_REGWAIT: RegisterWaitForSingleObject → devolución de llamada │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Configuración de Evasión AMSI │ │
│ │ │ │
│ │ AMSI_PATCH: AMSI_HWBP: │ │
│ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │
│ │ │ 1. Copia de respaldo │ │ 1. Agregar Manejador VEH │ │ │
│ │ │ de 4 bytes │ │ 2. RtlCaptureContext │ │ │
│ │ │ 2. NtProtectVirtualMem │ │ 3. Establecer DR0 = │ │ │
│ │ │ (RW) │ │ AmsiScanBuffer │ │ │
│ │ │ 3. Escribir: │ │ 4. Habilitar punto de │ │ │
│ │ │ 48 31 C0 xor rax,rax│ │ interrupción DR7 │ │ │
│ │ │ C3 ret │ │ 5. NtContinue (aplicar ctx) │ │ │
│ │ │ 4. NtProtectVirtualMem │ │ │ │ │
│ │ │ (restaurar) │ │ Al llamar a AmsiScanBuffer: │ │ │
│ │ └─────────────────────────┘ │ → Excepción #BP │ │ │
│ │ │ → VEH redirige a RET │ │ │
│ │ │ → RAX = 0 │ │ │
│ │ └──────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Evasión ETW (si está habilitada) │ │
│ │ • NtProtectVirtualMemory(NtTraceEvent, RW) │ │
│ │ • Copia de respaldo de 4 bytes │ │
│ │ • Escribir: 48 31 C0 C3 (xor rax,rax; ret) │ │
│ │ • NtProtectVirtualMemory(restaurar protección) │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Configuración de Redirección de Salida │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. CreateNamedPipeW(\\.\pipe\{NombrePersonalizado}) → hPipe │ │ │
│ │ │ 2. CreateFileW(ruta de pipe) → hFile │ │ │
│ │ │ 3. AllocConsole() + ShowWindow(SW_HIDE) → Consola oculta │ │ │
│ │ │ │ │ │
│ │ │ 4. Manipulación del PEB: │ │ │
│ │ │ • Copia de seguridad: hCurrentStdOut = PEB->ProcessParameters->StdOut │ │ │
│ │ │ • Copia de seguridad: hCurrentStdErr = PEB->ProcessParameters->StdErr │ │ │
│ │ │ • Redirigir: PEB->StdOut = hFile │ │ │
│ │ │ • Redirigir: PEB->StdErr = hFile │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Hospedaje CLR y Ejecución del Ensamblado (ExecuteAssembly) │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. Detección de Versión CLR │ │ │
│ │ │ • Escanear bytes del ensamblado en busca de "v2.0.50727" │ │ │
│ │ │ o "v4.0.30319" │ │ │
│ │ │ │ │ │
│ │ │ 2. Inicialización CLR │ │ │
│ │ │ • CLRCreateInstance → ICLRMetaHost │ │ │
│ │ │ • GetRuntime(v2/v4) → ICLRRuntimeInfo │ │ │
│ │ │ • GetInterface → ICorRuntimeHost │ │ │
│ │ │ • Start() │ │ │
│ │ │ │ │ │
│ │ │ 3. Gestión de AppDomain │ │ │
│ │ │ • GetDefaultDomain() → AppDomain por defecto │ │ │
│ │ │ • CreateDomain(NombrePersonalizado) → AppDomain aislado │ │ │
│ │ │ │ │ │