Analisando Persistência de Malware com Autoruns
Visão Geral
O Sysinternals Autoruns extrai dados de centenas de Pontos de Extensibilidade de Inicialização Automática (ASEPs) no Windows, escaneando mais de 18 categorias, incluindo chaves Run/RunOnce, serviços, tarefas agendadas, drivers, entradas Winlogon, provedores LSA, monitores de impressão, assinaturas WMI e DLLs AppInit. A verificação de assinatura digital filtra entradas assinadas pela Microsoft. A função de comparação identifica persistência recém-adicionada via diff de linha de base. A integração com VirusTotal verifica a reputação de hashes. A análise offline através da flag -z permite examinar imagens de disco forense.
Quando Usar
- Ao investigar incidentes de segurança que exigem análise de persistência de malware com autoruns
- Ao construir 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
- Sysinternals Autoruns (GUI) e Autorunsc (CLI)
- Privilégios administrativos no sistema alvo
- Python 3.9+ para análise automatizada
- Chave de API VirusTotal para verificações de reputação
- Exportação de linha de base limpa para comparação
Fluxo de Trabalho
Passo 1: Varredura Automatizada de Persistência
#!/usr/bin/env python3
"""Automatiza análise de persistência baseada em Autoruns."""
import subprocess
import csv
import json
import sys
def scan_and_analyze(autorunsc_path="autorunsc64.exe", csv_path="scan.csv"):
cmd = [autorunsc_path, "-a", "*", "-c", "-h", "-s", "-nobanner", "*"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
with open(csv_path, 'w') as f:
f.write(result.stdout)
return parse_and_flag(csv_path)
def parse_and_flag(csv_path):
suspicious = []
with open(csv_path, 'r', errors='replace') as f:
for row in csv.DictReader(f):
reasons = []
signer = row.get("Signer", "")
if not signer or signer == "(Not verified)":
reasons.append("Binário não assinado")
if not row.get("Description") and not row.get("Company"):
reasons.append("Metadados ausentes")
path = row.get("Image Path", "").lower()
for sp in ["\\temp\\", "\\appdata\\local\\temp", "\\users\\public\\"]:
if sp in path:
reasons.append(f"Caminho suspeito")
launch = row.get("Launch String", "").lower()
for kw in ["powershell", "cmd /c", "wscript", "mshta", "regsvr32"]:
if kw in launch:
reasons.append(f"LOLBin: {kw}")
if reasons:
row["reasons"] = reasons
suspicious.append(row)
return suspicious
if __name__ == "__main__":
if len(sys.argv) > 1:
results = parse_and_flag(sys.argv[1])
print(f"[!] {len(results)} entradas suspeitas")
for r in results:
print(f" {r.get('Entry','')} - {r.get('Image Path','')}")
for reason in r.get('reasons', []):
print(f" - {reason}")
Critérios de Validação
- Todas as categorias ASEP escaneadas e catalogadas
- Entradas não assinadas sinalizadas para investigação
- Caminhos suspeitos e strings de inicialização LOLBin destacados
- Comparação de linha de base identifica novos mecanismos de persistência