All Playbooks
intermediate60 minThreat Intelligence Analyst / Brand Protection

Phishing Domain Detection with Typosquatting Analysis

What you will achieve

An automated daily scan that detects typosquatting domains targeting your brand, with live reputation checking and alerting when a suspicious domain becomes active.

PythonisMalicious APIdnstwistWazuh
Jean-Vincent QUILICHINIJean-Vincent QUILICHINIMar 8, 2026

What You Will Achieve

By the end of this playbook you will have:

  • A typosquatting generator producing 200+ variants of your brand domain
  • DNS resolution checks to identify which variants are actively registered
  • isMalicious reputation scoring for all active variants
  • Automated alerts when a new suspicious domain comes online
  • Wazuh integration for SIEM visibility

Prerequisites

| Requirement | Details | |---|---| | isMalicious API key | Free tier works; Pro for higher rate limits | | Python 3.9+ | Script runtime | | dnstwist | pip install dnstwist | | Your brand domains | List of domains to protect |


Step 1: Generate Typosquatting Variants

python
import dnstwist
import json

PROTECTED_DOMAINS = [
    "yourdomain.com",
    "your-product.com",
]

def generate_variants(domain):
    dt = dnstwist.DnsTwist(domain)
    dt.generate()
    dt.resolve()
    
    # Return only registered/live domains
    return [
        entry for entry in dt.domains
        if entry.get("dns_a") or entry.get("dns_mx")
    ]

all_variants = []
for domain in PROTECTED_DOMAINS:
    variants = generate_variants(domain)
    all_variants.extend(variants)
    print(f"{domain}: {len(variants)} live variants found")

print(f"\nTotal live suspicious domains: {len(all_variants)}")

Step 2: Check Reputation with isMalicious

python
import base64
import requests
import time

API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
HEADERS = {
    "X-API-KEY": base64.b64encode(f"{API_KEY}:{API_SECRET}".encode()).decode()
}

def check_reputation(domain):
    try:
        resp = requests.get(
            "https://api.ismalicious.com/check",
            params={"query": domain},
            headers=HEADERS,
            timeout=10
        )
        if resp.ok:
            data = resp.json()
            return {
                "domain": domain,
                "malicious": data.get("malicious", False),
                "score": data.get("riskScore", {}).get("score", 0),
                "categories": data.get("categories", []),
                "confidence": data.get("confidenceScore", 0),
                "sources": [s["name"] for s in data.get("sources", [])],
            }
    except Exception as e:
        return {"domain": domain, "error": str(e)}

# Rate-limited batch check
results = []
for variant in all_variants:
    domain = variant.get("domain", "")
    if domain:
        result = check_reputation(domain)
        results.append({**variant, **result})
        time.sleep(0.1)  # Respect rate limits

# Sort by risk score descending
results.sort(key=lambda x: x.get("score", 0), reverse=True)

Step 3: Classify and Triage

python
HIGH_RISK_THRESHOLD = 60
SUSPICIOUS_THRESHOLD = 30

categories = {"high_risk": [], "suspicious": [], "monitor": []}

for r in results:
    score = r.get("score", 0)
    fuzzer = r.get("fuzzer", "unknown")
    
    if score >= HIGH_RISK_THRESHOLD or r.get("malicious"):
        categories["high_risk"].append(r)
    elif score >= SUSPICIOUS_THRESHOLD:
        categories["suspicious"].append(r)
    else:
        categories["monitor"].append(r)

print(f"High Risk:  {len(categories['high_risk'])}")
print(f"Suspicious: {len(categories['suspicious'])}")
print(f"Monitor:    {len(categories['monitor'])}")

Step 4: Automated Alerting

Email alert for new high-risk domains

python
import smtplib
from email.mime.text import MIMEText
from datetime import datetime

def send_alert(high_risk_domains):
    if not high_risk_domains:
        return
    
    body = f"Phishing Domain Alert - {datetime.now().strftime('%Y-%m-%d')}\n\n"
    body += f"Found {len(high_risk_domains)} high-risk typosquatting domains:\n\n"
    
    for d in high_risk_domains:
        body += f"  {d['domain']} (score: {d.get('score', 0)}, "
        body += f"cats: {', '.join(d.get('categories', []))})\n"
    
    body += "\nCheck full report at: https://ismalicious.com/app\n"
    
    msg = MIMEText(body)
    msg["Subject"] = f"⚠️ {len(high_risk_domains)} Phishing Domains Detected"
    msg["From"] = "alerts@yourdomain.com"
    msg["To"] = "security-team@yourdomain.com"
    
    with smtplib.SMTP("smtp.yourdomain.com") as server:
        server.send_message(msg)

Step 5: Wazuh SIEM Integration

Add detected domains as custom Wazuh alerts.

Custom decoder (/var/ossec/etc/decoders/ismalicious.xml)

xml
<decoder name="ismalicious-phishing">
  <prematch>ISMALICIOUS_PHISHING:</prematch>
  <regex offset="after_prematch">(\S+) score=(\d+) categories=(\S+)</regex>
  <order>domain, score, categories</order>
</decoder>

Log the detections

python
import logging

logger = logging.getLogger("ismalicious")
handler = logging.FileHandler("/var/ossec/logs/ismalicious.log")
logger.addHandler(handler)

for d in categories["high_risk"]:
    logger.warning(
        f"ISMALICIOUS_PHISHING: {d['domain']} "
        f"score={d.get('score', 0)} "
        f"categories={'|'.join(d.get('categories', []))}"
    )

Wazuh rule (/var/ossec/etc/rules/ismalicious_rules.xml)

xml
<group name="ismalicious,phishing">
  <rule id="100500" level="10">
    <decoded_as>ismalicious-phishing</decoded_as>
    <description>New phishing/typosquatting domain detected: $(domain)</description>
    <mitre>
      <id>T1566.002</id>
    </mitre>
  </rule>
</group>

Step 6: Full Pipeline Script

Save as phishing_scan.py and run via cron daily:

bash
# Daily at 6 AM
0 6 * * * /usr/bin/python3 /opt/ismalicious/phishing_scan.py >> /var/log/phishing_scan.log 2>&#x26;1

Expected Output

bash
yourdomain.com: 23 live variants found
Total live suspicious domains: 23

High Risk:  3
Suspicious: 7
Monitor:    13

High Risk Domains:
  yourdomian.com    (score: 87, cats: phishing)
  your-d0main.com   (score: 72, cats: phishing, malware)
  yooudomain.com    (score: 61, cats: phishing)

Next Steps

  • Add the high-risk domains to your isMalicious Watchlist for continuous monitoring
  • File takedown requests with registrars for confirmed phishing domains
  • Submit URLs to Google Safe Browsing for faster blocklist propagation
  • Integrate with your brand's legal team for rapid UDRP filings

Did this playbook work for you?

Protect Your Infrastructure

Enrich your detections with real-time threat intelligence from 500M+ records.