mcpField
T
tracking-threat-actor-infrastructure

tracking-threat-actor-infrastructure

github.com/mukul975安全35.2k102 次安装8 周前更新
代码仓库

关于 tracking-threat-actor-infrastructure

用于发现和追踪威胁行为者控制基础设施的威胁情报技能,介绍如何结合被动 DNS、证书透明度、扫描服务、WHOIS 和网络指纹进行关联,并整理时间线及导出为 STIX 2.1 对象。

主要功能

  1. 01被动 DNS 关联分析
  2. 02证书透明度日志监控
  3. 03Shodan 与 Censys 发现
  4. 04WHOIS 与网络指纹分析
  5. 05基础设施时间线及 STIX 2.1 导出

适用场景

  1. 01查找与已知 C2 IP 关联的域名
  2. 02通过证书记录识别可疑域名
  3. 03追踪基础设施随时间的变化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill tracking-threat-actor-infrastructure

安装后在 Claude Code 中输入/tracking-threat-actor-infrastructure确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

详细介绍

跟踪威胁行为者基础设施

概述

威胁行为者基础设施跟踪涉及监控和绘制对手控制的资产,包括命令与控制(C2)服务器、钓鱼域名、漏洞利用工具包主机、防弹托管和暂存服务器。本技能涵盖使用被动 DNS、证书透明度日志、Shodan/Censys 扫描、WHOIS 分析和网络指纹识别来发现、跟踪并随时间在威胁行为者基础设施之间进行跳转。

何时使用

  • 在管理需要跟踪威胁行为者基础设施的安全运营时
  • 在提升安全项目成熟度和运营流程时
  • 在为安全团队工作流建立标准化程序时
  • 在将威胁情报或漏洞数据集成到运营中时

先决条件

  • Python 3.9+ 以及 shodan、censys、requests、stix2 库
  • API 密钥:Shodan、Censys、VirusTotal、SecurityTrails、PassiveTotal
  • 理解 DNS、TLS/SSL 证书、IP 分配、ASN 结构
  • 熟悉被动 DNS 和证书透明度概念
  • 可访问域名注册(WHOIS)查询服务

关键概念

基础设施跳转

跳转是一种使用一个已知指标来发现相关基础设施的技术。从已知的 C2 IP 地址开始,分析师可以通过以下方式进行跳转:被动 DNS(查找域名)、反向 WHOIS(查找相关注册)、SSL 证书(查找共享证书)、SSH 密钥指纹、HTTP 响应指纹、JARM/JA3S 哈希以及 WHOIS 注册人数据。

被动 DNS

被动 DNS 数据库记录在递归解析器处观察到的 DNS 查询/响应数据。这使分析师能够查找历史域名到 IP 的映射、发现托管在已知 C2 IP 上的域名,并识别快速通量或域名生成算法(DGA)行为。

证书透明度

证书透明度(CT)日志公开记录 CA 颁发的所有 SSL/TLS 证书。监控 CT 日志可以揭示为可疑域名注册的新证书,有助于在钓鱼站点和 C2 基础设施活跃之前识别它们。

网络指纹识别
  • JARM:主动 TLS 服务器指纹(TLS 握手响应的哈希)
  • JA3S:被动 TLS 服务器指纹(Server Hello 的哈希)
  • HTTP 标头:服务器横幅、自定义标头、响应模式
  • Favicon 哈希:用于服务器识别的 HTTP favicon 哈希

工作流

步骤 1:Shodan 基础设施发现
import shodan

api = shodan.Shodan("YOUR_SHODAN_API_KEY")

def discover_infrastructure(ip_address):
    """Discover services and metadata for a target IP."""
    try:
        host = api.host(ip_address)
        return {
            "ip": host["ip_str"],
            "org": host.get("org", ""),
            "asn": host.get("asn", ""),
            "isp": host.get("isp", ""),
            "country": host.get("country_name", ""),
            "city": host.get("city", ""),
            "os": host.get("os"),
            "ports": host.get("ports", []),
            "vulns": host.get("vulns", []),
            "hostnames": host.get("hostnames", []),
            "domains": host.get("domains", []),
            "tags": host.get("tags", []),
            "services": [
                {
                    "port": svc.get("port"),
                    "transport": svc.get("transport"),
                    "product": svc.get("product", ""),
                    "version": svc.get("version", ""),
                    "ssl_cert": svc.get("ssl", {}).get("cert", {}).get("subject", {}),
                    "jarm": svc.get("ssl", {}).get("jarm", ""),
                }
                for svc in host.get("data", [])
            ],
        }
    except shodan.APIError as e:
        print(f"[-] Shodan error: {e}")
        return None

