Communitygithub.com

análise-de-configuração-cobalt-strike-beacon

Extrair e analisar a configuração do Cobalt Strike Beacon a partir de arquivos PE

O que é análise-de-configuração-cobalt-strike-beacon?

Esta skill capacita analistas de segurança a extrair e decodificar configurações de beacons Cobalt Strike a partir de arquivos PE, shellcode ou dumps de memória. O Cobalt Strike, amplamente utilizado por atores de ameaças, codifica sua configuração interna usando XOR (chave 0x69 para v3, 0x2e para v4) e armazena em formato TLV na seção .data. Com esta skill, é possível recuperar endereços de servidores C2, protocolos de comunicação, intervalos de sleep, jitter, perfis malleable C2, watermarks e chaves de criptografia. A skill oferece scripts Python que utilizam bibliotecas como dissect.cobaltstrike e pefile, além de um decodificador manual de XOR, regras YARA para detecção e análise de tráfego de rede. É essencial para mapear infraestrutura de ataque, correlacionar campanhas e gerar assinaturas para sistemas de detecção como Suricata e Snort.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-cobalt-strike-beacon-configuration

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Análise de Configuração do Cobalt Strike Beacon

Visão Geral

O Cobalt Strike é uma ferramenta comercial de simulação de adversários amplamente abusada por atores de ameaças para operações de pós-exploração. Os payloads Beacon contêm dados de configuração embutidos que revelam endereços de servidores C2, protocolos de comunicação, intervalos de sleep, valores de jitter, configurações de perfil malleable C2, identificadores de watermark e chaves de criptografia. Extrair essa configuração de arquivos PE, shellcode ou dumps de memória é essencial para que respondedores de incidentes mapeiem a infraestrutura do atacante e atribuam campanhas. A configuração do beacon é codificada com XOR usando um único byte (0x69 para a versão 3, 0x2e para a versão 4) e armazenada em formato Tipo-Comprimento-Valor (TLV) dentro da seção .data.

Quando Usar

  • Ao investigar incidentes de segurança que exigem análise da configuração de beacons Cobalt Strike
  • Ao construir regras de detecção ou consultas de caça a ameaças para este domínio
  • Quando analistas de SOC precisam de procedimentos estruturados para este tipo de análise
  • Ao validar a cobertura de monitoramento de segurança para técnicas de ataque relacionadas

Pré-requisitos

  • Python 3.9+ com dissect.cobaltstrike, pefile, yara-python
  • CobaltStrikeParser da SentinelOne (parse_beacon_config.py)
  • Editor hexadecimal (010 Editor, HxD) para inspeção manual
  • Compreensão do formato de arquivo PE e codificação XOR
  • Ferramentas de aquisição de dump de memória (Volatility3, WinDbg)
  • Ferramentas de análise de rede (Wireshark) para correlação de tráfego C2

Conceitos Chave

Estrutura da Configuração do Beacon

Os beacons do Cobalt Strike armazenam sua configuração como um bloco de entradas TLV dentro da seção .data do PE. Beacons sem estágio codificam todo o código do beacon com uma chave de 4 bytes. O próprio bloco de configuração usa uma chave XOR de um único byte. Cada entrada TLV contém um identificador de tipo de 2 bytes (por exemplo, 0x0001 para BeaconType, 0x0008 para C2Server), um comprimento de 2 bytes e dados de comprimento variável.

Perfis Malleable C2

A configuração do beacon codifica o perfil malleable C2 que dita transformações de requisição/resposta HTTP, incluindo caminhos URI, cabeçalhos, codificação de metadados (Base64, NetBIOS) e transformações de dados. Analisar essas configurações revela como o beacon disfarça seu tráfego para se misturar com tráfego web legítimo.

Identificação de Watermark e Licença

Cada licença do Cobalt Strike incorpora um watermark único (inteiro de 4 bytes) nos beacons gerados. Extrair o watermark pode vincular vários beacons ao mesmo operador ou a uma licença quebrada. Bancos de dados de watermark conhecidos mantidos por provedores de inteligência de ameaças mapeiam watermarks para atores de ameaças específicos ou chaves de licença vazadas.

Fluxo de Trabalho

Passo 1: Extrair Configuração com CobaltStrikeParser

#!/usr/bin/env python3
"""Extrair configuração do beacon Cobalt Strike de PE ou dump de memória."""
import sys
import json

# Usando o CobaltStrikeParser da SentinelOne
# pip install dissect.cobaltstrike
from dissect.cobaltstrike.beacon import BeaconConfig

