Saturday, September 26, 2026

Hiding Linux processes from ps and lsof with libprocesshider

Hiding Linux processes from ps and lsof with libprocesshider

libprocesshider is a tiny C shared library that uses the LD_PRELOAD mechanism to filter processes out of tools like ps and lsof, written to demonstrate Linux anti-forensics for defenders.

Toolgianlucaborello/libprocesshider — an LD_PRELOAD shared library that hides a Linux process from ps, lsof, and similar /proc-based observers
CategoryAnti-forensics / dynamic-linker research tool
Primary UseDemonstrating, in authorized labs, how readdir() interception on /proc blinds process enumeration so defenders can build countermeasures
Safe UseUse only on systems you own or are explicitly authorized to assess — training labs, purple-team demonstrations, and detection engineering against /etc/ld.so.preload abuse
Telemetry NoteThe technique leaves a hard artifact: an entry in /etc/ld.so.preload pointing at a .so in a world-writable-referenced path; kernel-side tools (sysdig, eBPF tracers, unhide) that bypass glibc see straight through it

libprocesshider is one of the smallest, most instructive anti-forensics demonstrations in the Linux security canon. Written by Gianluca Borello of Sysdig, the project is a single C source file that compiles into a shared library, libprocesshider.so, whose entire job is to make one chosen process invisible to common userland enumeration tools. The README is terse — a build step, an install step, and two truncated output screenshots showing ps aux and lsof -ni returning nothing suspicious — but the accompanying tutorial at sysdigcloud.com unpacks the technique that the code embodies.

The mechanism is the classic LD_PRELOAD interposition attack turned educational. On Linux, userland tools like ps and lsof do not ask the kernel for a process list through some magic syscall; they open /proc and iterate its directory entries via readdir(), which resolves through the dynamic linker. By loading a shared library ahead of libc — either through the LD_PRELOAD environment variable or, as this tool does, through the global /etc/ld.so.preload file — the library can wrap readdir() and simply omit the /proc/<pid> entry belonging to the process whose name is hardcoded into processhider.c.

That last detail is worth emphasizing from an architectural standpoint: the process name to conceal is compiled into the source, not passed at runtime. The Makefile builds with gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl, and anyone studying the tool is expected to edit processhider.c first to set the target name. This makes the project a deliberately minimal proof of concept rather than a configurable offensive framework — there is no CLI, no persistence logic beyond the ld.so.preload line, and no obfuscation of the library itself.

The install path shown in the README is a single, well-known administrative move: move the compiled .so into /usr/local/lib/ and append its path to /etc/ld.so.preload. Because ld.so.preload is honored system-wide for dynamically linked binaries, every subsequent invocation of ps, top, lsof, and friends loads the hooking library without any per-process environment variable. This is precisely why the technique is effective against naive admin triage and equally why it is noisy to anyone who audits that file.

From a detection standpoint, this project is arguably more valuable to blue teams than to anyone else. The /etc/ld.so.preload file is a high-signal artifact: on a well-managed distribution it should be empty or absent, so any entry — especially one pointing at a library in /usr/local/lib/ with a recent mtime — warrants immediate scrutiny. File-integrity monitoring on /etc/ld.so.preload, /etc/ld.so.conf.d/, and the system library directories is the canonical control, and this tool gives defenders a concrete, reproducible way to validate those rulesets in a lab.

The deeper lesson, and the reason Borello built the tool while working on sysdig, is that userland interposition only defeats userland observation. Tools that capture events from the kernel — sysdig itself, modern eBPF-based sensors, auditd rules on execve, or simply reading /proc from a context that bypasses the hooked glibc — see the hidden process without difficulty. Utilities like unhide and ps variants that use different enumeration paths also break the illusion. The hiding is a filter on the observer's library calls, not a change in the kernel's process table.

For a red-team training curriculum, libprocesshider is a clean vehicle for teaching LD_PRELOAD interposition generally: the same wrapper pattern around readdir() generalizes to hooking open(), stat(), write(), and other libc entry points, which is why LD_PRELOAD abuse appears in real intrusions and in EDR evasion research. Studying the ~dozen lines of processhider.c teaches function interposition with dlsym(RTLD_NEXT, ...) — which the -ldl link flag hints at — in a form short enough to audit by eye in a minute.

Operationally, the tool's limitations matter as much as its trick. It only affects dynamically linked binaries; a statically compiled enumerator or one that calls getdents() via a raw syscall is immune. It hides a process from directory listing, but the process's sockets, memory mappings, and /proc/<pid> directory itself still exist and remain directly accessible if you know or can guess the PID. And because the library must be readable by every process on the host, it is trivially discoverable by any inventory that hashes or lists shared libraries.

The project has accumulated over eleven hundred stars and remains a reference point precisely because it does one thing, transparently, in C, with no dependencies beyond gcc and glibc. For authorized assessment labs, purple-team demonstrations, and detection-engineering work against /etc/ld.so.preload tampering, it is an ideal controlled specimen. Anyone deploying it should treat it strictly as a research instrument on owned systems — the same one-line preload entry that makes it a teaching tool makes it a textbook indicator of compromise when found uninvited on production hosts.

Official project repository for gianlucaborello/libprocesshider.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.