Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions zak/agents/phising/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# DomainShield Agent 🛡️

> AI-powered phishing detection ZAK agent that enforces **strict domain whitelisting** on incoming email — flagging, categorizing, and blocking any message from outside the approved domain list.

---

## Project Structure

```
phising/
├── agents/
│ └── domain-shield-agent.yaml ← ZAK DSL contract
├── tools/
│ ├── __init__.py
│ ├── email_ingestion_tools.py ← IMAP / file / raw ingestion
│ ├── domain_verification_tools.py ← whitelist, SPF, DKIM, DMARC, IDN
│ ├── phishing_detection_tools.py ← display-name spoof + risk classifier
│ ├── alerting_tools.py ← alert generation + Slack/SIEM webhook
│ ├── logging_tools.py ← JSONL audit log + CSV export
│ └── policy_tools.py ← admin whitelist CRUD + config store
├── config/
│ ├── config.env.example ← environment variable template
│ └── policy.json ← live whitelist policy store
├── tests/
│ └── test_domain_shield.py ← pytest test suite (5 scenarios)
├── logs/ ← auto-created audit logs (JSONL + CSV)
├── domain_shield_agent.py ← BaseAgent class (9-phase pipeline)
├── run.py ← CLI entry point
├── requirements.txt
└── README.md
```

---

## Quick Start

### 1. Install dependencies
```powershell
pip install -r requirements.txt
```

### 2. Configure
```powershell
Copy-Item config\config.env.example config\config.env
# Edit config\config.env with your whitelist domains, IMAP credentials, etc.
```

### 3. Run – test with a raw email string
```powershell
python run.py --source raw --raw-eml "From: alice@company.com`r`nSubject: Hello`r`n`r`nBody"
```

### 4. Run – scan IMAP inbox
```powershell
python run.py --source imap
# (Credentials loaded from config/config.env)
```

### 5. JSON output mode
```powershell
python run.py --source raw --raw-eml "..." --json
```

---

## Sample Configuration

```env
WHITELIST_DOMAINS=company.com,trustedpartner.com
STRICT_MODE=true
ALERT_THRESHOLD=medium_and_above
WEBHOOK_URL=https://hooks.slack.com/services/your/webhook/url
WEBHOOK_FORMAT=slack
```

---

## Admin Commands

| Command | Description |
|---|---|
| `python run.py --admin add-domain --admin-arg partner.org` | Add domain to whitelist |
| `python run.py --admin remove-domain --admin-arg old.com` | Remove domain |
| `python run.py --admin list-policy` | Show current policy |
| `python run.py --admin export-log` | Export audit log to CSV |
| `python run.py --admin set-strict --admin-arg true` | Enable strict mode |
| `python run.py --admin set-threshold --admin-arg high_only` | Change alert threshold |

---

## Risk Classification

| Risk Level | Trigger | Action (strict mode) |
|---|---|---|
| `SAFE` | Whitelisted domain + all auth checks pass | `ALLOW` |
| `MEDIUM_RISK` | External domain not in whitelist | `BLOCK` |
| `HIGH_RISK` | Spoofing / auth failure / subdomain hijack | `BLOCK` |

---

## Detection Signals

1. **Domain Whitelist** – exact domain match (subdomains require explicit listing)
2. **SPF Alignment** – `Received-SPF` + `Authentication-Results` parsing
3. **DKIM Alignment** – signing domain vs. `From:` header
4. **DMARC** – policy outcome from `Authentication-Results`
5. **Display-Name Spoof** – fuzzy match against whitelisted org names + 20+ known brands
6. **Subdomain Spoof** – detects `evil.company.com` bypassing `company.com`
7. **IDN Normalization** – punycode decode prevents Unicode look-alike bypass

---

## Running Tests

```powershell
python -m pytest tests/ -v
python -m pytest tests/ -v --tb=short --cov=tools --cov=domain_shield_agent
```

### Test Scenarios

| Test | Email | Expected |
|---|---|---|
| `TestValidInternalEmail` | `alice@company.com` + all auth pass | `SAFE` / no alert |
| `TestSpoofedDomainEmail` | Display name "Company IT" + `evil-company.net` + auth fail | `HIGH_RISK` / `BLOCK` |
| `TestExternalUnknownDomain` | `newsletter@external-vendor.io` (good auth) | `MEDIUM_RISK` / alert |
| `TestSubdomainSpoof` | `phish@mail.evil.company.com` | `HIGH_RISK` |
| `TestWhitelistedDomainAuthFailure` | `ceo@company.com` + SPF/DKIM/DMARC all fail | `HIGH_RISK` |

---

## Integration Points

| System | How |
|---|---|
| **IMAP / Exchange** | `source=imap` via `imaplib` (SSL) |
| **Slack** | `WEBHOOK_FORMAT=slack` → Block Kit payload |
| **SIEM / generic** | `WEBHOOK_FORMAT=generic` → raw JSON POST |
| **ZAK Platform** | `agents/domain-shield-agent.yaml` + `register_agent` decorator |

---

## Security Notes

- **No whitelist inheritance** – `mail.company.com` is NOT trusted unless explicitly added
- **IDN/Punycode** – domains normalized before comparison to prevent homograph attacks
- **Auth failure on whitelisted domain** → escalated to `HIGH_RISK` (possible internal spoofing)
- **Audit logs** – append-only JSONL; never delete email content
- **Strict mode** – set `STRICT_MODE=false` only to downgrade blocking to warnings

