[HN Gopher] Hiding Linux Processes with Bind Mounts
___________________________________________________________________
Hiding Linux Processes with Bind Mounts
Author : indigodaddy
Score : 63 points
Date : 2024-07-24 15:52 UTC (7 hours ago)
(HTM) web link (righteousit.com)
(TXT) w3m dump (righteousit.com)
| awaythrow999 wrote:
| Interesting but
|
| >> My guess is that nobody is going to notice this unless they
| are specifically looking for this technique.
|
| But having two identical PIDs is a pretty weak cloak. Even more
| so when reducing terminal clutter e.g. run "ps | grep procname"
| ... anyone not completely asleep is bound to notice it.
| o11c wrote:
| If you're relying on such superficial disguising, just put your
| process name in brackets directly, no mount privileges required.
|
| As a general rule, if malware gets root privilege, no other
| process on the same system (container, at least) should be
| expected to be able to detect it.
| breakingcups wrote:
| It rather involved being on the other side of this airtight
| hatchway:
| https://devblogs.microsoft.com/oldnewthing/20060508-22/?p=31...
| tanelpoder wrote:
| This would help against basic ps commands but if your security
| tool reads the task's PF_ flags (from /proc/PID/stat or kernel
| memory), you'd still see that your [task] is not an actual
| kernel task... (the PF_KTHREAD flag is 0x200000):
| $ ln -s /bin/sleep '[kernelstuff]' $ ./\[kernelstuff\]
| 999 & [2] 29499 $ awk '{ printf("%x\n", $9)
| }' /proc/29499/stat 40400000 $ pgrep
| kthreadd 2 $ awk '{ printf("%x\n", $9) }'
| /proc/2/stat 208040
|
| Edit: as you said, it's superficial disguising (that may even
| work in some cases)
| bpoyner wrote:
| I'm so old I remember when ps would directly get the processes
| via system calls to the kernel and none of this reading from
| /proc.
| deepsun wrote:
| To me it actually sounds like a better approach than blindly
| following "everything is a file" mantra.
| kjeetgill wrote:
| I'm totally with you for processes should probably use
| glibc/platform API calls, but procfs is nothing short of
| brilliant and a great validation of the power of the
| "everything is a file".
| yjftsjthsd-h wrote:
| What's blind about it? Reading files is nicer than parsing ps
| output or needing to write native code over a syscall.
| jcranmer wrote:
| Trying to parse the output of several procfs files isn't as
| easy as it looks. The per-pid maps file for one (smaps is
| even worse). Much better if I could just get a struct with
| all this information.
| 0xedd wrote:
| Asking DevOps to program for basic tasks. Cool story,
| bro.
| metadat wrote:
| Is this still possible in Linux? Or were the aforementioned
| syscalls removed?
| kmeisthax wrote:
| Linux never removes syscalls.
| LegionMammal978 wrote:
| Though it does stop implementing obsolete syscalls on newer
| architectures. So the set of syscalls you can effectively
| use often rotates as the hardware treadmill turns.
| upon_drumhead wrote:
| Are you sure? I know BSDs use kvm_getprocs, but I don't know
| what the comparable sys call would have been on Linux.
|
| FWIW, /proc was added in Linux v0.97.3, September 1992, which
| is early enough I couldn't find ps source for linux earlier
| then that date.
| yjftsjthsd-h wrote:
| The post you're replying to didn't say "on Linux" - IIRC,
| _unix_ ps worked by reading /dev/kmem or so
|
| Edit: My mistake, it was /dev/mem - https://github.com/lsahn-
| gh/unix-v6/blob/master/source/s2/ps...
| upon_drumhead wrote:
| Agh, completely fair. The topic was about Linux and I
| incorrectly presumed that the original comment was made in
| the same context. My mistake.
| rwmj wrote:
| The original 'ps' got the data by reading kernel memory
| directly (/dev/kmem or /dev/mem), and I'm old enough to
| remember systems doing that. I don't think there were any Unix-
| derivatives that used system calls? Minix is closest, in that
| you could query the 'mm' task using RPCs which are sort of
| system calls.
| efitz wrote:
| The abstraction of representing everything as files is often
| leaky (and often clunky).
| jordemort wrote:
| If you have the privilege to pull off bind-mounting on top of a
| particular process directory in /proc you should also be able to
| mount something on top of /proc itself that will present a false
| /proc/mounts and conceal your trickery. I experimented a bit and
| wasn't able to bind a single file on top of /proc/mounts and I
| seem to be having trouble getting procfs to participate in an
| overlayfs, but if you were really dedicated you could construct a
| whole fake /proc by hand, or create something using FUSE to
| create a /proc that redacts anything you want, including
| mountpoints.
| indigodaddy wrote:
| Interesting. Could you not perhaps tank the system attempting
| something like that?
| yjftsjthsd-h wrote:
| How? I don't think the kernel cares what the directory looks
| like - userspace will break in funny ways, but you can boot
| without procfs even mounted (well, I say boot, but more like
| "you can start a shell and some things will still work")
| jordemort wrote:
| Oh yes, very easily, although you'd be surprised at how much
| works without a functional /proc.
| eptcyka wrote:
| Can you do similar trickery to ensure `mount` doesn't list your
| bind mount?
| duskwuff wrote:
| I don't see why not - that's just reading from /proc/mounts.
| dredmorbius wrote:
| Nitpicking: _mount_ reads from /proc/ _self_ /mounts, that
| is, the mounts as seen _from that process_. This is how
| tricks such as chroot jails work, as they present a
| different mount set and filesystem tree from the base
| system.
| compsciphd wrote:
| creating a whole fake proc is simple. I mean the code is
| already in the kernel as a module. Just copy it, put a few
| if/else's in the code to control what its readdir ( this case
| just pid's there's proc_readdir() that calls
| proc_pid_readdir(), just modify that very simply).
|
| mount is a bit harder (as its calls into code that is more in
| the core kernel fs code, but one can just reimplement it
| oneself, to filter out the mounts you don't want to show.
| jasonjayr wrote:
| If you have root of course, you can do anything, BUT -- could a
| eBPF module be loaded into the kernel to just filter the
| syscalls to hide some nefarious process? This simplifies the
| 'evil VM' attack. Does eBPF have anything that could plausably
| help with that?
| tatref wrote:
| https://sysdig.com/blog/ebpf-offensive-capabilities/
___________________________________________________________________
(page generated 2024-07-24 23:02 UTC)