Behavioral DNA: Fingerprinting Attackers Without IP Addresses
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 = 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(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 IDUnion-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.
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.
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.
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 = 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: 91Risk 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:
curl -fsSL https://innerwarden.com/install | sudo bashDNA 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
- Cross-layer correlation - how correlated attack chains feed into DNA profiling for richer attacker fingerprints.
- Threat intelligence sharing - how the mesh network distributes DNA hashes and campaign data across nodes.
- TLS fingerprinting - another fingerprinting technique that complements behavioral DNA with network-layer identification.
- SSH bruteforce detection - the most common detector that feeds into DNA profiling.