---
title: "XSOAR Domain Enrichment Playbook: WHOIS, DNS & Subdomains"
slug: "/resources/blog/xsoar-playbook-enrich-suspicious-domains-with-whois-dns-subdomains-before-blocking"
description: "Build an XSOAR enrichment playbook that queries WhoisFreaks for WHOIS, DNS, and subdomain data before any block decision. Full workflow with curl examples."
---

# XSOAR Playbook: Enrich Suspicious Domains with WHOIS + DNS + Subdomains Before Blocking

Written By [Nadeem Khan](https://www.linkedin.com/in/nadeem-khan-75a069197), WhoisFreaks Team Published: May 19, 2026, Last Updated: May 19, 2026

**TL;DR:** When XSOAR receives a suspicious domain indicator, three API calls to WhoisFreaks (one for WHOIS registration data, one for live DNS records, one for the active subdomain list) give you enough context to score the domain before any block action fires. This playbook walks through configuring each task, the curl equivalent for each call, a scoring model with defined thresholds, and the condition logic that routes to auto-block or analyst review.

## Why Blocking Without Enrichment Creates Risk

When a SIEM alert or threat intelligence platform surfaces a suspicious domain, the instinct is to block it immediately. That instinct is right about the direction but often wrong about the scope and the confidence level.

Three specific problems appear when blocking fires without prior enrichment.

The first is false positives tied to shared infrastructure. A domain that looks malicious may resolve to a shared IP that also hosts legitimate services. Blocking at the domain level without reviewing the A records and nameserver identity can take down co-hosted properties or trigger unnecessary firewall noise that buries the real threat.

The second is incomplete blocking because the subdomain surface is unknown. Blocking `malicious.com` without knowing that `c2.malicious.com`, `payload.malicious.com`, and `panel.malicious.com` are all active leaves the operational infrastructure running. The original alert gets closed. The campaign does not.

The third is the absence of a documented decision trail. When a business unit challenges a block, or when a post-incident review asks why a domain was blocked two minutes after the alert arrived, the analyst needs to show what was known at the time. Registration age, registrar identity, nameserver configuration, and subdomain count are the core of that justification. Without them, the block is a judgment call with no paper behind it.

## What Each Enrichment Layer Provides

### WHOIS: Registration identity and domain age

WHOIS records contain the metadata that describes a domain's legal and operational existence: who registered it, through which registrar, when it was created, when it expires, and what nameservers are authorized to answer for it. For threat triage, the fields with the most practical weight are `create_date`, `domain_registrar.registrar_name`, `registrant_contact`, `domain_status`, and `name_servers`.

Domain age is the single clearest signal. A domain registered eight days ago appearing in a phishing alert has no plausible legitimate explanation. A domain registered three years ago at a known enterprise registrar requires a different level of scrutiny. Historical WHOIS adds a second layer: ownership transfers, registrar changes, and repeated re-registrations are patterns that passive DNS alone won't show.

### DNS records: Infrastructure fingerprint

DNS records reveal where the domain resolves and how its mail and naming infrastructure is configured. The A record gives you the resolved IP. The NS records identify the nameserver operator, which frequently carries more threat signal than the domain itself. The MX record tells you whether the domain is set up for email delivery, which matters for phishing infrastructure classification. The TXT and SPF records indicate whether the domain has any anti-spoofing posture configured, an absence that is consistent with purpose-built phishing domains. A CNAME pointing to a decommissioned external service indicates subdomain takeover exposure.

### Subdomains: Active attack surface map

The subdomain list is the part most playbooks skip entirely. A domain flagged in a single alert may have dozens of active subdomains each serving a distinct function in the attack chain: `login.`, `api.`, `cdn.`, `c2.`, `panel.`, `bot.`. The `first_seen` and `last_seen` timestamps tell you when subdomains appeared and whether they are currently active. When 15 subdomains were all first seen on the same date, the infrastructure was provisioned in a single automated event, not built up organically over time. That is a campaign signal, not a coincidence.

## Configuring the WhoisFreaks HTTP Request Integration in XSOAR

### Setting up the integration instance

XSOAR ships with a built-in HTTP integration that sends arbitrary GET and POST requests to external APIs. No custom content pack is required to call WhoisFreaks. Navigate to Settings > Integrations > HTTP Feed > Add Instance. Name the instance `WhoisFreaks`. All three API calls in this playbook share the same base domain: `https://api.whoisfreaks.com`.

If your instance runs behind a proxy, configure it under the integration instance settings before testing any task.

### Authentication and base URL configuration

The [WhoisFreaks WHOIS API](https://whoisfreaks.com/products/whois-api) authenticates via an `apiKey` query parameter appended to every request. There is no OAuth flow or token exchange. Store the API key as an XSOAR credential under Settings > Credentials, set the type to "Password," and name it `WhoisFreaksAPIKey`. Reference it in each HTTP task URL as `${inputs.WhoisFreaksAPIKey}` rather than hardcoding the value. Set the suspicious domain as a playbook input named `SuspiciousDomain` so all three tasks pull from the same variable.

The WhoisFreaks live WHOIS API returns responses within 1 to 2 seconds under standard load. Running all three tasks in parallel (covered in the FAQ below) brings total enrichment time to roughly that same window.

## Playbook Step 1: Query Live WHOIS Data

### Task configuration

Add an Automatic task to the playbook canvas. Select the HTTP integration instance you created above. Set the request method to GET. Set the full URL to:

```
https://api.whoisfreaks.com/v2.0/whois/live?apiKey=${inputs.WhoisFreaksAPIKey}&domainName=${inputs.SuspiciousDomain}&format=json
```

Set the response context path to `WhoisFreaks.WHOIS`. XSOAR parses the JSON response and stores the complete object there. Downstream tasks reference individual fields as `${WhoisFreaks.WHOIS.create_date}`, `${WhoisFreaks.WHOIS.domain_registrar.registrar_name}`, and so on.

### The curl equivalent

To inspect the response structure before building the playbook task, run:

```
curl "https://api.whoisfreaks.com/v2.0/whois/live?apiKey=YOUR_KEY&domainName=suspicious.com&format=json"
```

The response of this includes `create_date`, `update_date`, `expiry_date`, `domain_registered`, `domain_registrar`, `registrant_contact`, `domain_status`, and `name_servers`.

Not every WHOIS field carries triage weight. The ones that feed the risk scoring model are:

| Field | Threat signal |
| --- | --- |
| `create_date` | Domain age in days. Under 30 days is high risk. |
| `domain_registrar.registrar_name` | Registrar reputation. Cross-reference against known high-abuse registrars. |
| `registrant_contact.email_address` | When not redacted, a pivot point for related domain discovery via reverse WHOIS. |
| `domain_status` | `clientHold` or `pendingDelete` indicate a domain under registry action. |
| `name_servers` | Nameserver identity. Bulletproof hosting name servers are a strong malicious indicator. |
| `expiry_date` | A registration expiring in 30 to 90 days is consistent with throwaway infrastructure. |

## Playbook Step 2: Query DNS Records

### Task configuration and record types

Add a second automatic task. Use the same HTTP integration instance. Set the URL to:

```
https://api.whoisfreaks.com/v2.0/dns/live?apiKey=${inputs.WhoisFreaksAPIKey}&domainName=${inputs.SuspiciousDomain}&type=all&format=json
```

Set the response context path to `WhoisFreaks.DNS`. The `type=all` parameter retrieves all eight record types in a single request: A, AAAA, MX, NS, SPF, SOA, TXT, and CNAME. The `dnsRecords` array in the response contains one object per record with `dnsType`, `address` (for A records), `target` (for NS and CNAME records), `strings` (for TXT and SPF records) and `ttl`.

### The curl equivalent

```
curl "https://api.whoisfreaks.com/v2.0/dns/live?apiKey=YOUR_KEY&domainName=suspicious.com&type=all&format=json"
```

You can also query individual record types by replacing `type=all` with a specific type, for example `type=ns` to retrieve nameserver records only.

### Indicators of fast-flux and bulletproof hosting

Three patterns in the DNS response warrant an automatic escalation to high risk regardless of domain age.

Fast-flux indicators appear as multiple A records each with a TTL below 300 seconds. Fast-flux botnets cycle IP addresses rapidly to keep infrastructure accessible after individual IPs get blocked. If the `dnsRecords` array returns more than five A records all with TTL under 300, treat the domain as fast-flux until proven otherwise.

Bulletproof nameserver matches require a comparison list. NS records pointing to nameserver operators known for hosting criminal infrastructure should trigger an immediate score spike. Store a Custom Indicator Type in XSOAR for "Bulletproof Nameserver" and populate it with known malicious NS domains. The condition task compares each NS record's `target` field against this indicator type.

Missing SPF with an active MX record is the phishing infrastructure pattern. Check whether the `dnsRecords` array contains any entry with `dnsType: SPF`. If SPF is absent and an MX record is present, the domain is configured to send email with no anti-spoofing posture. Add this as a scoring signal, not a standalone block trigger, since legitimate new domains sometimes ship without SPF configured.

## Playbook Step 3: Query Subdomains

### Task configuration

Add a third automatic task. Set the URL to:

```
https://api.whoisfreaks.com/v2.0/subdomains?apiKey=${inputs.WhoisFreaksAPIKey}&domainName=${inputs.SuspiciousDomain}&status=active&format=json
```

Set the response context path to `WhoisFreaks.Subdomains`. The [Subdomain Lookup API](https://whoisfreaks.com/products/subdomains-api) draws from a database of over 5.2 billion hostnames built from DNS crawls, certificate transparency logs, and passive DNS collection. The `status=active` parameter filters to currently resolving subdomains. Remove the filter to include inactive records if your workflow needs full historical coverage of the domain's past subdomain footprint.

### The curl equivalent

```
curl "https://api.whoisfreaks.com/v2.0/subdomains?apiKey=YOUR_KEY&domainName=suspicious.com&status=active&format=json"
```

The response object includes `total_records` at the top level and a `subdomains` array. Each entry in the array carries the subdomain hostname, `first_seen`, `last_seen`, and an `inactive_from` timestamp when applicable.

### Interpreting first_seen, last_seen, and naming patterns

A high subdomain count on a recently registered domain is one of the clearest operational signals in the enrichment dataset. Legitimate domains registered 10 days ago rarely have 35 active subdomains. When `total_records` exceeds 20 and `${WhoisFreaks.WHOIS.create_date}` places the domain under 30 days old, the combination points to automated infrastructure provisioning. Treat it as high risk regardless of what other signals say.

`first_seen` clustering exposes campaign timing. Fifteen subdomains that all appear in the `first_seen` field with the same date were created in a single provisioning event, not through organic growth. This pattern recurs consistently across phishing kits and C2 infrastructure deployments.

Subdomain naming carries functional intent. Names like `c2`, `panel`, `bot`, `cdn`, `payload`, `api`, and `login` appear in threat actor infrastructure at a frequency that makes them worth checking explicitly. Use a Set Variable task before the condition block to iterate the subdomain list and flag any name-match against this keyword set. Store the result as a boolean context key `SubdomainThreatPattern`.

## Building the Risk Scoring Logic

After all three enrichment tasks complete, a Set Variable task aggregates the signals into a single risk score. The table below maps each signal to a score increment and the condition logic routes on the total.

| Signal | Condition | Score addition |
| --- | --- | --- |
| Domain age | Under 30 days | +40 |
| Domain age | 30 to 180 days | +20 |
| Domain age | Over 180 days | 0   |
| Subdomain count vs. domain age | Over 20 subdomains, domain under 30 days old | +30 |
| A record TTL | More than 5 A records each with TTL under 300s | +20 |
| SPF record | Absent with MX present | +15 |
| WHOIS privacy | Registrant contact redacted | +10 |
| NS record | Matches bulletproof indicator list | +25 |

### Domain age as the primary signal

Domain age carries the highest weight because it is reliable, cheap to retrieve, and hard to fake without a credible domain history. A domain created 8 days ago has no history, no reputation, and no business reason to appear in an alert queue. In the Set Variable task, compute the age by running XSOAR's built-in `TimeStampToDate` transformer against `${WhoisFreaks.WHOIS.create_date}` and comparing it against the incident creation timestamp.

### Nameserver and registrar reputation

The NS check requires a maintained comparison list. Store a Custom Indicator Type in XSOAR named "Bulletproof Nameserver" and populate it through your threat intelligence process. The condition task compares each value from `${WhoisFreaks.DNS.dnsRecords}` where `dnsType` equals `NS` against this indicator type. A match adds 25 to the score and should also set a dedicated context key for visibility in the War Room output.

### Subdomain count and naming flags

Use a ForEach loop task over `${WhoisFreaks.Subdomains.subdomains}`. Inside the loop, check each subdomain hostname against the threat keyword list (`c2, panel, bot, payload, cdn, login, api`). If any match is found, set `SubdomainThreatPattern = true` in context. The scoring task treats this flag as a binary modifier rather than a numeric increment, since a single matching subdomain name is already a significant indicator regardless of overall count.

### Condition task branching

The condition task after the scoring block has three branches:

Score 65 or above routes to the automatic blocking task. No analyst input is required at this threshold. The domain score is too clear to hold for review.

Score 35 to 64 routes to a manual task. The analyst sees the enrichment summary, the score breakdown, and two action options: "Confirm Block" or "Close Without Action". Their choice is logged with username and timestamp.

Score under 35 routes to a Work Note task that records the enrichment data and closes the playbook without action. The note remains on the incident if additional correlated alerts arrive later.

## The Blocking Task and Analyst Handoff

### Passing enriched context to the block integration

The blocking task in this playbook is intentionally integration-agnostic. It calls a sub-playbook named "Block Domain - Generic," which checks which blocking integrations are active in your XSOAR instance (firewall, DNS sinkhole, proxy, or web filter) and routes accordingly. This keeps the enrichment playbook decoupled from your specific blocking stack.

Pass the following context keys to the sub-playbook: `SuspiciousDomain`, `WhoisFreaks.WHOIS`, `WhoisFreaks.DNS`, `WhoisFreaks.Subdomains`, and `RiskScore`. Including the full enrichment context in the sub-playbook call means the analyst can see the complete decision basis from inside the incident view without navigating to the parent playbook.

### Mandatory annotation before execution

Insert a Work Note task immediately before the blocking sub-playbook call. Set it to Automatic. The note should record the domain name, the computed risk score, the three highest-weight scoring signals, the `WhoisFreaks.WHOIS.create_date` value, the nameserver check result, and the subdomain count. This note is part of the incident audit trail. For environments with a change management integration (ServiceNow, Jira Service Management), pass the same content to a ticket creation task at this point. The ticket documents the block decision before the block executes.

## War Room Output

When the playbook completes, the analyst sees a structured incident record in the XSOAR War Room.

The WHOIS task posts a table with registration date, registrar name, domain status codes, and nameserver list. The DNS task posts the full record set grouped by type with TTL values visible. The subdomain task posts the active subdomain list with `first_seen` and `last_seen` dates alongside the total record count. The scoring task posts a breakdown showing which signals contributed and what value each added.

For analyst-review cases (score 35 to 64), the manual task presents all three enrichment tables with a single binary action. The analyst's decision and username are logged on the incident.

For auto-block cases, the Work Note appears in the War Room before the blocking sub-playbook output, giving any analyst who reviews the incident a complete picture of what was blocked and why.
