Available

Search posts

Defence Evasion (Cobalt Edition)

A consolidated reference for Cobalt Strike artifacts, script inspection, Beacon memory and command behavior, with OPSEC considerations, telemetry checks and a practical validation checklist.

Contents

1. Detection surfaces and OPSEC

Detection can occur before execution, during loading or after Beacon starts performing tasks. File signatures, script content, memory characteristics and behavior are complementary sources of evidence. Changing one representation does not remove the others.

OPSEC: record the command, identity, host and resulting changes. No command family guarantees an absence of telemetry.

SurfaceExamples of observable evidenceAssessment question
Compiled artifactFile hash, PE metadata, imports, service imageWhich exact file and architecture were tested?
Script artifactScript content, interpreter activity, AMSI inspectionWas only the stored text examined, or also runtime behavior?
Beacon memoryExecutable regions, permissions, PE structures, threadsWhat differs from the process’s normal memory layout?
Post-exploitationChild processes, process access, named pipes, module loadsWhich implementation does the selected command actually use?
NetworkDNS, connections, destinations, timing, authenticationDoes the evidence agree with the host timeline?
Services and remote executionService configuration, executable path, remote logonWhich local and remote systems retain evidence?

A single result is bounded by the tested file, product configuration, security intelligence version and execution path. Neither an absent alert nor a successful task establishes that an activity is undetectable.

2. Artifact Kit, Resource Kit and Malleable C2

These components affect different parts of the execution chain. Keep their versions and outputs separate when documenting a example.

ComponentRoleEvidence to retain
Artifact KitSource/templates for executable, DLL and service wrappersSource revision, build metadata and hashes of generated files
Resource KitScript templates and delivery resourcesTemplate revision, generated script and delivery-time content
Malleable C2 profileConfiguration for communications and supported runtime behaviorProfile hash, server version and loaded configuration
Aggressor scriptsClient extensions and hooksScript names, revisions and load state
Beacon command implementationCode path used for an individual taskCommand, version, architecture and observed effects

An artifact wrapper prepares and launches embedded Beacon material. Beacon’s loader then maps the payload, resolves imports and relocations, and transfers execution. File, loader and runtime observations therefore describe different stages.

Compiled artifact naming

Name componentTemplate meaning
32 / 64Target architecture
bigStageless template variant
svcService executable variant
EXE / DLLEntry-point and loading model

The source layout includes executable, service and DLL entry points, plus shared loading logic. A change to an EXE wrapper does not automatically change every script, DLL, service or already running Beacon.

Source layout and build inputs

ComponentFiles or directoriesPurpose
Artifact Kit entry pointssrc-main/main.c, svcmain.c, dllmain.cExecutable, service and DLL entry points
Artifact Kit shared implementationsrc-common, patch.c, injector.c, start_thread.cShared payload preparation and execution implementation
Artifact Kit client integrationartifact.cnaSelects the generated artifact templates in the client
Resource Kit templatestemplate.x64.ps1, template.x86.ps1 and other format templatesArchitecture- and format-specific script resources
Resource Kit delivery wrappercompress.ps1Represents compressed template content for delivery
Resource Kit client integrationresources.cnaConnects generated resources to the client
Malleable configuration.profile fileTeam-server configuration; separate from both kit builds

Build scripts and their positional arguments are version-specific. The installed kit’s README and script define the supported inputs. A stage-size constant copied from a different version is not a universal value. Windows paths and their WSL /mnt/c/ equivalents refer to the same files, but their quoting and separators differ.

Inspect the installed source tree from its kit directory before documenting a build:

bash
# Read the build requirements and supported arguments
rg --files -g '*README*' -g 'build.sh' -g '*.cna'
rg -n 'usage|Usage|mingw|compiler|architecture|output' README* build.sh

# Check shell syntax without building or executing a payload
bash -n ./build.sh

Shell syntax validation does not verify the compiler toolchain, C code, generated templates or runtime behavior. Record these separately.

Configuration and output lifecycle

ChangeWhat must be checked afterwards
Kit source revisionBuild requirements, generated output directory and exact output hashes
Client integration scriptWhich .cna is loaded and which output directory it references
Resource templateWhether a generated script actually uses that template revision
Profile revisionWhether the intended team server loaded that exact profile
Generated artifact revisionWhether the file being examined was regenerated after the relevant changes

