Communitygithub.com

análisis-forense-de-correo-pst-de-outlook

Analiza archivos PST y OST de Microsoft Outlook usando libpff y pst-utils para extraer contenido de mensajes, cabeceras, archivos adjuntos, elementos eliminados y metadatos MAPI, incluyendo la recuperación de elementos de la carpeta Elementos Recuperables. Útil para investigaciones forenses de correo, e-descubrimiento legal o respuesta a incidentes que requieran reconstruir patrones de comunicación o rastrear el enrutamiento de mensajes a partir de archivos de Outlook.

¿Qué es análisis-forense-de-correo-pst-de-outlook?

Esta habilidad está diseñada para investigadores forenses digitales, analistas de SOC y profesionales de respuesta a incidentes que necesitan analizar correos electrónicos almacenados en archivos PST y OST de Microsoft Outlook. Proporciona un enfoque estructurado y automatizado para extraer y analizar metadatos forenses clave, incluyendo cabeceras de correo, archivos adjuntos, elementos eliminados de la carpeta Elementos Recuperables y metadatos MAPI. Utiliza herramientas open-source como libpff/pffexport y bibliotecas de Python (pypff, libratom) para realizar un análisis completo sin depender de software comercial. La habilidad incluye un script en Python que recorre recursivamente la estructura de carpetas del PST, extrae información detallada de cada mensaje (asunto, remitente, destinatario, marcas de tiempo, cabeceras de transporte), procesa archivos adjuntos con límites de tamaño configurables y genera un informe JSON estructurado con estadísticas del análisis. Es compatible con plataformas como Claude Code, Cursor, Codex y otras herramientas que soporten la ejecución de scripts de Python y comandos de shell, facilitando la integración en flujos de trabajo forenses más amplios.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-outlook-pst-for-email-forensics

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Análisis Forense de Archivos PST de Outlook

Descripción General

Los archivos PST (Tabla de Almacenamiento Personal) y OST (Tabla de Almacenamiento sin Conexión) de Microsoft Outlook son fuentes de evidencia críticas en las investigaciones forenses digitales. Los archivos PST almacenan mensajes de correo electrónico, eventos de calendario, contactos, tareas y notas en un formato binario propietario basado en el sistema de propiedades MAPI (Interfaz de Programación de Aplicaciones de Mensajería). El análisis forense de estos archivos permite la recuperación de correos electrónicos eliminados (de la carpeta Elementos Recuperables), la extracción de cabeceras de correo para rastrear rutas de mensajes, el análisis de archivos adjuntos para detectar malware o datos exfiltrados, y la reconstrucción de patrones de comunicación. Los archivos PST modernos usan formato Unicode con páginas de 4 KB y pueden crecer hasta 50 GB, mientras que el formato ANSI heredado está limitado a 2 GB.

Cuándo Usarlo

  • Cuando se investigan incidentes de seguridad que requieran analizar archivos PST de Outlook para fines forenses de correo
  • Cuando se construyen reglas de detección o consultas de caza de amenazas para este dominio
  • Cuando los analistas de SOC necesitan procedimientos estructurados para este tipo de análisis
  • Cuando se valida la cobertura de monitoreo de seguridad para técnicas de ataque relacionadas

Prerrequisitos

  • libpff/pffexport (analizador PST de código abierto)
  • Python 3.8+ con bibliotecas pypff o libratom
  • MailXaminer, Forensic Email Collector o SysTools PST Forensics (comerciales)
  • Microsoft Outlook (opcional, para acceso nativo a PST)
  • Suficiente espacio en disco para el contenido extraído

Ubicaciones de Archivos PST

OrigenRuta
Outlook 2016+ (predeterminado)%USERPROFILE%\Documents\Outlook Files*.pst
Outlook heredado%LOCALAPPDATA%\Microsoft\Outlook*.pst
Caché OST%LOCALAPPDATA%\Microsoft\Outlook*.ost
Archivo%USERPROFILE%\Documents\Outlook Files\archive.pst

Análisis con Herramientas de Código Abierto

libpff / pffexport

# Exportar todos los elementos de un archivo PST
pffexport -m all evidence.pst -t exported_pst

# Exportar solo mensajes de correo
pffexport -m items evidence.pst -t exported_emails

# Exportar elementos eliminados/recuperados
pffexport -m recovered evidence.pst -t recovered_items

