Isometric blueprint of Linux servers with amber-highlighted user accounts showing TeamTNT XMRig cryptomining resource drain

Group-IB published research on July 30, 2026 documenting a Monero mining campaign first identified in May 2026, in which the operators gained root on Linux servers and then deliberately gave it up. Root activity generates SOC alerts; standard user activity generally does not. (Source: Infosecurity-Magazine)

Initial access came through a trusted third-party relationship — a vendor or client connection into the victim network rather than an internet-facing exploit. That detail matters for anyone with cross-environment links: the account that opens the door may be one your monitoring treats as legitimate by design.

What pam_rootok actually does

Linux Pluggable Authentication Modules (PAM) is the framework that decides how a program verifies who you are — password prompts, key checks, account restrictions. Programs like su and sudo don't implement authentication themselves; they call PAM and act on the answer.

The pam_rootok module returns success without any credential check when the calling process is already running as UID 0. It exists so root can run su - someuser without being asked for that user's password, which is normal administrative behavior.

The operators abused that policy to assume the identities of multiple standard accounts, with no passwords needed and no failed-authentication events to correlate. Mining processes, cron entries and shell history then belonged to ordinary users who had no reason to be under scrutiny.

Persistence spread across shadowed accounts

Redundant cron jobs were planted across those impersonated accounts, so cleanup scoped to the root compromise left the implant able to regenerate. Group-IB described the outcome directly:

Group-IB called the result "a forensic smokescreen" — activity and persistence scattered across accounts nobody was monitoring.

The operators also stopped core logging services and tampered with authentication logs, leaving minimal on-disk trace of either the privilege escalation or the PAM manipulation that followed. For an incident responder, that means the timeline of how root was obtained is largely gone before the investigation starts.

Process and network-layer concealment

A custom flag in the miner build enabled process masquerading, spoofing legitimate names such as ssh in process listings. Group-IB mapped this to MITRE ATT&CK T1564.013 (Hide Artifacts: Bind Mounts). An analyst scanning ps output sees a daemon they expect to see.

Mining traffic carried a Java/Agent user agent so its Stratum packets blended into ordinary web application flows. Network monitoring tuned to spot unusual protocols or unfamiliar clients passes it through as application traffic.

The XMRig build itself

The implant is a modified XMRig 6.25.0, cross-compiled with musl libc and carrying a hardcoded banner identifying it as a private botnet version. Its behavior on execution follows a consistent sequence:

  • Creates a file-based mutex at /tmp/.lock so only one instance runs, avoiding the resource contention that would destabilize the host and draw administrator attention
  • Deletes its own binary from disk while continuing to execute, moving entirely into memory — conventional disk scans come back clean
  • Reads the host CPU topology and spawns worker threads to match, interacting with kernel model-specific registers (MSR) and allocating Huge Pages to raise hash rate
  • Runs a companion bash script that terminates competing miners
  • Conceals its configuration behind layered XOR keys

Decrypting those keys exposed a hardcoded campaign identifier that Group-IB linked to a wider family used to aggregate hash rates across compromised hosts.

Key Insight: The cost to the victim is CPU capacity consumed by someone else's mining, plus a compromised server holding root-level access that was reached through a partner connection.

XMRig Cryptomining Impact on Linux Infrastructure

The implant is a modified build of XMRig 6.25.0, cross-compiled against musl libc and carrying a hardcoded banner identifying it as a private botnet version. That means it is not the off-the-shelf miner your endpoint tooling may already have a signature for, and the static linking lets it run across Linux distributions without matching library dependencies on the host.

On startup it reads the host's CPU topology and spawns worker threads to match. Your server's core count determines how much of it the miner consumes — a larger, more expensive machine gives the operators proportionally more hash rate, so your best-provisioned hosts absorb the most damage.

It also interacts with kernel model-specific registers (MSR) and allocates Huge Pages, both tuning steps that raise Monero hash rate at the cost of memory and CPU cache your own workloads were using. In practice this is sustained, deliberate resource contention rather than a brief spike.

The operational consequences show up in places your team already watches, just without an obvious cause:

  • Application latency and timeouts on database, API, and batch-processing hosts sharing the compromised machine.
  • Cloud and hosting spend increases where autoscaling groups add instances in response to CPU pressure, or where billing is tied to compute consumption.
  • Failed capacity planning — the baselines you use to size infrastructure now include someone else's mining workload.
  • SLA exposure if response-time commitments to customers depend on the affected tier.
  • Hardware wear and thermal throttling on physical servers held near full utilization for extended periods.

