QLNX and Watching the Surroundings: Behavioral Detection for Linux
You cannot detect a malware sample that deletes itself from disk before your EDR blinks. That is the honest starting point for any discussion of QLNX.
Trend Micro’s TrendAI Research team discovered Quasar Linux – QLNX – a previously undocumented Linux remote access trojan with near-zero initial detection rates. It executes entirely from memory via memfd_create and execveat, wipes its own binary from disk, and spoofs its process name to look like a kernel thread. By the time a traditional scanner would look for it, there is nothing on disk to scan.
But here is what the Trend Micro report also documents in exhaustive detail: everything QLNX does after it arrives. And that activity is surprisingly legible.
QLNX compiles rootkit code on the target using gcc. It writes to /etc/ld.so.preload. It creates a lock file at a predictable, hardcoded path. It queries ip-api.com before sending its first beacon. It embeds the string QLNX_MANAGED into every persistence artifact it installs. It logs stolen credentials to hidden files under /var/log/. For a malware family explicitly designed to be invisible, it hands defenders an unusual number of handholds.
This post builds a Sigma detection suite around those handholds. We write IOC rules too – because the bottom of the Pyramid of Pain still matters – but the behavioral rules are where durable detection lives. They will catch the next campaign that uses the same techniques, even if the binary hash rotates and the C2 infrastructure changes overnight.
Why QLNX Is a Supply Chain Problem First
Full technical analysis is available in Trend Micro’s original report, linked at the bottom of this post. What matters for detection context is understanding the target.
QLNX does not target servers. It targets developer workstations. Specifically, it harvests the credentials that underpin modern software development and cloud infrastructure: NPM authentication tokens from .npmrc, PyPI API keys from .pypirc, AWS credentials and configuration files, Kubernetes kubeconfig and service account tokens, Docker Hub credentials from .docker/config.json, Git credentials and personal access tokens, GitHub CLI tokens, HashiCorp Vault tokens, Terraform credentials, SSH private keys, and .env files.
A single compromised developer laptop can give an attacker the ability to publish trojanized packages to NPM or PyPI, inject backdoors into container images, pivot from a personal machine into production cloud environments, and move laterally through every server the developer’s SSH keys touch.
This is not theoretical. The LiteLLM supply chain compromise in March 2026 followed exactly this pattern: stolen credentials from one developer’s machine were used to trojanize a Python package with 3.4 million daily downloads. QLNX’s capability set maps directly to every step of that kill chain.
Developer workstations are the new perimeter. QLNX was built for exactly that reality.
What QLNX Does That We Can Actually Detect
The fileless execution and self-deletion are opaque to standard log sources. Everything else is not. Here is a map of QLNX’s operational behaviors and where each one shows up in telemetry.
gcc invoked to compile a shared library from a /tmp/ source file. Both the LD_PRELOAD rootkit and the PAM backdoor follow the same pattern: write C source code to a randomly-named temp file, then invoke gcc -shared -fPIC to compile a .so. On a production server or developer workstation, gcc compiling a shared library from /tmp/ is essentially never a legitimate operation.
/etc/ld.so.preload modified by a non-package-manager process. Both the rootkit and the PAM backdoor register themselves here. Legitimate writes to this file are performed by package managers during software installation. Anything else writing to it should page immediately.
Process name masquerading as a kernel thread. QLNX sets its process name to strings like [kworker/0:0], [migration/0], and [ksoftirqd/0] using prctl(PR_SET_NAME). Legitimate kernel threads with those names exist – but they are owned by uid 0 and execute from kernel space. A user-owned process with a bracketed kernel-thread name executing from a real path on disk is a contradiction that should never appear in your telemetry.
ip-api.com queried before the first C2 beacon. QLNX resolves the victim’s geolocation from ip-api.com and includes it in its registration packet to the C2 server. Legitimate developer tools do not query ip-api.com as a precursor to establishing network connections.
Predictable lock file at /tmp/.X752e2ca1-lock. QLNX computes a DJB2 hash of the string “quasar_linux” and creates a single-instance lock file at that path. The hash is 0x752e2ca1. The path will be identical on every host this malware runs on, across every campaign, until the authors rename their project.
QLNX_MANAGED in every persistence artifact. Every systemd service file, init.d script, crontab entry, XDG autostart file, and .bashrc injection that QLNX installs contains the hardcoded comment QLNX_MANAGED. Any file written to a persistence location containing this string is definitionally malicious.
Hidden credential logs under /var/log/. Harvested PAM passwords are written to /var/log/.ICE-unix. SSH and sudo credentials go to /var/log/.Test-unix. These paths do not exist in a clean Linux installation.
Each of these behaviors maps to a Sigma rule. Let us build them.
Sigma Rule Suite: qlnx-behavioral-suite
All six rules carry the tag qlnx-behavioral-suite. Build a correlation condition in your SIEM: two or more rules from this suite firing on the same host within 24 hours escalates to a critical case. One rule firing is a signal. Two is a pattern. Three is an incident.
Rule 1: GCC Compiling a Shared Object from a Temp-Path Source File
Technique: T1027.004 – Obfuscated Files or Information: Compile After Delivery
QLNX carries its rootkit and PAM backdoor as embedded C source code strings, writes them to randomly-named temp files, and compiles them locally using the host’s own gcc. The three temp file patterns are /tmp/.hide_src_, /tmp/.pcs_, and /tmp/.pam_src_*. The compilation arguments are consistent: -shared -fPIC to produce a shared object.
This compile-after-delivery technique avoids shipping precompiled binaries that scanners can fingerprint. The tradeoff is that gcc has to run – and that is observable.
title: GCC Compiling Shared Object from Temp Directory Source File
id: 1a3c5e7f-9b2d-4e6a-8c0f-2b4d6f8a0e1c
status: stable
description: >
Detects gcc invoked to compile a shared object (-shared -fPIC) where the
source file resides in a world-writable temp directory (/tmp, /var/tmp,
/dev/shm). This compile-after-delivery pattern is used by QLNX to deploy
its LD_PRELOAD rootkit and PAM backdoor without shipping precompiled
binaries. Legitimate shared library builds do not use temp-path source files.
references:
- https://www.trendmicro.com/en_us/research/26/e/quasar-linux-qlnx-a-silent-foothold-in-the-software-supply-chain.html
- https://attack.mitre.org/techniques/T1027/004/
author: Cyber Mixology
date: 2026-05-11
tags:
- attack.defense_evasion
- attack.t1027.004
- qlnx-behavioral-suite
logsource:
category: process_creation
product: linux
detection:
selection_gcc:
Image|endswith:
- "/gcc"
- "/cc"
- "/gcc-12"
- "/gcc-11"
- "/gcc-10"
selection_shared:
CommandLine|contains|all:
- "-shared"
- "-fPIC"
selection_tmppath:
CommandLine|contains:
- "/tmp/"
- "/var/tmp/"
- "/dev/shm/"
condition: selection_gcc and selection_shared and selection_tmppath
falsepositives:
- Some legitimate build systems that compile shared libraries in temp
directories as part of CI/CD pipelines. Scope suppression to known
CI/CD agent hostnames rather than removing the rule.
level: high
Tuning tip: On developer laptops, this rule will have a very low false positive rate – legitimate builds use proper build directories. On CI/CD agents, add hostname-based suppression for known build infrastructure. On production servers, the false positive rate should be near zero and this rule can be elevated to critical.
Rule 2: /etc/ld.so.preload Modified by Non-Package-Manager Process
Technique: T1574.006 – Hijack Execution Flow: Dynamic Linker Hijacking
This is the highest-fidelity rule in the suite. /etc/ld.so.preload is a system file that causes a shared library to be injected into every dynamically linked process on the system. Legitimate writes to this file are performed by package managers during software installation. On a healthy system, this file may not even exist.
Any process that is not dpkg, rpm, apt-get, yum, dnf, or a similar package manager writing to this file is a near-certain indicator of rootkit or backdoor installation.
title: /etc/ld.so.preload Modified by Non-Package-Manager Process
id: 4b6d8f0a-2c4e-4a8c-9e1f-3d5a7c9b1e4f
status: stable
description: >
Detects writes to /etc/ld.so.preload by any process that is not a
recognized package manager. This file causes a shared library to be
loaded into every dynamically-linked process on the system. Legitimate
modifications are performed only by package managers. QLNX writes both
its LD_PRELOAD rootkit (libsecurity_utils.so.1) and PAM backdoor
(libpam_cache.so / pam_security.so) to this file.
references:
- https://www.trendmicro.com/en_us/research/26/e/quasar-linux-qlnx-a-silent-foothold-in-the-software-supply-chain.html
- https://attack.mitre.org/techniques/T1574/006/
author: Cyber Mixology
date: 2026-05-11
tags:
- attack.persistence
- attack.t1574.006
- qlnx-behavioral-suite
logsource:
category: file_event
product: linux
detection:
selection:
TargetFilename: "/etc/ld.so.preload"
filter_package_managers:
Image|endswith:
- "/dpkg"
- "/rpm"
- "/apt-get"
- "/apt"
- "/yum"
- "/dnf"
- "/pacman"
- "/zypper"
- "/pkg"
condition: selection and not filter_package_managers
falsepositives:
- Manual system configuration by administrators (rare; investigate anyway)
- Some container image build steps
level: critical
Tuning tip: This rule should almost never false positive. If you see a hit, investigate immediately. Do not wait for corroboration from other rules in the suite.
Rule 3: Process Name Masquerading as Kernel Thread
Technique: T1036.004 – Masquerading: Masquerade Task or Service
QLNX selects a fake kernel thread name and applies it consistently across argv[0], prctl(PR_SET_NAME), and /proc/self/comm. The names it uses – [kworker/0:0], [migration/0], [ksoftirqd/0], [rcu_sched], [watchdog/0], [kthread] – are all legitimate kernel thread names. The difference is that real kernel threads are owned by uid 0 and do not appear as processes executing from a file path on disk.
This rule catches the contradiction: a process with a bracketed kernel thread name executing from a real filesystem path.
title: Process Masquerading as Linux Kernel Thread
id: 7e9f1b3d-5c7a-4d9b-8f1e-5a7c9e1f3b6d
status: experimental
description: >
Detects processes whose command line or image name matches common Linux
kernel thread names but which are executing from real filesystem paths
rather than kernel space. QLNX applies this masquerade via prctl and
argv overwrite to blend into process listings alongside legitimate
kernel threads. Legitimate kernel threads do not execute from /tmp,
/usr, /home, or similar user-accessible paths.
references:
- https://www.trendmicro.com/en_us/research/26/e/quasar-linux-qlnx-a-silent-foothold-in-the-software-supply-chain.html
- https://attack.mitre.org/techniques/T1036/004/
author: Cyber Mixology
date: 2026-05-11
tags:
- attack.defense_evasion
- attack.t1036.004
- qlnx-behavioral-suite
logsource:
category: process_creation
product: linux
detection:
selection_kthread_names:
CommandLine|contains:
- "[kworker/"
- "[migration/"
- "[ksoftirqd/"
- "[rcu_sched]"
- "[watchdog/"
- "[kthread]"
- "[kswapd"
- "[khugepaged]"
filter_kernel_space:
# Real kernel threads have no executable image path
Image: ""
filter_known_tools:
# Some monitoring tools may display kernel thread names in output
Image|endswith:
- "/ps"
- "/top"
- "/htop"
condition: selection_kthread_names and not filter_kernel_space and not filter_known_tools
falsepositives:
- Security tooling or monitoring agents that wrap or display kernel thread
information in their own process arguments
level: high
Tuning tip: The key differentiator is whether the Image field is populated. A real kernel thread has no executable path. Adjust the filter_kernel_space logic based on how your EDR or auditd populates the Image field for kernel threads in your environment.
Rule 4: ip-api.com Geolocation Query from Developer or Server Endpoint
Technique: T1082 – System Information Discovery
Before establishing its C2 connection, QLNX queries ip-api.com to retrieve geographic information about the infected host. This geolocation data is included in the check-in packet. Developer tools, production servers, and network infrastructure devices have no legitimate reason to query ip-api.com as part of their normal operation.
This rule targets DNS or proxy logs. It is intentionally narrow – ip-api.com is specific enough that false positives should be minimal outside of developer tooling and browser-based browsing activity.
title: ip-api.com Geolocation Query from Non-Browser Process
id: 2d4f6a8c-0e2b-4f8a-9c1d-3e5f7a9c1e3f
status: experimental
description: >
Detects DNS resolution or HTTP requests to ip-api.com originating from
non-browser processes. QLNX queries ip-api.com to retrieve victim
geolocation data before sending its initial C2 check-in beacon. Legitimate
use of this service from developer endpoints or servers is uncommon;
use from production infrastructure or security devices is near-impossible
in normal operations.
references:
- https://www.trendmicro.com/en_us/research/26/e/quasar-linux-qlnx-a-silent-foothold-in-the-software-supply-chain.html
- https://attack.mitre.org/techniques/T1082/
author: Cyber Mixology
date: 2026-05-11
tags:
- attack.discovery
- attack.t1082
- qlnx-behavioral-suite
logsource:
category: dns_query
product: linux
detection:
selection:
QueryName|endswith: "ip-api.com"
filter_browsers:
Image|endswith:
- "/firefox"
- "/chrome"
- "/chromium"
- "/brave"
- "/opera"
condition: selection and not filter_browsers
falsepositives:
- Developer scripts or tools that use ip-api.com for geolocation lookups
- VPN clients that check external IP on connect
level: medium
Tuning tip: This rule becomes high-fidelity when scoped to server infrastructure and network appliances where browser activity is absent. On developer laptops it may generate some noise from scripts and tools. Pair it with Rule 5 or Rule 6 for higher confidence on general-purpose endpoints.
Rule 5: QLNX_MANAGED String in Persistence Artifact Path
Technique: T1543.002 – Create or Modify System Process: Systemd Service
Every persistence artifact QLNX installs contains the comment QLNX_MANAGED. This string appears in systemd service files, init.d scripts, crontab entries, XDG autostart .desktop files, and .bashrc injections. The malware uses it internally to distinguish its own entries during enumeration and cleanup.
It also makes every one of those artifacts trivially detectable. This is the closest thing to a signed confession that a malware family can leave behind.
title: QLNX_MANAGED String Found in Persistence Artifact
id: 8f0b2d4e-6a8c-4f0b-9d1e-4f6a8c0f2d4e
status: stable
description: >
Detects file creation or modification events where the file content or
path matches known QLNX persistence artifact locations and the file
contains the hardcoded QLNX_MANAGED marker string. QLNX embeds this
string as a comment in every persistence mechanism it installs, including
systemd service files, init.d scripts, crontab entries, XDG autostart
files, and .bashrc injections. Any file containing QLNX_MANAGED in a
persistence context is definitionally malicious.
references:
- https://www.trendmicro.com/en_us/research/26/e/quasar-linux-qlnx-a-silent-foothold-in-the-software-supply-chain.html
- https://attack.mitre.org/techniques/T1543/002/
author: Cyber Mixology
date: 2026-05-11
tags:
- attack.persistence
- attack.t1543.002
- attack.t1546.004
- qlnx-behavioral-suite
logsource:
category: file_event
product: linux
detection:
selection_paths:
TargetFilename|startswith:
- "/etc/systemd/system/"
- "/etc/init.d/"
- "/home/"
- "/root/"
TargetFilename|endswith:
- ".service"
- ".desktop"
- ".sh"
- "/.bashrc"
selection_content:
# Match on file write events where content is observable
# In auditd/Sysmon for Linux this may require content-aware rules
Contents|contains: "QLNX_MANAGED"
condition: selection_paths and selection_content
falsepositives:
- None expected. QLNX_MANAGED is a hardcoded string specific to this
malware family. Any hit on this rule should be treated as confirmed
malicious activity pending investigation.
level: critical
Tuning tip: Not all log sources surface file content in write events. If your telemetry does not capture file content, this rule can be adapted as a hunting query using grep or a file integrity monitoring platform to scan persistence paths for the QLNX_MANAGED string periodically.
Rule 6: IOC Coverage – Hashes, Artifact Paths, and Hidden Credential Log Files
Technique: Multiple
The bottom of the pyramid. We write it anyway. The file hashes will rotate with recompilation. The artifact paths are structural – they are tied to the codebase, not the build. The lock file path at /tmp/.X752e2ca1-lock is derived from a DJB2 hash of the string “quasar_linux” and will remain consistent across all QLNX campaigns unless the authors rename their project. The hidden log file paths /var/log/.ICE-unix and /var/log/.Test-unix are hardcoded in both PAM backdoor implementations. The master password O$$f$QtYJK is hardcoded in the inline-hook PAM backdoor.
These paths and strings give you IOC coverage that outlasts the current binary.
title: QLNX Known IOC Match -- Hashes, Artifact Paths, and Credential Log Files
id: 5a7c9e1f-3b5d-4f7a-8c0e-1d3f5a7c9e2f
status: stable
description: >
Matches known indicators of compromise associated with the QLNX Linux RAT
as documented by Trend Micro TrendAI Research. Covers binary hashes,
compiled component hashes, predictable artifact paths derived from
hardcoded values, hidden PAM credential log files, and the hardcoded
master password string. Hash-based indicators may rotate with recompilation;
path-based indicators are structural and more durable.
references:
- https://www.trendmicro.com/en_us/research/26/e/quasar-linux-qlnx-a-silent-foothold-in-the-software-supply-chain.html
author: Cyber Mixology
date: 2026-05-11
tags:
- attack.persistence
- attack.defense_evasion
- attack.credential_access
- qlnx-behavioral-suite
logsource:
category: file_event
product: linux
detection:
selection_hashes:
Hashes|contains:
- "ea1d34b21b739a6bbf89b3f7e67978005cf7f3eda612cefc7eac1c8ead7c5545"
- "82DAA93219BA40A6E41CDF3174BA57EB5D3383D1CD805584E9954EB0200182A1"
- "42D0C420EB5FE181388F2E4F0B7D7C0D302971E7A06FDC1BEC481B68C8CCAE1F"
- "C99CF0DC1EF1057D713CB082ACAF42E4DF4656809C91741752BDDCAB39BBFACA"
- "EA89CAAB82181881D971BE312412795051F6322B105C8B9D29CFB5729FAB8D33"
- "417430b2d4ae8d005224a9ff5dcb4007d452338acbcbcbb62c4e8ed1a70552dd"
- "d55549d5655e2f202e215676f4bdb0994ea08a93d15ec4ded413f64cfa7facc8"
selection_artifact_paths:
TargetFilename:
- "/tmp/.X752e2ca1-lock"
- "/usr/lib/libsecurity_utils.so.1"
- "/usr/lib/.libpam_cache.so"
- "/var/log/.ICE-unix"
- "/var/log/.Test-unix"
- "/tmp/.pam_cache"
selection_master_password:
# Match in process arguments, environment, or log content if observable
CommandLine|contains: "O$$f$QtYJK"
condition: selection_hashes or selection_artifact_paths or selection_master_password
falsepositives:
- None expected for hash and artifact path matches. The lock file path
is derived from a DJB2 hash of "quasar_linux" and is structurally
tied to this malware family.
level: critical
Blue Team Advice Beyond the SIEM
The Developer Endpoint Coverage Gap
QLNX was explicitly built for developer workstations because EDR coverage on these machines is inconsistent. Developers often push back on endpoint agents for performance reasons. Security teams sometimes make exceptions. The result is a class of high-value, credential-rich machines with weaker visibility than the servers they have access to.
Close that gap. Developer laptops should carry the same EDR policy as your production servers. The credentials on a developer’s machine can be worth more than the server credentials themselves.
Enable file integrity monitoring on /etc/ld.so.preload and /etc/pam.d/ as a minimum baseline on every Linux machine you care about. These files change rarely in legitimate operation. Any unexpected modification should alert.
Check your kernel’s Yama ptrace scope setting. QLNX reads /proc/sys/kernel/yama/ptrace_scope at startup to gauge whether process injection via ptrace is possible. Set it to 1 (restricted) or 2 (admin-only) in your kernel hardening baseline. It will not stop QLNX from using its /proc/pid/mem injection path, but it raises the bar for one of its techniques and signals to QLNX what injection methods are available – which is information you would prefer not to hand over.
Supply Chain Credential Hygiene
QLNX specifically targets the credentials that control package publishing pipelines. A few targeted controls reduce the blast radius of a compromised developer machine:
Enable two-factor publishing requirements on your organization’s NPM and PyPI accounts. Most registries now support this. It means a stolen .npmrc token alone is not sufficient to publish a malicious package.
Audit which developer machines have .npmrc tokens with publish scope as opposed to read-only scope. Least privilege applies to registry tokens too.
Set rotation schedules for long-lived registry and cloud credentials. A token that has not been rotated in two years on a compromised machine is far more dangerous than one rotated last month.
The P2P Mesh Complication
QLNX includes a peer-to-peer mesh networking capability that allows individual implants to route C2 traffic through each other. This has a direct implication for incident response: if one machine in your environment is compromised, it may be relaying commands to or from other compromised machines in the same network.
If the rule suite fires on one host, do not assume it is an isolated incident. Hunt the entire developer fleet before declaring containment. Look for the ip-api.com DNS query, the lock file path, and the ld.so.preload modification across all Linux endpoints before closing the case.
Remediation Order Matters
This is the most operationally important point in this post. If QLNX has installed its LD_PRELOAD persistence, the standard instinct – kill the process, then clean up – will fail. The LD_PRELOAD entry in /etc/ld.so.preload causes the malware’s shared library to be loaded into every dynamically linked process. That includes rm, bash, and every other tool you would use for cleanup. Killing the process without removing the preload entry first means the next command you run will spawn a new instance.
The correct remediation sequence is:
- Remove the QLNX entries from /etc/ld.so.preload before touching the process
- Kill the malware process
- Remove the compiled .so files (libsecurity_utils.so.1, libpam_cache.so, pam_security.so)
- Remove all persistence artifacts (check systemd, init.d, crontab, autostart, .bashrc)
- Rotate all credentials on the machine – every token, key, and password in the harvester’s target list
The Bigger Picture: Watching the Surroundings
The lesson QLNX reinforces is one we keep coming back to on this blog. The exploit or the initial delivery is often invisible. The occupation never is.
QLNX goes to considerable lengths to erase its arrival. It executes from memory. It deletes itself from disk. It spoofs its process name. But then it has to do the work it was built for: persist, harvest credentials, maintain C2 access, and eventually exfiltrate the developer keys that make supply chain attacks possible. Every one of those steps produces an artifact.
That is the game worth playing. Not trying to catch the ghost at the door – watching what happens in every room of the house after it gets inside.
Build the suite. Tag it consistently. Correlate across rules. And remember that when these detections fire, the machine is not just compromised. The credentials it held may already be in the attacker’s hands. Respond to the alert and rotate the secrets in parallel. Do not wait for forensics to finish before you start revoking tokens.
The detection tells you something happened. The credential rotation limits how far it can go.
Full technical analysis of QLNX, including memory forensics, command handler tables, and network protocol deconstruction, is available in Trend Micro’s original research at trendmicro.com. This post builds detection strategy on top of their work – their analysis is the foundation and is worth reading in full.