# Obtener información del archivo PST
pffinfo evidence.pst

Análisis con Python

import pypff
import os
import json
import hashlib
import email
import sys
from datetime import datetime
from collections import defaultdict


class PSTForensicAnalyzer:
    """Análisis forense de archivos PST/OST de Outlook."""

    def __init__(self, pst_path: str, output_dir: str):
        self.pst_path = pst_path
        self.output_dir = output_dir
        os.makedirs(output_dir, exist_ok=True)
        self.pst = pypff.file()
        self.pst.open(pst_path)
        self.messages = []
        self.attachments = []
        self.stats = defaultdict(int)

    def process_folder(self, folder, folder_path: str = ""):
        """Procesa carpetas PST de forma recursiva y extrae mensajes."""
        folder_name = folder.name or "Root"
        current_path = f"{folder_path}/{folder_name}" if folder_path else folder_name

        for i in range(folder.number_of_sub_messages):
            try:
                message = folder.get_sub_message(i)
                msg_data = self.extract_message(message, current_path)
                if msg_data:
                    self.messages.append(msg_data)
                    self.stats["total_messages"] += 1
            except Exception as e:
                self.stats["parse_errors"] += 1

        for i in range(folder.number_of_sub_folders):
            try:
                subfolder = folder.get_sub_folder(i)
                self.process_folder(subfolder, current_path)
            except Exception:
                continue

    def extract_message(self, message, folder_path: str) -> dict:
        """Extrae metadatos forenses de un solo mensaje de correo."""
        msg_data = {
            "folder": folder_path,
            "subject": message.subject or "",
            "sender": message.sender_name or "",
            "sender_email": "",
            "creation_time": str(message.creation_time) if message.creation_time else None,
            "delivery_time": str(message.delivery_time) if message.delivery_time else None,
            "modification_time": str(message.modification_time) if message.modification_time else None,
            "has_attachments": message.number_of_attachments > 0,
            "attachment_count": message.number_of_attachments,
            "body_size": len(message.plain_text_body or b""),
            "html_size": len(message.html_body or b""),
        }

        # Extraer cabeceras de transporte para análisis de enrutamiento
        headers = message.transport_headers
        if headers:
            msg_data["headers_present"] = True
            msg_data["headers_size"] = len(headers)
            # Analizar cabeceras clave
            parsed = email.message_from_string(headers)
            msg_data["from_header"] = parsed.get("From", "")
            msg_data["to_header"] = parsed.get("To", "")
            msg_data["date_header"] = parsed.get("Date", "")
            msg_data["message_id"] = parsed.get("Message-ID", "")
            msg_data["x_originating_ip"] = parsed.get("X-Originating-IP", "")
            msg_data["received_headers"] = parsed.get_all("Received", [])

        # Procesar archivos adjuntos
        for j in range(message.number_of_attachments):
            try:
                attachment = message.get_attachment(j)
                att_data = {
                    "message_subject": msg_data["subject"],
                    "name": attachment.name or f"attachment_{j}",
                    "size": attachment.size,
                    "content_type": "",
                }
                self.attachments.append(att_data)
                self.stats["total_attachments"] += 1
            except Exception:
                continue

        return msg_data

    def save_attachments(self, max_size_mb: int = 100):
        """Exporta archivos adjuntos al disco para su análisis."""
        att_dir = os.path.join(self.output_dir, "attachments")
        os.makedirs(att_dir, exist_ok=True)

        root = self.pst.get_root_folder()
        self._save_attachments_recursive(root, att_dir, max_size_mb)

    def _save_attachments_recursive(self, folder, att_dir, max_size_mb):
        for i in range(folder.number_of_sub_messages):
            try:
                message = folder.get_sub_message(i)
                for j in range(message.number_of_attachments):
                    att = message.get_attachment(j)
                    if att.size and att.size < max_size_mb * 1024 * 1024:
                        name = att.name or f"unknown_{i}_{j}"
                        safe_name = "".join(c if c.isalnum() or c in ".-_" else "_" for c in name)
                        path = os.path.join(att_dir, safe_name)
                        try:
                            data = att.read_buffer(att.size)
                            with open(path, "wb") as f:
                                f.write(data)
                        except Exception:
                            continue
            except Exception:
                continue

        for i in range(folder.number_of_sub_folders):
            try:
                self._save_attachments_recursive(folder.get_sub_folder(i), att_dir, max_size_mb)
            except Exception:
                continue

    def generate_report(self) -> str:
        """Genera un informe completo de análisis forense de PST."""
        root = self.pst.get_root_folder()
        self.process_folder(root)

        report = {
            "analysis_timestamp": datetime.now().isoformat(),
            "pst_file": self.pst_path,
            "pst_size_bytes": os.path.getsize(self.pst_path),
            "statistics": dict(self.stats),
            "messages": self.messages[:500],
            "attachments": self.attachments[:200],
        }

        report_path = os.path.join(self.output_dir, "pst_forensic_report.json")
        with open(report_path, "w") as f:
            json.dump(report, f, indent=2, default=str)

        print(f"[*] Mensajes totales: {self.stats['total_messages']}")
        print(f"[*] Archivos adjuntos totales: {self.stats['total_attachments']}")
        print(f"[*] Errores de análisis: {self.stats['parse_errors']}")
        return report_path

    def close(self):
        self.pst.close()


