phishing defense

Implementing Email Sandboxing with Proofpoint

Email sandboxing detonates suspicious attachments and URLs in isolated environments to detect zero-day malware and evasive phishing payloads. Proofpoint Targeted Attack Protection (TAP) is an industry-leading solution that uses multi-stage sandboxing, URL rewriting, and predictive analysis. This skill covers configuring Proofpoint TAP, integrating with email flow, analyzing sandbox reports, and tuning detection policies.

awarenessdmarcemail-securityphishingproofpointsandboxingsocial-engineering
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Email sandboxing detonates suspicious attachments and URLs in isolated environments to detect zero-day malware and evasive phishing payloads. Proofpoint Targeted Attack Protection (TAP) is an industry-leading solution that uses multi-stage sandboxing, URL rewriting, and predictive analysis. This skill covers configuring Proofpoint TAP, integrating with email flow, analyzing sandbox reports, and tuning detection policies.

When to Use

  • When deploying or configuring implementing email sandboxing with proofpoint capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • Proofpoint Email Protection license with TAP add-on
  • Admin access to Proofpoint admin console
  • Understanding of email delivery architecture (MX records, mail flow rules)
  • SIEM integration capability

Key Concepts

Proofpoint TAP Capabilities

  1. Attachment sandboxing: Detonates files in virtual machines (Windows, macOS, Android)
  2. URL Defense: Rewrites URLs, detonates at time-of-click
  3. Threat Intelligence: Proofpoint's NexusAI threat intelligence integration
  4. TAP Dashboard: Real-time visibility into threats targeting the organization
  5. Campaign correlation: Groups related attacks into campaigns
  6. Very Attacked People (VAP): Identifies most-targeted individuals

Sandbox Evasion Techniques Detected

  • Delayed execution (time-bomb malware)
  • VM detection bypass
  • User interaction requirements (click-to-enable macros)
  • Sandbox-aware malware that checks for analysis environment
  • Encrypted/password-protected attachments
  • Multi-stage payloads with delayed C2 retrieval

Workflow

Step 1: Configure TAP in Proofpoint

  • Enable TAP for inbound email policy
  • Configure sandbox profiles (attachment types to detonate)
  • Set URL Defense rewriting policy
  • Configure quarantine actions for malicious verdicts

Step 2: Tune Attachment Policies

Recommended attachment policy:
- Detonate: .exe, .dll, .scr, .doc(m), .xls(m), .ppt(m), .pdf, .zip, .rar, .7z, .iso
- Block without detonation: .bat, .cmd, .ps1, .vbs, .js, .wsf, .hta
- Password-protected archives: Attempt common passwords, then quarantine
- Dynamic delivery: Deliver email body, hold attachment until verdict

Step 3: Configure URL Defense

  • Enable URL rewriting for all inbound email
  • Set time-of-click detonation
  • Block access to malicious URLs
  • Show warning page for suspicious (not confirmed malicious) URLs
  • Configure allowed domains bypass list

Step 4: Set Up TAP Dashboard Monitoring

  • Configure daily threat digest emails to security team
  • Set up real-time alerts for targeted attacks
  • Monitor VAP report for high-risk users
  • Review campaign clusters for coordinated attacks

Step 5: Integrate with SIEM

  • Configure syslog/API export to SIEM
  • Create correlation rules for TAP alerts
  • Set up automated response workflows

Tools & Resources

Validation

  • Attachment detonation catches EICAR test file and macro-enabled document
  • URL Defense rewrites and blocks known phishing URLs
  • TAP Dashboard displays threat summary
  • SIEM receives and alerts on TAP events
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.5 KB

API Reference: Implementing Email Sandboxing with Proofpoint

Proofpoint TAP SIEM API

import requests
resp = requests.get(
    "https://tap-api-v2.proofpoint.com/v2/siem/all",
    auth=(principal, secret),
    params={"sinceSeconds": 3600, "format": "json"})
data = resp.json()
# Keys: messagesDelivered, messagesBlocked, clicksPermitted, clicksBlocked

TAP API Endpoints

Endpoint Description
/v2/siem/all All threat events
/v2/siem/messages/blocked Blocked messages only
/v2/siem/messages/delivered Delivered threats
/v2/siem/clicks/blocked Blocked URL clicks
/v2/siem/clicks/permitted Permitted URL clicks

Threat Categories

Category Description Severity
Malware Malicious attachment CRITICAL
Phish Credential harvesting HIGH
Impostor BEC/spoofing HIGH
Spam Unsolicited LOW