In the client, Cobalt Strike → Script Manager identifies loaded integration scripts, while Cobalt Strike → Malleable C2 Profile exposes the loaded profile. Loading a client script and changing a team-server profile are separate actions. Neither retroactively changes files already generated or proves that an existing session uses the new settings.

Practical artifact inventory

Run locally in PowerShell. Set the path to the actual exercise output directory.

powershell
$artifactRoot = 'C:\Payloads'

# Record filenames, sizes and timestamps before comparing results
Get-ChildItem -LiteralPath $artifactRoot -File |
    Select-Object Name, Length, LastWriteTimeUtc

# Identify the exact bytes associated with each observation
Get-ChildItem -LiteralPath $artifactRoot -File |
    Get-FileHash -Algorithm SHA256

# Inspect signature state independently from antivirus findings
Get-ChildItem -LiteralPath $artifactRoot -File |
    ForEach-Object { Get-AuthenticodeSignature -LiteralPath $_.FullName } |
    Select-Object Path, Status

A valid signature is an identity/integrity signal, not proof of benign behavior. A hash identifies file content; it does not identify the memory state of a running process.

3. Script artifacts, AMSI and runtime evaluation

AMSI is an interface through which participating applications submit content to an antimalware provider. It is distinct from PowerShell logging and from scanning a file on disk.

PowerShell can construct or evaluate content dynamically. The stored script, decoded content and subsequently executed code may therefore differ. A file-oriented check does not reproduce every runtime inspection point. Base64 and compression change representation; they do not establish trust or safety.

LayerWhat it can establishWhat it cannot establish alone
File-oriented inspectionResult for supplied bytes under a particular engine/configurationAll later decoded or evaluated content
AMSI inspectionProvider assessment of content submitted by the applicationComplete visibility into every process or execution mechanism
Script Block LoggingScript-block evidence when supported and enabledUniversal logging without policy and host support
Endpoint process telemetryInterpreter launches and related behaviorFull script content in every case

A stageless PowerShell template and its compressed delivery wrapper are different representations. Preserve both when correlating results. ThreatCheck locates a detection boundary in supplied input; its result is not a certification of runtime behavior.

Inspect which PowerShell event channels exist on the host:

powershell
# Windows PowerShell and PowerShell 7 use different operational channels
Get-WinEvent -ListLog '*PowerShell*' |
    Select-Object LogName, IsEnabled, RecordCount

# Query a known exercise interval in Windows PowerShell's channel
$since = (Get-Date).AddHours(-1)
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    Id = 4104
    StartTime = $since
} -MaxEvents 100 |
    Select-Object TimeCreated, Id, Message

For PowerShell 7, query the available PowerShellCore/Operational channel instead. Missing events may mean the relevant logging was unavailable, disabled, filtered or outside retention. See Microsoft’s PowerShell logging documentation.

4. Beacon memory: what to examine

Memory inspection complements artifact analysis. Writable/executable allocations, PE structures, module association and recognizable strings are separate characteristics. None is a standalone verdict.

ObservationWhy it mattersImportant limitation
RWX memoryA region is simultaneously writable and executableJIT runtimes and legitimate software can also use dynamic executable memory
Private executable memoryExecutable pages may lack an ordinary image mappingSome legitimate applications also generate code dynamically
PE structures in memoryCan reveal a mapped or manually loaded executable imageTheir absence does not prove executable memory is benign
Image-backed executable pagesSuggest association with a mapped moduleAssociation alone does not prove the pages match the disk image
Embedded stringsCan connect memory to a family or componentA changed or missing string does not eliminate behavioral evidence
Thread informationStart location, owning process and related activity provide contextA plausible address alone does not prove legitimate execution

In System Informer or an equivalent inspection tool, correlate the process, region type, protection, mapped file and thread information. Inspection permissions and tool behavior affect visibility. Avoid treating every unsigned region or unusual string as proof of compromise.

Module stomping and string transformations affect different aspects of an image. Compare the claimed module identity with memory content and observed execution. Preserve protocol strings and application behavior when assessing whether a test artifact still functions; a crash or broken workflow is not a successful detection result.

5. Beacon commands: behavior and OPSEC

Housekeeping commands

Configure Beacon or manage client/session state. Some are client-side; others create tasks or affect later activity. This is not a “zero OPSEC cost” category.

