Skip to content
Threat Intelligence

Behavioral DNA: Fingerprinting Attackers Without IP Addresses

9 min read

IP addresses are the foundation of most threat intelligence. Block the bad IP. Report the bad IP. Share the bad IP. But attackers rotate IPs constantly. A botnet uses thousands. A VPN changes them on demand. A cloud provider reassigns them hourly. The IP address is the least stable identifier in security. It is time to fingerprint the behavior, not the address.

Inner Warden's Behavioral DNA system creates a unique hash of each attacker's behavior pattern. Two attackers coming from different IPs but exhibiting identical behavior produce the same DNA hash. They are the same campaign. Different IPs. Same attacker.

Why IP-based intelligence fails

Consider what happens when you block an attacker's IP address:

  • VPN rotation - the attacker switches to a different exit node. New IP, same attack. Your block is useless in 30 seconds.
  • Cloud elasticity - the attacker provisions a new VM on AWS, GCP, or Azure. The IP was clean yesterday. It is malicious today. It will be reassigned to a legitimate customer tomorrow.
  • Botnet distribution - a single campaign uses 10,000 compromised devices across 50 countries. Blocking one IP blocks 0.01% of the attack surface.
  • Residential proxies - attackers route through legitimate residential IPs. Blocking them blocks real users.

IP blocklists are reactive, slow, and increasingly inaccurate. You need something that survives IP rotation.

How behavioral DNA hashing works

Inner Warden computes a DNA hash for each attacker by combining four behavioral dimensions into a single SHA-256 fingerprint:

DNA hash computation
DNA = SHA-256(
  sorted(detectors_triggered),  // which detectors fired
  sorted(tools_used),           // what tools the attacker ran
  sorted(targets_attacked),     // which services/ports/paths
  hour_distribution             // 24-bucket activity histogram
)

Example:
  detectors: [ssh_bruteforce, credential_stuffing, port_scan]
  tools:     [hydra, nmap, medusa]
  targets:   [ssh:22, http:80, http:443]
  hours:     [0,0,0,1,3,5,8,12,8,5,3,1,0,0,0,0,0,0,0,0,1,2,3,2]

  DNA: a7f3c9e2d1b8...  (SHA-256 truncated to 16 bytes)

The detectors and tools are sorted before hashing so that order does not matter. An attacker who runs nmap then hydra produces the same DNA as one who runs hydra then nmap. The hour distribution captures the attacker's timezone and work schedule, which is surprisingly stable even across campaigns.

Campaign detection with union-find

Identical DNA hashes from different IPs are trivially linked. But what about attackers who share most but not all behavior? A botnet operator might use slightly different tool configurations on different nodes. Inner Warden uses a union-find algorithm with Jaccard similarity to cluster related attackers into campaigns.

Jaccard similarity on shared IOCs
Jaccard(A, B) = |IOCs_A ∩ IOCs_B| / |IOCs_A ∪ IOCs_B|

IOCs include:
  - DNA hash (exact match = Jaccard 1.0)
  - User agents used
  - Credential pairs attempted
  - Paths requested
  - Timing patterns

Threshold: Jaccard >= 0.6 → same campaign
  → Union-Find merges the two attacker nodes
  → All IPs in the merged set share campaign ID

Union-find is the right data structure here because campaigns grow incrementally. IP_1 is linked to IP_2. Later, IP_3 is linked to IP_2. All three are now in the same campaign. The union-find with path compression makes lookups O(1) amortized, which matters when you are tracking thousands of IPs.

Case study: 47 IPs, 8 countries, one botnet

In a real deployment, Inner Warden observed 47 unique IP addresses over 72 hours, originating from 8 different countries: Brazil, Vietnam, Indonesia, India, Russia, China, Nigeria, and Turkey. Traditional IP-based analysis would treat these as 47 separate attackers.

What IP analysis sees

47 attackers from 8 countries. No obvious connection. Each IP tried a handful of SSH passwords. Individually unremarkable. None triggered rate limits because the load was distributed.

What Behavioral DNA sees

One campaign. All 47 IPs share the same DNA hash: identical detector pattern (ssh_bruteforce + credential_stuffing), identical tool signature (libssh-based scanner), identical credential list (top 200 passwords in the same order), and identical hour distribution peaking at 02:00-06:00 UTC.

Outcome

Inner Warden linked all 47 IPs into Campaign #C-2891. When a new IP appeared with the same DNA, it was immediately flagged as part of the campaign and blocked before completing a single authentication attempt.

Pattern classification

Not all attackers behave the same way. Inner Warden classifies behavioral patterns into three categories based on timing and detector diversity:

regular_scannerPredictable intervals between probes. Low detector diversity (usually just ssh_bruteforce or port_scan). Automated scanning with fixed timing. Typical of botnets and Shodan-like services.
opportunisticRandom timing. Medium detector diversity. Tries multiple attack vectors but without a clear plan. Typical of script kiddies and spray-and-pray campaigns.
targetedMultiple detectors triggered across sessions. Many return visits over days or weeks. Adapts techniques between visits. Typical of APTs and determined attackers.

The classification influences how the agent responds. A regular_scanner might be auto-blocked and forgotten. A targeted attacker gets elevated to an ongoing investigation with full forensic data collection.

Risk scoring: 0 to 100

Each attacker profile receives a risk score from 0 to 100. The score is computed from multiple signals:

Risk score formula
risk_score = min(100,
  detector_diversity_weight      // 0-25: more detector types = higher risk
  + incident_severity_weight     // 0-30: Critical incidents add more than Low
  + session_count_weight         // 0-15: return visitors are more dangerous
  + campaign_size_weight         // 0-15: part of a large campaign = higher risk
  + pattern_weight               // 0-15: targeted > opportunistic > regular
)

Examples:
  Single SSH bruteforce, 1 session       → risk: 12
  Port scan + web scan, 3 sessions       → risk: 38
  Credential stuffing + reverse shell    → risk: 72
  Multi-detector, 8 visits, targeted     → risk: 91

Risk scores drive automated decisions. Below 30: log and monitor. Between 30 and 70: block IP and alert operator. Above 70: block IP, alert operator, initiate forensic data collection, and share with mesh network peers.

Monthly threat reports

Behavioral DNA data accumulates over time into publishable threat intelligence. Inner Warden generates monthly reports that aggregate campaign data across all monitored hosts (via the mesh network):

  • Campaign profiles - top campaigns by IP count, duration, and risk score. Each profile includes the DNA hash, detector pattern, tool signatures, and geographic distribution.
  • Trend analysis - month-over-month changes in attack patterns. Are SSH bruteforce campaigns growing or shrinking? Are new tool signatures appearing?
  • Attacker evolution - when a known campaign changes its DNA (new tools, new targets), Inner Warden tracks the evolution. You can see an attacker adapt their techniques over time.
  • Shared intelligence - DNA hashes and campaign IDs are shared across the mesh network. When one node identifies a campaign, all nodes benefit from the detection.

Enable Behavioral DNA

Behavioral DNA is enabled by default when you install Inner Warden. It starts building attacker profiles from the first detected incident:

Install
curl -fsSL https://innerwarden.com/install | sudo bash

DNA profiles are stored in the agent's state store and use approximately 6 MB of memory for 10,000 tracked attackers. There is no external database dependency. Campaign data is available in the dashboard under the Threats tab, where you can explore attacker profiles, view DNA hashes, and drill into campaign members.

What to do next