dissect.cobaltstrike.c2

This module is responsible for working with Cobalt Strike C2 traffic.

Module Contents

Classes

EncryptedPacket

Container to hold ciphertext and HMAC signature.

C2Data

Container for holding C2 data that is used for transform and recover steps.

ServerC2Data

Container for holding recovered server-side C2Data.

ClientC2Data

Container for holding recovered client-side C2Data.

HttpRequest

HTTP Request container.

HttpResponse

HTTP Response container.

BeaconKeys

Helper container to hold beacon session keys (AES + HMAC).

HttpDataTransform

Transform and recover Cobalt Strike HTTP C2 data using transformation steps.

C2Http

Class for decrypting and encrypting Cobalt Strike HTTP C2 traffic.

Functions

enable_reprlib_c2()

Enables reprlib __repr__ for most of the namedtuple classes in this module.

c2packet_to_record(→ flow.record.Record)

Convert c2packet to a flow.record.

parse_raw_http(→ Union[HttpRequest, HttpResponse])

Parse a raw HTTP request/response bytes and returns a HttpRequest or HttpResponse accordingly.

decrypt_metadata(...)

Decrypt encrypted_metadata using RSA private_key.

encrypt_metadata(→ bytes)

Encrypt metadata using RSA public_key.

derive_aes_hmac_keys(→ Tuple[bytes, bytes])

Derive the AES and HMAC keys from the aes_random bytes.

pad(→ bytes)

Mimics the padding behaviour in Cobalt Strike (which is to fill it with b'A').

encrypt_data(→ bytes)

AES encrypt data with given aes_key and iv.

decrypt_data(→ bytes)

AES decrypt the data with given aes_key and iv and return the decrypted bytes.

decrypt_packet(→ bytes)

Decrypt EncryptedPacket packet and return the decrypted plaintext bytes.

encrypt_packet(→ EncryptedPacket)

Encrypt plaintext bytes and return a EncryptedPacket.

Attributes

TransformStep

Type TransformStep.

C2Packet

Type that is either a BeaconMetadata, a TaskPacket or a CallbackPacket.

logger

dissect.cobaltstrike.c2.TransformStep[source]

Type TransformStep.

dissect.cobaltstrike.c2.C2Packet[source]

Type that is either a BeaconMetadata, a TaskPacket or a CallbackPacket.

dissect.cobaltstrike.c2.logger[source]
class dissect.cobaltstrike.c2.EncryptedPacket[source]

Bases: NamedTuple

Container to hold ciphertext and HMAC signature.

ciphertext: bytes[source]
signature: bytes[source]
dumps()[source]

Return the EncryptedPacket as a bytes object with a size frame header.

| size | ciphertext | signature |

raise_for_signature(hmac_key: bytes)[source]
Parameters:

hmac_key – HMAC key to use for signature verification

Raises:

ValueError – if signature of the ciphertext is incorrect.

class dissect.cobaltstrike.c2.C2Data[source]

Bases: NamedTuple

Container for holding C2 data that is used for transform and recover steps.

output: bytes | None[source]
metadata: bytes | None[source]
id: bytes | None[source]
class dissect.cobaltstrike.c2.ServerC2Data[source]

Bases: C2Data

Container for holding recovered server-side C2Data.

iter_encrypted_packets() Iterator[EncryptedPacket][source]

Iterate over EncryptedPacket, parsed from server-side c2data.output data.

For server-side data this is always one packet.

class dissect.cobaltstrike.c2.ClientC2Data[source]

Bases: C2Data

Container for holding recovered client-side C2Data.

iter_encrypted_packets() Iterator[EncryptedPacket][source]

Iterate over EncryptedPacket, parsed from client-side c2data.output data.

For client-side data this could be one or more packets.

class dissect.cobaltstrike.c2.HttpRequest[source]

Bases: NamedTuple

HTTP Request container.

