I tested the Singularity Linux kernel rootkit on VirusTotal using only basic obfuscation. At the time of submission, none of the engines detected the sample. This seems to highlight ongoing gaps in static detection for Linux kernel-level malware, especially custom or non-widespread threats.
The rootkit now disables SELinux enforcing mode on-demand when the ICMP reverse shell is triggered, leaving zero audit logs.
How it works: SELinux maintains a global kernel structure called selinux_state that contains the enforcement flag. The rootkit resolves this non-exported symbol via kallsyms at module load time, then directly writes enforcing = 0 when triggered. This bypasses the normal setenforce() interface entirely.
The clever part is the dual-layer approach:
* Hooks netlink_unicast to drop audit messages for hidden PIDs
* Attempts to modify selinux_state->enforcing directly in kernel memory
On kernels built with CONFIG_SECURITY_SELINUX_DEVELOP=y, SELinux enforcement may stop at the kernel decision level, while userspace tools continue to report enforcing mode and /var/log/audit/audit.log shows nothing.
- Advanced Network Hiding
Previous versions only hide TCP connections from /proc/net/tcp* by hooking tcp_seq_show, which blocked netstat. But modern tools like ss and conntrack bypass /proc entirely - they query the kernel directly via netlink.
The new version filters at the netlink layer:
* SOCK_DIAG filtering: ss uses NETLINK_SOCK_DIAG protocol to get socket info directly from the kernel. Singularity hooks recvmsg to intercept and filter these netlink responses before userspace sees them. Commands like ss -tapen or lsof -i return empty for hidden connections.
* Conntrack filtering: Connection tracking (nf_conntrack) maintains state for all network flows. Reading /proc/net/nf_conntrack or running conntrack -L would expose hidden connections. The rootkit now filters both the proc interface and NETLINK_NETFILTER messages with conntrack types.
* UDP hiding: Added hooks for udp4_seq_show and udp6_seq_show - previous versions only hide TCP.
- Other improvements:
* Optimized log filtering (switched from multiple strstr() calls to switch-case with strncmp())
* Audit statistics tracking (get_blocked_audit_count(), get_total_audit_count())
* Automated setup script
This rootkit doesn't just hide from detection tools, it blinds them at the kernel level. When security tools try to enable ftrace (the standard syscall tracing method), the rootkit intercepts writes to /proc/sys/kernel/ftrace_enabled, pretends it succeeded, stores a fake "enabled" value in memory, and returns it on reads while never actually enabling tracing, so tools like perf and ftrace think they're working but see nothing.
It blocks all dangerous eBPF program types (kprobes, tracepoints, LSM hooks, iterators) making modern security tools like Falco, bpftrace, Tracee, Cilium are completely blind.
This kernel rootkit also can evade detection on modern EDRs like Trend Micro EDR, Crowdstrike falcon (since blocks eBPF operations), Elastic Security, Sophos, and others.
It hooks every read syscall variant (read, pread64, readv, preadv, preadv2, plus 32-bit versions) to filter /proc/kmsg, /var/log/kern.log, /var/log/syslog, dmesg output, and audit logs, removing any lines containing "taint", "hook", "ftrace", or "kallsyms_lookup_name" before they reach userspace. For process hiding, it doesn't just filter /proc but hooks 20+ syscalls (getdents64, stat, lstat, statx, newfstatat, chdir, readlink, openat, kill, getsid, getpgid, pidfd_open) returning ENOENT/ESRCH for hidden PIDs.
It hooks netlink_unicast to drop audit messages about hidden processes before they reach auditd. It hooks init_module and finit_module so you can't load detection kernel modules, always return -ENOEXEC (Exec format error).
It hides network connections by hooking tcp4_seq_show, tcp6_seq_show, and tpacket_rcv.
And it has other very strong and stealthy hooks, which makes it scary because it doesn't have much of an impact on the system, and it doesn't slow it down like other rootkits.
Once a machine is compromised with singularity rootkit, trusting any observability from that kernel becomes impossible, your security tools are running and reporting "all clear" while being completely deceived.
Nowadays, there's only one rootkit that can hide itself so perfectly: the Singularity rootkit. It also hides from auditd by using netlink_unicast hooking and other evasive functionalities. Analyzing a machine compromised with Singularity loaded is a real headache, since it prevents memory dumps for analysis.
reply