← Back to Insights

What 21 Days of Honeypot Attacks Taught Us About SSH Persistence and NIST 800-171 Compliance

Threat Intel

Between March 18 and April 8, 2026, the Cowrie SSH (Secure Shell) honeypot we operate captured three distinct attack campaigns sharing one technique: write an SSH public key into ~/.ssh/authorized_keys, then lock the file with Linux extended filesystem attributes so that even a root-level administrator cannot remove the backdoor without knowing to look for the lock. The campaigns differ in tooling, infrastructure, and attribution. One uses a Go-language SSH client and operates from AS0 "not routed" address space consistent with BGP-hijacked infrastructure. A second, tracked externally as the Outlaw botnet and documented by Elastic Security Labs and Kaspersky, uses bulletproof hosting registered to Virtualine Technologies. A third is correlated by SANS Internet Storm Center (ISC) diary 32024 to the Redtail cryptominer campaign, with payload hashes confirmed across multiple honeypot researchers worldwide. Twenty-one days of sessions. Three distinct operators. One identical persistence mechanism. For a comprehensive overview, see CMMC Compliance for Small Defense Contractors: The Complete Guide.

The compliance implication is direct. Under NIST SP 800-171 Revision 2, defense contractors and subcontractors handling Controlled Unclassified Information (CUI) are required to monitor authentication artifacts, maintain audit logs, and detect unauthorized system use. An undetected SSH key persistence backdoor fails multiple controls simultaneously. Under the CMMC (Cybersecurity Maturity Model Certification) Level 2 framework, failing to detect it is not the same as not being attacked. The assessor asks for evidence that monitoring was in place and that the monitoring would have caught it. Most small primes and subcontractors cannot produce that evidence, not because they were careless, but because the off-the-shelf security stacks they deploy are optimized for detecting binary malware, not for catching a text file modification that zero of 76 commercial antivirus engines will flag.

What Pattern Did We Keep Seeing Across Three Campaigns?

The pattern is consistent enough to describe as a campaign archetype. The attacker authenticates over SSH using brute-forced root credentials, executes a cleanup script to evict competing malware, runs a setup script to install its own tooling, then executes a precise five-step key injection sequence. The sequence is identical across the Go SSH campaign, the Outlaw botnet campaign, and the Redtail campaign. The scripts self-delete after execution. The key injection itself completes in under 30 seconds.

The Go SSH campaign operated from IP 130.12.180.51 using an SSH-2.0-Go client with HASSH fingerprint 5f904648ee8964bef0e8834012e26003, indicating a custom compiled binary built on Go's golang.org/x/crypto/ssh library. The same IP returned six times over seven days. The injected key carries the comment rsa-key-20230629, meaning this campaign has been operating with the same key material for nearly three years. As detailed in our companion analysis of nation-state tradecraft, the AS0 routing of this IP is consistent with BGP-hijacked address space, an indicator of purpose-built attack infrastructure rather than a compromised residential host.

The Outlaw botnet campaign used the same source IP across six sessions over six days, operating from Virtualine Technologies infrastructure that Spamhaus has designated a bulletproof hosting provider and that Recorded Future's Insikt Group classifies as a Threat Activity Enabler. VirusTotal shows 14 of 94 vendors flagging the IP as malicious. The Redtail campaign, confirmed via the SANS ISC diary correlation, executed nine sessions over eight days using the same Go SSH client string and HASSH fingerprint as the Go campaign, with payload hashes across four CPU architectures matching those documented by independent honeypot researchers.

The three campaigns share the SSH key artifact with comment rsa-key-20230629 and SHA-256 hash 8a68d1c08ea31250063f70b1ccb5051db1f7ab6e17d46e9dd3cc292b9849878b. Zero of 76 commercial antivirus engines flag this file as malicious. It is a standard OpenSSH RSA key. The malicious context is entirely in how it is deployed, not in the file itself.

How Does the Attack Chain Work?

The technical sequence is worth reading in full because the NIST 800-171 control mapping that follows depends on understanding what the attacker actually does. Each session runs a single compound command that completes in 28 seconds or less:

chmod +x clean.sh; sh clean.sh; rm -rf clean.sh;
chmod +x setup.sh; sh setup.sh; rm -rf setup.sh;
mkdir -p ~/.ssh;
chattr -ia ~/.ssh/authorized_keys;
echo "ssh-rsa AAAAB3NzaC1yc2E... rsa-key-20230629" > ~/.ssh/authorized_keys;
chattr +ai ~/.ssh/authorized_keys;
uname -a;
echo -e "\x61\x75\x74\x68\x5F\x6F\x6B\x0A";

The cleanup and setup scripts execute and immediately self-delete, leaving no disk artifacts for forensic analysis on a real system. The key injection phase begins with mkdir -p ~/.ssh to ensure the directory exists, then chattr -ia ~/.ssh/authorized_keys to strip any existing immutable or append-only attributes. This step handles the case where a previous run of this same bot, or a competing attacker using the same technique, already locked the file. Without stripping these attributes first, the overwrite on the next line fails with "Operation not permitted."

