A coordinated credential-harvesting campaign built from someone else’s home internet connections.
Observed: 2026-05-26 → 2026-06-02 (7 days)
First published: 2026-06-24
Signal: 5,469 connection attempts from 88 unique IPs across four sensor regions
Core finding: identical HASSH fingerprint, identical Python SSH library, zero auth successes — pure credential-list construction at scale
Defensive value: HASSH signature, behavioral detection rule, ISP prefix aggregates
What we observed
Over seven days, our sensors logged 5,469 connection attempts from 88 unique source IPs against honeypot sensors deployed across four regions. Every single attempt used the same SSH client fingerprint. Every single attempt failed to authenticate. No post-auth activity was ever recorded.
This is not a brute-force attack. It is credential validation: an operator testing whether a harvested list of username-password pairs opens SSH on internet-exposed servers, producing a filtered list of working credentials for later use.
The 88 source IPs share one property: they are all residential broadband addresses on two Vietnamese ISPs, Viettel and VNPT. They are not rented VPS nodes, not datacenter infrastructure, not Tor exits. They are home internet connections — routers, DSL modems, FTTH CPE — that have been compromised and recruited into a scanning fleet.
Technical fingerprint
SSH client library
Every connection carried the banner SSH-2.0-AsyncSSH_2.1.0.
AsyncSSH is a Python library for asynchronous SSH operations. It is not a compiled scanner. An attacker who builds a credential-validation tool on top of AsyncSSH is writing Python, not C or Go. This matters for attribution and for detection: a Python-based scanner running on compromised residential hardware implies a specific operator profile — one comfortable with Python scripting and able to maintain persistent access to a fleet of home devices.
HASSH fingerprint
All 88 IPs produced the same HASSH value:
fda360b1b4f4d345...
HASSH is a network fingerprint derived from the key exchange algorithms, encryption ciphers, MAC algorithms, and compression methods advertised by an SSH client. A matching HASSH across 88 nodes confirms they are running the same tool version on the same configuration — not independent actors who happen to use AsyncSSH, but a single coordinated fleet.
This fingerprint was consistent across all four sensor regions and across the full seven-day window with no rotation. The operator did not attempt to vary the fingerprint to evade detection.
No successful logins
Across 5,469 attempts and 88 source IPs: zero successful authentications.
The honeypots accept a range of common credential pairs. The fact that none of the attempted credentials succeeded tells us either that the wordlist used by this operator does not overlap with the credentials accepted by our sensors, or that our sensors are not the primary target and the operator is testing a more specific list against a specific set of services. Either way, the operator was not exploiting anything — they were probing.
Infrastructure
Fleet composition
The 88 IPs fall inside five ISP broadband allocations belonging to two Vietnamese operators, Viettel Group (AS7552) and VNPT (AS45899):
| Allocation | Operator | Type | Hosts |
|---|---|---|---|
27.79.0.0/16 | Viettel Group | FTTH/DSL broadband | 27 |
116.110.0.0/16 | Viettel Group | broadband / mobile | 26 |
171.231.0.0/16 | Viettel Group | mobile 4G (CGNAT) | 14 |
171.243.0.0/16 | Viettel Group | mobile 4G (CGNAT) | 9 |
116.99.0.0/16 | VNPT | FTTH/DSL broadband | 12 |
| Total | 88 |
These are end-user broadband and mobile allocations, not datacenter or hosting space: the APNIC records for the covering blocks describe them as consumer broadband and mobile services.
The mobile addresses (171.231.*, 171.243.*) are 4G LTE ranges served via carrier-grade NAT. Attribution to a specific device behind these addresses is not possible without ISP cooperation; the IPs represent NAT gateway exit points, not individual devices.
Cross-region coordination
The same core set of IPs — particularly those from Viettel’s 27.79.0.0/16 range — appeared across all four sensor regions within the same seven-day window:
| Sensor region | Unique IPs | Events |
|---|---|---|
| Region A (primary) | 82 | 4,387 |
| Region B | 17 | 362 |
| Region C | 16 | 318 |
| Region D | 15 | 402 |
Seven hosts appeared in three or more of the sensor regions — six in Viettel 27.79.0.0/16 and one in VNPT 116.99.0.0/16. These are the most active nodes in the fleet, and their cross-regional presence confirms centralized task distribution — a controller is assigning targets to nodes, not each node operating independently.
Assessment
The behavioral profile is consistent with the reconnaissance phase of a credential-stuffing operation:
- A set of credentials has been harvested from a previous breach, phishing campaign, or purchase.
- The operator needs to know which credentials are still valid against live SSH servers.
- The validation tool is deployed on compromised residential devices to reduce detection risk and rate-limiting exposure.
- Valid credentials are collected for later use — lateral movement, persistence, resale, or integration into a larger botnet.
The choice of AsyncSSH (a Python library) over commodity Go-based scanners (the dominant choice for well-resourced actors) suggests either a smaller-scale operator with Python tooling preferences, or deliberate selection of a less-detected library. AsyncSSH’s legitimate use cases mean it is less likely to appear in threat intelligence feeds than purpose-built scanners.
The residential broadband infrastructure adds a layer of operational security: blocklists for residential CIDRs are rarely deployed in production environments because blocking large ISP ranges produces unacceptable false-positive rates. An operator who can maintain persistence on dozens of home routers or CPE devices gets a fleet that is harder to block than a datacenter cluster.
We do not attribute this campaign to a specific threat actor. The operator responsible for distributing the scanning script to these 88 devices is not identified by this data. The ISPs involved (Viettel, VNPT) are the owners of the compromised end-user devices, not the campaign operator.
Detection
No single signal is sufficient here. HASSH identifies a client build and configuration, not an actor: every install of the same AsyncSSH version on the same configuration yields the same value, legitimate ones included. Combine signals.
Composite rule
- Client banner —
SSH-2.0-AsyncSSH_2.1.0 - HASSH —
fda360b1b4f4d345... - Authentication outcome — repeated failures, no success anywhere in the session
- Destination dispersion — many distinct destination hosts rather than one target
- Timing cadence — regular machine-paced intervals rather than human bursts
Signals 1 and 2 narrow the field. Signals 3, 4 and 5 are what separate a scanning fleet from a legitimate AsyncSSH automation that happens to share a build.
Behavioral fallback
Where HASSH is unavailable: AsyncSSH 2.1.0 banner with no successful authentication in the session, correlated across more than one destination. This survives a client upgrade; the HASSH value will not.
The prefixes are descriptive, not a blocklist
The /20 prefixes under IOCs record where the fleet sat during the observation window. They are consumer broadband and CGNAT mobile allocations: each covers roughly 4,096 addresses, assignment is dynamic, and the overwhelming majority of subscribers inside them had nothing to do with this campaign. A prefix filter would penalise thousands of uninvolved customers to reach a few dozen compromised devices — and would stop matching the fleet as soon as leases rotate. Use the prefixes to understand the shape of the campaign, not to build filtering rules.
IOCs
Fleet distribution over the 2026-05-26 → 2026-06-02 window, aggregated to /20. Per-host addresses are not published — see Data handling below.
| /20 prefix | Operator | Hosts |
|---|---|---|
27.79.0.0/20 | Viettel Group | 19 |
27.79.32.0/20 | Viettel Group | 8 |
116.99.160.0/20 | VNPT | 12 |
116.110.0.0/20 | Viettel Group | 7 |
116.110.16.0/20 | Viettel Group | 1 |
116.110.144.0/20 | Viettel Group | 9 |
116.110.208.0/20 | Viettel Group | 9 |
171.231.176.0/20 | Viettel Group | 10 |
171.231.192.0/20 | Viettel Group | 4 |
171.243.144.0/20 | Viettel Group | 9 |
| Total | 88 |
The 88 hosts spread across 54 distinct /24 subnets inside those ten /20s — consistent with dynamically assigned consumer addresses rather than a contiguous allocation under single control.
HASSH: fda360b1b4f4d345...
SSH client banner: SSH-2.0-AsyncSSH_2.1.0
Data handling
What is published. Aggregated indicators only: ISP allocations, /20 prefixes with host counts, the HASSH value, the client banner, and the behavioral signature. This is what a defender needs to write a detection rule.
What is not published. The per-host address list. These are residential subscriber connections. The device owners are victims of the compromise described here, not participants in it, and a per-host list paired with a dated observation window is information their network operator can resolve to named subscribers. Prefix aggregation keeps the report operationally useful without carrying that cost. We do not publish hashed addresses either — the IPv4 space is small enough that a hashed address is trivially reversible, so a hash would be a per-host list wearing a disguise.
Available on request. The per-host list is available on request to national CERTs, to the
network operators responsible for the allocations above, and to verified incident responders
and researchers working a confirmed case, at research@ohiiho.com. We respond to requests;
we do not push this data to anyone.
Correction and removal. Requests to correct or remove any indicator in this report go to
research@ohiiho.com. We act on a request from the affected network operator without
requiring it to be justified.
Retention. The underlying telemetry is kept internally, under restricted access, for as long as it serves research reproducibility and our contractual obligations — an indicator that cannot be re-derived from source data cannot be defended — and is deleted once that purpose ends. We do not claim a fixed statutory period: we document the purpose and the deletion.
Sensor data: HIIH distributed SSH sensor network, 4 regions. Observation window: 2026-05-26 → 2026-06-02. Methodology: passive capture, no active probing.