CommandPurposeOPSEC consideration
help / help <command>Display available commands or command helpCheck installed syntax before relying on examples
checkinRequest a Beacon check-inCan affect communication timing
sleep <seconds> [jitter]Set callback interval and jitterChanges communication behavior; does not remove network evidence
clearClear pending Beacon tasksDoes not erase endpoint events or completed activity
downloadsDisplay tracked downloadsA client listing is separate from the transfer itself
cancel <download>Cancel a tracked downloadDoes not undo data already transferred
jobsList post-exploitation jobsA listed job may be operating in another process
note <text>Add an operator annotationRecords context; does not change the endpoint identity
powershell-importImport a script for later PowerShell useImport state and later execution are different stages
ppidConfigure parent-process attribution for supported operationsNot a universal setting for all process-creation paths
spawntoConfigure the temporary process used by supported operationsDoes not govern every service or existing-process workflow
windows_error_code <number>Explain a Windows errorAn error description does not identify the blocking component
shell
# Inspect command support and current task state
help
help clear
help downloads
jobs
downloads

# Decode the error without attributing it to a particular security product
windows_error_code 5
# ERROR_ACCESS_DENIED: investigate permissions, policy and security events

API-only commands

Built-in operations that use Windows APIs rather than requiring a command interpreter for the operation itself. Their effects can still be visible to endpoint and network monitoring.

CommandPurposeObservable effects
pwdDisplay the working directoryQueries process state
cd <path>Change the working directoryChanges context for later relative paths
ls [path]List files or directoriesFilesystem access; a UNC path can involve remote authentication
download <path>Transfer a target file to the operator’s infrastructureFile reads and data transfer
upload <path>Transfer a local file to the targetFile writes and data transfer
getuidReport the effective identityIdentity query; does not prove access to a resource
psList processesProcess enumeration
make_tokenCreate and impersonate an alternate network contextLogon/authentication state changes
steal_tokenImpersonate an accessible process tokenProcess/token access
rev2selfEnd current token impersonationReturns to the original context; does not purge tickets
kill <PID>Terminate a processProcess termination and possible application disruption
exitEnd the Beacon sessionSession termination; earlier evidence remains
shell
# Basic context inspection in Beacon
getuid
pwd
ps
ls

# Inspect supported syntax without performing file transfers or token changes
help download
help upload
help make_token
help steal_token

Inline commands: BOFs

A Beacon Object File is compiled native code executed within a Beacon session. Classify both the execution container and the action performed: an inline command can still create a service, access another process or communicate remotely.

Command or familyFunctionOPSEC consideration
reg query / reg queryvRead registry dataRegistry access remains observable
kerberos_ticket_useImport a Kerberos ticketChanges a logon session’s ticket cache
kerberos_ticket_purgeClear the selected session’s ticketsCan disrupt authentication if the wrong session is selected
clipboardClipboard-related collectionSensitive data access; behavior depends on implementation
getsystemAttempt a SYSTEM context transitionPrivilege-related activity; success is context-dependent
jump psexec familyService-backed remote executionInline implementation does not remove service or remote-host evidence
runasadmin familyAdministrative-context operationsToken/process activity and policy-dependent behavior
shell
# Inspect the installed registry and ticket commands
help reg
help kerberos_ticket_use
help kerberos_ticket_purge

OPSEC: “BOF” does not mean “no threads” or “no child processes.” The BOF’s own implementation determines which APIs it invokes. In-process execution is a location, not an assurance of low visibility.

Fork-and-run and explicit-process jobs

Fork-and-run creates a temporary process and executes a post-exploitation component there. Explicit-process variants target an already existing process. Both can involve process access, executable memory and result channels.

CommandExecution patternFunction
execute-assemblyFork-and-runExecute a .NET assembly
powerpickFork-and-runExecute PowerShell through a runspace
psinjectExplicit processRun PowerShell in a selected process
portscanSpawn or explicit-process variantPort discovery
mimikatzSpawn or explicit-process variantCredential/security operations
keyloggerSpawn or explicit-process variantKeystroke collection
printscreen / desktopSpawn or explicit-process variantScreen capture / desktop interaction
shell
# Check installed argument support and track existing jobs
help execute-assembly
help powerpick
help psinject
jobs