URL Defense Configuration

{
  "url_defense": {
    "rewrite_all_urls": true,
    "real_time_scanning": true,
    "sandbox_detonation": true,
    "click_time_protection": true
  }
}

Splunk Integration

index=proofpoint sourcetype=tap:siem
| where classification="malicious"
| stats count by sender, threatType, subject

References

standards.md1.4 KB

Standards & References: Email Sandboxing with Proofpoint

MITRE ATT&CK Coverage

  • T1566.001: Phishing: Spearphishing Attachment (primary detection)
  • T1566.002: Phishing: Spearphishing Link (URL Defense)
  • T1204.001/002: User Execution: Malicious Link/File
  • T1059: Command and Scripting Interpreter (macro detection)
  • T1027: Obfuscated Files or Information

NIST Guidelines

  • NIST SP 800-177: Trustworthy Email - attachment security
  • NIST SP 800-83 Rev.1: Guide to Malware Incident Prevention
  • NIST SP 800-53: SI-3 Malicious Code Protection, SI-8 Spam Protection

Proofpoint TAP API Endpoints

Endpoint Description
/v2/siem/all All threat events for SIEM
/v2/siem/messages/blocked Blocked message events
/v2/siem/messages/delivered Delivered message events with threats
/v2/siem/clicks/blocked Blocked URL click events
/v2/siem/clicks/permitted Permitted URL click events
/v2/people/vap Very Attacked People list
/v2/campaign/{id} Campaign details

Sandbox File Types

Category Extensions Action
Executables .exe, .dll, .scr, .com Detonate + Block
Office docs .doc(x/m), .xls(x/m), .ppt(x/m) Detonate
PDF .pdf Detonate
Archives .zip, .rar, .7z, .tar.gz Extract + Detonate
Scripts .js, .vbs, .ps1, .bat, .cmd Block
Disk images .iso, .img, .vhd Detonate
workflows.md1.7 KB

Workflows: Email Sandboxing with Proofpoint

Workflow 1: Attachment Detonation Pipeline

Email with attachment arrives at Proofpoint gateway
  |
  v
[Pre-filter: Check attachment type]
  +-- Blocked types (.bat, .ps1, .vbs) --> Quarantine immediately
  +-- Detonable types --> Send to sandbox
  +-- Known safe types (.txt, .csv) --> Deliver
  |
  v
[Sandbox detonation]
  +-- Execute in multiple environments (Win10, Win11, macOS)
  +-- Monitor: file system changes, registry, network, process creation
  +-- Timeout: 60-120 seconds per environment
  |
  v
[Verdict]
  +-- MALICIOUS --> Quarantine, alert, extract IOCs
  +-- SUSPICIOUS --> Quarantine for analyst review
  +-- CLEAN --> Deliver with dynamic delivery

Workflow 2: URL Defense Time-of-Click

Email with URL arrives
  |
  v
[URL rewritten to Proofpoint URL Defense proxy]
  |
  v
[Email delivered to user]
  |
  v
[User clicks rewritten URL]
  |
  v
[Proofpoint performs real-time analysis]
  +-- Reputation check
  +-- Content analysis
  +-- Sandbox detonation of landing page
  |
  +-- SAFE --> Redirect to original URL
  +-- MALICIOUS --> Block access, show warning page
  +-- SUSPICIOUS --> Show interstitial warning, allow proceed

Workflow 3: TAP Dashboard Monitoring

Daily operations:
  +-- Review TAP Dashboard threat digest
  +-- Check VAP (Very Attacked People) changes
  +-- Review campaign clusters
  +-- Investigate quarantined messages
  +-- Monitor false positive rate
  |
Weekly:
  +-- Analyze threat trends
  +-- Review sandboxing effectiveness
  +-- Tune policies based on FP/FN data
  +-- Update blocked file type list
  |
Monthly:
  +-- Generate executive report from TAP
  +-- Review VAP list with HR/management
  +-- Assess ROI and threat prevention metrics

Scripts 2