method: bytes[source]
uri: bytes[source]
params: Dict[bytes, bytes][source]
headers: Dict[bytes, bytes][source]
body: bytes[source]
class dissect.cobaltstrike.c2.HttpResponse[source]

Bases: NamedTuple

HTTP Response container.

status: int[source]
headers: Dict[bytes, bytes][source]
reason: bytes[source]
body: bytes[source]
request: HttpRequest | None[source]
class dissect.cobaltstrike.c2.BeaconKeys[source]

Bases: NamedTuple

Helper container to hold beacon session keys (AES + HMAC).

DEFAULT_AES_IV = b'abcdefghijklmnop'[source]
aes_key: bytes | None[source]
hmac_key: bytes | None[source]
iv: bytes[source]
classmethod from_aes_rand(aes_rand: bytes, iv: bytes = DEFAULT_AES_IV) BeaconKeys[source]

Create a BeaconKeys instance from AES random bytes.

classmethod from_beacon_metadata(metadata: dissect.cobaltstrike.c_c2.BeaconMetadata, iv: bytes = DEFAULT_AES_IV) BeaconKeys[source]

Create a BeaconKeys instance from BeaconMetadata.

dissect.cobaltstrike.c2.enable_reprlib_c2()[source]

Enables reprlib __repr__ for most of the namedtuple classes in this module.

dissect.cobaltstrike.c2.c2packet_to_record(c2packet: C2Packet) flow.record.Record[source]

Convert c2packet to a flow.record.

dissect.cobaltstrike.c2.parse_raw_http(data: bytes) HttpRequest | HttpResponse[source]

Parse a raw HTTP request/response bytes and returns a HttpRequest or HttpResponse accordingly.

Parameters:

data – raw HTTP request or response data bytes.

Returns:

Either a HttpRequest or HttpResponse object based on the data.

Raises:

ValueError – if it cannot be parsed as HttpRequest or HttpResponse.

class dissect.cobaltstrike.c2.HttpDataTransform(steps: List[TransformStep], reverse: bool = False, build: str = None)[source]

Transform and recover Cobalt Strike HTTP C2 data using transformation steps.

transform(c2data: C2Data, request: HttpRequest | None = None) HttpRequest[source]

Transform c2data information into a HttpRequest namedtuple.

Parameters:
  • c2dataC2Data named tuple that needs to be transformed

  • request – Optional initial HTTP request data

Returns:

Transformed HTTP request data

Return type:

HttpRequest

recover(http: HttpRequest) ClientC2Data[source]
recover(http: HttpResponse) ServerC2Data

Recovers the transformed data in http object and returns a C2Data namedtuple.

Parameters:

http – a HttpRequest or HttpResponse namedtuple

Returns:

Either a ClientC2Data or ServerC2Data namedtuple based on the http data.

class dissect.cobaltstrike.c2.C2Http(bconfig: dissect.cobaltstrike.beacon.BeaconConfig, aes_key: bytes | None = None, hmac_key: bytes | None = None, aes_rand: bytes | None = None, rsa_private_key: Crypto.PublicKey.RSA.RsaKey | None = None, verify_hmac=True)[source]

Class for decrypting and encrypting Cobalt Strike HTTP C2 traffic.

It requires to be initialized with a BeaconConfig and one of the following key material:

  • aes_key and optionally hmac_key

  • aes_rand

  • rsa_private_key (most preferred when available)

get_transform_for_http(http: HttpRequest | HttpResponse | bytes) HttpDataTransform[source]

Return the correct HttpDataTransform instance for given http.

Parameters:

http – either a HttpRequest or HttpResponse object or raw HTTP bytes.

Returns:

The correct HttpDataTransform instance for given http.

Return type:

HttpDataTransform

Raises:

ValueError – if no correct transform can be found for given http object.

iter_recover_http(http: bytes | HttpRequest | HttpResponse, keys: BeaconKeys | None = None) Iterator[C2Packet][source]

Yield decrypted C2Packet objects from given http object.

