Análisis de Inteligencia de Sitios de Filtración de Ransomware
Resumen
Los grupos de ransomware que operan bajo modelos de doble extorsión mantienen sitios de filtración de datos (DLS) en servicios ocultos de Tor, donde publican nombres de víctimas, muestras de datos robados y temporizadores de cuenta regresiva para presionar el pago. En el primer semestre de 2025, 96 grupos únicos de ransomware estaban activos, listando aproximadamente 535 víctimas por mes. Monitorear estos sitios proporciona inteligencia sobre grupos de amenazas activos, sectores objetivo, patrones geográficos y familias de ransomware emergentes. Esta habilidad cubre la recolección segura de inteligencia DLS, la extracción de datos estructurados, el seguimiento de tendencias de actividad de grupos y la producción de evaluaciones de riesgo sectoriales.
Cuándo Usar
- Al investigar incidentes de seguridad que requieran analizar inteligencia de sitios de filtración de ransomware
- Al construir reglas de detección o consultas de caza de amenazas para este dominio
- Cuando los analistas del SOC necesiten procedimientos estructurados para este tipo de análisis
- Al validar la cobertura de monitoreo de seguridad para técnicas de ataque relacionadas
Prerrequisitos
- Python 3.9+ con las bibliotecas
requests,beautifulsoup4,pandas,matplotlib - Proxy Tor (SOCKS5) para acceder a sitios .onion o feeds comerciales de monitoreo DLS
- Comprensión del modelo de negocio de doble extorsión de ransomware
- Familiaridad con las principales familias de ransomware (Qilin, Akira, LockBit, BlackCat, Clop)
- Acceso a feeds de seguimiento de ransomware (Ransomwatch, RansomLook, DarkFeed)
Conceptos Clave
Modelo de Doble Extorsión
Los grupos de ransomware modernos cifran los datos de la víctima Y los exfiltran antes del cifrado. Los sitios de filtración sirven como presión pública: las víctimas se enumeran con un temporizador de cuenta regresiva, muestras de datos parciales y árboles de archivos. Si no se paga el rescate, se publican los datos completos. Algunos grupos han pasado a la triple extorsión, agregando amenazas de DDoS o contactando directamente a los clientes de las víctimas.
Valor de la Inteligencia DLS
Los sitios de filtración proporcionan: identificación de víctimas (nombre de la empresa, sector, país), línea de tiempo del ataque (cuándo se listó, fecha límite, datos publicados), estimaciones de volumen de datos, evaluación de capacidades del grupo (sectores objetivo, frecuencia de ataque, ritmo operativo) y análisis de tendencias (nuevos grupos emergentes, grupos que cambian de nombre, desmantelamientos por parte de las autoridades).
Prácticas de Recolección Seguras
Nunca acceda directamente a los sitios DLS en un entorno de producción. Utilice servicios de monitoreo dedicados (Ransomwatch, DarkFeed, KELA, Flashpoint), máquinas virtuales de investigación aisladas con Tor, plataformas comerciales de inteligencia de amenazas o conjuntos de datos mantenidos por la comunidad. Todo el análisis debe realizarse en entornos aislados con la autorización adecuada.
Flujo de Trabajo
Paso 1: Ingestar Datos de Sitios de Filtración de Ransomware desde Fuentes Públicas
import requests
import json
import pandas as pd
from datetime import datetime, timedelta
from collections import Counter
class RansomwareIntelCollector:
"""Recopila inteligencia DLS de ransomware desde fuentes de seguimiento públicas."""
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):
"""Obtiene publicaciones de víctimas de ransomware desde ransomwatch."""
resp = requests.get(self.RANSOMWATCH_API, timeout=30)
if resp.status_code == 200:
self.posts = resp.json()
print(f"[+] Cargadas {len(self.posts)} publicaciones de víctimas desde ransomwatch")
else:
print(f"[-] Error al obtener publicaciones: {resp.status_code}")
resp = requests.get(self.RANSOMWATCH_GROUPS, timeout=30)
if resp.status_code == 200:
self.groups = resp.json()
print(f"[+] Cargados {len(self.groups)} perfiles de grupos de ransomware")
return self.posts
def get_recent_victims(self, days=30):
"""Obtiene víctimas publicadas en los últimos N días."""
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)} víctimas en los últimos {days} días")
return recent
def get_group_activity(self, group_name):
"""Obtiene todas las publicaciones de un grupo de ransomware específico."""
group_posts = [
p for p in self.posts
if p.get("group_name", "").lower() == group_name.lower()
]
print(f"[+] {group_name}: {len(group_posts)} víctimas totales")
return group_posts
collector = RansomwareIntelCollector()
collector.fetch_ransomwatch_data()
recent = collector.get_recent_victims(days=30)
Paso 2: Analizar la Actividad y Tendencias de los Grupos
def analyze_group_trends(posts, top_n=15):
"""Analiza las tendencias de actividad de los grupos de ransomware."""
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=== Actividad de Grupos de Ransomware ===")
print(f"Víctimas totales rastreadas: {analysis['total_posts']}")
print(f"Grupos activos: {analysis['unique_groups']}")
print(f"\nTop {top_n} Grupos:")
for group, count in analysis["top_groups"]:
print(f" {group}: {count} víctimas")
return analysis
trends = analyze_group_trends(collector.posts)
Paso 3: Evaluación de Riesgo Sectorial y Geográfico
def assess_sector_risk(posts, target_sector=None, target_country=None):
"""Evalúa el riesgo de ransomware para un sector o geografía específica."""
sector_data = {}
country_data = {}
for post in posts:
# Extraer sector si está disponible (no todos los feeds lo incluyen)
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
# Puntuación de riesgo sectorial
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)
Paso 4: Rastrear Grupos Emergentes y con Cambio de Marca
def track_new_groups(posts, lookback_days=90):
"""Identifica grupos de ransomware recién emergidos."""
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
}
# Contar víctimas totales por grupo nuevo
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=== Nuevos Grupos (últimos {lookback_days} días) ===")
for group, info in sorted(new_groups.items(), key=lambda x: -x[1]["total_victims"]):
print(f" {group}: {info['total_victims']} víctimas, "
f"visto por primera vez {info['first_seen'].strftime('%Y-%m-%d')}")
return new_groups
new_groups = track_new_groups(collector.posts, lookback_days=90)
Paso 5: Generar Informe de Inteligencia
def generate_ransomware_intel_report(trends, risk, new_groups):
"""Genera un informe de inteligencia de amenazas de ransomware."""
report = f"""# Informe de Inteligencia de Amenazas de Ransomware
Generado: {datetime.now().isoformat()}
## Resumen Ejecutivo
- **Víctimas totales rastreadas**: {trends['total_posts']}
- **Grupos de ransomware activos**: {trends['unique_groups']}
- **Nuevos grupos (últimos 90 días)**: {len(new_groups)}
## Grupos Más Activos
| Ranking | Grupo | Víctimas |
|---------|-------|----------|
"""
for i, (group, count) in enumerate(trends["top_groups"][:10], 1):
report += f"| {i} | {group} | {count} |\n"
report += "\n## Nuevos Grupos Emergentes\n"
for group, info in sorted(new_groups.items(), key=lambda x: -x[1]["total_victims"])[:10]:
report += f"- **{group}**: {info['total_victims']} víctimas desde {info['first_seen'].strftime('%Y-%m-%d')}\n"
report += "\n## Evaluación de Riesgo por Sector\n"
report += "| Sector | Víctimas | % | Nivel de Riesgo |\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 += """
## Recomendaciones
1. Monitorear los feeds DLS diariamente para su organización y socios de la cadena de suministro
2. Priorizar el parcheo de vulnerabilidades explotadas por los grupos activos principales
3. Implementar una estrategia de copias de seguridad fuera de línea para reducir el poder de extorsión
4. Realizar ejercicios de mesa para la respuesta a escenarios de ransomware
5. Compartir indicadores con los ISAC sectoriales y las comunidades de intercambio de amenazas
"""
with open("ransomware_intel_report.md", "w") as f:
f.write(report)
print("[+] Informe guardado: ransomware_intel_report.md")
return report
generate_ransomware_intel_report(trends, risk, new_groups)
Criterios de Validación
- Datos de víctimas de ransomware ingeridos desde fuentes de seguimiento públicas
- Tendencias de actividad de grupos analizadas con desgloses mensuales
- Evaluación de riesgo sectorial y geográfico producida
- Nuevos grupos emergentes identificados con métricas de actividad
- Informe de inteligencia generado con recomendaciones accionables
- Toda la recolección realizada a través de fuentes públicas autorizadas