agent.py5.3 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for implementing and monitoring Proofpoint email sandboxing."""

import json
import argparse
from datetime import datetime

try:
    import requests
except ImportError:
    requests = None


def get_tap_threats(base_url, principal, secret, time_range="PT1H"):
    """Query Proofpoint TAP SIEM API for threats."""
    url = f"{base_url}/v2/siem/all"
    resp = requests.get(url, auth=(principal, secret),
                        params={"sinceSeconds": 3600, "format": "json"}, timeout=60)
    resp.raise_for_status()
    data = resp.json()
    return {
        "messages_delivered": len(data.get("messagesDelivered", [])),
        "messages_blocked": len(data.get("messagesBlocked", [])),
        "clicks_permitted": len(data.get("clicksPermitted", [])),
        "clicks_blocked": len(data.get("clicksBlocked", [])),
        "threats": data.get("messagesBlocked", [])[:50],
    }


def analyze_sandbox_results(results_path):
    """Analyze Proofpoint sandbox detonation results."""
    with open(results_path) as f:
        results = json.load(f)
    findings = []
    for result in results if isinstance(results, list) else results.get("results", []):
        verdict = result.get("verdict", result.get("classification", ""))
        score = result.get("score", result.get("threat_score", 0))
        if verdict.lower() in ("malicious", "phish", "spam") or int(score) > 70:
            findings.append({
                "message_id": result.get("message_id", ""),
                "sender": result.get("sender", result.get("from", "")),
                "subject": result.get("subject", ""),
                "verdict": verdict,
                "score": score,
                "threats_found": result.get("threats", []),
                "attachment": result.get("attachment_name", ""),
                "url_detonated": result.get("url", ""),
                "severity": "CRITICAL" if int(score) > 90 else "HIGH",
            })
    return findings


def calculate_email_metrics(log_path):
    """Calculate email security metrics from logs."""
    total = 0
    blocked = 0
    delivered = 0
    by_category = {}
    with open(log_path) as f:
        for line in f:
            try:
                entry = json.loads(line)
            except json.JSONDecodeError:
                continue
            total += 1
            action = entry.get("action", entry.get("policy_action", "")).lower()
            if action in ("block", "quarantine", "reject"):
                blocked += 1
            else:
                delivered += 1
            cat = entry.get("category", entry.get("threat_type", "clean"))
            by_category[cat] = by_category.get(cat, 0) + 1
    return {
        "total_messages": total, "blocked": blocked, "delivered": delivered,
        "block_rate": round(blocked / total * 100, 1) if total else 0,
        "by_category": by_category,
    }


def generate_url_defense_config():
    """Generate Proofpoint URL Defense configuration."""
    return {
        "url_defense": {
            "enabled": True,
            "rewrite_all_urls": True,
            "real_time_scanning": True,
            "sandbox_detonation": True,
            "click_time_protection": True,
        },
        "attachment_defense": {
            "enabled": True,
            "sandbox_analysis": True,
            "supported_types": ["exe", "dll", "doc", "docx", "xls", "xlsx",
                               "pdf", "zip", "rar", "iso", "lnk"],
            "action_on_malicious": "quarantine",
        },
    }


def main():
    parser = argparse.ArgumentParser(description="Proofpoint Email Sandboxing Agent")
    parser.add_argument("--tap-url", default="https://tap-api-v2.proofpoint.com")
    parser.add_argument("--principal", help="TAP API principal")
    parser.add_argument("--secret", help="TAP API secret")
    parser.add_argument("--results", help="Sandbox results JSON")
    parser.add_argument("--log", help="Email log (JSON lines)")
    parser.add_argument("--output", default="proofpoint_sandbox_report.json")
    parser.add_argument("--action", choices=["tap", "analyze", "metrics", "config", "full"],
                        default="full")
    args = parser.parse_args()

    report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}

    if args.action in ("tap", "full") and args.principal and args.secret:
        data = get_tap_threats(args.tap_url, args.principal, args.secret)
        report["findings"]["tap_threats"] = data
        print(f"[+] Blocked: {data['messages_blocked']}, Delivered: {data['messages_delivered']}")

    if args.action in ("analyze", "full") and args.results:
        findings = analyze_sandbox_results(args.results)
        report["findings"]["sandbox_findings"] = findings
        print(f"[+] Malicious sandbox results: {len(findings)}")

    if args.action in ("metrics", "full") and args.log:
        metrics = calculate_email_metrics(args.log)
        report["findings"]["email_metrics"] = metrics
        print(f"[+] Block rate: {metrics['block_rate']}%")

    if args.action in ("config", "full"):
        config = generate_url_defense_config()
        report["findings"]["config"] = config
        print("[+] URL/Attachment Defense config generated")

    with open(args.output, "w") as fout:
        json.dump(report, fout, indent=2, default=str)
    print(f"[+] Report saved to {args.output}")


if __name__ == "__main__":
    main()
process.py9.0 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Proofpoint TAP API Integration and Analysis

Pulls threat data from Proofpoint TAP SIEM API, analyzes sandbox results,
identifies Very Attacked People, and generates threat reports.

Usage:
    python process.py threats --hours 24
    python process.py vap
    python process.py campaign --id <campaign-id>
    python process.py report --hours 168 --output report.html
"""

