关于 tracking-threat-actor-infrastructure
用于发现和追踪威胁行为者控制基础设施的威胁情报技能,介绍如何结合被动 DNS、证书透明度、扫描服务、WHOIS 和网络指纹进行关联,并整理时间线及导出为 STIX 2.1 对象。
主要功能
- 01被动 DNS 关联分析
- 02证书透明度日志监控
- 03Shodan 与 Censys 发现
- 04WHOIS 与网络指纹分析
- 05基础设施时间线及 STIX 2.1 导出
适用场景
- 01查找与已知 C2 IP 关联的域名
- 02通过证书记录识别可疑域名
- 03追踪基础设施随时间的变化
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill tracking-threat-actor-infrastructure安装后在 Claude Code 中输入/tracking-threat-actor-infrastructure确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.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