Threat reportMalwareTL-2026-2624
eBPF Rootkit Detection: VoidLink, LinkPro, and Atomic Arch Evade Kernel-Level Monitoring
Datadog Security Labs documents three distinct in-the-wild eBPF rootkit techniques — VoidLink's Netlink message-length tampering via bpf_probe_write_user(), LinkPro's bpf_override_return() enumeration spoofing, and Atomic Arch's bpf_send_signal() debugger-killing — and proposes load-time BPF_PROG_LOAD helper-fingerprinting as a defense that runs before any of the three can corrupt the kernel's introspection surface. First disclosed .
Key facts for VoidLink LinkPro Atomic Arch eBPF
| Identifiers | TL-2026-2624, CVE-2024-23897 |
|---|---|
| Also known as | VoidLink, LinkPro, Atomic Arch |
| Severity | MEDIUM |
| First disclosed | |
| Exploitation status | Exploited in the wild; Listed in CISA KEV: CVE-2024-23897 (added ) |
| EPSS | CVE-2024-23897: 99.9% (99.9th percentile) |
| Affected products | Linux Kernel eBPF/BPF subsystem; Jenkins Jenkins Server; Arch Linux Arch User Repository (AUR) packages; npm / Bun package ecosystem atomic-lockfile, lockfile-js, js-digest |
| Weaknesses (CWE) | CWE-22 |
| Malware | Atomic Arch, LinkPro, VoidLink |
| Tools | vShell |
| MITRE ATT&CK techniques | T1014 Rootkit, T1027 Obfuscated Files or Information, T1036.005 Match Legitimate Resource Name or Location, T1059.004 Command and Scripting Interpreter: Unix Shell, T1070.006 Indicator Removal: Timestomp, T1071.001 Application Layer Protocol: Web Protocols, T1082 System Information Discovery, T1090.002 Proxy: External Proxy, T1190 Exploit Public-Facing Application, T1195.002 Supply Chain Compromise: Compromise Software Supply Chain, T1205.002 Socket Filters, T1497 Virtualization/Sandbox Evasion and 6 more in the attack flow |
| Motivation | FINANCIAL |
| Target sectors | technology, cloud services, software development |
| Target regions | Global |
| Detection rules | 9 (1 shown free) |
| Sources | 8 cited sources |
Detection coverage for VoidLink LinkPro Atomic Arch eBPF
As of 2026-09-22, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-2624 across Splunk SPL, Microsoft KQL and Sigma, covering 24 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.
Free detection: eBPF Rootkit Installation — Dangerous BPF_PROG_LOAD Helper Combination
Detects BPF_PROG_LOAD syscalls requesting bpf_probe_write_user, bpf_override_return, or bpf_send_signal/bpf_send_signal_thread — the load-time helper fingerprint Datadog Security Labs identified as common to VoidLink, LinkPro, and Atomic Arch — correlated with LinkPro's fake systemd-resolveld persistence unit and LD_PRELOAD fallback library drop, and multiple dangerous loads from one process within an hour per Datadog's proposed high-confidence rule.
- Languages: Splunk SPL, Microsoft KQL, Sigma
- ATT&CK: T1014, T1622, T1543.002, T1574.006, T1070.006, T1036.005, T1497
- Data sources: ebpf_runtime_sensor, linux_auditd, sysmon_for_linux, file_integrity_monitoring
- Severity: critical
- Confidence: high
Splunk SPL
index=ebpf_audit sourcetype="bpf:prog_load"
| eval dangerous_helper=if(match(helpers,"(?i)bpf_probe_write_user|bpf_override_return|bpf_send_signal_thread|bpf_send_signal"), 1, 0)
| where dangerous_helper=1
| bin _time span=1h as load_hour
| stats count as load_count values(helpers) as helper_list values(prog_type) as prog_types min(_time) as first_load max(_time) as last_load by host, pid, process_name, load_hour
| eval multi_load_1h=if(load_count>1, 1, 0)
| join type=left host
[ search index=linux_audit sourcetype IN ("auditd","sysmon:linux") (path="/etc/systemd/system/systemd-resolveld.service" OR path="/usr/lib/.system/.tmp~data.resolveld" OR path="/etc/libld.so")
| stats count as persistence_artifact_count values(path) as persistence_paths by host ]
| where multi_load_1h=1 OR persistence_artifact_count>0
| table host, pid, process_name, helper_list, prog_types, first_load, last_load, load_count, persistence_artifact_count, persistence_pathsMicrosoft KQL
let DangerousBpfLoads =
BpfProgramEvents_CL
| where TimeGenerated > ago(1h)
| where Helpers_s has_any ("bpf_probe_write_user", "bpf_override_return", "bpf_send_signal_thread", "bpf_send_signal")
| summarize LoadCount=count(), Helpers=make_set(Helpers_s), FirstLoad=min(TimeGenerated), LastLoad=max(TimeGenerated) by DeviceName, ProcessId=Pid_d, ProcessName_s;
let PersistenceArtifacts =
DeviceFileEvents
| where Timestamp > ago(1h)
| where FolderPath in~ ("/etc/systemd/system/systemd-resolveld.service", "/usr/lib/.system/.tmp~data.resolveld", "/etc/libld.so")
| summarize ArtifactCount=count(), Paths=make_set(FolderPath) by DeviceName;
DangerousBpfLoads
| join kind=leftouter (PersistenceArtifacts) on DeviceName
| where LoadCount > 1 or isnotempty(Paths)
| project DeviceName, ProcessId, ProcessName_s, Helpers, LoadCount, FirstLoad, LastLoad, ArtifactCount, PathsSigma
title: eBPF Rootkit Installation via Dangerous BPF_PROG_LOAD Helper Combination
id: 1d3e5f7a-8b9c-4d1e-2f3a-4b5c6d7e8f04
status: experimental
description: Detects a BPF_PROG_LOAD event requesting bpf_probe_write_user, bpf_override_return, or bpf_send_signal(_thread) — the load-time helper fingerprint common to the VoidLink, LinkPro, and Atomic Arch eBPF rootkits per Datadog Security Labs' "Detection primitives for eBPF rootkits".
references:
- https://securitylabs.datadoghq.com/articles/detection-primitives-for-ebpf-rootkits/
- https://www.synacktiv.com/en/publications/linkpro-ebpf-rootkit-analysis
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-09-22
tags:
- attack.persistence
- attack.defense-evasion
- attack.t1014
- attack.t1622
- attack.t1543.002
- attack.t1574.006
- attack.tool.linkpro
- attack.tool.voidlink
logsource:
category: process_creation
product: linux
detection:
selection_bpf_load:
syscall: 'bpf'
bpf_cmd: 'BPF_PROG_LOAD'
selection_dangerous_helper:
helpers|contains:
- 'bpf_probe_write_user'
- 'bpf_override_return'
- 'bpf_send_signal'
- 'bpf_send_signal_thread'
condition: selection_bpf_load and selection_dangerous_helper
falsepositives:
- Legitimate eBPF-based observability/security tooling (Falco, Tetragon, Datadog CWS, Cilium, BCC tools) that intentionally loads programs using these helpers — allowlist by verified binary path/signature
level: criticalKnown false positives:
- Legitimate eBPF-based observability/security tooling (Falco, Tetragon, Datadog CWS, Cilium, BCC tools) intentionally loading programs that use bpf_probe_write_user/bpf_override_return/bpf_send_signal — allowlist by verified binary path, hash, and systemd unit
Tuning notes: Build an allowlist of verified eBPF loader binaries (path + hash + code-signing) for Falco/Tetragon/Datadog CWS/Cilium/BCC and suppress matches from those processes; retain the correlation requiring either >1 dangerous-helper load from the same process within an hour or co-occurrence with a LinkPro persistence artifact (systemd-resolveld.service, .tmp~data.resolveld, libld.so) to keep single-load false positives low, per Datadog's proposed high-confidence rule.
- Jenkins CVE-2024-23897 CLI File-Read Exploitation Preceding EKS Rootkit Deployment (Sentinel) · unlock with TL Creds
- eBPF Rootkit Installation — Dangerous BPF_PROG_LOAD Helper Combination (Sentinel) · unlock with TL Creds
- LinkPro C2 Beaconing and Magic-Packet Port Knock Activation (Sentinel) · unlock with TL Creds
- Jenkins CLI CVE-2024-23897 Arbitrary File Read Exploitation Attempt · unlock with TL Creds
- eBPF Rootkit Anti-Debug Trigger — ptrace SIGKILL via bpf_send_signal · unlock with TL Creds
- VoidLink Netlink Socket-Diagnostic Concealment via bpf_probe_write_user · unlock with TL Creds
- Jenkins CVE-2024-23897 CLI File-Read Exploitation Preceding EKS Rootkit Deployment · unlock with TL Creds
- LinkPro C2 Beaconing and Magic-Packet Port Knock Activation · unlock with TL Creds
Indicators of compromise for VoidLink LinkPro Atomic Arch eBPF
As of 2026-09-22, Threadlinqs Intelligence tracks 24 indicators of compromise for TL-2026-2624.
Sample indicators (3 of 24)
- IP address:
56.155.98[.]37 - Domain:
vnt[.]wherewego[.]top - URL:
hxxps://fixupcount[.]s3[.]dualstack[.]ap-northeast-1[.]amazonaws[.]com/wehn/rich.png
Defanged, TLP:CLEAR. Full set of 24 indicators: unlock with TL Creds.
How VoidLink LinkPro Atomic Arch eBPF works
Datadog Security Labs' "Detection primitives for eBPF rootkits" (2026-07-27) synthesizes three separately disclosed Linux rootkit/malware families to argue that eBPF helper-function combinations requested at BPF_PROG_LOAD time are a durable, pre-verifier detection signal because load time is "the last moment the kernel's view of an eBPF program can be trusted."
VoidLink, documented by Check Point Research on 2026-01-13, is a modular, Zig-written cloud-native C2 framework with 37 in-memory plugins spanning reconnaissance, cloud/Kubernetes privilege escalation (docker_escape, k8s_privesc), credential harvesting (ssh_harvester, browser_stealer, passwd_dump, keyring_dump), persistence, lateral movement, and anti-forensics, plus HTTP/HTTPS, ICMP, DNS-tunneling, and partial P2P/mesh C2 channels. Its network-hiding eBPF program places a kprobe/kretprobe pair on __sys_recvmsg to intercept SOCK_DIAG_BY_FAMILY Netlink responses, then calls bpf_probe_write_user() to inflate the nlmsg_len field of the inet_diag_msg record preceding the one to hide by exactly NLMSG_ALIGN(B.nlmsg_len) — enough to make NLMSG_NEXT's traversal cursor skip the hidden record entirely while still passing NLMSG_OK bounds validation, so ss and netstat silently omit selected TCP connections. Check Point assessed the framework was built by a single, Chinese-affiliated developer using AI-assisted tooling (the TRAE IDE) in under a week, and found no evidence of real-world infections at publication — VoidLink is best treated as an advanced but not-yet-deployed capability.
LinkPro, discovered by Synacktiv's CSIRT (published 2025-10-14) during incident response on a compromised AWS environment, IS observed in a live intrusion. Initial access was an exposed Jenkins server vulnerable to CVE-2024-23897 (CVSS 9.8, CLI @-file-path expansion allowing unauthenticated arbitrary file read), which the actor used to pivot into multiple Amazon EKS clusters and deploy the malicious Docker Hub image kvlnt/vv. That image's start.sh launched a Vnt VPN client (/app/link, connecting to vnt.wherewego.top:29872) and a Rust downloader (/app/app, "vGet") that pulled a vShell 4.9.3 implant staged on S3 (https://fixupcount.s3.dualstack.ap-northeast-1.amazonaws.com/wehn/rich.png) before dropping the Golang LinkPro rootkit itself. LinkPro's Hide eBPF module places tracepoint/kretprobe hooks on getdents64 and sys_bpf: on sys_bpf it checks BPF_PROG_GET_NEXT_ID / BPF_MAP_GET_NEXT_ID / BPF_LINK_GET_NEXT_ID enumeration calls (bpf(2) commands 11, 12, 31) against an allowlist and calls bpf_override_return(ctx, -ENOENT) on a match — which has the side effect of truncating enumeration of every subsequent, non-malicious program with a higher ID as well, and requires a kernel built with CONFIG_BPF_KPROBE_OVERRIDE (present on recent Amazon Linux and Ubuntu 24.04); LinkPro falls back to an /etc/ld.so.preload shared-library hook (/etc/libld.so) when that config is absent. Its Knock module uses an XDP ingress program to watch for a "magic packet" (TCP SYN, window size 54321), records the source IP in a 1-hour-TTL map, and rewrites inbound/outbound TCP ports (via a paired TC egress program) to redirect real C2 traffic to port 2233/2333 while any port scan of the host shows nothing listening. The backdoor persists as a fake systemd unit (/etc/systemd/system/systemd-resolveld.service enabling a binary at /usr/lib/.system/.tmp~data.resolveld, masquerading as systemd-resolved and timestomped to match /etc/passwd), supports interactive shell, file management, chunked Base64 exfiltration, and SOCKS5 reverse-proxy pivoting, and was observed beaconing to 56.155.98.37 (active/forward mode, WebSocket) and 18.199.101.111. Synacktiv found no formal attribution beyond apparent financial motivation.
Atomic Arch is a supply-chain campaign, first reported by Sonatype and expanded on by Corgea and StepSecurity, that on 2026-06-11/12 adopted roughly 1,619 orphaned Arch User Repository (AUR) packages and poisoned their PKGBUILD install scripts to pull malicious npm/Bun dependencies — atomic-lockfile@1.4.2, lockfile-js@1.4.2 (Sonatype-2026-003775 / -003808), and a second-wave js-digest@4.2.2 — whose bundled Rust ELF payload (deps, sha256 6144d433f8a0316869877b5f834c801251bbb936e5f1577c5680878c7443c98b) harvests GitHub tokens, SSH keys, HashiCorp Vault credentials, browser cookies, and chat-app (Slack/Discord/Teams/Telegram) session data, exfiltrating over HTTP POST /api/upload and controlled via POST /api/agent. When run as root the payload deploys an eBPF rootkit (referencing source scales.bpf.c) that hooks getdents64() to hide PIDs, filenames, and socket inodes from /proc via hidden_pids/hidden_names/hidden_inodes maps, interferes with NETLINK_SOCK_DIAG-based socket enumeration, and — the technique that gives the campaign its place in Datadog's article — runs an enter_ptrace program on tp/syscalls/sys_enter_ptrace that inspects every ptrace() call for PTRACE_ATTACH (0x10) or PTRACE_SEIZE (0x4206) against a hidden-PID map and calls bpf_send_signal()/bpf_send_signal_thread() to SIGKILL the calling debugger — not the target — before the kernel completes the attach, leaving no visible sign that an eBPF program caused the crash.
Datadog's proposed countermeasure instruments the BPF_PROG_LOAD syscall itself: an LSM security_bpf_prog hook records program type/attach type/name/tag/ID, a kprobe on check_helper_call extracts the raw helper IDs a program requests before the verifier can rewrite them, and the syscall-exit path stitches identity and helper metadata into one event evaluated against rules such as "BPF_PROG_LOAD && BPF_PROBE_WRITE_USER in bpf.prog.helpers", the same pattern for BPF_OVERRIDE_RETURN, and for BPF_SEND_SIGNAL / BPF_SEND_SIGNAL_THREAD — with correlation of multiple such loads from one process within an hour flagged as high-confidence rootkit installation.
MITRE ATT&CK techniques by tactic:
Stealth
T1014 Rootkit; T1027 Obfuscated Files or Information; T1036.005 Match Legitimate Resource Name or Location; T1070.006 Indicator Removal: Timestomp; T1205.002 Socket Filters; T1497 Virtualization/Sandbox Evasion; T1622 Debugger Evasion
Execution
T1059.004 Command and Scripting Interpreter: Unix Shell
Command and Control
T1071.001 Application Layer Protocol: Web Protocols; T1090.002 Proxy: External Proxy
Discovery
T1082 System Information Discovery
Initial Access
T1190 Exploit Public-Facing Application; T1195.002 Supply Chain Compromise: Compromise Software Supply Chain
Persistence
T1543.002 Create or Modify System Process: Systemd Service
Credential Access
T1552.001 Unsecured Credentials: Credentials In Files; T1555.003 Credentials from Password Stores: Credentials from Web Browsers
stealth
T1574.006 Hijack Execution Flow: Dynamic Linker Hijacking
Privilege Escalation
Remediation for VoidLink LinkPro Atomic Arch eBPF
Patches
- Jenkins security advisory fix for CVE-2024-23897 (2.442+ / LTS 2.426.3+)
Immediate actions
- Patch Jenkins beyond 2.441 / LTS 2.426.2 (CVE-2024-23897) or disable the Jenkins CLI's @-file-path command expansion until patched
- Hunt for LinkPro IOCs on Linux/EKS hosts: /etc/systemd/system/systemd-resolveld.service, /usr/lib/.system/.tmp~data.resolveld, /etc/libld.so, outbound traffic to 56.155.98.37 and 18.199.101.111, and the kvlnt/vv Docker Hub image
- Audit CI/build systems and developer workstations for atomic-lockfile, lockfile-js, or js-digest in npm/Bun lockfiles and package caches; if found, treat all credentials on that host as compromised (GitHub tokens, SSH keys, HashiCorp Vault tokens, browser sessions, chat-app sessions) and rotate them
- Review any recently AUR-adopted/orphaned packages before rebuilding them with yay/paru; diff PKGBUILD changes against the prior maintainer's version
Workarounds
- Disable remoting-based CLI access to Jenkins controllers that cannot be immediately patched
- Pin AUR/npm/Bun dependency versions and require manual review of any newly adopted or newly published transitive dependency
Longer-term hardening
- Deploy load-time BPF_PROG_LOAD monitoring (LSM security_bpf_prog hook plus a kprobe on check_helper_call, per Datadog's proposal) to flag any program requesting bpf_probe_write_user, bpf_override_return, or bpf_send_signal/bpf_send_signal_thread, and alert on multiple such loads from one process within an hour
- Restrict which workloads may hold CAP_BPF/CAP_SYS_ADMIN and require CONFIG_BPF_KPROBE_OVERRIDE-aware allowlisting for eBPF program loaders on production Kubernetes/EKS nodes
- Adopt a CWPP/eBPF-aware runtime sensor capable of correlating BPF_PROG_LOAD events with process lineage and container identity, since userspace tools (ss, netstat, ps, bpftool) can no longer be trusted once any of these three techniques is installed
Affected and fixed versions
- Linux Kernel — eBPF/BPF subsystem
Vulnerable versions: Kernels built with CONFIG_BPF_KPROBE_OVERRIDE (e.g. recent Amazon Linux, Ubuntu 24.04) for bpf_override_return abuse; any kernel ≥ 5.5 for eBPF-capable rootkits generally - Jenkins — Jenkins Server
Vulnerable versions: 2.441 and earlier; LTS 2.426.2 and earlier
Fixed in: 2.442+; LTS 2.426.3+ - Arch Linux — Arch User Repository (AUR) packages
Vulnerable versions: ~1,619 orphaned AUR packages adopted and poisoned June 11-12, 2026 - npm / Bun package ecosystem — atomic-lockfile, lockfile-js, js-digest
Vulnerable versions: atomic-lockfile 1.4.2; lockfile-js 1.4.2; js-digest 4.2.2
Timeline of VoidLink LinkPro Atomic Arch eBPF
- CVE-2024-23897 (Jenkins CLI @-file-path expansion, CVSS 9.8) is publicly disclosed; later used as locked-ioc-23's initial-access vector against an exposed Jenkins server.
- Synacktiv's CSIRT publishes "locked-ioc-23: eBPF rootkit analysis," disclosing the Hide and Knock eBPF modules discovered during incident response on a compromised AWS/EKS environment.
- The Hacker News and other outlets report on locked-ioc-23's magic-packet port-knocking and bpf_override_return enumeration-spoofing techniques.
- Check Point Research publishes "locked-ioc-22: The Cloud-Native Malware Framework," detailing the Zig-based C2 and its bpf_probe_write_user Netlink nlmsg_len-inflation technique; no real-world infections observed.
- locked-ioc-20 campaign begins: attackers adopt orphaned Arch User Repository (AUR) packages and poison PKGBUILD install scripts to pull the malicious npm package locked-ioc-13.
- A second locked-ioc-20 wave introduces Bun-based installation via locked-ioc-16 (published 10:21:34Z, unpublished 11:53:23Z) and locked-ioc-15 (published 13:01:03Z, unpublished 16:29:49Z), bringing the campaign to roughly 1,619 affected AUR packages.
- Corgea and StepSecurity publish follow-on technical analyses of the locked-ioc-20 eBPF rootkit component (scales.bpf.c), documenting its getdents64 hooking and PTRACE_ATTACH/PTRACE_SEIZE anti-debug logic.
- Datadog Security Labs publishes "Detection primitives for eBPF rootkits," synthesizing locked-ioc-22, locked-ioc-23, and locked-ioc-20 and proposing BPF_PROG_LOAD-time helper-function fingerprinting as a load-time detection primitive.
Sources cited for VoidLink LinkPro Atomic Arch eBPF
- CVE-2024-23897 Detail NVD (NIST) · Advisory · 2024-01-24
- Detection primitives for eBPF rootkits securitylabs.datadoghq.com · Research · 2026-07-27
- LinkPro: eBPF rootkit analysis synacktiv.com · Research · 2025-10-14
- VoidLink: The Cloud-Native Malware Framework Check Point Research · Vendor report · 2026-01-13
- Atomic Arch npm Campaign Adds Malicious Dependency sonatype.com · Vendor report · 2026-06-12
- Atomic Arch turned orphaned AUR packages into npm and Bun malware launchers corgea.com · Research · 2026-06-13
- 400+ AUR Packages Hijacked: What the "Atomic Arch" Campaign Means for Supply-Chain Security stepsecurity.io · Blog · 2026-06-15
- LinkPro Linux Rootkit Uses eBPF to Hide and Activates via Magic TCP Packets The Hacker News · News · 2025-10-16
Other reports on CVE-2024-23897
Previous and next in malware
Drafted by the Threadlinqs research pipeline from 8 sources; published ; last updated —.