import argparse
import json
import sys
import os
from datetime import datetime, timezone, timedelta
from collections import defaultdict
from dataclasses import dataclass, field, asdict

try:
    import requests
    HAS_REQUESTS = True
except ImportError:
    HAS_REQUESTS = False

PP_SERVICE_PRINCIPAL = os.environ.get("PP_SERVICE_PRINCIPAL", "")
PP_SECRET = os.environ.get("PP_SECRET", "")
PP_BASE_URL = "https://tap-api-v2.proofpoint.com"


class ProofpointTAPClient:
    """Client for Proofpoint TAP SIEM API."""

    def __init__(self, principal: str, secret: str):
        self.auth = (principal, secret)
        self.base = PP_BASE_URL

    def _get(self, endpoint: str, params: dict = None) -> dict:
        resp = requests.get(f"{self.base}{endpoint}",
                            auth=self.auth, params=params, timeout=30)
        resp.raise_for_status()
        return resp.json()

    def get_all_threats(self, since_seconds: int = 3600) -> dict:
        params = {"sinceSeconds": since_seconds, "format": "json"}
        return self._get("/v2/siem/all", params)

    def get_blocked_messages(self, since_seconds: int = 3600) -> dict:
        params = {"sinceSeconds": since_seconds, "format": "json"}
        return self._get("/v2/siem/messages/blocked", params)

    def get_delivered_threats(self, since_seconds: int = 3600) -> dict:
        params = {"sinceSeconds": since_seconds, "format": "json"}
        return self._get("/v2/siem/messages/delivered", params)

    def get_blocked_clicks(self, since_seconds: int = 3600) -> dict:
        params = {"sinceSeconds": since_seconds, "format": "json"}
        return self._get("/v2/siem/clicks/blocked", params)

    def get_permitted_clicks(self, since_seconds: int = 3600) -> dict:
        params = {"sinceSeconds": since_seconds, "format": "json"}
        return self._get("/v2/siem/clicks/permitted", params)

    def get_vap(self, window: int = 14) -> dict:
        params = {"window": window}
        return self._get("/v2/people/vap", params)

    def get_campaign(self, campaign_id: str) -> dict:
        return self._get(f"/v2/campaign/{campaign_id}")


def analyze_threats(threat_data: dict) -> dict:
    """Analyze threat data and produce summary statistics."""
    messages_blocked = threat_data.get("messagesBlocked", [])
    messages_delivered = threat_data.get("messagesDelivered", [])
    clicks_blocked = threat_data.get("clicksBlocked", [])
    clicks_permitted = threat_data.get("clicksPermitted", [])

    # Threat classification counts
    threat_types = defaultdict(int)
    threat_families = defaultdict(int)
    targeted_users = defaultdict(int)
    sender_domains = defaultdict(int)

    all_messages = messages_blocked + messages_delivered
    for msg in all_messages:
        for threat in msg.get("threatsInfoMap", []):
            threat_types[threat.get("classification", "unknown")] += 1
            if threat.get("threatType") == "attachment":
                threat_families[threat.get("threat", "unknown")] += 1

        for recipient in msg.get("recipient", []) if isinstance(msg.get("recipient"), list) else [msg.get("recipient", "")]:
            if recipient:
                targeted_users[recipient] += 1

        sender = msg.get("senderDomain", msg.get("fromAddress", ""))
        if sender:
            sender_domains[sender] += 1

    summary = {
        "total_messages_blocked": len(messages_blocked),
        "total_messages_delivered_with_threats": len(messages_delivered),
        "total_clicks_blocked": len(clicks_blocked),
        "total_clicks_permitted": len(clicks_permitted),
        "threat_type_breakdown": dict(threat_types),
        "top_threat_families": dict(sorted(threat_families.items(),
                                           key=lambda x: x[1], reverse=True)[:10]),
        "top_targeted_users": dict(sorted(targeted_users.items(),
                                          key=lambda x: x[1], reverse=True)[:10]),
        "top_sender_domains": dict(sorted(sender_domains.items(),
                                          key=lambda x: x[1], reverse=True)[:10]),
    }
    return summary