def extract_beacon_config(filepath):
    """Analisar configuração do beacon a partir do arquivo."""
    configs = list(BeaconConfig.from_path(filepath))

    if not configs:
        print(f"[-] Nenhuma configuração de beacon encontrada em {filepath}")
        return None

    for i, config in enumerate(configs):
        print(f"\n[+] Configuração do Beacon #{i+1}")
        print(f"{'='*60}")

        settings = config.as_dict()

        # Campos críticos para resposta a incidentes
        critical_fields = [
            "SETTING_C2_REQUEST",
            "SETTING_C2_RECOVER",
            "SETTING_PUBKEY",
            "SETTING_DOMAINS",
            "SETTING_BEACONTYPE",
            "SETTING_PORT",
            "SETTING_SLEEPTIME",
            "SETTING_JITTER",
            "SETTING_MAXGET",
            "SETTING_SPAWNTO_X86",
            "SETTING_SPAWNTO_X64",
            "SETTING_PIPENAME",
            "SETTING_WATERMARK",
            "SETTING_C2_VERB_GET",
            "SETTING_C2_VERB_POST",
            "SETTING_USERAGENT",
            "SETTING_PROTOCOL",
        ]

        for field in critical_fields:
            value = settings.get(field, "N/A")
            print(f"  {field}: {value}")

        return settings

    return None


def extract_c2_indicators(config):
    """Extrair indicadores C2 acionáveis da configuração do beacon."""
    indicators = {
        "c2_domains": [],
        "c2_ips": [],
        "c2_urls": [],
        "user_agent": "",
        "named_pipes": [],
        "spawn_processes": [],
        "watermark": "",
    }

    if not config:
        return indicators

    # Extrair domínios C2
    domains = config.get("SETTING_DOMAINS", "")
    if domains:
        for domain in str(domains).split(","):
            domain = domain.strip().rstrip("/")
            if domain:
                indicators["c2_domains"].append(domain)

    # Extrair user agent
    indicators["user_agent"] = str(config.get("SETTING_USERAGENT", ""))

    # Extrair named pipes
    pipe = config.get("SETTING_PIPENAME", "")
    if pipe:
        indicators["named_pipes"].append(str(pipe))

    # Extrair processos spawn-to
    for arch in ["SETTING_SPAWNTO_X86", "SETTING_SPAWNTO_X64"]:
        proc = config.get(arch, "")
        if proc:
            indicators["spawn_processes"].append(str(proc))

    # Extrair watermark
    indicators["watermark"] = str(config.get("SETTING_WATERMARK", ""))

    return indicators


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Uso: {sys.argv[0]} <arquivo_beacon_ou_dump>")
        sys.exit(1)

    config = extract_beacon_config(sys.argv[1])
    if config:
        indicators = extract_c2_indicators(config)
        print(f"\n[+] Indicadores C2 Extraídos:")
        print(json.dumps(indicators, indent=2))

Passo 2: Descriptografia Manual XOR da Configuração do Beacon

import struct

def find_and_decrypt_config(data):
    """Localizar e descriptografar manualmente a configuração do beacon."""
    # Cobalt Strike 4.x usa 0x2e como chave XOR
    xor_keys = [0x2e, 0x69]  # v4, v3

    for xor_key in xor_keys:
        # Procurar pelos bytes mágicos da configuração após XOR
        # A configuração começa com 0x0001 (BeaconType) XOR'd com a chave
        magic = bytes([0x00 ^ xor_key, 0x01 ^ xor_key,
                       0x00 ^ xor_key, 0x02 ^ xor_key])

        offset = data.find(magic)
        if offset == -1:
            continue

        print(f"[+] Configuração encontrada no offset 0x{offset:x} (chave XOR: 0x{xor_key:02x})")

        # Descriptografar o bloco de configuração (tipicamente 4096 bytes)
        config_size = 4096
        encrypted = data[offset:offset + config_size]
        decrypted = bytes([b ^ xor_key for b in encrypted])

        # Analisar entradas TLV
        entries = parse_tlv(decrypted)
        return entries

    return None


