Phase 7: Behavioral Detection

Phase 7: Behavioral Detection (Abnormal Simulator)

Objective

Build a Python script that reads delivered mail via IMAP (post-delivery), parses headers, scores behavioral anomalies, auto-remediates suspicious messages, and forwards detection events to Wazuh. This simulates how Abnormal Security operates — API-based, post-delivery, behavioral.

Maps to Work

Lab CHLA (Abnormal)

Python reads IMAP (post-delivery)

Abnormal reads M365 Graph API (post-delivery)

Parse Authentication-Results headers

Abnormal ingests SPF/DKIM/DMARC verdicts from M365

Behavioral scoring (domain similarity, urgency, sender history)

Abnormal behavioral AI (BEC detection, account takeover, invoice fraud)

Move to quarantine folder via IMAP

Abnormal auto-remediation (move to junk, delete, banner)

Forward events to Wazuh API

Abnormal API → Sentinel integration

Why Post-Delivery?

This is the fundamental architectural difference between ESA and Abnormal:

  • ESA (inline): sits in the SMTP path. If ESA rejects, the message never arrives. If ESA is down, mail stops.

  • Abnormal (API): reads after M365 delivers. Mail always arrives. Abnormal remediates after the fact. If Abnormal is down, mail still flows — you just lose detection.

Building this in the lab lets you experience that tradeoff firsthand.

Script Architecture

mail-detector.py
├── connect_imap()        — Connect to dovecot via IMAPS
├── fetch_new_messages()  — Read unprocessed messages from INBOX
├── parse_headers()       — Extract Authentication-Results, From, Reply-To, Received chain
├── score_message()       — Behavioral scoring engine
│   ├── check_auth_results()   — SPF/DKIM/DMARC pass/fail
│   ├── check_domain_similarity() — Levenshtein distance on From domain
│   ├── check_urgency()        — Keyword scan (urgent, wire transfer, password, click here)
│   └── check_sender_history() — First-time sender detection
├── remediate()           — Move suspicious messages to Quarantine folder
└── report_to_wazuh()     — POST detection event to Wazuh API

Detection Signals

Signal What It Catches Score Weight

SPF fail

Unauthorized sender IP

+30

DKIM fail

Tampered message content

+30

DMARC fail

Domain alignment failure

+20

Domain similarity > 0.8

Lookalike domains (examp1e.com vs example.com)

+25

Urgency keywords

Social engineering pressure (BEC indicator)

+15

From != Reply-To domain

Reply-to hijacking

+20

First-time sender

No prior communication history

+10

Score >= 50: quarantine. Score >= 30: flag. Score < 30: pass.

Wazuh Integration

Forward detection events via Wazuh API:

import requests

def report_to_wazuh(event: dict) -> None:
    """Send detection event to Wazuh manager API."""
    wazuh_url = "https://{k3s-master-ip}:55000"
    payload = {
        "event": {
            "type": "mail-behavioral-detection",
            "score": event["score"],
            "signals": event["signals"],
            "from": event["from"],
            "subject": event["subject"],
            "action": event["action"],  # quarantine | flag | pass
        }
    }
    # POST to Wazuh active response or custom integration
    requests.post(f"{wazuh_url}/active-response", json=payload, verify=False)

Deployment

# On mail-01
sudo dnf install -y python3 python3-pip
pip3 install --user imapclient python-Levenshtein requests

# Create service
sudo tee /etc/systemd/system/mail-detector.service <<EOF
[Unit]
Description=Behavioral Mail Detection (Abnormal Simulator)
After=dovecot.service

[Service]
Type=simple
User=evan
ExecStart=/usr/bin/python3 /opt/mail-detector/mail-detector.py
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable --now mail-detector

Verification Checklist

  • Script connects to dovecot via IMAPS

  • Clean messages score < 30 and pass through

  • SPF-fail messages score >= 30 and get flagged

  • Spoofed/lookalike domain messages score >= 50 and get quarantined

  • Detection events appear in Wazuh

  • Quarantine IMAP folder contains remediated messages