The echo command then overwrites the entire authorized_keys file with the attacker's RSA key, destroying any legitimate keys or competing backdoor keys on the system. MITRE ATT&CK classifies this as T1098.004, Account Manipulation: SSH Authorized Keys. The final persistence step, chattr +ai ~/.ssh/authorized_keys, applies both the immutable (+i) and append-only (+a) extended filesystem attributes. MITRE ATT&CK classifies the chattr abuse as T1222.002, File and Directory Permissions Modification: Linux. The combined effect: the file cannot be modified, deleted, renamed, or hard-linked, even by root. A sysadmin who finds the unauthorized key and runs rm ~/.ssh/authorized_keys gets "Operation not permitted." Most configuration management tools, including Ansible and Puppet, do not handle extended filesystem attributes by default, so the backdoor survives automated remediation.

The final line sends "auth_ok" back to the attacker's automation, encoded in hex (\x61\x75\x74\x68\x5F\x6F\x6B) to evade string-matching intrusion detection rules. This small detail reveals operational discipline: the attacker encodes a six-byte success signal specifically to avoid triggering IDS signatures that string-match on plaintext indicators. That is not a script kiddie behavior.

Why Does This Map to NIST 800-171?

The attack touches nine NIST SP 800-171 controls because it exploits gaps that exist at every layer of the access control and monitoring stack. The control mapping below is not theoretical. Each gap corresponds to something the attacker's payload directly abuses or directly evades.

NIST SP 800-171 Control Mapping: SSH Authorized Keys Persistence

3.1.1 (Authorized access) — Unauthorized key grants persistent authentication to a system that only authorized users should access.
3.1.5 (Least privilege) — The attack chain requires root; systems that permit root SSH login violate this control.
3.1.6 (Non-privileged accounts) — All observed sessions authenticate as root rather than a named non-privileged user.
3.3.1 (Audit records) — Without FIM (File Integrity Monitoring) on authorized_keys, the key injection generates no audit record.
3.4.1 (Baseline configurations) — An immutable unauthorized key is a deviation from the system baseline that configuration scanning must detect.
3.13.1 (Boundary protection) — No perimeter control stops an attacker from using the installed key for re-entry on an open SSH port.
3.13.11 (CUI cryptographic protection) — The attacker's key provides cryptographically authenticated access to a system that may store CUI.
3.14.3 (Security alerts) — Without alerts on authorized_keys changes, the backdoor persists indefinitely without triggering a response.
3.14.7 (Unauthorized use identification) — The attacker's authenticated sessions appear as legitimate SSH logins in default connection logs.

Under NIST SP 800-171 Revision 3, published in 2024, the requirements around continuous monitoring of authentication artifacts are tightened relative to Revision 2. The baseline configuration control (3.4.1) in Revision 3 explicitly requires that deviations from the established baseline be detected and reported. An immutable unauthorized key that survives automated configuration management is precisely the kind of deviation this control targets. Contractors who assessed against Revision 2 and never revisited their monitoring coverage are carrying a gap they may not know exists.

What Are Most Subcontractors Missing?

The telemetry gap is specific. Most small defense contractors deploy endpoint detection and response (EDR) tooling, and that tooling is competent at detecting executable malware: binary drops, process injection, shellcode execution. What it does not do well is monitor a text file modification on a Linux system, particularly when the modification uses only standard system utilities and the modified file is a legitimate system artifact.

File Integrity Monitoring (FIM) on SSH configuration artifacts requires deliberate configuration that is separate from EDR. Tools like Wazuh, OSSEC, or AIDE (Advanced Intrusion Detection Environment) can watch ~/.ssh/authorized_keys for every user on a system and alert on content changes, file creation, and extended attribute changes. But these tools must be explicitly configured to do so. The default Wazuh FIM configuration does not include per-user SSH directories. AIDE (Advanced Intrusion Detection Environment) requires a baseline scan and a cron-based comparison job. Neither runs automatically out of the box in most deployments.

The second gap is lsattr coverage. Even organizations that run FIM on authorized_keys content often do not alert on attribute changes. The chattr +ai step appears as a metadata modification in FIM if the monitoring configuration watches for attribute changes, but most FIM deployments watch for content and checksum changes, not extended attribute state. An attacker who injects a key and locks it with chattr +ai may not trigger an alert even on a system with FIM enabled, because the content change and the attribute lock are separate events and only one of them is being watched.

The third gap is configuration management coverage. Contractors who rely on Ansible or Puppet to enforce system state are protected against key injection only if their playbooks explicitly check for and strip extended filesystem attributes before writing to authorized_keys. Most playbooks do not. The result is that automated remediation passes over the locked file, reports success, and the backdoor persists. Under DFARS 252.204-7012, a contractor who relies on automated configuration enforcement and never validates whether that enforcement actually succeeded has a process control gap that extends to every system in their CUI boundary.

The DISA STIGs (Defense Information Systems Agency Security Technical Implementation Guides) for Red Hat Enterprise Linux and Ubuntu require disabling root SSH login and enforcing key-based authentication. A contractor whose Linux systems accept root password authentication is not in STIG compliance. Every session we observed across all three campaigns authenticated as root with a password. STIG compliance would have blocked all of them at the initial access phase, before any persistence was attempted.

