Linux process hiding
TL;DR
Prevent specific files on procfs from being read using ld preload.
Principle
Tools such as ps
and lsof
primarily use procfs to obtain information about processes.
If one wants to know about a process with a certain PID, reading files under /proc/
is the way to go.
Conversely, if you don’t want information about a process with a certain PID to be known, you just need to prevent the reading of files under /proc/
.
Implementation
Prepare a custom readdir(64)
and use it in combination with LD_PRELOAD
.
For this case, open
is left as is (to avoid complications).
If the file name matches the target process such as /proc/PID/cmdline
or /proc/PID/stat
, the dirent
should simply be skipped.
Such a library can also be created in Rust. You can use a crate called redhook.
It was not maintained before, so I forked it, but it seems the original has also been corrected.
An actual implementation is as follows:
prochide
hook! {
unsafe fn readdir(dirp: *mut DIR) -> *mut dirent => hide_readdir {
loop {
let d = real!(readdir)(dirp);
if !d.is_null() {
let name = String::from_utf8(Vec::from((*d).d_name).iter().map(|c| *c as u8).collect());
if let Err(_) = name { continue }
let name = name.unwrap();
if name.starts_with("/proc") && check_process(name) {
continue
}
}
return d;
}
}
}
Hooks can be created very simply.
The real!
macro is also used to call actual library functions.
demo
$ cmatrix &
$ ps | grep cmatrix
1156946 pts/33 00:00:00 cmatrix
[1] + Stopped (tty output) cmatrix
$ LD_PRELOAD=./libprochide.so ps | grep cmatrix
$
Furthermore
This method can also be used by malware, and as introduced in a previous article, malware persistently uses this type of library with /etc/ld.so.preload
.
Make sure to monitor such system-wide affecting files.
Conclusion
This article is the 8th day’s post of the n01e0 Advent Calendar 2023.
Not sure if there will be a post tomorrow.
This also serves as the 8th day’s post of the IPFactory OB Advent Calendar 2023.
Comments