Analyse du Renseignement des Sites de Fuite de Rançongiciels
Aperçu
Les groupes de rançongiciels opérant sous des modèles de double extorsion maintiennent des sites de fuite de données (DLS) sur des services cachés Tor où ils publient les noms des victimes, des échantillons de données volées et des comptes à rebours pour faire pression sur le paiement. Au premier semestre 2025, 96 groupes de rançongiciels uniques étaient actifs, listant environ 535 victimes par mois. Surveiller ces sites fournit des renseignements sur les groupes de menaces actifs, les secteurs ciblés, les schémas géographiques et les familles de rançongiciels émergentes. Cette compétence couvre la collecte sécurisée de renseignements DLS, l'extraction de données structurées, le suivi des tendances d'activité des groupes et la production d'évaluations de risques sectorielles.
Quand l'utiliser
- Lors de l'investigation d'incidents de sécurité nécessitant l'analyse du renseignement des sites de fuite de rançongiciels
- Lors de l'élaboration de règles de détection ou de requêtes de chasse aux menaces pour ce domaine
- Lorsque les analystes SOC ont besoin de procédures structurées pour ce type d'analyse
- Lors de la validation de la couverture de surveillance de sécurité pour les techniques d'attaque connexes
Prérequis
- Python 3.9+ avec les bibliothèques
requests,beautifulsoup4,pandas,matplotlib - Proxy Tor (SOCKS5) pour accéder aux sites .onion ou aux flux de surveillance DLS commerciaux
- Compréhension du modèle économique de la double extorsion par rançongiciel
- Familiarité avec les principales familles de rançongiciels (Qilin, Akira, LockBit, BlackCat, Clop)
- Accès aux flux de suivi des rançongiciels (Ransomwatch, RansomLook, DarkFeed)
Concepts Clés
Modèle de Double Extorsion
Les groupes de rançongiciels modernes chiffrent les données des victimes ET les exfiltrent avant le chiffrement. Les sites de fuite servent de pression publique : les victimes sont listées avec un compte à rebours, des échantillons de données partiels et des arborescences de fichiers. Si la rançon n'est pas payée, toutes les données sont publiées. Certains groupes sont passés à la triple extorsion, ajoutant des menaces de DDoS ou contactant directement les clients des victimes.
Valeur du Renseignement DLS
Les sites de fuite fournissent : l'identification des victimes (nom de l'entreprise, secteur, pays), la chronologie des attaques (date de publication, date limite, publication des données), les estimations de volume de données, l'évaluation des capacités des groupes (secteurs ciblés, fréquence des attaques, rythme opérationnel) et l'analyse des tendances (nouveaux groupes émergents, groupes se rebaptisant, démantèlements par les forces de l'ordre).
Pratiques de Collecte Sécurisées
N'accédez jamais directement aux sites DLS dans un environnement de production. Utilisez des services de surveillance dédiés (Ransomwatch, DarkFeed, KELA, Flashpoint), des machines virtuelles de recherche isolées par Tor, des plateformes commerciales de renseignement sur les menaces ou des ensembles de données maintenus par la communauté. Toute analyse doit être menée dans des environnements isolés avec une autorisation appropriée.
Flux de Travail
Étape 1 : Ingérer les Données des Sites de Fuite de Rançongiciels à partir de Flux Publics
import requests
import json
import pandas as pd
from datetime import datetime, timedelta
from collections import Counter
class RansomwareIntelCollector:
"""Collecter le renseignement DLS des rançongiciels à partir de sources de suivi publiques."""
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):
"""Récupérer les publications de victimes de rançongiciel depuis ransomwatch."""
resp = requests.get(self.RANSOMWATCH_API, timeout=30)
if resp.status_code == 200:
self.posts = resp.json()
print(f"[+] Chargé {len(self.posts)} publications de victimes depuis ransomwatch")
else:
print(f"[-] Échec de la récupération des publications : {resp.status_code}")
resp = requests.get(self.RANSOMWATCH_GROUPS, timeout=30)
if resp.status_code == 200:
self.groups = resp.json()
print(f"[+] Chargé {len(self.groups)} profils de groupes de rançongiciels")
return self.posts
def get_recent_victims(self, days=30):
"""Obtenir les victimes publiées au cours des N derniers jours."""
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"[+] {len(recent)} victimes dans les {days} derniers jours")
return recent
def get_group_activity(self, group_name):
"""Obtenir toutes les publications d'un groupe de rançongiciel spécifique."""
group_posts = [
p for p in self.posts
if p.get("group_name", "").lower() == group_name.lower()
]
print(f"[+] {group_name} : {len(group_posts)} victimes au total")
return group_posts
collector = RansomwareIntelCollector()
collector.fetch_ransomwatch_data()
recent = collector.get_recent_victims(days=30)
Étape 2 : Analyser l'Activité et les Tendances des Groupes
def analyze_group_trends(posts, top_n=15):
"""Analyser les tendances d'activité des groupes de rançongiciels."""
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=== Activité des Groupes de Rançongiciels ===")
print(f"Total des victimes suivies : {analysis['total_posts']}")
print(f"Groupes actifs : {analysis['unique_groups']}")
print(f"\nTop {top_n} Groupes :")
for group, count in analysis["top_groups"]:
print(f" {group} : {count} victimes")
return analysis
trends = analyze_group_trends(collector.posts)
Étape 3 : Évaluation des Risques Sectoriels et Géographiques
def assess_sector_risk(posts, target_sector=None, target_country=None):
"""Évaluer le risque de rançongiciel pour un secteur ou une zone géographique spécifique."""
sector_data = {}
country_data = {}
for post in posts:
# Extraire le secteur si disponible (tous les flux ne l'incluent pas)
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
# Score de risque sectoriel
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)
Étape 4 : Suivre les Groupes Émergents et en Rebranding
def track_new_groups(posts, lookback_days=90):
"""Identifier les groupes de rançongiciels nouvellement apparus."""
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
}
# Compter le nombre total de victimes par nouveau groupe
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=== Nouveaux Groupes (derniers {lookback_days} jours) ===")
for group, info in sorted(new_groups.items(), key=lambda x: -x[1]["total_victims"]):
print(f" {group} : {info['total_victims']} victimes, "
f"première apparition le {info['first_seen'].strftime('%Y-%m-%d')}")
return new_groups
new_groups = track_new_groups(collector.posts, lookback_days=90)
Étape 5 : Générer un Rapport de Renseignement
def generate_ransomware_intel_report(trends, risk, new_groups):
"""Générer un rapport de renseignement sur les menaces de rançongiciels."""
report = f"""# Rapport de Renseignement sur les Menaces de Rançongiciels
Généré le : {datetime.now().isoformat()}
## Résumé Exécutif
- **Total des victimes suivies** : {trends['total_posts']}
- **Groupes de rançongiciels actifs** : {trends['unique_groups']}
- **Nouveaux groupes (90 derniers jours)** : {len(new_groups)}
## Principaux Groupes Actifs
| Rang | Groupe | Victimes |
|------|--------|----------|
"""
for i, (group, count) in enumerate(trends["top_groups"][:10], 1):
report += f"| {i} | {group} | {count} |\n"
report += "\n## Nouveaux Groupes Émergents\n"
for group, info in sorted(new_groups.items(), key=lambda x: -x[1]["total_victims"])[:10]:
report += f"- **{group}** : {info['total_victims']} victimes depuis le {info['first_seen'].strftime('%Y-%m-%d')}\n"
report += "\n## Évaluation des Risques Sectoriels\n"
report += "| Secteur | Victimes | % | Niveau de Risque |\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 += """
## Recommandations
1. Surveiller quotidiennement les flux DLS pour votre organisation et vos partenaires de la chaîne d'approvisionnement
2. Prioriser le correction des vulnérabilités exploitées par les groupes actifs les plus importants
3. Mettre en œuvre une stratégie de sauvegarde hors ligne pour réduire le levier d'extorsion
4. Organiser des exercices de simulation pour la réponse aux scénarios de rançongiciel
5. Partager les indicateurs avec les ISAC sectoriels et les communautés de partage de menaces
"""
with open("rapport_renseignement_rancongiciel.md", "w") as f:
f.write(report)
print("[+] Rapport sauvegardé : rapport_renseignement_rancongiciel.md")
return report
generate_ransomware_intel_report(trends, risk, new_groups)
Critères de Validation
- Données des victimes de rançongiciel ingérées à partir de flux de suivi publics
- Tendances d'activité des groupes analysées avec des répartitions mensuelles
- Évaluation des risques sectoriels et géographiques produite
- Groupes nouveaux et émergents identifiés avec des métriques d'activité
- Rapport de renseignement généré avec des recommandations exploitables
- Toute la collecte effectuée via des sources publiques autorisées
Références
- Ransomwatch GitHub
- SOCRadar : Statistiques clés sur les rançongiciels 2025
- Bitsight : Tendances des rançongiciels et du web profond
- Sophos : Rapport de renseignement sur les menaces 2025
- H-ISAC : Rapport sur les sites de fuite de données de rançongiciels
- CYFIRMA : Rapports de renseignement hebdomadaires