What Is the Remediation Sequence?

The controls below are ordered by leverage: the highest-impact changes appear first, and each NIST SP 800-171 control reference is included so the remediation maps directly to your System Security Plan (SSP).

  1. Disable root SSH login on every Linux CUI system (3.1.5, 3.1.6). Set PermitRootLogin no in /etc/ssh/sshd_config. All three campaigns targeted root exclusively. This single change blocks the entire attack chain before any payload executes. Verify with sshd -T | grep permitrootlogin.
  2. Disable SSH password authentication (3.1.1, 3.13.11). Set PasswordAuthentication no. Require key-based authentication with a managed key inventory. The brute-forced credentials across our observed sessions included root/P, root/root, root/password, and root/12345. All of them are in every wordlist. Disabling password authentication removes the entire brute-force surface.
  3. Deploy FIM on authorized_keys for every user account (3.3.1, 3.14.3). Configure Wazuh, OSSEC, or AIDE to monitor ~/.ssh/authorized_keys across all user home directories. Alert on content modification, file creation, deletion, and extended attribute changes. The attribute change alert is the one most deployments omit and the one most relevant to this attack pattern.
  4. Add lsattr checks to your baseline configuration scan (3.4.1). Include the following in your periodic compliance scan:
    find /home /root -name authorized_keys -exec lsattr {} \; 2>/dev/null | grep -v "^----"
    Any output indicates a file with non-default extended attributes. An authorized_keys file with the i or a flag set should be treated as an indicator of compromise until proven otherwise.
  5. Implement a managed SSH key inventory (3.1.1, 3.4.1). Maintain a documented list of all authorized SSH public keys across your CUI systems, including key fingerprint, owner, creation date, and authorized systems. Audit quarterly. Keys with generic comments like rsa-key-20230629 that do not match your naming convention are candidates for immediate revocation and investigation.
  6. Configure SIEM (Security Information and Event Management) correlation rules for SSH authentication anomalies (3.14.3, 3.14.7). Alert on SSH authentications from keys not in the managed inventory. Alert on chattr commands in SSH session audit logs. The hex-encoded success beacon (\x61\x75\x74\x68\x5F\x6F\x6B) is a detectable pattern with low false-positive rates when applied to SSH session command logs.
  7. Block traffic from known anomalous routing (3.13.1). AS0 "not routed" traffic has no legitimate business purpose for federal contractors. Apply perimeter rules that drop traffic from IP ranges with no BGP announcement. Review CISA (Cybersecurity and Infrastructure Security Agency) free tools for threat feed integration options that include BGP routing anomaly data.
  8. Document the authorized_keys monitoring controls in your SSP (3.3.1, 3.14.7). The SSP entry should name the specific FIM tool, the specific paths monitored, the alert threshold, the ticketing process triggered by an alert, and the SOP for investigating an unauthorized key. This documentation is what a CMMC Level 2 assessor will ask to see.

What Will a CMMC Level 2 Assessor Actually Ask For?

CMMC (Cybersecurity Maturity Model Certification) Level 2 assessments are not checkbox reviews. The assessor examines evidence of practice, meaning they want to see that the control is operational, not just that it is documented. For SSH key monitoring, the evidence package needs to demonstrate three things.

First, the assessor will ask for audit logs showing that authorized_keys files are actively monitored. This means log entries, preferably from a centralized SIEM, showing that your FIM configuration generates alerts when authorized_keys is modified. A clean EDR dashboard is not sufficient evidence. The assessor knows that EDR does not cover this file class. Bring Wazuh logs, AIDE output, or OSSEC alerts that specifically reference SSH configuration file changes.

Second, the assessor will ask for the documented SOP for handling a detected unauthorized key. The SOP should cover: who gets the alert, what investigation steps follow, how the key is removed (including the chattr -ia step that most helpdesk personnel do not know is required), how the incident is classified under DFARS 252.204-7012, and what post-incident review process applies. A verbal description of what you would do is not evidence. A written SOP with a version date is.

Third, the assessor will verify that your baseline configuration scan includes extended filesystem attribute checks. Ask your security team whether your current configuration scan runs lsattr against SSH directories on any cadence. If the answer is no, you have a gap that is simple to close and, once documented, provides direct evidence for control 3.4.1.

The assessor perspective matters here because the CMMC program has moved past paper compliance. The DoD published the final CMMC rule in December 2024, and third-party assessments for Level 2 contracts are active. The question is not whether your SSP says you monitor authentication artifacts. The question is whether you can demonstrate that monitoring is operational and that it would produce a detectable signal if an attacker ran the exact command sequence we captured in our honeypot. We can show you the log evidence from our own environment. We know what that signal looks like. Contractors who have never seen the attack do not.

Does your current security stack detect authorized_keys tampering?

TDS-IS operates its own threat intelligence infrastructure and has built the specific detection controls that CMMC Level 2 assessors look for. We work with SDVOSB (Service-Disabled Veteran-Owned Small Business) subcontractors and prime contractors who need managed IT and cybersecurity that holds up under assessment.

Request Our Capability Statement