Compromising a developer workstation is one of the highest-leverage moves an attacker can make on a Linux network. A single infected machine can expose source repositories, signing keys, package registry tokens, and production cloud credentials all at once. Recently identified by researchers at TrendMicro, Quasar Linux (QLNX) is a previously undocumented Linux Remote Access Trojan (RAT) purpose-built to exploit exactly that leverage while remaining almost entirely invisible to traditional file-based defenses. Despite the name, QLNX is not related to the Windows-based QuasarRAT commonly known as Quasar RAT.
QLNX is a full-featured Remote Access Trojan engineered specifically for Linux environments, with developer and DevOps workstations as its primary target. Built around a 58-command RAT framework, it combines fileless execution, an eBPF-based kernel rootkit, a Pluggable Authentication Module (PAM) backdoor, and a peer-to-peer (P2P) mesh network between infected hosts. The end goal is high-value credential theft including SSH private keys, NPM and PyPI tokens, Git Personal Access Tokens (PATs), AWS and Kubernetes configuration secrets, browser-stored credentials, and the contents of .env files.
What makes QLNX especially dangerous is the population it targets. A compromised developer workstation is rarely just a single endpoint, instead, it is an entry point into source repositories, build pipelines, package registries, and production cloud accounts. A successful infection is effectively a supply-chain incident waiting to happen.
| Type | Platform | Primary Target | Key Capabilities |
|---|---|---|---|
| RAT / Credential Stealer | Linux (x86_64) | Developer & DevOps workstations | Fileless execution, eBPF rootkit, PAM backdoor, P2P C2 mesh, 58-command framework |
As TrendMicro mentions it, QLNX has been observed primarily on Linux developer workstations and CI/CD build hosts running mainstream distributions (Debian, Ubuntu, RHEL, Fedora, Arch). Because the malware compiles its rootkit and PAM modules at runtime against the local kernel headers using the system's own gcc, it adapts to a wide range of kernel versions rather than depending on prebuilt binaries.
IoCs, sample hashes, and the embedded source artifacts are covered in standard threat-intel feeds like TrendAI Vision One, IBM X-Force Exchange, and SOC Prime (Active Threat Feed) tracking QLNX. Most Linux EDRs are turned to catch persistent binaries, suspicious corn jobs, and known malicious hashes. QLNX produces almost none of those, making it potent malware to look out for using SIEM solutions like Guardsix.
QLNX ships as a single self-contained Executable and Linkable Format (ELF) binary, but almost none of its runtime activity leaves a recognizable trace on disk. The chain unfolds in six stages:
/dev/fd/ and invokes the local gcc to compile a kernel-version-specific shared object. This sidesteps static signature detection on the rootkit components, since the resulting .so is unique per host.libsecurity_utils.so.1, pam_security.so, and libpam_cache.so, and are registered via /etc/ld.so.preload and the PAM stack. As they are registered via /etc/ld.so.preload, every newly spawned process uses the malicious library, and every authentication event flows through the PAM hook.sudo events into XOR-encrypted hidden files — typically /var/log/.ICE-unix, /var/log/.Test-unix, and /tmp/.pam_cache. In parallel, the implant walks ~/.ssh, ~/.npmrc, ~/.pypirc, ~/.aws, ~/.kube, and project-level .env files to harvest tokens and keys.This design avoids most of the indicators that traditional Linux EDR rules look for. There are no obvious persistent binaries, the rootkit .so is recompiled per host, and the C2 traffic looks like ordinary outbound TLS until inspected closely.
| Tactic | Technique | Technique ID | Capabilities observed with QLNX |
|---|---|---|---|
| Initial Access | Supply Chain Compromise | T1195 | Initial Access is via Supply Chain Compromise by compromising Linux developer or CI/CD hosts, stealing repository, package registry, cloud, and signing credentials, and positioning attackers to alter source code, build pipelines, or published packages. |
| Execution | Native API | T1106 | Directly invokes memfd_create and execveat syscalls to launch payload from an in-memory file descriptor. |
| Persistence | Create or Modify System Process: Systemd Service | T1543.002 | Drops quasar_linux.service under /etc/systemd/system/ and ~/.config/systemd/user/. |
| Scheduled Task/Job: Cron | T1053.003 | Installs @reboot cron entries. |
|
| Boot or Logon Initialization Scripts: RC Scripts | T1037.004 | Drops persistence script at /etc/init.d/quasar_linux. |
|
| Modify Authentication Process: Pluggable Authentication Modules | T1556.003 | Registers pam_security.so / libpam_cache.so in the PAM stack to both backdoor authentication and record cleartext passwords from local logins and sudo events into XOR-encrypted hidden files. |
|
| Persistence, Privilege Escalation | Event Triggered Execution: Unix Shell Configuration Modification | T1546.004 | Appends startup commands to the user's .bashrc. |
| Boot or Logon Autostart Execution: XDG Autostart Entries | T1547.013 | Drops quasar_linux.desktop in ~/.config/autostart/ to launch at desktop logon. |
|
| Stealth | Hijack Execution Flow: Dynamic Linker Hijacking | T1574.006 | Adds libsecurity_utils.so.1 to /etc/ld.so.preload so the rootkit is injected system-wide into every newly spawned process. |
| Reflective Code Loading | T1620 | Writes the real payload into an anonymous memfd and executes it via execveat, leaving the running process with no on-disk executable. |
|
| Masquerading: Match Legitimate Name or Location | T1036.005 | Rewrites comm and argv[0] to imitate kernel worker threads such as [kworker/0:0] and [migration/0]. |
|
| Obfuscated Files or Information: Compile After Delivery | T1027.004 | Embeds C source for the rootkit and PAM module inside the implant and compiles it per-host at runtime against local kernel headers, yielding a unique .so hash per victim. |
|
| Rootkit | T1014 | Loads an eBPF-based kernel rootkit compiled against the local kernel. | |
| Indicator Removal: File Deletion | T1070.004 | Unlinks the original on-disk ELF binary shortly after launching the in-memory copy. | |
| Indicator Removal: Clear Linux or Mac System Logs | T1070 | Log rotation/truncation and journalctl --vacuum operations post-persistence. |
|
| Credential Access | Unsecured Credentials: Credentials In Files | T1552.001 | Harvests tokens from ~/.npmrc, ~/.pypirc, ~/.aws, ~/.kube, and project-level .env files. |
| Unsecured Credentials: Private Keys | T1552.004 | Walks ~/.ssh to steal SSH private keys. |
|
| Credentials from Password Stores: Credentials from Web Browsers | T1555.003 | Steals browser-stored credentials. | |
| Discovery | File and Directory Discovery | T1083 | Enumerates ~/.ssh, ~/.aws, ~/.kube, and project trees to locate credential material. |
| Command and Control | Encrypted Channel: Asymmetric Cryptography | T1573.002 | Wraps the custom C2 protocol in TLS. |
| Proxy: Multi-hop Proxy | T1090.003 | Establishes a peer-to-peer mesh between infected hosts so operator commands can be relayed through any node, preventing single-point C2 takedown. |
Not all of these are strictly required to detect QLNX. However, combining them dramatically improves coverage, because the implant deliberately splits its activity across kernel, userspace, authentication, and network layers.
Despite the sophistication of QLNX, its operational behavior follows a recognizable pattern:
memfd_create and execveat.gcc./etc/ld.so.preload to inject the rootkit and PAM modules./tmp and /var/log.Each of these steps maps cleanly to a different log source. Individually, several of them are noisy or benign; correlated together, they form a high-confidence signal.
A practical investigation flow is to follow the order of the implant's own actions rather than relying on a single alert.
norm_id=Unix event_type= "SYSCALL" system_call=memfd_create
-path IN["*java*", "*node*","*python*"]
We can obtain following primary evidence for fileless execution:
path=/proc/self/fd/3 log proves a process was launched from an anonymous memory file descriptor rather than a physical file on the filesystem.memfd_create), writes the malicious binary into it, and executes it directly via the fd path.norm_id=Unix event_type="EXECVE" command IN ["*gcc*", "*cc1*", "*clang*", "*g++*"]
command IN ["*-o /tmp/*.so*", "*-o /tmp/lib*", "*libsecurity*"]
The logs confirm the malware dropped raw C source code (/tmp/malicious_payload.c) and compiled it locally into a shared object (/tmp/libsecurity.so) rather than downloading a pre-built binary.
norm_id=Unix* ((event_type ="PATH" -name_type="NORMAL") OR event_id=11)
path IN ["*/etc/ld.so.preload", "*/etc/ld.so.conf*", "*/etc/ld.so.conf.d/*"]
We can see logs revealing QLNX's rootkit behavior as:
path=/etc/ld.so.preload is the primary mechanism QLNX uses to establish its user-space rootkit. The malware writes the path of its malicious shared object into this file.ld.so) to load the malicious payload into the memory space of every single new process launched on the system before the legitimate program even starts.kworker), and intercept authentication attempts in the PAM stack./etc/ld.so.preload for system-wide library injection, deploys hidden shared objects such as libsecurity_utils.so and .libpam_cache.so under /usr/lib, and stores captured credentials in concealed files like .ICE-unix, .Test-unix, and .pam_cache under /var/log and /tmp. These files are rarely present on legitimate developer workstations, making auditd correlation against these paths a high-confidence method for identifying QLNX activity even after the original fileless implant has disappeared from disk.A simple correlation query for auditd events targeting these artifacts would be:
norm_id=Unix event_type IN ["PATH", "SYSCALL", "CONFIG_CHANGE"]
path IN [
"*/etc/ld.so.preload*",
"*/usr/lib/libsecurity_utils.so*",
"*/usr/lib/.libpam_cache.so*",
"*/var/log/.ICE-unix*",
"*/var/log/.Test-unix*",
"*/tmp/.pam_cache*",
"*/tmp/.X752e2ca1-lock*"
]
kthreadd) or maintain user-space network connections. Hunt for processes whose comm field matches a kernel thread pattern but whose parent is a userspace process:norm_id=Unix
(
(event_type IN ["EXECVE", "PATH"]
AND (path IN ["*/etc/pam.d/*", "*/lib/security/*.so*"]
OR command IN ["*/etc/pam.d/*", "*/lib/security/*.so*", "*pam_*.so*"] ))
)
Evidences these logs reveal regarding QLNX's authentication backdoor behavior:
/lib/security/ mirrors QLNX dropping its custom-compiled Pluggable Authentication Module (PAM) payload onto the filesystem, disguising it as a standard system library./etc/pam.d/ (specifically targeting services like SSH) represents the malware reconfiguring the system's authentication stack. This forces the OS to load the malicious module whenever a user attempts to log in.sudo or ssh credentials) before passing them along to the legitimate authentication daemon.The QLNX infection chain is unusually resistant to partial cleanup because it combines an eBPF kernel rootkit, library injection, PAM hooks, and a peer-to-peer mesh. A standard "remove the binary and reboot" response is not sufficient.
The most reliable remediation is a full wipe and OS reinstall from a verified clean image for every host that shows confirmed indicators. Anything short of that leaves residual risk that an eBPF program or a rebuilt rootkit .so survives.
If immediate reimaging is not possible, the following short-term containment steps reduce ongoing damage:
/etc/ld.so.preload to stop further injection of the rootkit and PAM modules into newly spawned processes./etc/systemd/system/quasar_linux.service, ~/.config/systemd/user/quasar_linux.service, /etc/init.d/quasar_linux, ~/.config/autostart/quasar_linux.desktop, the @reboot cron entries, and any QLNX modifications to .bashrc./tmp/.X752e2ca1-lock./var/log/.ICE-unix, /var/log/.Test-unix, and /tmp/.pam_cache for forensic analysis before deletion. These files indicate which credentials were captured and over what time window.These containment steps reduce active credential capture but do not remove the eBPF component, which is why reimaging remains the only fully reliable remediation.
Beyond responding to an active infection, several preventive controls significantly reduce QLNX's effectiveness on developer fleets:
/etc/ld.so.preload. This file is rarely modified on a properly managed system. Any change should generate a high-priority alert and ideally be blocked by an EDR or MAC policy.r/lib/libsecurity_utils.so.1/usr/lib/.libpam_cache.so/var/log/.ICE-unix/var/log/.Test-unix/tmp/.pam_cache/tmp/.X752e2ca1-lockYou can use the Configuration for AgentX FIM below by adding it to the ossec.conf in /opt/logpoint/ossec/etc/ossec.conf:
gcc access prevents the dynamic compilation of QLNX's rootkit and PAM modules.memfd_create, execveat, and writes to PAM and ld.so.preloadconfiguration files. These rules have low overhead and high signal for fileless Linux malware in general, not just QLNX.authorized_keys entries, NPM/PyPI/Git PATs, AWS and Kubernetes credentials, all .env secrets, and browser session cookies for any account that authenticated on a compromised host.These mitigations do not substitute for reimaging an actively infected host, but together they significantly raise the cost of a successful QLNX campaign and shorten the window between initial compromise and detection.