You can pass your own set of BeaconKeys keys to use for decryption instead of the default initialized ones. This can be useful if you are processing multiple Beacon sessions and do some sort of session tracking outside this class.

Parameters:
  • http – A HttpRequest or HttpResponse object, or raw HTTP request or response bytes.

  • keys – Optional BeaconKeys to use for decryption instead of current default keys.

Yields:

C2Packet – A C2Packet object for each decrypted packet found in the HTTP request or response.

dissect.cobaltstrike.c2.decrypt_metadata(encrypted_metadata: bytes, private_key: Crypto.PublicKey.RSA.RsaKey) dissect.cobaltstrike.c_c2.BeaconMetadata[source]

Decrypt encrypted_metadata using RSA private_key.

Parameters:
  • encrypted_metadata – the encrypted metadata bytes

  • private_key – the RSA private key used for decryption

Returns:

The decrypted metadata.

Return type:

BeaconMetadata

Raises:

ValueError – if RSA failed to decrypt or metadata magic is invalid

dissect.cobaltstrike.c2.encrypt_metadata(metadata: dissect.cobaltstrike.c_c2.BeaconMetadata, public_key: Crypto.PublicKey.RSA.RsaKey) bytes[source]

Encrypt metadata using RSA public_key.

Parameters:
  • metadataBeaconMetadata object to encrypt

  • public_key – the RSA public key used for encryption

Returns:

The encrypted metadata as bytes

dissect.cobaltstrike.c2.derive_aes_hmac_keys(aes_random: bytes) Tuple[bytes, bytes][source]

Derive the AES and HMAC keys from the aes_random bytes.

Parameters:

aes_random – the bytes to derive the keys from

Returns:

Tuple of (aes_key, hmac_key)

dissect.cobaltstrike.c2.pad(data: bytes, block_size: int = AES.block_size) bytes[source]

Mimics the padding behaviour in Cobalt Strike (which is to fill it with b’A’).

Parameters:
  • data – the data to pad

  • block_size – the block size to use for padding

Returns:

The padded data

dissect.cobaltstrike.c2.encrypt_data(data: bytes, aes_key: bytes, iv: bytes) bytes[source]

AES encrypt data with given aes_key and iv.

Parameters:
  • data – the data to encrypt

  • aes_key – the AES key to use

  • iv – the initialization vector to use

Returns:

The encrypted data as bytes

dissect.cobaltstrike.c2.decrypt_data(data: bytes, aes_key: bytes, iv: bytes) bytes[source]

AES decrypt the data with given aes_key and iv and return the decrypted bytes.

Parameters:
  • data – the encrypted data

  • aes_key – the AES key to use for decryption

  • iv – the AES IV to use for decryption

Returns:

The decrypted data as bytes

dissect.cobaltstrike.c2.decrypt_packet(packet: EncryptedPacket, aes_key: bytes, hmac_key: bytes | None = None, iv: bytes = BeaconKeys.DEFAULT_AES_IV, verify: bool = True) bytes[source]

Decrypt EncryptedPacket packet and return the decrypted plaintext bytes.

If hmac_key is defined, the signature of the ciphertext is verified first before decrypting.

Parameters:
  • packet – the EncryptedPacket to decrypt

  • aes_key – the AES key to use for decryption

  • hmac_key – the HMAC key to use for signature verification

  • iv – the AES IV to use for decryption

  • verify – whether to verify the HMAC signature of the ciphertext

Returns:

The decrypted plaintext bytes

dissect.cobaltstrike.c2.encrypt_packet(plaintext: bytes, aes_key: bytes, hmac_key: bytes, iv: bytes = BeaconKeys.DEFAULT_AES_IV) EncryptedPacket[source]

Encrypt plaintext bytes and return a EncryptedPacket.

Parameters:
  • plaintext – the plaintext bytes to encrypt

  • aes_key – the AES key to use for encryption

  • hmac_key – the HMAC key to use for signature generation

  • iv – the AES IV to use for encryption

Returns:

The EncryptedPacket containing the ciphertext and HMAC signature