def format_threat_report(summary: dict, hours: int) -> str:
    """Format threat summary as text report."""
    lines = []
    lines.append("=" * 60)
    lines.append("  PROOFPOINT TAP THREAT REPORT")
    lines.append("=" * 60)
    lines.append(f"  Period: Last {hours} hours")
    lines.append(f"  Generated: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}")
    lines.append("")

    lines.append("[OVERVIEW]")
    lines.append(f"  Messages Blocked:           {summary['total_messages_blocked']}")
    lines.append(f"  Delivered with Threats:      {summary['total_messages_delivered_with_threats']}")
    lines.append(f"  Clicks Blocked:              {summary['total_clicks_blocked']}")
    lines.append(f"  Clicks Permitted:            {summary['total_clicks_permitted']}")
    lines.append("")

    if summary["threat_type_breakdown"]:
        lines.append("[THREAT TYPES]")
        for t, count in sorted(summary["threat_type_breakdown"].items(),
                                key=lambda x: x[1], reverse=True):
            lines.append(f"  {t}: {count}")
        lines.append("")

    if summary["top_targeted_users"]:
        lines.append("[MOST TARGETED USERS]")
        for user, count in list(summary["top_targeted_users"].items())[:10]:
            lines.append(f"  {user}: {count} threats")
        lines.append("")

    if summary["top_sender_domains"]:
        lines.append("[TOP THREAT SENDER DOMAINS]")
        for domain, count in list(summary["top_sender_domains"].items())[:10]:
            lines.append(f"  {domain}: {count}")

    lines.append("=" * 60)
    return "\n".join(lines)


def main():
    parser = argparse.ArgumentParser(description="Proofpoint TAP Analysis")
    subparsers = parser.add_subparsers(dest="command")

    threats_parser = subparsers.add_parser("threats", help="Get recent threats")
    threats_parser.add_argument("--hours", type=int, default=24)

    vap_parser = subparsers.add_parser("vap", help="Get Very Attacked People")
    vap_parser.add_argument("--window", type=int, default=14, help="Days to look back")

    campaign_parser = subparsers.add_parser("campaign", help="Get campaign details")
    campaign_parser.add_argument("--id", required=True)

    report_parser = subparsers.add_parser("report", help="Generate threat report")
    report_parser.add_argument("--hours", type=int, default=168)
    report_parser.add_argument("--output", "-o")

    parser.add_argument("--json", action="store_true")
    parser.add_argument("--principal", default=PP_SERVICE_PRINCIPAL)
    parser.add_argument("--secret", default=PP_SECRET)

    args = parser.parse_args()

    if not HAS_REQUESTS:
        print("Error: requests library required", file=sys.stderr)
        sys.exit(1)

    principal = args.principal
    secret = args.secret

    if not principal or not secret:
        print("Error: Proofpoint TAP credentials required.", file=sys.stderr)
        print("Set PP_SERVICE_PRINCIPAL and PP_SECRET environment variables.", file=sys.stderr)
        sys.exit(1)

    client = ProofpointTAPClient(principal, secret)

    if args.command == "threats":
        seconds = args.hours * 3600
        data = client.get_all_threats(seconds)
        summary = analyze_threats(data)
        if args.json:
            print(json.dumps(summary, indent=2))
        else:
            print(format_threat_report(summary, args.hours))

    elif args.command == "vap":
        data = client.get_vap(args.window)
        users = data.get("users", [])
        print(f"Very Attacked People (last {args.window} days):")
        for user in users:
            identity = user.get("identity", {})
            print(f"  {identity.get('emails', [''])[0]} - "
                  f"Attacks: {user.get('threatStatistics', {}).get('attackIndex', 0)}")

    elif args.command == "campaign":
        data = client.get_campaign(args.id)
        if args.json:
            print(json.dumps(data, indent=2))
        else:
            print(f"Campaign: {data.get('name', 'Unknown')}")
            print(f"Description: {data.get('description', '')}")
            actors = data.get("actors", [])
            for actor in actors:
                print(f"  Actor: {actor.get('name', 'Unknown')}")

    elif args.command == "report":
        seconds = args.hours * 3600
        data = client.get_all_threats(seconds)
        summary = analyze_threats(data)
        report = format_threat_report(summary, args.hours)
        if args.output:
            with open(args.output, "w") as f:
                f.write(report)
            print(f"Report written to {args.output}")
        else:
            print(report)

    else:
        parser.print_help()


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 1.2 KB
Keep exploring