def main():
    if len(sys.argv) < 3:
        print("Uso: python process.py <archivo_pst> <directorio_salida>")
        sys.exit(1)
    analyzer = PSTForensicAnalyzer(sys.argv[1], sys.argv[2])
    analyzer.generate_report()
    analyzer.close()


if __name__ == "__main__":
    main()

Análisis de Cabeceras de Correo

Cabeceras clave para la investigación forense:

CabeceraValor Forense
ReceivedCadena de enrutamiento del mensaje (leer de abajo arriba)
X-Originating-IPDirección IP real del remitente
Message-IDIdentificador único para correlación
DateMarca de tiempo de envío
Return-PathDirección de rebote (puede diferir de From)
DKIM-SignatureFirma de autenticación del dominio
Authentication-ResultsResultados de verificación SPF, DKIM, DMARC
X-MailerCliente de correo utilizado

Referencias

Ejemplo de Salida

$ pffexport /evidence/jsmith_archive.pst -t /analysis/pst_output

pffexport 20231205 - Herramienta de Exportación PST/OST de libpff
=================================================
Entrada: /evidence/jsmith_archive.pst (2.3 GB)

Exportando contenido PST...
  Carpetas:       45
  Mensajes:       12,456
  Archivos adjuntos:   3,234
  Contactos:      567
  Calendario:     234
  Tareas:         89

Exportación completada en 3m 42s.

$ python3 pst_analyzer.py /analysis/pst_output /analysis/email_report

Informe de Análisis Forense PST
==============================
Fuente: jsmith_archive.pst ([email protected])
Rango de Fechas: 2023-06-01 a 2024-01-18

--- Estadísticas del Buzón ---
  Correos Totales:          12,456
  Enviados:                 4,567
  Recibidos:                7,889
  Con Archivos Adjuntos:    3,234
  Eliminados (recuperados): 234

--- Correos de Phishing / Sospechosos ---
Correo #8923
  Fecha:        2024-01-15 14:30:22 UTC
  De:           "IT Support" <[email protected]>
  Para:         [email protected]
  Asunto:       Urgente: Restablecimiento de Contraseña Requerido
  Cabeceras:
    Return-Path:    [email protected]
    X-Originating-IP: 203.0.113.55
    Received:       de mail-relay.c0rporate-help.com (203.0.113.55)
    SPF:            FALLÓ (dominio c0rporate-help.com)
    DKIM:           NINGUNO
    DMARC:          FALLÓ
  Archivos Adjuntos:
    - Password_Reset_Form.xlsm (245 KB) SHA-256: 7a3b8c9d...e1f2a3b4
  Vista Previa del Cuerpo:  "Estimado Empleado, su contraseña caducará en 24 horas.
                  Abra el formulario adjunto para restablecer sus credenciales..."

--- Indicadores de Exfiltración de Datos ---
Correo #9102
  Fecha:        2024-01-16 03:15:45 UTC
  De:           [email protected]
  Para:         [email protected]
  Asunto:       (sin asunto)
  Archivos Adjuntos:
    - archive_part1.7z (24.5 MB) - encriptado
    - archive_part2.7z (24.5 MB) - encriptado

Correo #9103
  Fecha:        2024-01-16 03:18:22 UTC
  De:           [email protected]
  Para:         [email protected]
  Asunto:       Re:
  Archivos Adjuntos:
    - archive_part3.7z (18.2 MB) - encriptado