OPSEC: account for the host process, component, thread activity and IPC separately. A command can avoid launching powershell.exe while still executing PowerShell content. A tasking message is not proof of successful execution or of an absence of detection.

Process execution commands

CommandBehaviorResult and evidence
executeLaunch a programDoes not return ordinary command output
runLaunch a program and return outputNew process and command line
runasLaunch with alternate credentialsNew process plus authentication context
runuLaunch using the specified process context/parent mechanismCheck the installed command’s requirements and behavior
shellExecute through cmd.exeInterpreter process and /c command line
powershellExecute through powershell.exeInterpreter, arguments and script/runtime evidence
shell
# Benign comparison of execution paths
run whoami
shell whoami
powershell $PSVersionTable.PSVersion
# Compare process events and interpreter activity, not just displayed output

run whoami and shell whoami can return similar text through different process paths. The output alone does not describe what executed on the endpoint.

Service creation commands

Command familyFunctionEffects to account for
elevate svc-exeService-based local context transitionService configuration, process creation and image path
jump psexec, psexec64, psexec_pshService-based remote executionRemote authentication, service activity and target execution
remote-exec psexecRemote command through a serviceService and process activity on the destination

OPSEC: service workflows have their own executable and process behavior. Do not assume the temporary-process setting for ordinary post-exploitation jobs governs service executables. Inspect both source and destination evidence.

Quick classification

text
help / jobs / note         → session and client management
pwd / ls / getuid / ps     → native/API-oriented operations
reg query / ticket import → inline capability plus its actual action
execute-assembly          → post-exploitation job in a separate process
psinject                  → post-exploitation in an existing process
run                       → new executable process
shell                     → cmd.exe plus the requested command
powershell                → powershell.exe plus script/runtime activity
psexec family             → remote authentication, service and execution

Implementation and extension behavior vary by version. Confirm the installed behavior with the Cobalt Strike command reference.

6. Process trees, command lines and access-denied results

A process’s normal role may be inconsistent with its children or network activity. Examine the full relationship rather than relying on one process name. Parent attribution and sacrificial-process selection do not erase underlying execution activity.

powershell
# Current snapshot: executable, command line and reported parent PID
Get-CimInstance Win32_Process |
    Select-Object ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine

# Services provide a separate execution and persistence surface
Get-CimInstance Win32_Service |
    Select-Object Name, State, StartName, PathName, ProcessId

Some properties require additional permissions. PIDs can be reused, and the parent may have exited before this snapshot. Correlate with historical process events and timestamps.

Windows provides process-notification callbacks with information including image name, command line and creation status. A registered component can reject process creation. However, error 5 or ERROR_ACCESS_DENIED alone does not establish that Defender blocked the action: permissions, policy and other protection mechanisms can also explain it. Confirm the cause with the corresponding event evidence. See Microsoft’s PS_CREATE_NOTIFY_INFO documentation.

7. Correlate endpoint telemetry

Availability depends on installation, audit policy and filtering. Sysmon does not record every memory operation or injection technique, and the absence of a particular event is not proof that the action did not occur.

SourceUseful evidence
Defender OperationalDetection and action records; configuration changes
PowerShell OperationalScript-block content where supported and enabled
Sysmon 1Process creation and associated context
Sysmon 3Network connections, if configured
Sysmon 7Image loading, if configured
Sysmon 8 / 10Remote-thread creation / process access
Sysmon 17 / 18Named-pipe creation / connection
Sysmon 25Supported process-tampering detections
System 7045Service installation records

Event definitions: Sysmon documentation. A detected threat and an action taken are separate observations in Defender’s event reference.

powershell
$since = (Get-Date).AddHours(-1)

# Inspect protection state and intelligence version without changing settings
Get-MpComputerStatus |
    Select-Object AMServiceEnabled, AntivirusEnabled, RealTimeProtectionEnabled,
        AntivirusSignatureVersion, AntivirusSignatureLastUpdated

# Review active and historical detection records
Get-MpThreatDetection

# Defender: detection, action and configuration-change events
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-Windows Defender/Operational'
    Id = 1116, 1117, 5007
    StartTime = $since
} -MaxEvents 100 |
    Select-Object TimeCreated, Id, Message

# Sysmon: query only if installed and the channel is available
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-Sysmon/Operational'
    Id = 1, 3, 7, 8, 10, 17, 18, 25
    StartTime = $since
} -MaxEvents 200 |
    Select-Object TimeCreated, Id, Message

