Home/ Blog/ Security news/ Article
Blog · Security news

Velvet Ant's PAM-OpenSSH decade is an auth-stack blind spot, not a Linux bug

Sygnia found nine backdoored pam_unix.so variants and four trojanized OpenSSH binaries on one victim. Why auth-stack integrity is the SIEM-invisible gap.

Stone watchtower at night with purple light glowing through its windows and doorway

The Linux auth path was the wrong thing to trust. For ten years, a China-nexus group sat inside one organization's PAM and OpenSSH binaries, watching every successful login, harvesting every password, and producing telemetry that defenders read as proof the network was clean. The story disclosed this week by Sygnia is not really about a new actor or a new technique. It is about what happens when the one process that says "yes, this user is who they claim to be" is the lie.

The cluster is being filed as another Velvet Ant disclosure. That filing undersells it. Group attribution matters less here than the engineering: a single victim with nine separately compiled variants of pam_unix.so, four backdoored OpenSSH binaries, a custom flag on ssh to suppress its own credential log, and a FastCGI tunnel that reached a network the organization believed was isolated. Read the writeup and the practitioner question is not "did this happen to me," it is "would I be able to tell."

What Sygnia actually found

Sygnia's incident-response team, publishing under the name Operation Highland, traced the intrusion to 2016. They identified nine distinct backdoored variants of pam_unix.so, each built in a separate compile environment. The newer variants accepted a hardcoded password (one sample used the string Pamauth@123456) and wrote captured credentials to /usr/sbin/.ssh.log. Memory was scrubbed immediately after authentication, so a debugger snapshot would not contain the password.

The OpenSSH side was where the operation showed real OpSec discipline. An older variant modified only ssh and sshd. The newer variant added scp and ssh-keygen. The modified sshd wrote keystrokes to encrypted files under /usr/share/man9/ph/ with filenames derived from MD5 of user plus TTY. And the modified ssh binary accepted a custom -d flag that, when supplied, suppressed its own credential and keystroke logging. The attacker built a kill switch for their own surveillance, used when operating interactively, so the only sessions getting captured were the legitimate ones.

Reaching the segregated network was done through a custom binary called uptime, deployed on a backend Nginx server and exposed through a FastCGI wrapper. HTTP POST parameters told uptime which host to SSH into and what to run there. From the outside, traffic looked like web requests against an internal service. From the inside, it was a remote-execution gateway. The kit also included a GS-Netcat variant called auditdb that disguised its process as [khubd], a kernel thread, and a custom Perl SOCKS5 proxy masquerading as smbd -D. BleepingComputer carried the disclosure alongside the Sygnia post on June 13.

If sshd lies, every log lies

This is the blind spot the disclosure exposes, and it is bigger than Linux. Every event in your SIEM that says "user X authenticated to host Y at time Z" is downstream of a process you assume is honest. When that process is the attacker's, the SIEM does not detect anything wrong because nothing visible to it is wrong. The username matches. The source IP matches. The MFA token validated against a real provider. The login is telemetry-as-cover.

Take that seriously and a few things change. Auth-stack integrity stops being a sub-task of endpoint monitoring and becomes its own signal. You cannot ask the compromised sshd whether sshd has been modified. The answer has to come from somewhere the attacker did not reach: a separate file-integrity job, an out-of-band package-manager attestation, or a re-hash from a known-good golden image. Correlation quality across layers matters more than the category label on your detection platform, and Velvet Ant is the reason. No correlation helps if every layer is sourcing from the same lying process.

The four assumptions this breaks

1. PAM module file integrity gets watched. It rarely is. AIDE, Tripwire, and OSSEC ship sensible defaults that cover /usr/lib/x86_64-linux-gnu/security/, but in practice many teams disabled file-integrity monitoring during cloud migrations and never turned it back on. Nine variants in one victim is a tell that the attacker has seen this gap repeat.

2. OpenSSH binaries tamper-detect themselves. They do not. Distribution packaging signs the upstream tarball, not the on-disk binary after install. A rebuilt sshd dropped in by root passes every casual check. The custom -d flag is the operational confession: the attacker engineered a way to use their own backdoor without leaving traces. Hunt for argv anomalies on sshd and ssh, not just on user processes. MITRE tracks the technique as T1556.003.

3. Air-gap means no path. It usually means no inbound TCP. The Nginx-fronted uptime binary in this case bridged an internet-exposed web tier to a segregated network because legitimate ops needed a path there for management. Walk every path your own ops uses for legitimate access, then assume the attacker has the same one. The through-line is familiar across recent supply-chain disclosures: a trusted shipping channel becomes a delivery channel.

