ランサムウェアリークサイトインテリジェンス分析 は何をしますか?
概要
二重恐喝モデルで活動するランサムウェアグループは、Tor隠しサービス上にデータリークサイト(DLS)を運営し、被害者名、盗難データサンプル、支払い圧力をかけるためのカウントダウンタイマーを公開しています。2025年上半期には、96のユニークなランサムウェアグループが活動しており、月間約535件の被害者がリストアップされました。これらのサイトを監視することで、活動中の脅威グループ、標的となるセクター、地理的パターン、新興のランサムウェアファミリーに関するインテリジェンスを得ることができます。このスキルでは、DLSインテリジェンスの安全な収集、構造化データの抽出、グループ活動傾向の追跡、セクター固有のリスク評価の作成をカバーします。
使用タイミング
- ランサムウェアリークサイトインテリジェンスの分析を必要とするセキュリティインシデントを調査する場合
- このドメインに関連する検出ルールや脅威ハンティングクエリを構築する場合
- SOCアナリストがこの分析タイプの構造化された手順を必要とする場合
- 関連する攻撃手法に対するセキュリティ監視カバレッジを検証する場合
前提条件
- Python 3.9以上、
requests、beautifulsoup4、pandas、matplotlibライブラリ - .onionサイトにアクセスするためのTorプロキシ(SOCKS5)、または商用DLSモニタリングフィード
- ランサムウェアの二重恐喝ビジネスモデルに関する理解
- 主要なランサムウェアファミリー(Qilin、Akira、LockBit、BlackCat、Clop)に関する知識
- ランサムウェア追跡フィード(Ransomwatch、RansomLook、DarkFeed)へのアクセス
主要な概念
二重恐喝モデル
現代のランサムウェアグループは、被害者のデータを暗号化するかつ暗号化前にデータを外部に持ち出します。リークサイトは公開圧力として機能します。被害者はカウントダウンタイマー、部分的なデータサンプル、ファイルツリーとともにリストアップされます。身代金が支払われなければ、完全なデータが公開されます。一部のグループは、DDoS脅威を追加したり、被害者の顧客に直接連絡したりする三重恐喝に移行しています。
DLSインテリジェンスの価値
リークサイトは以下を提供します:被害者の特定(企業名、セクター、国)、攻撃のタイムライン(リスト掲載日、期限、データ公開日)、データ量の推定、グループ能力の評価(標的とするセクター、攻撃頻度、活動テンポ)、傾向分析(新興グループ、グループのリブランディング、法執行機関による摘発)。
安全な収集方法
本番環境でDLSサイトに直接アクセスしないでください。専用の監視サービス(Ransomwatch、DarkFeed、KELA、Flashpoint)、Tor分離型研究用VM、商用脅威インテリジェンスプラットフォーム、またはコミュニティ管理データセットを使用してください。すべての分析は、適切な権限を持つ隔離環境で実施する必要があります。
ワークフロー
ステップ1: 公開フィードからランサムウェアリークサイトデータを取り込む
import requests
import json
import pandas as pd
from datetime import datetime, timedelta
from collections import Counter
class RansomwareIntelCollector:
"""公開追跡ソースからランサムウェアDLSインテリジェンスを収集します。"""
RANSOMWATCH_API = "https://raw.githubusercontent.com/joshhighet/ransomwatch/main/posts.json"
RANSOMWATCH_GROUPS = "https://raw.githubusercontent.com/joshhighet/ransomwatch/main/groups.json"
def __init__(self):
self.posts = []
self.groups = []
def fetch_ransomwatch_data(self):
"""ransomwatchからランサムウェア被害者投稿を取得します。"""
resp = requests.get(self.RANSOMWATCH_API, timeout=30)
if resp.status_code == 200:
self.posts = resp.json()
print(f"[+] ransomwatchから{len(self.posts)}件の被害者投稿を読み込みました")
else:
print(f"[-] 投稿の取得に失敗しました: {resp.status_code}")
resp = requests.get(self.RANSOMWATCH_GROUPS, timeout=30)
if resp.status_code == 200:
self.groups = resp.json()
print(f"[+] {len(self.groups)}件のランサムウェアグループプロフィールを読み込みました")
return self.posts
def get_recent_victims(self, days=30):
"""過去N日間に投稿された被害者を取得します。"""
cutoff = datetime.now() - timedelta(days=days)
recent = []
for post in self.posts:
try:
discovered = datetime.fromisoformat(
post.get("discovered", "").replace("Z", "+00:00")
)
if discovered.replace(tzinfo=None) >= cutoff:
recent.append(post)
except (ValueError, TypeError):
continue
print(f"[+] 過去{days}日間の被害者: {len(recent)}件")
return recent
def get_group_activity(self, group_name):
"""特定のランサムウェアグループによるすべての投稿を取得します。"""
group_posts = [
p for p in self.posts
if p.get("group_name", "").lower() == group_name.lower()
]
print(f"[+] {group_name}: 合計{len(group_posts)}件の被害者")
return group_posts
collector = RansomwareIntelCollector()
collector.fetch_ransomwatch_data()
recent = collector.get_recent_victims(days=30)
ステップ2: グループ活動と傾向を分析する
def analyze_group_trends(posts, top_n=15):
"""ランサムウェアグループの活動傾向を分析します。"""
group_counts = Counter(p.get("group_name", "unknown") for p in posts)
monthly_activity = {}
for post in posts:
try:
date = datetime.fromisoformat(
post.get("discovered", "").replace("Z", "+00:00")
)
month_key = date.strftime("%Y-%m")
group = post.get("group_name", "unknown")
if month_key not in monthly_activity:
monthly_activity[month_key] = Counter()
monthly_activity[month_key][group] += 1
except (ValueError, TypeError):
continue
analysis = {
"total_posts": len(posts),
"unique_groups": len(group_counts),
"top_groups": group_counts.most_common(top_n),
"monthly_totals": {
month: sum(counts.values())
for month, counts in sorted(monthly_activity.items())
},
"monthly_top_groups": {
month: counts.most_common(5)
for month, counts in sorted(monthly_activity.items())
},
}
print(f"\n=== ランサムウェアグループ活動 ===")
print(f"追跡中の被害者総数: {analysis['total_posts']}")
print(f"活動グループ数: {analysis['unique_groups']}")
print(f"\nトップ{top_n}グループ:")
for group, count in analysis["top_groups"]:
print(f" {group}: {count}件の被害者")
return analysis
trends = analyze_group_trends(collector.posts)
ステップ3: セクターおよび地理的リスク評価
def assess_sector_risk(posts, target_sector=None, target_country=None):
"""特定のセクターまたは地域に対するランサムウェアリスクを評価します。"""
sector_data = {}
country_data = {}
for post in posts:
sector = post.get("sector", post.get("industry", "unknown"))
country = post.get("country", "unknown")
if sector not in sector_data:
sector_data[sector] = {"count": 0, "groups": Counter(), "recent": []}
sector_data[sector]["count"] += 1
sector_data[sector]["groups"][post.get("group_name", "")] += 1
if country not in country_data:
country_data[country] = {"count": 0, "groups": Counter()}
country_data[country]["count"] += 1
country_data[country]["groups"][post.get("group_name", "")] += 1
total = len(posts)
risk_assessment = {
"total_victims": total,
"sectors": {},
"countries": {},
}
for sector, data in sorted(sector_data.items(), key=lambda x: -x[1]["count"]):
pct = (data["count"] / total * 100) if total > 0 else 0
risk_assessment["sectors"][sector] = {
"victim_count": data["count"],
"percentage": round(pct, 1),
"top_groups": data["groups"].most_common(5),
"risk_level": (
"critical" if pct > 15
else "high" if pct > 8
else "medium" if pct > 3
else "low"
),
}
for country, data in sorted(country_data.items(), key=lambda x: -x[1]["count"]):
pct = (data["count"] / total * 100) if total > 0 else 0
risk_assessment["countries"][country] = {
"victim_count": data["count"],
"percentage": round(pct, 1),
"top_groups": data["groups"].most_common(5),
}
return risk_assessment
risk = assess_sector_risk(collector.posts)
ステップ4: 新興およびリブランディンググループを追跡する
def track_new_groups(posts, lookback_days=90):
"""新たに出現したランサムウェアグループを特定します。"""
group_first_seen = {}
for post in posts:
group = post.get("group_name", "")
try:
date = datetime.fromisoformat(
post.get("discovered", "").replace("Z", "+00:00")
)
if group not in group_first_seen or date < group_first_seen[group]["first_seen"]:
group_first_seen[group] = {
"first_seen": date,
"first_victim": post.get("post_title", ""),
}
except (ValueError, TypeError):
continue
cutoff = datetime.now() - timedelta(days=lookback_days)
new_groups = {
group: info for group, info in group_first_seen.items()
if info["first_seen"].replace(tzinfo=None) >= cutoff
}
for group in new_groups:
victims = [p for p in posts if p.get("group_name") == group]
new_groups[group]["total_victims"] = len(victims)
new_groups[group]["avg_per_month"] = round(
len(victims) / max(1, lookback_days / 30), 1
)
print(f"\n=== 新規グループ(過去{lookback_days}日間) ===")
for group, info in sorted(new_groups.items(), key=lambda x: -x[1]["total_victims"]):
print(f" {group}: {info['total_victims']}件の被害者、"
f"初回確認日 {info['first_seen'].strftime('%Y-%m-%d')}")
return new_groups
new_groups = track_new_groups(collector.posts, lookback_days=90)
ステップ5: インテリジェンスレポートを生成する
def generate_ransomware_intel_report(trends, risk, new_groups):
"""ランサムウェア脅威インテリジェンスレポートを生成します。"""
report = f"""# ランサムウェア脅威インテリジェンスレポート
生成日時: {datetime.now().isoformat()}
## エグゼクティブサマリー
- **追跡中の被害者総数**: {trends['total_posts']}
- **活動中のランサムウェアグループ数**: {trends['unique_groups']}
- **新規グループ(過去90日間)**: {len(new_groups)}
## トップ活動グループ
| 順位 | グループ | 被害者数 |
|------|----------|----------|
"""
for i, (group, count) in enumerate(trends["top_groups"][:10], 1):
report += f"| {i} | {group} | {count} |\n"
report += "\n## 新興グループ\n"
for group, info in sorted(new_groups.items(), key=lambda x: -x[1]["total_victims"])[:10]:
report += f"- **{group}**: {info['total_victims']}件の被害者({info['first_seen'].strftime('%Y-%m-%d')}以降)\n"
report += "\n## セクターリスク評価\n"
report += "| セクター | 被害者数 | % | リスクレベル |\n|----------|----------|---|------------|\n"
for sector, data in list(risk["sectors"].items())[:10]:
report += f"| {sector} | {data['victim_count']} | {data['percentage']}% | {data['risk_level'].upper()} |\n"
report += """
## 推奨事項
1. 組織およびサプライチェーン関係者向けにDLSフィードを毎日監視する
2. 上位活動グループが悪用する脆弱性のパッチ適用を優先する
3. 恐喝のレバレッジを減らすため、オフラインバックアップ戦略を実装する
4. ランサムウェアシナリオ対応のための机上演習を実施する
5. セクターISACや脅威共有コミュニティと指標を共有する
"""
with open("ransomware_intel_report.md", "w") as f:
f.write(report)
print("[+] レポートを保存しました: ransomware_intel_report.md")
return report
generate_ransomware_intel_report(trends, risk, new_groups)
検証基準
- ランサムウェアの被害者データが公開追跡フィードから取り込まれていること
- グループ活動傾向が月次内訳で分析されていること
- セクターおよび地理的リスク評価が作成されていること
- 新規および新興グループが活動指標とともに特定されていること
- 実用的な推奨事項を含むインテリジェンスレポートが生成されていること
- すべての収集が承認された公開ソースを通じて実施されていること