---

## Exit Codes

| Code | Meaning |
|---|---|
| `0` | All emails safe |
| `2` | One or more suspicious emails detected |
| `1` | Fatal error (misconfiguration, ingestion failure) |
108 changes: 108 additions & 0 deletions zak/agents/phising/agents/domain-shield-agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: domain-shield-agent
version: "1.0.0"
description: >
AI-powered phishing detection agent that enforces strict domain whitelisting
on incoming emails. Flags, categorizes, and alerts on any email sourced from
domains outside the approved whitelist using SPF/DKIM/DMARC header analysis.

domain: email_security

metadata:
author: ZAK Platform
tags: [phishing, email-security, domain-whitelist, zero-trust, siem]
compliance: [SOC2, ISO27001, CIS-Controls]

# ─── Capabilities ───────────────────────────────────────────────────────────
capabilities:
tools:
- action_id: ingest_email
- action_id: parse_email_headers
- action_id: verify_domain_whitelist
- action_id: check_spf_alignment
- action_id: check_dkim_alignment
- action_id: check_dmarc_alignment
- action_id: detect_display_name_spoof
- action_id: detect_subdomain_spoof
- action_id: normalize_domain
- action_id: classify_phishing_risk
- action_id: generate_alert
- action_id: log_email_event
- action_id: export_audit_log
- action_id: manage_whitelist
- action_id: forward_webhook_alert

# ─── Policy ─────────────────────────────────────────────────────────────────
policy:
strict_mode: true # block (not just warn) on suspicious emails
approval_gate: none # fully autonomous; no human-in-the-loop prompts
require_elevation: false
max_batch_size: 500 # emails processed per agent run
alert_on_error: true

# ─── Boundaries ─────────────────────────────────────────────────────────────
boundaries:
allowed_actions:
- ingest_email
- parse_email_headers
- verify_domain_whitelist
- check_spf_alignment
- check_dkim_alignment
- check_dmarc_alignment
- detect_display_name_spoof
- detect_subdomain_spoof
- normalize_domain
- classify_phishing_risk
- generate_alert
- log_email_event
- export_audit_log
- manage_whitelist
- forward_webhook_alert
disallowed_actions:
- delete_email_permanently # audit trail must be preserved
- modify_email_content # no tampering with email body

# ─── Inputs ─────────────────────────────────────────────────────────────────
inputs:
whitelist_domains:
type: list[string]
required: true
example: ["company.com", "trustedpartner.com"]
strict_mode:
type: boolean
default: true
alert_threshold:
type: string
enum: [high_only, medium_and_above, all]
default: medium_and_above
webhook_url:
type: string
required: false
imap_host:
type: string
required: false
imap_port:
type: integer
default: 993
imap_user:
type: string
required: false
imap_password:
type: string
required: false

# ─── Outputs ────────────────────────────────────────────────────────────────
outputs:
processed_count:
type: integer
safe_count:
type: integer
suspicious_count:
type: integer
high_risk_count:
type: integer
medium_risk_count:
type: integer
alerts:
type: list[object]
audit_log_path:
type: string
10 changes: 10 additions & 0 deletions zak/agents/phising/config/config.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Auto-generated by Easy Start
WHITELIST_DOMAINS=deltajohnsons.com,minitts.net
STRICT_MODE=false
ALERT_THRESHOLD=all
IMAP_HOST=imap.tempm.com
IMAP_PORT=993
IMAP_USER=ksag@vuatrochoi.nl
IMAP_PASSWORD=New1234567890
IMAP_FOLDER=INBOX
MAX_EMAILS=20
27 changes: 27 additions & 0 deletions zak/agents/phising/config/config.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# DomainShield Agent – Configuration
# Copy this file to config/config.env and fill in your values.

# ── Whitelist ─────────────────────────────────────────────────────────────────
# Comma-separated list of approved sender domains
WHITELIST_DOMAINS=tcu2o7hyzp@xkxkud.com, fodyhywy@denipl.com

# ── Policy ────────────────────────────────────────────────────────────────────
# strict_mode=true → BLOCK suspicious emails; false → WARN only
STRICT_MODE=true

# Alert threshold: high_only | medium_and_above | all
ALERT_THRESHOLD=medium_and_above

# ── Webhook / SIEM Integration ────────────────────────────────────────────────
# Leave blank to disable webhook forwarding
WEBHOOK_URL=
# generic → raw JSON POST; slack → Slack Block Kit format
WEBHOOK_FORMAT=generic

# ── IMAP (optional – only needed for source=imap) ─────────────────────────────
IMAP_HOST=imap.ethereal.email
IMAP_PORT=993
IMAP_USER=hattie.macejkovic55@ethereal.email
IMAP_PASSWORD=SuQPrURwdQXU3uCWNv
IMAP_FOLDER=INBOX
MAX_EMAILS=50
8 changes: 8 additions & 0 deletions zak/agents/phising/config/policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"whitelist_domains": ["company.com", "trustedpartner.com"],
"strict_mode": true,
"alert_threshold": "medium_and_above",
"webhook_url": "",
"last_modified": "",
"modified_by": "system"
}
Loading
Loading