A companion bash script terminates competing miners on the host. The operators want your CPU cycles exclusively, and that behavior tells you something useful about your exposure: if this crew found the server, others likely can too.

The miner creates a file-based mutex at /tmp/.lock so only one instance runs at a time. That restraint is deliberate — running multiple copies would destabilize the host and prompt an administrator to investigate. Your monitoring sees degraded but functioning services, which is exactly the condition most likely to be filed as a performance ticket rather than a security incident.

After launch, the binary deletes itself from disk while continuing to execute from memory. Disk-based antivirus scans and file integrity checks on the affected server come back clean, so your existing evidence trail supports a conclusion that nothing is wrong. Recovering the artifact requires memory acquisition, which most organizations do not perform on a server that is merely slow.

Process masquerading compounds this. The build carries a custom flag that spoofs legitimate process names such as ssh in process listings, mapped to MITRE technique T1564.013. When an administrator runs a process listing to find the source of high CPU load, the top consumer looks like normal system activity.

Mining traffic reaches the pool over Stratum but carries a Java/Agent user agent, blending the sessions into ordinary web application traffic on the wire. Network egress monitoring that flags unusual protocols or known mining pool signatures has less to work with here.

For finance and leadership, the loss is not a ransom demand or a data breach notification — it is compute you paid for, delivered to someone else, alongside layered XOR-encrypted configuration tying your host to a campaign identifier that aggregates hash rate across many victims. Your infrastructure becomes a revenue line for a third party, and the cost accrues quietly on your cloud invoice for as long as the miner runs.

Detection Strategies When PAM Evasion Blocks Standard Tools

Start with your external log collector, not the host. The operators stopped core logging services and edited authentication records, so the compromised server's own logs are the least reliable evidence you have. Pull the same time window from wherever you forward logs and look for the gap — a period where a host that normally reports steadily goes quiet is itself the indicator.

In the first hour, work the process and network layers, because those survive log tampering:

  • List every process named ssh and resolve its binary with ls -l /proc/<pid>/exe. A running process whose executable link resolves to a path marked (deleted) is the self-unlinking miner still resident in memory. This is MITRE T1564.013, and it is the single highest-confidence finding on the host.
  • Check for the file-based mutex at /tmp/.lock. It is transient, so its absence proves nothing, but its presence on a production server warrants immediate escalation.
  • Run ss -tnp and look for long-lived outbound TCP sessions owned by ordinary service or user accounts. Stratum mining traffic is persistent by design — the connection stays up for as long as the worker runs.
  • Capture memory before you reboot or rebuild. Once the process dies, the only copy of the implant is gone, along with the decrypted configuration and campaign identifier.

Within 24 hours, widen the search past the account that first drew your attention. Enumerate cron entries for every local account, not just root and not just the accounts your team recognizes as administrative. The persistence is redundant and spread across standard users, so cleaning one crontab leaves the implant able to reinstall itself.

Then check your egress and proxy records for a Java/Agent user agent originating from hosts that run no Java application. The miner uses that string to make its pool traffic resemble ordinary web application flows, which means the anomaly is not the user agent itself but the mismatch between the user agent and the host's known software inventory. Feed that pairing to whoever owns your web filtering rather than treating it as noise.

On the resource side, skip fixed CPU percentage thresholds and alert on shape instead. The miner sizes its worker pool to the machine, interacts with kernel model-specific registers, and allocates Huge Pages — so the signature is sustained, evenly distributed utilization across all cores with no matching application load, plus a change in Huge Pages allocation that no deployment explains. Nightly batch jobs spike and stop; this does not.

The identity side is where this campaign is most likely to reappear. In environments Capstone manages, Adlumin correlates authentication events forwarded off-host, so PAM-based identity switching to accounts that have no interactive login history surfaces as an authentication anomaly even when the local record has been edited. That matters because the accounts being impersonated are ones your baseline treats as legitimate.

Two findings together — a process whose binary is deleted and a cron entry under a standard user account — mean the host is actively compromised. Capture memory, preserve the crontabs, then rebuild rather than clean, and audit the vendor or client connection that reaches into that network segment.

Containment and Removal for Compromised Linux Systems

