$npx -y skills add killvxk/cybersecurity-skills-zh --skill analyzing-ransomware-leak-site-intelligence监控和分析勒索软件组织的数据泄露站点(DLS),追踪受害者发布情况,提取组织战术的威胁情报,并评估特定行业的勒索软件风险以实现主动防御。
| 1 | # 分析勒索软件数据泄露站点情报 |
| 2 | |
| 3 | ## 概述 |
| 4 | |
| 5 | 采用双重勒索模式运营的勒索软件(Ransomware)组织在 Tor 隐藏服务上维护数据泄露站点(DLS),在那里发布受害者名称、被盗数据样本和倒计时器以施压付款。2025 年上半年,96 个独特勒索软件组织活跃,每月约发布 535 名受害者。监控这些站点提供了关于活跃威胁组织、目标行业、地理模式和新兴勒索软件家族的情报。本技能涵盖安全收集 DLS 情报、提取结构化数据、追踪组织活动趋势,以及生成行业特定风险评估。 |
| 6 | |
| 7 | ## 前置条件 |
| 8 | |
| 9 | - Python 3.9+,安装 `requests`、`beautifulsoup4`、`pandas`、`matplotlib` 库 |
| 10 | - Tor 代理(SOCKS5)用于访问 .onion 站点,或商业 DLS 监控情报 |
| 11 | - 了解勒索软件双重勒索商业模式 |
| 12 | - 熟悉主要勒索软件家族(Qilin、Akira、LockBit、BlackCat、Clop) |
| 13 | - 访问勒索软件追踪情报(Ransomwatch、RansomLook、DarkFeed) |
| 14 | |
| 15 | ## 核心概念 |
| 16 | |
| 17 | ### 双重勒索模式 |
| 18 | |
| 19 | 现代勒索软件组织在加密受害者数据之前还会将其外泄(Exfiltration)。泄露站点作为公开施压工具:受害者以倒计时器、部分数据样本和文件目录的形式被列出。若未支付赎金,完整数据将被公开。部分组织已转向三重勒索,追加 DDoS 威胁或直接联系受害者客户。 |
| 20 | |
| 21 | ### DLS 情报价值 |
| 22 | |
| 23 | 泄露站点提供:受害者识别(公司名称、行业、国家)、攻击时间线(列出时间、截止日期、数据发布时间)、数据量估算、组织能力评估(目标行业、攻击频率、操作节奏),以及趋势分析(新组织出现、组织品牌重塑、执法打击)。 |
| 24 | |
| 25 | ### 安全收集实践 |
| 26 | |
| 27 | 切勿在生产环境中直接访问 DLS 站点。使用专用监控服务(Ransomwatch、DarkFeed、KELA、Flashpoint)、Tor 隔离研究虚拟机、商业威胁情报平台或社区维护的数据集。所有分析应在隔离环境中进行,并获得适当授权。 |
| 28 | |
| 29 | ## 实践步骤 |
| 30 | |
| 31 | ### 步骤 1:从公开情报源导入勒索软件泄露站点数据 |
| 32 | |
| 33 | ```python |
| 34 | import requests |
| 35 | import json |
| 36 | import pandas as pd |
| 37 | from datetime import datetime, timedelta |
| 38 | from collections import Counter |
| 39 | |
| 40 | class RansomwareIntelCollector: |
| 41 | """从公开追踪来源收集勒索软件 DLS 情报。""" |
| 42 | |
| 43 | RANSOMWATCH_API = "https://raw.githubusercontent.com/joshhighet/ransomwatch/main/posts.json" |
| 44 | RANSOMWATCH_GROUPS = "https://raw.githubusercontent.com/joshhighet/ransomwatch/main/groups.json" |
| 45 | |
| 46 | def __init__(self): |
| 47 | self.posts = [] |
| 48 | self.groups = [] |
| 49 | |
| 50 | def fetch_ransomwatch_data(self): |
| 51 | """从 ransomwatch 获取勒索软件受害者发布数据。""" |
| 52 | resp = requests.get(self.RANSOMWATCH_API, timeout=30) |
| 53 | if resp.status_code == 200: |
| 54 | self.posts = resp.json() |
| 55 | print(f"[+] 已从 ransomwatch 加载 {len(self.posts)} 条受害者记录") |
| 56 | else: |
| 57 | print(f"[-] 获取记录失败: {resp.status_code}") |
| 58 | |
| 59 | resp = requests.get(self.RANSOMWATCH_GROUPS, timeout=30) |
| 60 | if resp.status_code == 200: |
| 61 | self.groups = resp.json() |
| 62 | print(f"[+] 已加载 {len(self.groups)} 个勒索软件组织画像") |
| 63 | |
| 64 | return self.posts |
| 65 | |
| 66 | def get_recent_victims(self, days=30): |
| 67 | """获取最近 N 天内发布的受害者。""" |
| 68 | cutoff = datetime.now() - timedelta(days=days) |
| 69 | recent = [] |
| 70 | for post in self.posts: |
| 71 | try: |
| 72 | discovered = datetime.fromisoformat( |
| 73 | post.get("discovered", "").replace("Z", "+00:00") |
| 74 | ) |
| 75 | if discovered.replace(tzinfo=None) >= cutoff: |
| 76 | recent.append(post) |
| 77 | except (ValueError, TypeError): |
| 78 | continue |
| 79 | print(f"[+] 最近 {days} 天内 {len(recent)} 名受害者") |
| 80 | return recent |
| 81 | |
| 82 | def get_group_activity(self, group_name): |
| 83 | """获取特定勒索软件组织的所有发布记录。""" |
| 84 | group_posts = [ |
| 85 | p for p in self.posts |
| 86 | if p.get("group_name", "").lower() == group_name.lower() |
| 87 | ] |
| 88 | print(f"[+] {group_name}: 共 {len(group_posts)} 名受害者") |
| 89 | return group_posts |
| 90 | |
| 91 | collector = RansomwareIntelCollector() |
| 92 | collector.fetch_ransomwatch_data() |
| 93 | recent = collector.get_recent_victims(days=30) |
| 94 | ``` |
| 95 | |
| 96 | ### 步骤 2:分析组织活动和趋势 |
| 97 | |
| 98 | ```python |
| 99 | def analyze_group_trends(posts, top_n=15): |
| 100 | """分析勒索软件组织活动趋势。""" |
| 101 | group_counts = Counter(p.get("group_name", "unknown") for p in posts) |
| 102 | monthly_activity = {} |
| 103 | |
| 104 | for post in posts: |
| 105 | try: |
| 106 | date = datetime.fromisoformat( |
| 107 | post.get("discovered", "").replace("Z", "+00:00") |
| 108 | ) |
| 109 | month_key = date.strftime("%Y-%m") |
| 110 | group = post.get("group_name", "unknown") |
| 111 | if month_key not in monthly_activity: |
| 112 | monthly_activity[month_key] = Counter() |
| 113 | monthly_activity[month_key][group] += 1 |
| 114 | except (ValueError, TypeError): |
| 115 | continue |
| 116 | |
| 117 | analysis = { |
| 118 | "total_posts": len(posts), |
| 119 | "unique_groups": len(group_counts), |
| 120 | "top_groups": group_counts.most_common(top_n), |
| 121 | "monthly_totals": { |
| 122 | month: sum(counts.values()) |
| 123 | for month, counts in sorted(monthly_activity.items()) |
| 124 | }, |
| 125 | "monthly_top_groups": { |
| 126 | month: counts.most_common(5) |
| 127 | for month, counts in sorted(monthly_activity.items()) |
| 128 | }, |
| 129 | } |
| 130 | |
| 131 | print(f"\n=== 勒索软件组织活动 ===") |
| 132 | print(f"追踪受害者总数: {analysis['total_posts']}") |
| 133 | print(f"活跃组织数量: {analysis['unique_groups']}") |
| 134 | print(f"\n前 {top_n} 活跃组织:") |
| 135 | for group, count in analysis["top_groups"]: |
| 136 | print(f" {group}: {count} 名受害者") |
| 137 | |
| 138 | return analysis |
| 139 | |
| 140 | trends = analyze_group_trends(collector.posts) |
| 141 | ``` |
| 142 | |
| 143 | ### 步骤 3:行业和地理风险评估 |
| 144 | |
| 145 | ```python |
| 146 | def assess_sector_risk(posts, target_sector=None, target_country=None): |
| 147 | """评估特定行业或地区的勒索软件风险。""" |
| 148 | sector_data = {} |
| 149 | country_data = {} |
| 150 | |
| 151 | for post in posts: |
| 152 | # 提取行 |