Jump & Remote-Exec

Aggressor can be used to register new techniques under jump and remote-exec using beacon_remote_exploit_registerarrow-up-right and beacon_remote_exec_method_registerarrow-up-right respectively.

In this example, we'll integrate Invoke-DCOM.ps1 into jump. First, create a new text file in Visual Studio and save is somewhere as dcom.cna. Then add the following skeleton.

sub invoke_dcom
{
}

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

\

This will register "dcom" as a new option inside the jump command and specifies invoke_dcom as the associated callback function. The first thing to add inside this callback are some local variable declarations.

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

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

\

local defines variables that are local to the current function, so they will disappear once executed. Sleep can have global, closure-specific and local scopes. More information can be found in 5.2 Scalar Scope of the Sleep manual.

The next step is to acknowledge receipt of the task using btaskarrow-up-right. This takes the ID of the Beacon, the text to post and an ATT&CK tactic ID. This will print a message to the Beacon console and add it to the data model used in the activity and session reports that you can generate from Cobalt Strike.

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");
}

\

You'll notice $1, $2 and $3 variables here which are automatically passed in by the client. Where:

  • $1 is the Beacon ID.

  • $2 is the target to jump to.

  • $3 is the selected listener.

\

Furthermore, listener_describearrow-up-right expands a listener name into a more detailed description. For example, instead of "smb" it will say "windows/beacon_bind_pipe (\\.\pipe\<pipename>)".

\

Next, we want to read in the Invoke-DCOM script from our machine. This can be done openfarrow-up-right, getFileProperarrow-up-right and script_resourcearrow-up-right. Notice how we're assigning values to the variables we declared at the start.

\

The $script variable now holds the raw content of Invoke-DCOM.ps1. For Beacon to utilise it, we can use beacon_host_scriptarrow-up-right - this will host the script inside Beacon and returns a short snippet for running it.

If you want to see the content of these variables, you can use println($oneliner); and they'll appear in the Script Console (Cobalt Strike > Script Console).

\

The next step is to generate and upload a payload to the target using artifact_payloadarrow-up-rightand bupload_rawarrow-up-right. This will generate an EXE payload and upload it to the target in the C:\Windows\Temp directory.

$+ concatenates an interpolated string and requires additional whitespaces on each end.

\

Then, bpowerpickarrow-up-right can execute the Invoke-DCOM oneliner. We pass it the target computer name and the path to the uploaded payload. Also, because this could be a P2P payload - we want to automatically try and link to it, which can be done with beacon_linkarrow-up-right.

\

The final script:

\

Make sure to load the script via the Script Manger (Cobalt Strike > Script Manager).

\

\

The flexibility of Aggressor means that we can leverage anything from PowerShell, execute-assembly, shellcode injection, DLL injection and more.

Last updated