--- Coincidencias de Palabras Clave ---
  "confidencial":     45 correos
  "contraseña":       23 correos
  "transferencia":    12 correos
  "renuncia":         3 correos
  "eliminar evidencia":  1 correo (Correo #9200, 2024-01-17 22:30:00 UTC)

Resumen:
  Correos de phishing detectados:    1 (vector de compromiso inicial)
  Correos enviados sospechosos:      5 (a cuentas personales con archivos adjuntos)
  Archivos adjuntos encriptados:     3 (67.2 MB en total - posible exfiltración)
  Informe: /analysis/email_report/pst_forensic_report.json

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

abusing-dpapi-for-credential-access

Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket

abusing-shadow-credentials-for-privesc

Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target

achieving-cmmc-level-2-compliance

>-

acquiring-disk-image-with-dd-and-dcfldd

Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.

analyzing-active-directory-acl-abuse

Detect dangerous ACL misconfigurations in Active Directory using ldap3

analyzing-android-malware-with-apktool

Perform static analysis of Android APK malware using apktool for resource decompilation, jadx for Java source recovery, and androguard for manifest inspection, dangerous permission-combination detection, and identification of obfuscated code, dynamic code loading, and reflection-based API calls. Use to statically triage a suspicious APK without executing it or to build mobile malware detection rules.

analyzing-api-gateway-access-logs

Parses API Gateway access logs (AWS API Gateway, Kong, Nginx) to detect

analyzing-apt-group-with-mitre-navigator

Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups

analyzing-azure-activity-logs-for-threats

Queries Azure Monitor activity logs and sign-in logs via azure-monitor-query

analyzing-bootkit-and-rootkit-samples

Analyzes bootkit and advanced rootkit malware infecting the Master

analyzing-browser-forensics-with-hindsight

Parse Chromium-based browser databases with Hindsight to extract and correlate browsing history, downloads, cookies, cached content, autofill data, saved passwords, and extensions from Chrome, Edge, Brave, Opera, and Vivaldi into a unified timeline (XLSX, JSON, or SQLite output). Use during incident response, insider-threat investigations, or criminal cases when you need to reconstruct a user

analyzing-campaign-attribution-evidence

Systematically evaluate cyber-campaign evidence to attribute an operation to a threat actor, using the Diamond Model and Analysis of Competing Hypotheses (ACH) to weigh infrastructure overlaps, TTP consistency, malware code similarity, and timing/language artifacts into confidence-weighted attribution assessments. Use when an incident investigation needs a defensible attribution confidence level.

analyzing-certificate-transparency-for-phishing

Monitor Certificate Transparency logs using crt.sh and Certstream to

analyzing-cloud-storage-access-patterns

Detect abnormal access in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics for after-hours bulk downloads, new-IP access, and API-call spikes (e.g. GetObject) via statistical baselines and time-series anomaly detection. Use when investigating suspected cloud data exfiltration or building related detection rules.

analyzing-cobalt-strike-beacon-configuration

Extract and analyze Cobalt Strike beacon configuration from PE files

analyzing-cobaltstrike-malleable-c2-profiles

Parse and analyze Cobalt Strike Malleable C2 profiles with dissect.cobaltstrike (profiles and beacon-payload configs) and pyMalleableC2 (AST parsing) to extract HTTP/DNS transforms, URIs, headers, sleep/jitter, and injection behavior, then generate network detection signatures. Use when reverse-engineering a captured malleable profile or building detections against Cobalt Strike Beacon traffic.

analyzing-command-and-control-communication

Analyzes malware C2 communication over HTTP, HTTPS, DNS, and custom

analyzing-cyber-kill-chain

Analyzes intrusion activity against the Lockheed Martin Cyber Kill Chain

analyzing-disk-image-with-autopsy

Perform comprehensive forensic analysis of raw (dd), E01, or AFF disk images with Autopsy and The Sleuth Kit, recovering deleted files, examining metadata and embedded artifacts, keyword searching, and building investigation timelines with visual reports. Use for structured analysis of a forensic disk image or when stakeholders need visual reports from evidence.

analyzing-dns-logs-for-exfiltration

Analyzes DNS query logs to detect data exfiltration via DNS tunneling,

Skills relacionados