dissect.cobaltstrike.beacon
This module is responsible for extracting and parsing configuration from Cobalt Strike beacon payloads.
Module Contents
Classes
A |
Functions
|
Find and yield (possible) Cobalt Strike configuration bytes from file fh using xorkey (eg: b"x69"). |
|
Yield tuple with found Beacon config_block_bytes from file fobj and extra_info dict |
|
Return all single-byte bytes as an ordered list, excluding exclude bytes. |
|
Returns an iterator yielding |
|
Collect data into fixed-length chunks or blocks |
|
Parse |
|
Parse |
|
Parse |
Parse |
|
|
Parse |
|
Parse |
|
Return the SHA-256 digest of der_data |
|
Return null terminated data as bytes. |
|
Return null terminated data as string. Non ascii characters are ignored. |
|
Entrypoint for beacon-dump. |
Attributes
Default XOR keys used by Cobalt Strike for obfuscating Beacon config bytes |
|
BeaconSetting enum to pretty function mapping |
- dissect.cobaltstrike.beacon.CS_DEF = Multiline-String[source]
Show Value
1enum BeaconSetting: uint16 { 2 SETTING_PROTOCOL = 1, 3 SETTING_PORT = 2, 4 SETTING_SLEEPTIME = 3, 5 SETTING_MAXGET = 4, 6 SETTING_JITTER = 5, 7 SETTING_MAXDNS = 6, 8 SETTING_PUBKEY = 7, 9 SETTING_DOMAINS = 8, 10 SETTING_USERAGENT = 9, 11 SETTING_SUBMITURI = 10, 12 SETTING_C2_RECOVER = 11, 13 SETTING_C2_REQUEST = 12, 14 SETTING_C2_POSTREQ = 13, 15 SETTING_SPAWNTO = 14, // releasenotes.txt 16 17 // CobaltStrike version >= 3.4 (27 Jul, 2016) 18 SETTING_PIPENAME = 15, 19 SETTING_KILLDATE_YEAR = 16, 20 SETTING_KILLDATE_MONTH = 17, 21 SETTING_KILLDATE_DAY = 18, 22 SETTING_DNS_IDLE = 19, 23 SETTING_DNS_SLEEP = 20, 24 25 // CobaltStrike version >= 3.5 (22 Sept, 2016) 26 SETTING_SSH_HOST = 21, 27 SETTING_SSH_PORT = 22, 28 SETTING_SSH_USERNAME = 23, 29 SETTING_SSH_PASSWORD = 24, 30 SETTING_SSH_KEY = 25, 31 SETTING_C2_VERB_GET = 26, 32 SETTING_C2_VERB_POST = 27, 33 SETTING_C2_CHUNK_POST = 28, 34 SETTING_SPAWNTO_X86 = 29, 35 SETTING_SPAWNTO_X64 = 30, 36 37 // CobaltStrike version >= 3.6 (8 Dec, 2016) 38 SETTING_CRYPTO_SCHEME = 31, 39 40 // CobaltStrike version >= 3.7 (15 Mar, 2016) 41 SETTING_PROXY_CONFIG = 32, 42 SETTING_PROXY_USER = 33, 43 SETTING_PROXY_PASSWORD = 34, 44 SETTING_PROXY_BEHAVIOR = 35, 45 46 // CobaltStrike version >= 3.8 (23 May 2017) 47 // DEPRECATED_SETTING_INJECT_OPTIONS = 36, 48 49 // Renamed from DEPRECATED_SETTING_INJECT_OPTIONS in CobaltStrike 4.5 50 SETTING_WATERMARKHASH = 36, 51 52 // CobaltStrike version >= 3.9 (Sept 26, 2017) 53 SETTING_WATERMARK = 37, 54 55 // CobaltStrike version >= 3.11 (April 9, 2018) 56 SETTING_CLEANUP = 38, 57 58 // CobaltStrike version >= 3.11 (May 24, 2018) 59 SETTING_CFG_CAUTION = 39, 60 61 // CobaltStrike version >= 3.12 (Sept 6, 2018) 62 SETTING_KILLDATE = 40, 63 SETTING_GARGLE_NOOK = 41, // https://www.youtube.com/watch?v=nLTgWdXrx3U 64 SETTING_GARGLE_SECTIONS = 42, 65 SETTING_PROCINJ_PERMS_I = 43, 66 SETTING_PROCINJ_PERMS = 44, 67 SETTING_PROCINJ_MINALLOC = 45, 68 SETTING_PROCINJ_TRANSFORM_X86 = 46, 69 SETTING_PROCINJ_TRANSFORM_X64 = 47, 70 SETTING_PROCINJ_ALLOWED = 48, 71 72 // CobaltStrike version >= 3.13 (Jan 2, 2019) 73 SETTING_BINDHOST = 49, 74 75 // CobaltStrike version >= 3.14 (May 4, 2019) 76 SETTING_HTTP_NO_COOKIES = 50, 77 SETTING_PROCINJ_EXECUTE = 51, 78 SETTING_PROCINJ_ALLOCATOR = 52, 79 SETTING_PROCINJ_STUB = 53, // .self = MD5(cobaltstrike.jar) 80 81 // CobaltStrike version >= 4.0 (Dec 5, 2019) 82 SETTING_HOST_HEADER = 54, 83 SETTING_EXIT_FUNK = 55, 84 85 // CobaltStrike version >= 4.1 (June 25, 2020) 86 SETTING_SSH_BANNER = 56, 87 SETTING_SMB_FRAME_HEADER = 57, 88 SETTING_TCP_FRAME_HEADER = 58, 89 90 // CobaltStrike version >= 4.2 (Nov 6, 2020) 91 SETTING_HEADERS_REMOVE = 59, 92 93 // CobaltStrike version >= 4.3 (Mar 3, 2021) 94 SETTING_DNS_BEACON_BEACON = 60, 95 SETTING_DNS_BEACON_GET_A = 61, 96 SETTING_DNS_BEACON_GET_AAAA = 62, 97 SETTING_DNS_BEACON_GET_TXT = 63, 98 SETTING_DNS_BEACON_PUT_METADATA = 64, 99 SETTING_DNS_BEACON_PUT_OUTPUT = 65, 100 SETTING_DNSRESOLVER = 66, 101 SETTING_DOMAIN_STRATEGY = 67, 102 SETTING_DOMAIN_STRATEGY_SECONDS = 68, 103 SETTING_DOMAIN_STRATEGY_FAIL_X = 69, 104 SETTING_DOMAIN_STRATEGY_FAIL_SECONDS = 70, 105 106 // CobaltStrike version >= 4.5 (Dec 14, 2021) 107 SETTING_MAX_RETRY_STRATEGY_ATTEMPTS = 71, 108 SETTING_MAX_RETRY_STRATEGY_INCREASE = 72, 109 SETTING_MAX_RETRY_STRATEGY_DURATION = 73, 110 111 // CobaltStrike version >= 4.7 (Aug 17, 2022) 112 SETTING_MASKED_WATERMARK = 74, 113}; 114 115enum DeprecatedBeaconSetting: uint16 { 116 SETTING_KILLDATE_YEAR = 16, 117 SETTING_INJECT_OPTIONS = 36, 118}; 119 120enum TransformStep: uint32 { 121 APPEND = 1, 122 PREPEND = 2, 123 BASE64 = 3, 124 PRINT = 4, 125 PARAMETER = 5, 126 HEADER = 6, 127 BUILD = 7, 128 NETBIOS = 8, 129 _PARAMETER = 9, 130 _HEADER = 10, 131 NETBIOSU = 11, 132 URI_APPEND = 12, 133 BASE64URL = 13, 134 STRREP = 14, 135 MASK = 15, 136 // CobaltStrike version >= 4.0 (Dec 5, 2019) 137 _HOSTHEADER = 16, 138}; 139 140enum SettingsType: uint16 { 141 TYPE_NONE = 0, 142 TYPE_SHORT = 1, 143 TYPE_INT = 2, 144 TYPE_PTR = 3, 145}; 146 147struct Setting { 148 BeaconSetting index; // uint16 149 SettingsType type; // uint16 150 uint16 length; // uint16 151 char value[length]; 152}; 153 154flag BeaconProtocol { 155 http = 0, 156 dns = 1, 157 smb = 2, 158 tcp = 4, 159 https = 8, 160 bind = 16 161}; 162 163flag ProxyServer { 164 MANUAL = 0, 165 DIRECT = 1, 166 PRECONFIG = 2, 167 MANUAL_CREDS = 4 168}; 169 170enum CryptoScheme: uint16 { 171 CRYPTO_LICENSED_PRODUCT = 0, 172 CRYPTO_TRIAL_PRODUCT = 1 173}; 174 175enum InjectAllocator: uint8 { 176 VirtualAllocEx = 0, 177 NtMapViewOfSection = 1, 178}; 179 180enum InjectExecutor: uint8 { 181 CreateThread = 1, 182 SetThreadContext = 2, 183 CreateRemoteThread = 3, 184 RtlCreateUserThread = 4, 185 NtQueueApcThread = 5, 186 CreateThread_ = 6, 187 CreateRemoteThread_ = 7, 188 NtQueueApcThread_s = 8 189};
- dissect.cobaltstrike.beacon.DEFAULT_XOR_KEYS :List[bytes] = [b'i', b'.', b'\x00'][source]
Default XOR keys used by Cobalt Strike for obfuscating Beacon config bytes
- dissect.cobaltstrike.beacon.find_beacon_config_bytes(fh: BinaryIO, xorkey: bytes) Iterator[bytes] [source]
Find and yield (possible) Cobalt Strike configuration bytes from file fh using xorkey (eg: b”x69”).
This is done by scraping the file fh for XOR encoded configuration blocks. A beacon configuration block always (unless modified) starts with:
Setting(index=SETTING_PROTOCOL, type=TYPE_SHORT, length=0x2) # which translates to the following bytes b"\x00\x01\x00\x01\x00\x02\x00"
These bytes are used in conjuction with the XOR key for finding the (potential) start of a configuration block.
- Parameters
fh – file object
xorkey – XOR key (as bytes)
- Yields
Beacon configuration bytes (4096 bytes), in deobfuscated (un-XOR’d) form.
- dissect.cobaltstrike.beacon.iter_beacon_config_blocks(fobj: BinaryIO, xor_keys=None, xordecode=True, all_xor_keys=False) Iterator[Tuple[bytes, dict]] [source]
Yield tuple with found Beacon config_block_bytes from file fobj and extra_info dict
It always start seeking from the beginning of fobj. Side effects: file handle position due to seeking
The extra_info dictionary holds some metadata such as if the fobj was xorencoded and which xorkey was used.
- Parameters
xor_keys – list XOR keys (as bytes), defaults to:
DEFAULT_XOR_KEYS
if not specified.xordecode – If
True
it will also try to XorDecode the file object.all_xor_keys – Try ALL single-byte XOR keys if no beacon config is found using the default keys.
- Yields
Tuple as
(config_block_bytes, extra_info_dict)
– extra_info dict contains:{"xorkey": bytes, "xorencoded": bool}
- dissect.cobaltstrike.beacon.make_byte_list(exclude: List[bytes] = None) List[bytes] [source]
Return all single-byte bytes as an ordered list, excluding exclude bytes.
- dissect.cobaltstrike.beacon.iter_settings(fobj: Union[bytes, BinaryIO]) Iterator[Setting] [source]
Returns an iterator yielding
Setting
objects by reading data from fobjThe file position will be at the end of the Beacon config after parsing is done. This can be used to determine the exact size of the Beacon configuration block.
Some edge cases are also handled:
User-Agent string that exceeds the Setting length.
Deprecated setting SETTING_INJECT_OPTIONS
- Parameters
fobj – bytes or file-like object with Beacon configuration data
- Yields
Setting
objects
- dissect.cobaltstrike.beacon.grouper(iterable, n, fillvalue=None)[source]
Collect data into fixed-length chunks or blocks
- dissect.cobaltstrike.beacon.parse_recover_binary(program: bytes) List[Tuple[str, Union[int, bool]]] [source]
Parse
SETTING_C2_RECOVER
(.http-get.server.output) data
- dissect.cobaltstrike.beacon.parse_transform_binary(program: bytes, build: str = 'metadata') List[Tuple[str, Union[str, bytes, bool]]] [source]
Parse
SETTING_C2_{REQUEST,POSTREQ}
(http-{get,post}.client) data
- dissect.cobaltstrike.beacon.parse_execute_list(data: bytes) List[str] [source]
Parse
SETTING_PROCINJ_EXECUTE
(.process-inject.execute) data
- dissect.cobaltstrike.beacon.parse_process_injection_transform_steps(data: bytes) list [source]
Parse
SETTING_PROCINJ_TRANSFORM_X{86,64}
(process-inject.transform-x{86,64}) data
- dissect.cobaltstrike.beacon.parse_gargle(data: bytes) list [source]
Parse
SETTING_GARGLE_SECTIONS
(.stage.{sleep_mask,obfuscate,userwx}) data
- dissect.cobaltstrike.beacon.parse_pivot_frame(data: bytes) bytes [source]
Parse
SETTING_{TCP,SMB}_FRAME_HEADER
(.{tcp,smb}_frame_header) data
- dissect.cobaltstrike.beacon.sha256sum_pubkey(der_data: bytes) str [source]
Return the SHA-256 digest of der_data
- dissect.cobaltstrike.beacon.null_terminated_bytes(data: bytes) bytes [source]
Return null terminated data as bytes.
>>> null_terminated_bytes(b"Hello World\x00\x00Foobar\x00\x00") b'Hello World' >>> null_terminated_bytes(b"foo\xffbar\x00\x00\x00baz\x00") b'foo\xffbar'
- dissect.cobaltstrike.beacon.null_terminated_str(data: bytes) str [source]
Return null terminated data as string. Non ascii characters are ignored.
>>> null_terminated_str(b"Hello World\x00\x00foo bar\x00\x00") 'Hello World' >>> null_terminated_str(b"Goodbye\xffPlanet\x00\x00") 'GoodbyePlanet'
- dissect.cobaltstrike.beacon.SETTING_TO_PRETTYFUNC :Dict[BeaconSetting, Callable][source]
BeaconSetting enum to pretty function mapping
- class dissect.cobaltstrike.beacon.BeaconConfig(config_block: bytes)[source]
A
BeaconConfig
object represents a single Beacon configurationIt holds configuration data, parsed settings and other metadata of a Cobalt Strike Beacon and provides useful methods and properties for accessing the Beacon settings. It does not contain the Beacon payload data itself.
It can be directly instantiated using configuration data. Otherwise, use the following constructors:
The from_ constructors automatically tries to extract the configuration data (first candidate only) and also handles xorencoded payloads and XOR decoding of obfuscated configuration blocks that is common with Cobalt Strike.
- property setting_enums: list[source]
List of BeaconSetting enum values in the order of appearance within the Beacon configuration. Example value:
[1, 2, 3, 4, 5, 7, ..., 45, 46, 47, 53, 51, 52]
- property max_setting_enum: int[source]
The maximum BeaconSetting enum value present in the Beacon configuration.
- property raw_settings: Mapping[str, Any][source]
Read-only Beacon settings mapping with raw values, indexed by BeaconSetting name.
The raw bytes of TYPE_SHORT and TYPE_INT values are converted to int. Example value:
mappingproxy({ 'SETTING_PROTOCOL': 8, 'SETTING_PORT': 443, 'SETTING_SLEEPTIME': 60000, ... 'SETTING_C2_VERB_POST': b'POST\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'SETTING_PROCINJ_STUB': b'\x0c\xe2\xf5TD\xe4y5\x16\xb5\xaf\xe9g\xbe\x92U', })
- property raw_settings_by_index: Mapping[int, Any][source]
Read-only Beacon settings mapping with raw values, indexed by BeaconSetting constant.
The raw bytes of TYPE_SHORT and TYPE_INT values are converted to int. Example value:
mappingproxy({ 1: 8, 2: 443, 3: 60000, ... 27: b'POST\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 53: b'\x0c\xe2\xf5TD\xe4y5\x16\xb5\xaf\xe9g\xbe\x92U', })
- property settings: Mapping[str, Any][source]
Read-only Beacon settings mapping with human readable values, indexed by BeaconSetting name. Example value:
mappingproxy({ 'SETTING_PROTOCOL': 8, 'SETTING_PORT': 443, 'SETTING_SLEEPTIME': 60000, ... 'SETTING_C2_VERB_POST': 'POST', 'SETTING_PROCINJ_STUB': '0ce2f55444e4793516b5afe967be9255', })
- property settings_by_index: Mapping[int, Any][source]
Read-only Beacon settings mapping with human readable values, indexed by BeaconSetting constant. Example value:
mappingproxy({ 1: 8, 2: 443, 3: 60000, ... 27: 'POST', 53: '0ce2f55444e4793516b5afe967be9255', })
- property domain_uri_pairs: List[Tuple[str, str]][source]
List of configured (domain, uri) pairs in the Beacon. Example value:
[ ('c1.example.com', '/__utm.gif'), ('c2.example.com', '/en_US/all.js'), ]
- property uris: List[str][source]
List of configured Beacon URIs. Example value:
['/__utm.gif', '/en_US/all.js']
- property domains: List[str][source]
List of configured Beacon domains. Example value:
['c1.example.com', 'c2.example.com']
- property submit_uri: Optional[str][source]
The submit URI that the beacon uses for sending callback data. Example value:
'/submit.php'
- property killdate: Optional[str][source]
Normalized kill date as YYYY-mm-dd string or
None
if not defined in Beacon.Note
The reason why the return type is a
str
instead of adatetime.date
object is that the configured killdate in the Beacon can be arbitrary. e.g. 9999-99-99
- property protocol: Optional[str][source]
The protocol the Beacon uses for communication, e.g.
"http"
,"dns"
.None
if unknown.
- property port: Optional[int][source]
The port the Beacon uses for communication, e.g.
80
,443
.None
if not defined in config.
- property watermark: Optional[int][source]
Beacon watermark (also known as customer or authorization id).
- property is_trial: bool[source]
True if Beacon is a trial version (CRYPTO_TRIAL_PRODUCT). Otherwise, False.
- property version: dissect.cobaltstrike.version.BeaconVersion[source]
Deduced version of Cobalt Strike as
BeaconVersion
object.The version is deduced from the Beacon’s
pe_export_stamp
when available, otherwise frommax_setting_enum
.
- property sleeptime: Optional[int][source]
The sleep time in milliseconds the Beacon uses between communication attempts.
- property jitter: Optional[int][source]
The jitter in milliseconds the Beacon uses between communication attempts.
- xorkey :Optional[bytes][source]
XOR key that was used to obfuscate the configuration block,
None
if unknown.
- classmethod from_file(fobj: BinaryIO, xor_keys: List[bytes] = None, all_xor_keys: bool = False) BeaconConfig [source]
Create a
BeaconConfig
from file object, or raises ValueError if no beacon config is found.- Parameters
fobj – file-like object
xor_keys – override the default XOR keys (as bytes) when specified. Default
None
.all_xor_keys – if
True
, it will try ALL single-byte XOR keys if the defaults don’t work
- Returns
- Raises
ValueError – If no valid beacon configuration was found
- classmethod from_path(path: Union[str, os.PathLike], xor_keys: List[bytes] = None, all_xor_keys: bool = False) BeaconConfig [source]
Create a
BeaconConfig
from path, or raises ValueError if no beacon config is found.- Parameters
path – path to file on disk
xor_keys – override the default XOR keys (as bytes) when specified. Default
None
.all_xor_keys – if
True
it will try ALL single-byte XOR keys if the defaults don’t work
- Returns
- Raises
ValueError – If no valid beacon configuration was found
- classmethod from_bytes(data: bytes, xor_keys: List[bytes] = None, all_xor_keys: bool = False) BeaconConfig [source]
Create a
BeaconConfig
from bytes, or raises ValueError if no beacon config is found.- Parameters
data – configuration bytes
xor_keys – override the default XOR keys when specified. Default
None
.all_xor_keys – if
True
it will try ALL single-byte XOR keys if the defaults don’t work
- Returns
- Raises
ValueError – If no valid beacon configuration was found
- settings_map(index_type='enum', pretty=False, parse=True) types.MappingProxyType [source]
Return a read-only settings mapping indexed by given index_type.
- Parameters
index_type –
index type of the dictionary, can be one of:
name
: indexed by BeaconSetting name (str)const
: indexed by BeaconSetting constant (int)enum
: indexed by BeaconSetting enum (enum object).
pretty – if True, apply pretty functions on the values.
parse – if True, the raw bytes of TYPE_SHORT and TYPE_INT values are converted to int.
- Returns
OrderedDict