def parse_tlv(data):
    """Analisar entradas de configuração Tipo-Comprimento-Valor."""
    entries = {}
    offset = 0

    # Mapeamento de tipo de campo TLV
    field_names = {
        0x0001: "BeaconType",
        0x0002: "Port",
        0x0003: "SleepTime",
        0x0004: "MaxGetSize",
        0x0005: "Jitter",
        0x0006: "MaxDNS",
        0x0007: "Deprecated_PublicKey",
        0x0008: "C2Server",
        0x0009: "UserAgent",
        0x000a: "PostURI",
        0x000b: "Malleable_C2_Instructions",
        0x000c: "Deprecated_HttpGet_Metadata",
        0x000d: "SpawnTo_x86",
        0x000e: "SpawnTo_x64",
        0x000f: "CryptoScheme",
        0x001a: "Watermark",
        0x001d: "C2_HostHeader",
        0x0024: "PipeName",
        0x0025: "Year",
        0x0026: "Month",
        0x0027: "Day",
        0x0036: "ProxyHostname",
    }

    while offset + 6 <= len(data):
        entry_type = struct.unpack(">H", data[offset:offset+2])[0]
        entry_len_type = struct.unpack(">H", data[offset+2:offset+4])[0]
        entry_len = struct.unpack(">H", data[offset+4:offset+6])[0]

        if entry_type == 0:
            break

        value_start = offset + 6
        value_end = value_start + entry_len
        value_data = data[value_start:value_end]

        field_name = field_names.get(entry_type, f"Unknown_0x{entry_type:04x}")

        if entry_len_type == 1:  # Curto
            value = struct.unpack(">H", value_data[:2])[0]
        elif entry_len_type == 2:  # Inteiro
            value = struct.unpack(">I", value_data[:4])[0]
        elif entry_len_type == 3:  # String/Blob
            value = value_data.rstrip(b'\x00').decode('utf-8', errors='replace')
        else:
            value = value_data.hex()

        entries[field_name] = value
        print(f"  {field_name}: {value}")

        offset = value_end

    return entries

Passo 3: Regra YARA para Detecção de Beacon

import yara

cobalt_strike_rule = """
rule CobaltStrike_Beacon_Config {
    meta:
        description = "Detecta configuração de beacon Cobalt Strike"
        author = "Equipe de Análise de Malware"
        date = "2025-01-01"

    strings:
        // Marcador de configuração XOR'd para CS 4.x (chave 0x2e)
        $config_v4 = { 2e 2f 2e 2c }

        // Marcador de configuração XOR'd para CS 3.x (chave 0x69)
        $config_v3 = { 69 68 69 6b }

        // Strings comuns de beacon
        $str_pipe = "\\\\.\\pipe\\" ascii wide
        $str_beacon = "beacon" ascii nocase
        $str_sleeptime = "sleeptime" ascii nocase

        // Padrão de loader reflexivo
        $reflective = { 4D 5A 41 52 55 48 89 E5 }

    condition:
        ($config_v4 or $config_v3) or
        (2 of ($str_*) and $reflective)
}
"""

def scan_for_beacons(filepath):
    """Escaneia arquivo com regras YARA para beacons Cobalt Strike."""
    rules = yara.compile(source=cobalt_strike_rule)
    matches = rules.match(filepath)

    for match in matches:
        print(f"[+] Correspondência YARA: {match.rule}")
        for string_match in match.strings:
            offset = string_match.instances[0].offset
            print(f"    String: {string_match.identifier} no offset 0x{offset:x}")

    return matches

Passo 4: Correlação de Tráfego de Rede

from dissect.cobaltstrike.c2 import HttpC2Config

def analyze_c2_profile(beacon_config):
    """Analisar perfil malleable C2 a partir da configuração do beacon."""
    print("\n[+] Análise do Perfil Malleable C2")
    print("=" * 60)

    # Configuração HTTP GET
    get_verb = beacon_config.get("SETTING_C2_VERB_GET", "GET")
    get_uri = beacon_config.get("SETTING_C2_REQUEST", "")
    print(f"\n  Requisição HTTP GET:")
    print(f"    Verbo: {get_verb}")
    print(f"    URI: {get_uri}")

    # Configuração HTTP POST
    post_verb = beacon_config.get("SETTING_C2_VERB_POST", "POST")
    post_uri = beacon_config.get("SETTING_C2_POSTREQ", "")
    print(f"\n  Requisição HTTP POST:")
    print(f"    Verbo: {post_verb}")
    print(f"    URI: {post_uri}")

    # User Agent
    ua = beacon_config.get("SETTING_USERAGENT", "")
    print(f"\n  User-Agent: {ua}")

    # Cabeçalho Host
    host = beacon_config.get("SETTING_C2_HOSTHEADER", "")
    print(f"  Cabeçalho Host: {host}")

    # Sleep e jitter para padrão de tráfego
    sleep_ms = beacon_config.get("SETTING_SLEEPTIME", 60000)
    jitter = beacon_config.get("SETTING_JITTER", 0)
    print(f"\n  Tempo de Sleep: {sleep_ms}ms")
    print(f"  Jitter: {jitter}%")

    # Gerar assinaturas Suricata/Snort
    print(f"\n[+] Assinaturas de Rede Sugeridas:")
    if ua:
        print(f'  alert http any any -> any any (msg:\"CS Beacon UA\"; '
              f'content:\"{ua}\"; http_user_agent; sid:1000001; rev:1;)')
    if get_uri:
        print(f'  alert http any any -> any any (msg:\"CS Beacon URI\"; '
              f'content:\"{get_uri}\"; http_uri; sid:1000002; rev:1;)')