# Correlate service installation with the same time window
Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    Id = 7045
    StartTime = $since
} -MaxEvents 50 |
    Select-Object TimeCreated, Id, Message

An event query returning no matching records differs from an unavailable channel or an access-denied error. Record which case occurred. Also distinguish the host’s local event store from centrally retained EDR evidence.

8. Repeatable validation

Separate artifact, resource and profile layers when comparing execution paths. A connected Beacon cannot explain which individual change affected a detection.

Example stageEvidence required for a useful conclusion
Profile/configurationVersion, profile identity and confirmation of the configuration actually loaded
Compiled outputsExact file, architecture, hash and build revision
Script outputsTemplate, wrapper and actual delivery-time script
RuntimeHost protection state, timestamps, process/memory observations and task result
Post-exploitationActual process/service/authentication mechanism on every involved host
Final comparisonFunctional result and security observations recorded separately

Use one documented comparison at a time. Keep a baseline and preserve the same host configuration when drawing conclusions. Note any restart or regeneration because it changes what is being compared.

Disabling a protection or tampering with AMSI invalidates a claim that the same enabled protections accepted an artifact. Record control state explicitly and distinguish disabled inspection from a control that remained active but produced no detection.

9. Troubleshooting

FindingNext evidence to collect
File check is clean but execution is detectedRuntime script content, process events and Defender action records
Profile change appears ineffectiveLoaded profile identity, version and whether the running artifact predates the change
Script works locally but fails through deliveryActual delivered content, interpreter/version and script/runtime errors
Task returns access deniedIdentity, object permissions, policy and contemporaneous security events
Expected process is missingCreation failure, process termination and historical process events
No event appearsChannel availability, audit configuration, filters, time range and retention
Beacon connects but a post-ex task failsTask-specific implementation and dependency errors
Service-related behavior differs from other tasksService image/configuration and its distinct execution path

10. Quick checklist

Run the PowerShell commands locally on the observation host with the required read permissions. Replace paths and select a time window covering the exercise. The checklist records evidence without changing security controls.

text
BASELINE AND FILE IDENTITY
[ ] $since = (Get-Date).AddHours(-1)
[ ] Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, AntivirusSignatureVersion, AntivirusSignatureLastUpdated
[ ] Get-FileHash -LiteralPath 'C:\path\sample.exe' -Algorithm SHA256
[ ] Get-AuthenticodeSignature -LiteralPath 'C:\path\sample.exe'
[ ] Record product/tool version, architecture and configuration identity
[ ] Distinguish Artifact Kit, Resource Kit and profile changes

SCRIPT VISIBILITY
[ ] Get-WinEvent -ListLog '*PowerShell*' | Select-Object LogName, IsEnabled, RecordCount
[ ] Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104; StartTime=$since} -MaxEvents 100
[ ] Use PowerShellCore/Operational instead when applicable and available
[ ] Separate stored script, delivered wrapper and runtime content

PROCESS, MEMORY AND SERVICE CONTEXT
[ ] Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId, Name, CommandLine
[ ] Get-CimInstance Win32_Service | Select-Object Name, State, StartName, PathName, ProcessId
[ ] In the memory inspection tool, correlate regions, protections, mapped files and threads
[ ] Classify the actual task implementation; do not assume BOFs or native APIs are unmonitored
[ ] Correlate timestamps and historical identity because PIDs can be reused

DETECTION AND ACTION RECORDS
[ ] Get-MpThreatDetection
[ ] Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Windows Defender/Operational'; Id=1116,1117,5007; StartTime=$since} -MaxEvents 100
[ ] Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1,3,7,8,10,17,18,25; StartTime=$since} -MaxEvents 200
[ ] Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045; StartTime=$since} -MaxEvents 50
[ ] Record unavailable channels and permission errors separately from empty query results

OPSEC REVIEW AND CONCLUSION
[ ] Record file writes, process creation/access, script execution, pipes and remote authentication
[ ] Include every host affected by a remote or service-based task
[ ] Distinguish observed success, observed detection and confirmed blocking
[ ] Confirm that protection state was unchanged during the comparison
[ ] Preserve evidence; ending a session does not remove its earlier telemetry
[ ] Describe the result within the exact tested versions and configuration