O que Analisando Relacionamentos de Famílias de Malware com Malpedia faz?
Visão Geral
O Malpedia é uma plataforma colaborativa mantida pelo Fraunhofer FKIE que cataloga famílias de malware com seus aliases, regras YARA, associações a atores de ameaças e relatórios de referência. Com mais de 2.600 famílias de malware documentadas, ele serve como o recurso definitivo para entender linhagens de malware, rastrear a evolução de variantes e vincular malware a grupos de ameaças específicos. Esta skill cobre a consulta à API do Malpedia, o mapeamento de relacionamentos entre famílias de malware, a extração de regras YARA para detecção e a construção de inteligência sobre ecossistemas de malware usados por adversários.
Quando Usar
- Ao investigar incidentes de segurança que exigem a análise de relacionamentos de famílias de malware com o Malpedia
- Ao criar regras de detecção ou consultas de caça a ameaças para este domínio
- Quando analistas de SOC precisam de procedimentos estruturados para este tipo de análise
- Ao validar a cobertura de monitoramento de segurança para técnicas de ataque relacionadas
Pré-requisitos
- Python 3.9+ com as bibliotecas
requests,yara-python,stix2 - Chave de API do Malpedia (registre-se em https://malpedia.caad.fkie.fraunhofer.de/)
- Compreensão da classificação de malware e convenções de nomenclatura
- Familiaridade com a sintaxe de regras YARA para detecção
- Acesso a amostras de malware para validação (opcional)
Conceitos-chave
Modelo de Dados do Malpedia
O Malpedia organiza malware em Famílias (por exemplo, "win.cobalt_strike"), cada uma contendo: aliases (nomes específicos de fornecedores como "Beacon", "CobaltStrike"), regras YARA (contribuídas pela comunidade e fornecedores), associações a atores (grupos de ameaças que usam a família), relatórios de referência (relatórios de CTI que documentam a família) e hashes de amostras (amostras representativas para cada variante).
Nomenclatura de Famílias de Malware
O Malpedia usa o formato plataforma.nome_da_familia (por exemplo, win.emotet, elf.mirai, apk.flubot). As plataformas incluem win (Windows), elf (Linux), apk (Android), osx (macOS) e py (Python). Essa nomenclatura padronizada resolve o problema dos "muitos nomes", onde diferentes fornecedores atribuem nomes diferentes ao mesmo malware.
Relacionamentos entre Famílias
As famílias de malware têm relacionamentos que incluem: pai-filho (reutilização de código, forks), loader-payload (Emotet carrega TrickBot que carrega Ryuk), autoria compartilhada (mesmo ator de ameaça desenvolve múltiplas ferramentas) e compartilhamento de infraestrutura (frameworks C2 comuns).
Fluxo de Trabalho
Passo 1: Consultar a API do Malpedia para Famílias de Malware
import requests
import json
from collections import defaultdict
class MalpediaClient:
BASE_URL = "https://malpedia.caad.fkie.fraunhofer.de/api"
def __init__(self, api_key):
self.headers = {"Authorization": f"apitoken {api_key}"}
def get_family_list(self):
"""Obtém a lista de todas as famílias de malware."""
resp = requests.get(f"{self.BASE_URL}/list/families",
headers=self.headers, timeout=30)
if resp.status_code == 200:
families = resp.json()
print(f"[+] Malpedia: {len(families)} famílias de malware")
return families
return {}
def get_family_info(self, family_name):
"""Obtém informações detalhadas sobre uma família de malware."""
resp = requests.get(f"{self.BASE_URL}/get/family/{family_name}",
headers=self.headers, timeout=30)
if resp.status_code == 200:
info = resp.json()
print(f"[+] Família: {family_name}")
print(f" Aliases: {info.get('alt_names', [])}")
print(f" Atores: {[a.get('value', '') for a in info.get('attribution', [])]}")
print(f" URLs: {len(info.get('urls', []))} referências")
return info
print(f"[-] Família não encontrada: {family_name}")
return None
def get_family_yara(self, family_name):
"""Obtém regras YARA para uma família de malware."""
resp = requests.get(f"{self.BASE_URL}/get/yara/{family_name}",
headers=self.headers, timeout=30)
if resp.status_code == 200:
rules = resp.json()
rule_count = sum(len(v) for v in rules.values()) if isinstance(rules, dict) else 0
print(f"[+] Regras YARA para {family_name}: {rule_count} regras")
return rules
return {}
def get_actor_families(self, actor_name):
"""Obtém famílias de malware associadas a um ator de ameaça."""
resp = requests.get(f"{self.BASE_URL}/get/actor/{actor_name}",
headers=self.headers, timeout=30)
if resp.status_code == 200:
data = resp.json()
families = data.get("families", {})
print(f"[+] {actor_name}: {len(families)} famílias de malware")
return data
return {}
def search_families(self, keyword):
"""Pesquisa famílias por palavra-chave."""
all_families = self.get_family_list()
matches = {
name: info for name, info in all_families.items()
if keyword.lower() in name.lower()
or keyword.lower() in str(info.get("alt_names", [])).lower()
}
print(f"[+] Pesquisa '{keyword}': {len(matches)} correspondências")
return matches
client = MalpediaClient("SUA_CHAVE_API_MALPEDIA")
families = client.get_family_list()
emotet_info = client.get_family_info("win.emotet")
Passo 2: Mapear Relacionamentos entre Famílias de Malware
class MalwareFamilyMapper:
def __init__(self, malpedia_client):
self.client = malpedia_client
self.relationship_graph = defaultdict(list)
def map_actor_ecosystem(self, actor_name):
"""Mapeia o ecossistema de malware usado por um ator de ameaça."""
actor_data = self.client.get_actor_families(actor_name)
families = actor_data.get("families", {})
ecosystem = {
"actor": actor_name,
"families": [],
"family_count": len(families),
}
for family_name in families:
info = self.client.get_family_info(family_name)
if info:
ecosystem["families"].append({
"name": family_name,
"aliases": info.get("alt_names", []),
"description": info.get("description", "")[:200],
"shared_actors": [
a.get("value", "")
for a in info.get("attribution", [])
],
"reference_count": len(info.get("urls", [])),
})
print(f"\n=== Ecossistema de Malware do {actor_name} ===")
for fam in ecosystem["families"]:
shared = [a for a in fam["shared_actors"] if a != actor_name]
print(f" {fam['name']}")
print(f" Aliases: {fam['aliases'][:5]}")
if shared:
print(f" Também usado por: {shared}")
return ecosystem
def find_shared_tooling(self, actor_names):
"""Encontra famílias de malware compartilhadas entre atores de ameaça."""
actor_families = {}
for actor in actor_names:
data = self.client.get_actor_families(actor)
actor_families[actor] = set(data.get("families", {}).keys())
# Encontra sobreposições
shared = {}
for i, actor1 in enumerate(actor_names):
for actor2 in actor_names[i+1:]:
common = actor_families[actor1] & actor_families[actor2]
if common:
shared[f"{actor1} <-> {actor2}"] = sorted(common)
print(f"\n=== Análise de Ferramentas Compartilhadas ===")
for pair, families in shared.items():
print(f" {pair}: {len(families)} famílias compartilhadas")
for f in families[:5]:
print(f" - {f}")
return shared
def build_loader_payload_chain(self, family_name):
"""Constrói a cadeia de entrega loader-payload para uma família."""
info = self.client.get_family_info(family_name)
if not info:
return {}
chain = {
"family": family_name,
"description": info.get("description", ""),
"known_loaders": [],
"known_payloads": [],
}
# Cadeias de entrega conhecidas comuns
known_chains = {
"win.emotet": {"loaders": ["email/macro"], "payloads": ["win.trickbot", "win.qakbot", "win.cobalt_strike"]},
"win.trickbot": {"loaders": ["win.emotet"], "payloads": ["win.ryuk", "win.conti", "win.cobalt_strike"]},
"win.qakbot": {"loaders": ["email/macro", "win.emotet"], "payloads": ["win.cobalt_strike", "win.blackbasta"]},
"win.cobalt_strike": {"loaders": ["win.emotet", "win.trickbot", "win.qakbot"], "payloads": ["ransomware"]},
}
if family_name in known_chains:
chain["known_loaders"] = known_chains[family_name]["loaders"]
chain["known_payloads"] = known_chains[family_name]["payloads"]
return chain
mapper = MalwareFamilyMapper(client)
ecosystem = mapper.map_actor_ecosystem("Wizard Spider")
shared = mapper.find_shared_tooling(["Wizard Spider", "FIN7", "Lazarus Group"])
chain = mapper.build_loader_payload_chain("win.emotet")
Passo 3: Extrair e Compilar Regras YARA
def compile_yara_ruleset(client, family_names, output_file="malware_yara_rules.yar"):
"""Compila regras YARA para múltiplas famílias de malware."""
all_rules = []
for family in family_names:
yara_data = client.get_family_yara(family)
if isinstance(yara_data, dict):
for source, rules in yara_data.items():
if isinstance(rules, list):
for rule in rules:
all_rules.append(f"// Fonte: {source} - Família: {family}\n{rule}")
elif isinstance(rules, str):
all_rules.append(f"// Fonte: {source} - Família: {family}\n{rules}")
with open(output_file, "w") as f:
f.write(f"// Regras YARA do Malpedia - {len(all_rules)} regras\n")
f.write(f"// Famílias: {', '.join(family_names)}\n\n")
for rule in all_rules:
f.write(rule + "\n\n")
print(f"[+] Compiladas {len(all_rules)} regras YARA em {output_file}")
return all_rules
compile_yara_ruleset(client, ["win.emotet", "win.trickbot", "win.cobalt_strike"])
Critérios de Validação
- API do Malpedia consultada com sucesso para famílias de malware
- Informações da família recuperadas com aliases, atores e referências
- Relacionamentos ator-família mapeados corretamente
- Ferramentas compartilhadas entre atores identificadas
- Regras YARA extraídas e compiladas para detecção
- Cadeias loader-payload documentadas para inteligência de ameaças