Critérios de Validação

  • Configuração do beacon extraída com sucesso de arquivo PE ou dump de memória
  • Domínios/IPs de servidores C2 corretamente identificados com porta e protocolo
  • Parâmetros do perfil malleable C2 decodificados mostrando transformações HTTP
  • Valor do watermark extraído para correlação de atribuição
  • Tempo de sleep e valores de jitter correspondentes aos intervalos de beacon observados na rede
  • Regras YARA detectam beacon em amostras empacotadas e não empacotadas
  • Assinaturas de rede geradas a partir do perfil C2 extraído

Referências

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

abusing-dpapi-for-credential-access

Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket

abusing-shadow-credentials-for-privesc

Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target

achieving-cmmc-level-2-compliance

>-

acquiring-disk-image-with-dd-and-dcfldd

Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.

analyzing-active-directory-acl-abuse

Detect dangerous ACL misconfigurations in Active Directory using ldap3

analyzing-android-malware-with-apktool

Perform static analysis of Android APK malware using apktool for resource decompilation, jadx for Java source recovery, and androguard for manifest inspection, dangerous permission-combination detection, and identification of obfuscated code, dynamic code loading, and reflection-based API calls. Use to statically triage a suspicious APK without executing it or to build mobile malware detection rules.

analyzing-api-gateway-access-logs

Parses API Gateway access logs (AWS API Gateway, Kong, Nginx) to detect

analyzing-apt-group-with-mitre-navigator

Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups

analyzing-azure-activity-logs-for-threats

Queries Azure Monitor activity logs and sign-in logs via azure-monitor-query

analyzing-bootkit-and-rootkit-samples

Analyzes bootkit and advanced rootkit malware infecting the Master

analyzing-browser-forensics-with-hindsight

Parse Chromium-based browser databases with Hindsight to extract and correlate browsing history, downloads, cookies, cached content, autofill data, saved passwords, and extensions from Chrome, Edge, Brave, Opera, and Vivaldi into a unified timeline (XLSX, JSON, or SQLite output). Use during incident response, insider-threat investigations, or criminal cases when you need to reconstruct a user

analyzing-campaign-attribution-evidence

Systematically evaluate cyber-campaign evidence to attribute an operation to a threat actor, using the Diamond Model and Analysis of Competing Hypotheses (ACH) to weigh infrastructure overlaps, TTP consistency, malware code similarity, and timing/language artifacts into confidence-weighted attribution assessments. Use when an incident investigation needs a defensible attribution confidence level.

analyzing-certificate-transparency-for-phishing

Monitor Certificate Transparency logs using crt.sh and Certstream to

analyzing-cloud-storage-access-patterns

Detect abnormal access in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics for after-hours bulk downloads, new-IP access, and API-call spikes (e.g. GetObject) via statistical baselines and time-series anomaly detection. Use when investigating suspected cloud data exfiltration or building related detection rules.

analyzing-cobaltstrike-malleable-c2-profiles

Parse and analyze Cobalt Strike Malleable C2 profiles with dissect.cobaltstrike (profiles and beacon-payload configs) and pyMalleableC2 (AST parsing) to extract HTTP/DNS transforms, URIs, headers, sleep/jitter, and injection behavior, then generate network detection signatures. Use when reverse-engineering a captured malleable profile or building detections against Cobalt Strike Beacon traffic.

analyzing-command-and-control-communication

Analyzes malware C2 communication over HTTP, HTTPS, DNS, and custom

analyzing-cyber-kill-chain

Analyzes intrusion activity against the Lockheed Martin Cyber Kill Chain

analyzing-disk-image-with-autopsy

Perform comprehensive forensic analysis of raw (dd), E01, or AFF disk images with Autopsy and The Sleuth Kit, recovering deleted files, examining metadata and embedded artifacts, keyword searching, and building investigation timelines with visual reports. Use for structured analysis of a forensic disk image or when stakeholders need visual reports from evidence.

analyzing-dns-logs-for-exfiltration

Analyzes DNS query logs to detect data exfiltration via DNS tunneling,

analyzing-docker-container-forensics

Investigate compromised Docker containers by analyzing images, layers,

Habilidades Relacionadas