Use unhide to Check Linux for Hidden Processes

unhide runs on the installed Linux build, compares its standard checks, and tells you whether it found a hidden or fake thread. It is a detector, not a cleanup tool: a hit needs investigation, not an automatic reboot, kill or package change.

This guide matches the Ubuntu package unhide 20220611-1ubuntu1, whose executable reports upstream version 20211016. Allow about fifteen minutes for a quick check, longer if you need to investigate a discrepancy. You need shell access, sudo access, and a working /proc filesystem.

Security boundary: the actual Linux checks require root on this installation. The version and path checks below are read-only and can run without elevation. Do not use the output as proof a machine is clean: a hidden process, a false positive, or a compromised host can all affect what you see.

1. Confirm which unhide you have

Start by checking the package and the command your shell will actually execute:

$ dpkg-query -W -f='${Package} ${Version}\n' unhide
unhide 20220611-1ubuntu1
$ command -v unhide
/usr/sbin/unhide
$ ls -l /usr/sbin/unhide
lrwxrwxrwx ... /usr/sbin/unhide -> unhide-linux
$ unhide -V
Unhide 20211016

The exact package path, link metadata and copyright lines can differ. On this machine, the unqualified command links to the Linux implementation, which matters because that build provides tests such as quick, reverse, brute and procfs. Do not assume an alias has the same test list until you check it.

Checkpoint: if command -v unhide points somewhere unexpected, stop and verify the package or container image before collecting forensic evidence.

2. Run the quick comparison

For a first pass, compare the process views used by proc, procfs and sys:

$ sudo unhide quick
$ status=$?
$ printf 'unhide exit status: %s\n' "$status"
unhide exit status: 0

The manual describes quick as roughly twenty times faster than the corresponding full checks, with a higher risk of false positives. Status zero means it completed without reporting a hidden or fake thread; status one means it found one, according to the installed manual. Preserve the complete terminal output if the result is unexpected.

Do not treat a zero status as a security verdict. The check compares what different interfaces expose at one point in time, and very short-lived processes can make views disagree even without a rootkit involved.

3. Add the reverse check when the result matters

The reverse test checks that threads reported by ps can also be found through procfs and system calls. Combine it with the quick test:

$ sudo unhide quick reverse
$ printf 'unhide exit status: %s\n' "$?"
unhide exit status: 0

Run this from a quiet maintenance window if you can; busy hosts create more moving targets. If the command returns one, save the output, the date, the kernel version and the process list for a separate investigation. Do not kill the named process on the spot: unhide is reporting an inconsistency, and the process may still be legitimate.

4. Run a standard, slower comparison

When you want the direct procfs and system-call comparisons instead of the quick aggregate, use:

$ sudo unhide sys proc
$ printf 'unhide exit status: %s\n' "$?"
unhide exit status: 0

proc compares /proc with /bin/ps; sys compares information from ps with system calls. Running both gives a more readable baseline than relying only on the faster aggregate, though it still does not establish the host is uncompromised.

5. Use deeper checks carefully

For a more thorough pass, the manual gives this combination:

$ sudo unhide -m -d sys procall brute reverse

This can take longer and produce more output. It stays read-only with respect to processes: the manual says the kill test does not actually kill a process. That does not make the command harmless in every operational sense, so avoid running it during a latency-sensitive incident unless you have accepted the extra load.

6. Interpret warnings on current Linux

The installed manual warns that the sysinfo test can report false positives on Linux kernels newer than 2.6.33. Scheduler optimisation, cgroups and systemd can all contribute, and PREEMPT-RT can amplify the problem. A report involving the system-count comparison needs corroboration from another test and from host logs.

Use verbose output when you need the warning messages:

$ sudo unhide -v sys proc

You can repeat -v. -H adds ending messages and tells you when no hidden process is found. -u makes stdout writes unbuffered, useful when another program is consuming the output. These options change presentation, not the underlying evidence.

7. Keep logging separate from the evidence directory

The Linux options include -f, which writes unhide-linux.log in the current directory. Check the directory before using it:

$ pwd
/path/to/forensic-work
$ test ! -e unhide-linux.log && echo 'log destination is unused'
log destination is unused
$ sudo unhide -f quick

Choose a dedicated, access-controlled directory and preserve the resulting log with the rest of your evidence. Do not run -f from a shared directory or blindly overwrite an existing log; if you need to discard a test log, follow your evidence-handling policy rather than deleting it as an afterthought.

8. Know what the aliases mean

unhide-posix accepts only proc or sys and targets generic Unix systems and older Linux releases; the manual marks the Linux-only options unavailable there. unhide_rb is the C backport of the Ruby-style check, a different implementation rather than another spelling of every Linux test. Prefer the installed unhide link, or call unhide-linux explicitly, when examining a Linux 2.6-or-newer host.

There is nothing to undo in the commands above: they inspect process views and optionally write a log. They do not unload modules, edit services, remove files or terminate processes. If you ran with -f, retain or handle only that log according to your evidence policy.

Done means