Isolate the host at the network layer and leave it running. The miner deleted its own binary and lives entirely in memory, so powering off or rebooting a compromised server destroys the only copy of the implant you have. Apply a switch ACL or firewall rule that drops egress to the mining pool while keeping the machine reachable for acquisition, and cut the vendor or client connection that provided the original path in.

Preserve before you clean. Capture volatile memory with your acquisition tooling, then record the running process list, thread counts, open sockets, and the state of the /tmp/.lock mutex file if it still exists. Collect copies of the PAM configuration directory, every account's crontab, and whatever remains of the authentication logs — the tampering means these files are evidence of manipulation even when they are missing entries.

Persistence removal has to cover every account at once, not just root. The redundant cron jobs were scattered across multiple standard users, so a partial cleanup lets the implant regenerate from an account you skipped:

  • Enumerate scheduled tasks per account with crontab -l -u <user> for every local user, including service accounts with valid shells.
  • Check system-wide locations — /etc/cron.d, the /etc/cron.* directories, and systemctl list-timers --all for timer units.
  • Check user-scoped units with systemctl --user list-units for each account, since these survive independently of system services.
  • Look for the companion bash script that terminates competing miners; it typically sits alongside the same persistence entries.

Only after persistence is stripped should you kill the mining processes. Terminate them, then watch for respawn over a monitoring window before you declare the host clean — a process that returns tells you a scheduled entry or unit file was missed.

Restore PAM from a known-good baseline rather than editing by hand. Verify package integrity with rpm -Va or debsums -c depending on your distribution, and compare the pam_rootok lines against a matching, uncompromised system. PAM changes apply at the next authentication attempt, so no reboot is required — but keep an existing root session open while you edit, because a malformed stack locks out new logins on a machine you still need access to.

Re-enable the logging services the operators stopped, restart them, and confirm on the external collector that events are arriving again. Until that confirmation, you have no reliable telemetry on the host you are remediating.

Rotate credentials for every account whose identity was assumed. The impersonation did not require passwords, so treat rotation as closing everything else those accounts could reach: SSH keys in authorized_keys, API tokens and service credentials in files those users could read, sudoers entries, and the third-party access credential used for initial entry. Compromised credentials let attackers return with legitimate permissions, which is far harder to spot than a fresh intrusion.

SentinelOne flags the logging-service tampering and masqueraded process execution described earlier across managed environments, and its process telemetry persists after the binary unlinks itself from disk — the gap that conventional file scans miss.

Reboot last, once persistence is gone and PAM is verified, to clear memory-resident code and confirm nothing returns. For build servers, hypervisors, or any host where you cannot account for every modification, rebuild from a known-good image and restore data selectively.

Hardening Linux Systems Against PAM-Based Persistence

