Devs Beware: “SSH Brute‑Forcer” Go Module Is Actually Stealing Your Logins via Telegram
If a Go package promises “fast SSH brute‑force,” assume it could be stealing the very logins it helps find. A recent case shows a deceptive Go module that scans random IPv4s for SSH on port 22, tries weak credentials, then quietly beams any “hit” (IP, username, password) to a hard‑coded Telegram bot. The trick: it offloads the scanning to whoever runs it, spreads risk across those IPs, and centralizes stolen logins to the attacker. Below is a concise breakdown, plus a copy‑friendly checklist to protect developer environments.
What’s happening (in plain English)
-
The package poses as an SSH brute‑forcer but contains code to send the first successful credentials to a Telegram bot the attacker controls.
-
It disables SSH host‑key verification to avoid identity checks and runs aggressive concurrent attempts with a tiny wordlist (root/admin + weak passwords).
-
Because Telegram’s API rides over HTTPS, exfiltration can blend into normal web traffic, evading simplistic egress filters.
Why devs are at risk
-
Curious practitioners may run “testing tools” from public registries without auditing source.
-
Lab boxes often have permissive egress and minimal monitoring.
-
Teams sometimes copy-paste snippets without checking for hidden callbacks.
Quick indicators of compromise (IoCs) and suspicious behavior
-
Unexpected outbound requests to api.telegram.org or t.me right after “first success.”
-
Code references to HostKeyCallback set to ssh.InsecureIgnoreHostKey.
-
Hard‑coded Telegram bot tokens, handles, or HTTP calls in Go code.
-
Process making bursts of outbound SSH attempts (port 22) to random IPv4s.
-
Wordlists containing typical weak pairs (root/admin with common passwords).
Safe removal and containment steps
-
Immediately kill any running instances of the tool and remove binaries/source.
-
Rotate any SSH credentials that could have been exposed. Treat all “hits” as compromised.
-
Review firewall/egress logs around the time you ran the tool for Telegram API traffic.
-
Re-enable strict host‑key verification in your SSH clients and CI/CD steps.
-
If a lab machine was used, reimage or at least run a thorough malware scan and key audit.
Safer alternatives for legitimate testing
-
Use known‑good, auditable tools from trusted repos; pin versions and verify signatures when possible.
-
Run tests inside an isolated network segment with controlled egress (deny‑by‑default; allow only what’s required).
-
Prefer containers or ephemeral VMs; destroy after tests.
-
Keep a private internal wordlist and config—never pull opaque binaries for sensitive work.
Secure coding and supply‑chain hygiene (Go focus)
-
Always skim source before build: search for http(s) calls, bot tokens, or strange imports.
-
Enable go.sum verification and use private proxy/caches where possible.
-
Adopt code scanning in CI (SAST) and dependency checks; gate merges on security findings.
-
Maintain an internal “allow” registry of vetted packages; block unknown sources by policy.
Copy‑friendly dev checklist (paste this)
-
Don’t run “off-the-shelf” brute‑forcers from random repos.
-
Audit source for outbound calls (Telegram, Discord, paste sites, shorteners).
-
Enforce SSH host‑key verification in all tooling.
-
Isolate testing VMs/containers; restrict outbound traffic by default.
-
Rotate any credentials exposed during tests; replace keys, not just passwords.
-
Log and monitor egress to common C2 platforms (Telegram/Discord APIs).
-
Pin dependencies; verify checksums; scan code in CI before build.
-
Keep an internal list of approved security tools and their digests.
Minimal Go snippet: enforce host‑key checks
Use a strict host‑key policy instead of disabling it:
gosshConfig := &ssh.ClientConfig{ User: "user", Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { // Compare key to a known-good fingerprint or store/verify against a host DB if ssh.FingerprintSHA256(key) != "known-fingerprint" { return fmt.Errorf("unexpected host key for %s", hostname) } return nil }, Timeout: 5 * time.Second, }
Join the conversation