def search_c2_framework(framework_name):
    """Search Shodan for known C2 framework signatures."""
    c2_queries = {
        "cobalt-strike": 'product:"Cobalt Strike Beacon"',
        "metasploit": 'product:"Metasploit"',
        "covenant": 'http.html:"Covenant" http.title:"Covenant"',
        "sliver": 'ssl.cert.subject.cn:"multiplayer" ssl.cert.issuer.cn:"operators"',
        "havoc": 'http.html_hash:-1472705893',
    }

    query = c2_queries.get(framework_name.lower(), framework_name)
    results = api.search(query, limit=100)

    hosts = []
    for match in results.get("matches", []):
        hosts.append({
            "ip": match["ip_str"],
            "port": match["port"],
            "org": match.get("org", ""),
            "country": match.get("location", {}).get("country_name", ""),
            "asn": match.get("asn", ""),
            "timestamp": match.get("timestamp", ""),
        })

    return hosts
步骤 2:被动 DNS 跳转
import requests

def passive_dns_lookup(indicator, api_key, indicator_type="ip"):
    """Query SecurityTrails for passive DNS records."""
    base_url = "https://api.securitytrails.com/v1"
    headers = {"APIKEY": api_key, "Accept": "application/json"}

    if indicator_type == "ip":
        url = f"{base_url}/search/list"
        payload = {
            "filter": {"ipv4": indicator}
        }
        resp = requests.post(url, json=payload, headers=headers, timeout=30)
    else:
        url = f"{base_url}/domain/{indicator}/subdomains"
        resp = requests.get(url, headers=headers, timeout=30)

    if resp.status_code == 200:
        return resp.json()
    return None


def query_passive_total(indicator, user, api_key):
    """Query PassiveTotal for passive DNS and WHOIS data."""
    base_url = "https://api.passivetotal.org/v2"
    auth = (user, api_key)

    # Passive DNS
    pdns_resp = requests.get(
        f"{base_url}/dns/passive",
        params={"query": indicator},
        auth=auth,
        timeout=30,
    )

    # WHOIS
    whois_resp = requests.get(
        f"{base_url}/whois",
        params={"query": indicator},
        auth=auth,
        timeout=30,
    )

    results = {}
    if pdns_resp.status_code == 200:
        results["passive_dns"] = pdns_resp.json().get("results", [])
    if whois_resp.status_code == 200:
        results["whois"] = whois_resp.json()

    return results
步骤 3:证书透明度监控
import requests

def search_ct_logs(domain):
    """Search Certificate Transparency logs via crt.sh."""
    resp = requests.get(
        f"https://crt.sh/?q=%.{domain}&output=json",
        timeout=30,
    )

    if resp.status_code == 200:
        certs = resp.json()
        unique_domains = set()
        cert_info = []

        for cert in certs:
            name_value = cert.get("name_value", "")
            for name in name_value.split("\n"):
                unique_domains.add(name.strip())

            cert_info.append({
                "id": cert.get("id"),
                "issuer": cert.get("issuer_name", ""),
                "common_name": cert.get("common_name", ""),
                "name_value": name_value,
                "not_before": cert.get("not_before", ""),
                "not_after": cert.get("not_after", ""),
                "serial_number": cert.get("serial_number", ""),
            })

        return {
            "domain": domain,
            "total_certificates": len(certs),
            "unique_domains": sorted(unique_domains),
            "certificates": cert_info[:50],
        }
    return None


def monitor_new_certs(domains, interval_hours=1):
    """Monitor for newly issued certificates for a list of domains."""
    from datetime import datetime, timedelta

    cutoff = (datetime.utcnow() - timedelta(hours=interval_hours)).isoformat()
    new_certs = []

    for domain in domains:
        result = search_ct_logs(domain)
        if result:
            for cert in result.get("certificates", []):
                if cert.get("not_before", "") > cutoff:
                    new_certs.append({
                        "domain": domain,
                        "cert": cert,
                    })

    return new_certs
步骤 4:基础设施关联和时间线
from datetime import datetime

def build_infrastructure_timeline(indicators):
    """Build a timeline of infrastructure changes."""
    timeline = []

    for ind in indicators:
        if "passive_dns" in ind:
            for record in ind["passive_dns"]:
                timeline.append({
                    "timestamp": record.get("firstSeen", ""),
                    "event": "dns_resolution",
                    "source": record.get("resolve", ""),
                    "target": record.get("value", ""),
                    "record_type": record.get("recordType", ""),
                })

        if "certificates" in ind:
            for cert in ind["certificates"]:
                timeline.append({
                    "timestamp": cert.get("not_before", ""),
                    "event": "certificate_issued",
                    "domain": cert.get("common_name", ""),
                    "issuer": cert.get("issuer", ""),
                })

    timeline.sort(key=lambda x: x.get("timestamp", ""))
    return timeline

验证标准

  • Shodan/Censys 查询返回目标 IP 的基础设施详情
  • 被动 DNS 揭示历史域名-IP 映射
  • 证书透明度搜索找到关联域名
  • 基础设施跳转发现新的相关指标
  • 时间线显示基础设施随时间的演变
  • 结果可导出为 STIX 2.1 Infrastructure 对象

参考资料

评论

支持 Markdown