Claude
Skills
Sign in
Back

building-adversary-infrastructure-tracking-system

Included with Lifetime
$97 forever

Build an automated system to track adversary infrastructure using passive DNS, certificate transparency, WHOIS data, and IP enrichment to map and monitor threat actor command-and-control networks.

Securityinfrastructure-trackingpassive-dnsc2whoisthreat-actorpivotingthreat-intelligencedomain-analysisscripts

What this skill does

# Building Adversary Infrastructure Tracking System

## Overview

Adversary infrastructure tracking uses passive DNS records, certificate transparency logs, WHOIS registration data, and IP enrichment to discover, map, and monitor threat actor command-and-control (C2) networks. Attackers frequently reuse hosting providers, registrars, SSL certificates, and naming patterns across campaigns, enabling analysts to pivot from known indicators to discover new infrastructure. This skill covers building an automated tracking system that identifies infrastructure relationships, detects newly registered domains matching adversary patterns, and maintains a continuously updated map of threat actor networks.


## When to Use

- When deploying or configuring building adversary infrastructure tracking system capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation

## Prerequisites

- Python 3.9+ with `requests`, `dnspython`, `python-whois`, `shodan`, `networkx` libraries
- API keys: SecurityTrails, PassiveTotal/RiskIQ, Shodan, VirusTotal
- Access to passive DNS data sources
- Understanding of DNS infrastructure, hosting, and domain registration
- Graph database (Neo4j) or NetworkX for relationship visualization

## Key Concepts

### Passive DNS

Passive DNS captures historical DNS resolution data, recording which domains resolved to which IPs and when. Unlike active DNS queries, passive DNS preserves historical relationships even after records change, enabling analysts to track infrastructure changes, identify shared hosting patterns, and discover related domains that resolved to the same IP addresses over time.

### Infrastructure Pivoting

Pivoting identifies related infrastructure by following connections: IP pivot (find all domains on an IP), domain pivot (find all IPs a domain resolved to), WHOIS pivot (find domains with same registrant), certificate pivot (find hosts sharing SSL certificates), and NS/MX pivot (find domains using same name servers or mail servers).

### Adversary Infrastructure Patterns

Threat actors exhibit patterns: preferred registrars (Namecheap, REG.RU, Tucows), preferred hosting (bulletproof hosting providers, cloud services), domain generation algorithms (DGA), consistent naming patterns, and certificate reuse across campaigns.

## Workflow

### Step 1: Passive DNS Infrastructure Discovery

```python
import requests
import json
from collections import defaultdict
from datetime import datetime

class InfrastructureTracker:
    def __init__(self, securitytrails_key=None, vt_key=None, shodan_key=None):
        self.st_key = securitytrails_key
        self.vt_key = vt_key
        self.shodan_key = shodan_key
        self.infrastructure_graph = defaultdict(lambda: {"nodes": set(), "edges": []})

    def passive_dns_lookup(self, domain):
        """Query passive DNS for domain resolution history."""
        headers = {"apikey": self.st_key}
        url = f"https://api.securitytrails.com/v1/history/{domain}/dns/a"
        resp = requests.get(url, headers=headers, timeout=30)
        if resp.status_code == 200:
            records = resp.json().get("records", [])
            history = []
            for record in records:
                for value in record.get("values", []):
                    history.append({
                        "domain": domain,
                        "ip": value.get("ip", ""),
                        "first_seen": record.get("first_seen", ""),
                        "last_seen": record.get("last_seen", ""),
                        "type": record.get("type", "a"),
                    })
            print(f"[+] Passive DNS for {domain}: {len(history)} records")
            return history
        return []

    def reverse_ip_lookup(self, ip_address):
        """Find all domains hosted on an IP address."""
        headers = {"apikey": self.st_key}
        url = f"https://api.securitytrails.com/v1/ips/nearby/{ip_address}"
        resp = requests.get(url, headers=headers, timeout=30)
        if resp.status_code == 200:
            blocks = resp.json().get("blocks", [])
            domains = []
            for block in blocks:
                for site in block.get("sites", []):
                    domains.append(site)
            print(f"[+] Reverse IP for {ip_address}: {len(domains)} domains")
            return domains
        return []

    def whois_lookup(self, domain):
        """Get WHOIS registration data for pivoting."""
        headers = {"apikey": self.st_key}
        url = f"https://api.securitytrails.com/v1/domain/{domain}/whois"
        resp = requests.get(url, headers=headers, timeout=30)
        if resp.status_code == 200:
            data = resp.json()
            whois_data = {
                "domain": domain,
                "registrar": data.get("registrar", ""),
                "registrant_org": data.get("registrant_org", ""),
                "registrant_email": data.get("registrant_email", ""),
                "name_servers": data.get("nameServers", []),
                "created_date": data.get("createdDate", ""),
                "updated_date": data.get("updatedDate", ""),
                "expires_date": data.get("expiresDate", ""),
            }
            return whois_data
        return {}

    def pivot_from_seed(self, seed_indicator, indicator_type="domain", depth=2):
        """Recursively pivot from a seed indicator to discover infrastructure."""
        discovered = {"domains": set(), "ips": set(), "relationships": []}

        if indicator_type == "domain":
            discovered["domains"].add(seed_indicator)
            # Get IPs for domain
            pdns = self.passive_dns_lookup(seed_indicator)
            for record in pdns:
                ip = record["ip"]
                discovered["ips"].add(ip)
                discovered["relationships"].append({
                    "source": seed_indicator, "target": ip,
                    "type": "resolves_to",
                    "first_seen": record["first_seen"],
                    "last_seen": record["last_seen"],
                })

                if depth > 1:
                    # Reverse lookup on discovered IPs
                    reverse_domains = self.reverse_ip_lookup(ip)
                    for rd in reverse_domains[:20]:
                        discovered["domains"].add(rd)
                        discovered["relationships"].append({
                            "source": rd, "target": ip,
                            "type": "hosted_on",
                        })

        elif indicator_type == "ip":
            discovered["ips"].add(seed_indicator)
            domains = self.reverse_ip_lookup(seed_indicator)
            for domain in domains[:20]:
                discovered["domains"].add(domain)
                discovered["relationships"].append({
                    "source": domain, "target": seed_indicator,
                    "type": "hosted_on",
                })

        print(f"[+] Pivot from {seed_indicator}: "
              f"{len(discovered['domains'])} domains, "
              f"{len(discovered['ips'])} IPs, "
              f"{len(discovered['relationships'])} relationships")
        return discovered

tracker = InfrastructureTracker(
    securitytrails_key="YOUR_ST_KEY",
    vt_key="YOUR_VT_KEY",
)
```

### Step 2: Build Infrastructure Graph

```python
import networkx as nx

class InfrastructureGraph:
    def __init__(self):
        self.graph = nx.Graph()

    def add_discovery(self, discovery_data):
        """Add discovered infrastructure to graph."""
        for domain in discovery_data["domains"]:
            self.graph.add_node(domain, type="domain")
        for ip in discovery_data["ips"]:
            self.graph.add_node(ip, type="ip")
        for rel in discovery_data["relationships"]:
            self.graph.add_edg

Related in Security