4. Ten years undetected is the failure mode. It is not. The failure was the first missed checksum. The dwell time is the result, not the bug. A monthly cron that hashes pam_unix.so and sshd and diffs against a baseline would have caught this in 2016, regardless of how good the implant was. Sub-second containment is the metric everyone obsesses over, but containment speed only matters once you can see the event at all.

What to do this week

None of this requires a new product. It requires that the auth path be treated as a separately monitored asset. Concretely:

  • Generate SHA-256 hashes of /lib/security/pam_unix.so (and the architecture-specific variants), /usr/sbin/sshd, /usr/bin/ssh, /usr/bin/scp, and /usr/bin/ssh-keygen on every server. Store the baseline somewhere the local root cannot rewrite. Diff weekly.
  • Alert on RPATH values inside those binaries that do not match the distribution-shipped originals. Sygnia's variants kept non-standard build paths in the ELF header.
  • Inspect every server for the directories /usr/share/man9/ph/ and /var/lib/sam/, and for files matching /usr/sbin/auditdb. None belong on a clean system.
  • Look for processes named smbd -D on hosts that do not run Samba, and for [khubd] kernel-thread imposters that are actually userspace.
  • Audit FastCGI workers spawned by Nginx on internet-facing servers. Anything that resolves to an unknown binary in /usr/sbin/ deserves a manual look.
  • Review /etc/pam.d/ for recent modifications and confirm authorized_keys on every host matches a known list.

This is the start of a category, not a one-off

Auth-stack integrity is going to be its own product space inside the next two years. The pieces already exist: ELF-aware file-integrity monitoring, behavioral baselines on PAM and OpenSSH process arguments, distribution-signature attestation at boot, golden-image comparison at scale. None of the endpoint vendors have stitched them into a single signal yet because the assumption was always that the operating system was honest. Velvet Ant spent ten years inside the counterexample, and the only reason anyone outside that organization knows about it is that Sygnia's responders went looking for the answer in the place the SIEM said was fine.

Patch nothing this week. The story has no CVE. The defensive work is older, less glamorous, and exactly the kind of thing that gets descoped during a cloud migration. Put the file-integrity job back in.

Frequently asked questions

What is Operation Highland?

Operation Highland is the name Sygnia gave to a decade-long cyberespionage campaign by the China-nexus group Velvet Ant, disclosed in June 2026. Sygnia's responders found nine backdoored pam_unix.so variants and four trojanized OpenSSH binaries on a single victim, with forensic artifacts dating back to 2016.

Which Linux components did Velvet Ant modify?

Velvet Ant replaced pam_unix.so with nine separately compiled backdoored variants and modified the OpenSSH binaries ssh, sshd, scp, and ssh-keygen. The modified PAM modules accepted a hardcoded password and logged credentials to /usr/sbin/.ssh.log. The modified ssh accepted a custom -d flag to disable its own credential logging.

How did Velvet Ant reach an air-gapped network?

A custom binary called uptime was deployed on an internet-facing Nginx server and exposed through a FastCGI wrapper. HTTP POST parameters told it which segregated host to SSH into and what command to run. The path existed because legitimate operations needed a way to manage the isolated network.

How do you detect a backdoored pam_unix.so?

Compare the SHA-256 hash of pam_unix.so against the distribution package's known-good hash, ideally from a baseline stored off-host. AIDE and Tripwire automate this. Alert on RPATH values in the ELF header that do not match the distribution-shipped binary, and on modification-time changes for the file.

Why are PAM and OpenSSH attractive backdoor targets?

PAM and OpenSSH sit on the authentication path itself, so a backdoor there sees every login and forges every audit trail. Standard endpoint detection assumes those processes are honest. When sshd is the attacker, every login event downstream becomes telemetry that supports the intrusion, not signal against it.

How long was Velvet Ant inside before detection?

Forensic artifacts dated back to 2016, putting dwell time at approximately ten years before Sygnia's responders identified the campaign in June 2026. The long dwell was the result of a missed file-integrity baseline on PAM and OpenSSH, not of any extraordinary attacker capability. A monthly hash diff would have caught it years earlier.

Ready to meet the Guardians?

Deploys fast - agentless for monitoring and cloud, a lightweight agent for deep endpoint security. Just Suriq, standing watch.