Follow the Operator ยท 03 โ The Tool Fingerprint: How the Software Betrays the Hand
Follow the Operator โ Case 03. This register takes a cloud of unrelated-looking attacks and follows one forensic thread back to the single hand behind them, closing each case on the signal that clinched it: SHARED KEY ยท SHARED MALWARE ยท SHARED FINGERPRINT ยท SHARED INFRASTRUCTURE ยท SHARED BEHAVIOR ยท NAMED IDENTITY.
The first two cases attributed operators by the keys they carried โ one offered at the login, one planted on the victim. Both were credentials, things the operator chose and reused. This case attributes by something the operator does not choose at all, and mostly does not know he is emitting: the fingerprint of his software. When an SSH client connects, before it authenticates, before it does anything, it announces to the server the exact set of cryptographic algorithms it is willing to use โ its ciphers, its key-exchange methods, its message-authentication codes, in a specific order. That set is determined entirely by the client's software: which SSH library it was built on, which version, which build. Two connections from the same tool announce the same set; two connections from different tools announce different sets. Hash that ordered announcement and you have a HASSH โ a fingerprint not of the machine, not of the operator, but of the tool in his hand.
And the tool, it turns out, is one of the hardest things for an operator to vary. He can change his address in a second and his country in a minute, because those are external to his operation. But his tool is his operation โ the SSH client or the custom automation harness he built his whole fleet around, the thing that actually makes the connections and runs the commands. To vary the tool per host, he would have to build a different client for every machine, which is absurd; so he does not, and every connection his operation makes carries the same HASSH, because they all come from the same tool. The fingerprint is an invariant not because the operator forgot to change it but because changing it would mean rebuilding the operation, and no one rebuilds the operation to disguise a handshake. The tool is the invariant beneath the addresses, and the HASSH is how the honeypot reads it.
The honeypot holds a clean example, and its cleanness is in a number that should not be there. There is a cluster of 92 IPs that all fingerprint as the same client โ AsyncSSH 2.1.0, a specific build of a Python SSH library used for scripting connections at scale โ and those 92 IPs are concentrated in a single country. That single-country concentration is the tell. A common tool, run by the whole world, would fingerprint from everywhere; 92 IPs of one uncommon automation-library build, clustered in one country, do not look like the world running a common tool. They look like one operator running one custom harness from one base, varying his addresses within a region but not varying โ because he cannot cheaply vary โ the tool that defines the operation. Linkage signal: SHARED FINGERPRINT. But the register raises its guard here, and lowers its confidence, because the tool is the most shareable invariant it has yet used, and the whole difficulty of this case is telling a shared tool from a shared hand.
1. What the Handshake Announces
Begin with the mechanism, because HASSH is precise and its precision is the source of both its power and its limits. Every SSH session opens with a negotiation: the client and server each send a KEXINIT message listing the algorithms they support โ the key-exchange methods, the host-key types, the encryption ciphers, the MAC algorithms, the compression options โ each as an ordered, comma-separated list, in preference order. This is how the two ends agree on a mutually-supported set of cryptography before any secure channel exists. The lists are not secret and not authenticated; they are the opening declaration of the protocol, sent in the clear, at the very first exchange. HASSH โ a fingerprinting technique published openly by Salesforce โ takes the client's side of that declaration, the exact ordered algorithm lists, and hashes them into a single short fingerprint. Two clients that declare the same algorithms in the same order produce the same HASSH; two that differ in any element produce different HASSHes.
What determines a client's declaration is its software, and this is the crucial point: the algorithm list and its order are baked into the SSH library the client was built on and the way that build configures it. OpenSSH 7.4 declares one set; libssh 0.12.0 declares another; the Go SSH library declares another; AsyncSSH 2.1.0, a Python asyncio SSH implementation, declares its own. The HASSH is therefore a fingerprint of the client's toolchain โ the library, the version, the build, the configuration โ and not of anything the operator typed or chose per connection. He did not select those algorithms; his tool did, when it was built. So the HASSH identifies the tool, faithfully and automatically, on every connection the tool makes.
And, exactly as with the offered key of Case 01, the honeypot gets this for free, because the declaration comes first. The KEXINIT is sent at the start of the connection, before authentication, before any credential, before the operator has done anything at all โ so the honeypot fingerprints the client's tool on every connection that reaches the protocol negotiation, whether or not it ever tries to log in, whether or not the login would succeed. The tool announces itself as the price of speaking SSH at all. The honeypot's HASSH landscape โ its clusters of libssh 0.9.6 and 0.11.x and 0.12.0, of OpenSSH 7.4, of libssh2, of Go_SSH, of AsyncSSH, of Paramiko โ is exactly this: its traffic sorted by the tool that produced each connection, read off the opening handshake of every session it ever saw. The tool cannot hide, because speaking the protocol requires declaring the tool.
2. Why the Number in One Country Matters
Now the specific cluster, because the AsyncSSH cluster's evidential value is not in the shared fingerprint alone but in a combination, and understanding the combination is understanding what fingerprint attribution can and cannot do. Consider first what a shared HASSH does not prove. If the cluster were "500,000 IPs worldwide, all fingerprinting as stock OpenSSH," the shared fingerprint would prove nothing about a shared operator, because stock OpenSSH is the client on essentially every Unix machine on earth; those half-million IPs share a fingerprint the way half the planet shares a browser, which is to say they share nothing that ties them to one hand. A ubiquitous tool is a fingerprint with no attribution value, because the population that carries it is the whole world.
Now consider what makes the AsyncSSH cluster different, in two dimensions at once. First, the tool is specific and uncommon in this context: AsyncSSH 2.1.0 is not the default client anyone gets by accident; it is a Python library one chooses in order to script SSH connections programmatically, the kind of thing an operator builds an automation harness on, not the kind of thing a human types into a terminal. A fleet fingerprinting as one AsyncSSH build is a fleet driven by one automation tool, which is already a narrower population than "everyone with SSH." Second, and decisively, the 92 IPs are concentrated in a single country. That concentration is what a shared operator predicts and a shared tool does not: AsyncSSH is a public library available everywhere, so if these 92 were merely unrelated people who happened to use it, they would be scattered across the world like AsyncSSH's actual userbase. Instead they cluster in one country โ which is what you see when it is not many unrelated users of a public tool but one operator running one harness from one base, varying his launch addresses within a region while the tool, and its fingerprint, stays fixed.
So the attribution rests on the joint improbability: a specific, automation-grade build (narrowing the population from everyone to scripters) plus single-country concentration (narrowing it from AsyncSSH's global userbase to one locale) is far better explained by one operator's harness than by a coincidental convergence of unrelated users. That is a real inference, and a useful one, but the register states its confidence as MEDIUM-HIGH rather than HIGH, and the reason is honest: the fingerprint, unlike a bespoke key, is genuinely shareable. It remains possible that the 92 are several operators in one country who independently favor the same automation library โ a regional tooling fashion rather than one hand. The concentration makes that less likely than one operator, but not impossible, and the register will not launder "less likely" into "proven." The fingerprint is a strong lead that needs corroboration to become a verdict, which is exactly how the register uses it.
3. The Tool as the Most Shareable Invariant
Now the general principle, because this case is where the register's central tension comes into focus: the more useful an invariant is for building large clusters, the more shareable it tends to be, and the more shareable it is, the more it can lie. A bespoke key (Cases 01 and 02) is nearly unshareable by accident โ two operators do not generate the same key โ so it attributes strongly but only ties together what one operator actually reused. A tool fingerprint is the opposite: it is shared by everyone who uses the tool, so it can tie together huge populations, but most of what it ties together is not one operator, just one tool's userbase. The invariant that scales best is the invariant that discriminates worst, and the analyst who wants both is always negotiating between them.
This is why fingerprint attribution must be handled with a discipline the key cases did not require: it is trustworthy only in proportion to the rarity of the fingerprint and the corroboration around it. A common fingerprint (stock OpenSSH) attributes nothing and should be used only as a weak filter. A rare fingerprint (a custom build, an unusual library, a specific old version) attributes something, in proportion to how rare it is โ because the rarer the tool, the smaller its userbase, the more a shared fingerprint narrows the field toward one hand. But even a rare fingerprint is a population, not an individual, until something else โ a shared key, a shared behavior, a shared piece of infrastructure, geographic concentration โ narrows the population to one. The AsyncSSH cluster is trustworthy at MEDIUM-HIGH because the tool is uncommon and the concentration is tight; it would be untrustworthy at any confidence if the tool were stock and the spread global.
And so the honeypot does not use HASSH alone. It cross-references the fingerprint with the other signals โ does a fleet that shares a HASSH also share a key, a behavior, a timing? โ because convergence is what turns a shared tool into a shared hand. A cluster that shares only a common fingerprint is a tool's userbase; a cluster that shares an uncommon fingerprint and a bespoke key and a coordinated timing is one operator, and the fingerprint, in that convergence, adds real weight โ it says not just "one key" but "one key, driven by one tool, from one place," each signal narrowing what the others leave open. This is the register's method sharpening under pressure: with the strong, unshareable invariants of the key cases, a single signal plus light corroboration sufficed; with the weak, shareable invariant of the fingerprint, corroboration is not a nicety but the whole basis of the attribution. The fingerprint is where the register learns to distrust its most productive tool, and to lean on convergence precisely because the single signal is not enough.
4. SHARED FINGERPRINT โ The Tool Beneath the Disguise
The linkage signal is SHARED FINGERPRINT, and it earns its place in the six-word register as the signal that reads the operator's tooling rather than his credentials โ the third distinct thing an operator cannot help repeating, after the key he offers and the key he leaves. What makes the fingerprint a genuine addition rather than a weaker rerun of the key is that it survives cases the key does not. An operator careful enough to use a unique key per host โ defeating the Case 01 and Case 02 signals entirely โ still cannot cheaply use a different tool per host, so his fingerprint still ties his fleet together even when his keys do not. The fingerprint is the invariant that remains when the credential invariants have been defeated, which is why the register needs it: it attributes the disciplined operator who varied his keys but, like everyone, kept his tool.
The confidence, though, is deliberately and permanently lower, and the register is explicit about why, because this is the case that establishes the register's confidence gradient. SHARED KEY earned HIGH because a bespoke key is nearly unshareable by accident. SHARED FINGERPRINT earns MEDIUM-HIGH at best, and often less, because a tool is shareable by design โ its whole purpose is to be used by many. The confidence attached to a linkage signal is, in this register, essentially a measure of how unshareable the invariant is: the harder it is for the invariant to appear under two unrelated hands, the higher the confidence a shared instance supports. The key is near the unshareable end; the fingerprint is toward the shareable end; and later cases will use invariants further along that axis still, with confidence dropping accordingly. The fingerprint case is where that axis becomes visible, and where the register commits to reporting confidence as a function of shareability rather than as a uniform stamp.
That gradient is the register's honesty made operational. It would be easy to present every attribution at HIGH and let the reader assume they are equally sure; it would be dishonest, because they are not, and the difference is exactly the shareability of the invariant each rests on. By assigning SHARED FINGERPRINT a lower confidence than SHARED KEY โ and by saying plainly that it does so because a tool is more shareable than a key โ the register tells the reader how much to trust each attribution and why. The tool beneath the disguise is a real invariant and a real lead; the AsyncSSH cluster is very probably one operator's harness. But "very probably," honestly labeled MEDIUM-HIGH and corroborated by concentration and cross-referenced signals, is not "proven," and the register's refusal to blur that line is the thing that makes its HIGH mean something in the cases where it says HIGH.
5. Fingerprinting Your Adversary (and Being Fingerprinted)
The register owes the analyst and the defender, and the tool fingerprint gives each a lesson that is really the same lesson from two sides: your software announces itself, and that announcement is an identity you did not choose. For the analyst hunting operators, HASSH is a powerful sorting tool with a sharp warning label. Use it to cluster: sort your traffic by the tool that made each connection, and the uncommon builds will surface the automation harnesses that scattered addresses hide. But never let a shared fingerprint alone carry an attribution, because the fingerprint's population is the tool's userbase, not one hand. Weight the fingerprint by its rarity (a custom build is worth far more than stock OpenSSH), tighten it with concentration (single-country, single-window clusters are more likely one operator than global ones), and above all corroborate it with a less shareable signal before you believe it. The fingerprint tells you which tool; only convergence tells you which hand.
For the defender, the same fact is a caution about your own emissions and a gift for your own detection. Your outbound SSH tooling has a HASSH too, and if your organization's automation all uses one distinctive client, that fingerprint identifies your traffic wherever it goes โ an attribution handle on your own operations, in exactly the way the operator's harness is a handle on his. More usefully, HASSH is a detection signal you can turn inward: because malware and attack tooling often use distinctive SSH libraries (a Go or Python client where you would expect stock OpenSSH), fingerprinting the SSH traffic on your own network can surface tooling that does not belong โ a connection whose HASSH matches an automation library no one on your team should be running is a lead worth chasing. The fingerprint that betrays the operator to the honeypot can betray an intruder inside your own network to you, if you are reading handshakes.
The honest bound, one more time, is the shared-tool trap, and it deserves the last word of the defensive section because it is the error this case exists to inoculate against. The single most common way operator attribution goes wrong is mistaking a shared tool for a shared hand โ declaring "one actor" because two intrusions used the same scanner, the same exploit kit, the same SSH library, when in truth they used the same off-the-shelf product that thousands of unrelated actors also use. Tool-based attribution feels rigorous because it rests on a technical artifact, and that feeling is exactly the danger: the artifact is real, but its population is a market, not a person. The register uses HASSH constantly and trusts it never on its own, and its later split-cluster case โ where a single shared HASSH is shown to span two genuinely different operators โ is the deliberate demonstration that the trap is real and that the discipline of corroboration is what keeps the register out of it. Attribute the tool to the toolmaker's market; attribute the hand only when something less shareable than the tool agrees.
6. The counter-narrative, steelmanned
The strongest objection to this case is that HASSH is the textbook example of bad attribution โ a shared tool is not a shared actor, everyone knows this, and building even a MEDIUM-HIGH attribution on a shared SSH-library fingerprint is exactly the amateur mistake that has produced a decade of wrong "one actor" claims in threat intelligence.
The argument runs like this. A HASSH fingerprint, the objection notes, identifies a piece of software, full stop โ and software is made to be used by many. AsyncSSH is a public library anyone can pip-install; thousands of unrelated people script SSH with it every day. So 92 IPs sharing an AsyncSSH fingerprint tell you 92 connections used AsyncSSH, which is a fact about a library's popularity, not about an operator. The single-country concentration, the objection continues, is weak evidence and possibly an artifact: it could reflect a regional preference for the tool, a single cloud region popular in that country, a language community that favors the library, or simply the honeypot's own visibility skew โ none of which implies one hand. And the whole history of attribution, the objection concludes, is littered with analysts who saw a shared tool and cried "one actor," embarrassing themselves when the tool turned out to be commodity; the register, by using HASSH at all, is flirting with the field's most notorious error.
The register agrees with the objection so completely that it built the case around it, and the disagreement is only about whether naming a trap and then avoiding it is the same as falling into it. Yes โ a shared tool is not a shared actor; yes, AsyncSSH is public and popular; yes, tool-based "one actor" claims are the field's classic blunder. The register asserts every one of these, in the case body, as the reason fingerprint confidence is capped below the key cases and the reason HASSH is never used alone. So the objection and the register are on the same side about the danger; the question is whether the specific inference here is the blunder or the disciplined use. It is the disciplined use, for three stated reasons the objection does not fully engage. First, the confidence is explicitly MEDIUM-HIGH, not HIGH โ the register is already telling the reader this is a strong lead, not a proof, which is the opposite of the overconfident "one actor" cry the objection describes. Second, the attribution rests not on the shared tool alone but on the joint improbability of a specific automation-grade build and single-country concentration, and while each of the objection's alternative explanations for the concentration (regional preference, cloud region, visibility skew) is possible, they are precisely why the confidence is capped and corroboration required, not reasons to discard the lead. Third, and decisively, the register does not attribute this cluster to one hand on the fingerprint at all โ it uses the fingerprint as one converging signal alongside the key and behavior clusters, and it says so. The blunder the objection fears is "shared tool, therefore one actor, at high confidence, full stop." The register's actual claim is "specific shared tool, plus concentration, plus corroboration, therefore probably one operator, at MEDIUM-HIGH, pending the less-shareable signals." Those are different claims, and the register's later split-cluster case โ where it shows a shared HASSH spanning two operators and refuses the attribution โ is the proof that it can tell them apart.
7. Linkage Signal โ SHARED FINGERPRINT
Case 03 attributed by the operator's tool rather than his credentials. A HASSH fingerprint hashes the ordered algorithm set an SSH client declares in its opening KEXINIT โ a signature of the client's exact library and build, sent before any credential, captured by the honeypot on every connection. An operator who scripts his fleet with one bespoke automation harness stamps every connection with the same HASSH, because rebuilding the tool per host is absurd; the tool is the invariant beneath the scattered addresses. The honeypot's AsyncSSH 2.1.0 cluster โ 92 IPs concentrated in a single country โ is the clean example: a specific, automation-grade build plus single-country concentration reads far better as one operator's harness than as a coincidence of unrelated users of a public library.
The linkage signal โ the thread that clinched the lead โ is SHARED FINGERPRINT, at MEDIUM-HIGH confidence, and the confidence is deliberately lower than the key cases because a tool is shareable by design where a bespoke key is not. This case establishes the register's confidence gradient: the confidence of an attribution is a measure of how unshareable its invariant is, and the fingerprint, whose whole purpose is to be used by many, sits toward the shareable end. So the fingerprint is used as the register uses it throughout โ weighted by the rarity of the build, tightened by concentration, and never trusted alone, but cross-referenced with the less-shareable key and behavior signals until convergence turns a shared tool into a shared hand.
For the analyst, HASSH sorts traffic by tool and surfaces the automation harnesses that addresses hide โ a powerful lead with a sharp label: attribute the tool to its market, the hand only on corroboration. For the defender, your own tooling has a fingerprint that identifies your traffic, and reading HASSH inward can surface an intruder's out-of-place SSH library on your own network. The shared-tool trap โ a shared tool mistaken for a shared hand โ is the field's most common attribution error, and the register uses HASSH constantly while trusting it never alone, proving the discipline in its later split-cluster case. The vectors do not lie, and neither does the handshake: 92 addresses in one country said "we are strangers," and one tool fingerprint said "we were all built the same." We do not judge. We record. We let people judge โ and we mark, honestly, the difference between the tool we can see and the hand we can only infer.
Follow the Operator โ Case 03. Linkage signal: SHARED FINGERPRINT. Confidence: MEDIUM-HIGH โ a 92-IP, single-country cluster fingerprinting as the same specific AsyncSSH_2.1.0 build (HASSH), captured from the KEXINIT before authentication, read as one operator's automation harness on the joint improbability of an uncommon automation-grade build plus geographic concentration, and corroborated by cross-reference with the shared-key and behavior signals rather than trusted alone. Confidence is capped below the key cases because a tool is shareable by design โ this case establishes the register's rule that confidence tracks the unshareability of the invariant. The failure mode (a shared off-the-shelf tool mistaken for a shared hand โ the field's classic attribution error) is named directly and demonstrated in the register's later split-cluster case. The tool cluster is kept abstract; no real individual is named, and presumption of innocence is preserved. Classification: TLP:WHITE. Include everything โ the vectors do not lie, and they do not judge. The reader judges the tool beneath the disguise, and the honest gap between the software we see and the hand we infer.