Start with audit rules on the PAM configuration itself, because a change to /etc/pam.d/ is a rare, high-signal event on a production server. Add persistent watches to /etc/audit/rules.d/ so writes are recorded even when the actor is already root:

  • -w /etc/pam.d/ -p wa -k pam_config
  • -w /etc/pam.conf -p wa -k pam_config
  • -w /lib/security/ -p wa -k pam_module (add /lib64/security/ and /usr/lib/x86_64-linux-gnu/security/ to match your distribution's module path)
  • -w /etc/nsswitch.conf -p wa -k auth_config

These rules take under an hour to deploy and carry almost no operational risk. Their value depends entirely on the records leaving the box, since the operators in this campaign stopped logging services and edited authentication records on the host.

Next, establish a file integrity baseline for the authentication stack so you can answer the question "was this module replaced?" without trusting the compromised system. Package databases already hold known-good hashes: run rpm -Va | grep security on RPM systems or debsums -c libpam-modules libpam-runtime on Debian derivatives, and store the output off-host. An AIDE or Tripwire policy scoped to the PAM directories catches drift on a schedule rather than only during an investigation.

Tighten write access while you are there. Every file under /etc/pam.d/ should be root:root with mode 0644, the directory 0755, and shared objects in the security module path 0644. Confirm no configuration management agent, container runtime, or vendor-installed package runs with a service account that can write to those paths — that is the practical way a low-privileged foothold turns into a persistent authentication change.

Then prune the stack. Most servers ship PAM lines they never use, and each one is a place to insert something. Review each file for modules you cannot justify, and pay attention to pam_exec.so, which runs an arbitrary program during authentication and is a straightforward persistence mechanism. Where root-to-user switching is genuinely required for operations, gate it: restrict su to a specific group with pam_wheel.so use_uid and route the remaining cases through sudo -u with per-command rules, so identity switches produce an attributable log line instead of a silent session.

For runtime detection, watch what authentication daemons spawn. Legitimate sshd, su, and sudo processes start login shells; they do not start curl, wget, compilers, or writes into /tmp. An auditd execve rule keyed on those parents, or an equivalent EDR behavioral rule, flags the moment authentication machinery is used as a launcher. Pair it with a weekly sweep of per-user crontabs at /var/spool/cron/ across every standard account, not just the ones with interactive logins, since scheduled tasks under unmonitored users are what let the implant reappear after cleanup.

The longer-term work is drift control. Put your PAM stack under configuration management so that an unauthorized edit is reverted on the next run and reported as a deviation, and consider a kernel IMA appraisal policy to reject unsigned shared objects loading from the security module path. N-able Cove holds versioned offsite copies of system configuration across managed environments, which is what lets you restore a verified /etc/pam.d/ instead of reconstructing it from a host you no longer trust.

Sequence it as: audit rules and log forwarding first, integrity baseline and permissions second, module pruning and configuration management after that.

Why TeamTNT Targets Linux and What to Monitor

Cryptojacking crews target Linux because that is where the compute lives. Cryptojacking gangs such as TeamTNT have built their operations around Linux servers, cloud virtual machines and container hosts — machines that run continuously, carry high core counts, and are rarely watched at the same granularity as employee laptops. The Monero mining campaign Group-IB documented fits that pattern: it went after server infrastructure, not endpoints.

The economics are simple. A single compromised host produces a modest hash rate, but the decrypted configuration in this campaign carried a hardcoded campaign identifier that Group-IB tied to a wider family used to aggregate hash rates across many compromised hosts. Your server is not the target so much as one contributor to a pool, which is why operators prioritize staying resident over stealing anything.

That priority explains why the PAM abuse works so well in Linux-heavy estates. Production Linux hosts already run dozens of standard and service accounts — application users, deployment accounts, backup identities — and activity under those names is normal by design. Where a Windows environment tends to have a smaller set of interactive human logins, a data centre or cloud fleet gives an operator many plausible identities to hide behind, each with its own scheduled tasks and shell history.

Concealment continued at the process and network layers. A custom flag enabled process masquerading, spoofing legitimate names such as ssh in process listings, which Group-IB mapped to MITRE ATT&CK T1564.013. Mining traffic carried a Java/Agent user agent so its Stratum packets resembled ordinary web application traffic leaving the host.

For your business, the cost is not stolen data. It is CPU you are paying for being spent on someone else's mining, degraded application performance on shared nodes, and an actor holding persistent access to server infrastructure they can sell or repurpose later. The sections that follow break down the implant's behaviour and the practical response.

Immediate Actions for SOC Teams and System Administrators

The mining traffic used a Java/Agent user agent so its Stratum sessions blended into ordinary web application flows. The operators disabled logging and edited authentication records on the host, but they could not delete the outbound connection itself — network egress records are the one artifact they had no control over.

Start there. On each Linux server, enumerate established outbound sessions and the process behind each one:

ss -tnp state established

Then pull the same window from your egress proxy or NetFlow records and look for long-lived outbound TCP sessions from server subnets carrying a Java/Agent user agent. A production database or application host holding a persistent session to an external address it has no business reason to reach is worth a full triage regardless of whether you suspect PAM tampering anywhere in the estate.

Three follow-ups, in order:

  • Enumerate cron entries for every user account on the host, not just root. The operators spread redundant cron persistence across standard accounts, so a per-user pass is the only way to see all of it.
  • Check for unexpected Huge Pages allocation and MSR access on servers whose workloads do not require either. The miner touches model-specific registers and allocates Huge Pages to raise hash rate, which is unusual behaviour for a typical application server.
  • Inventory which third-party accounts hold interactive access into your Linux environment, and record what each one is expected to do.

Ownership: your SOC lead owns the egress and session hunt and reports findings into a single ticket. Your Linux platform owner takes the cron and Huge Pages review across the server inventory. Whoever manages vendor and client relationships produces the third-party access list. Set a review date on that ticket so all three close together rather than drifting apart.

In This Article

Top hits