The 'Invisibility Cloak' – Slash-Proc Magic
dfir.ch
dfir.ch
Like, my first impulse is "Why do we allow this?" And I guess, sure, the answer is "root is allowed to do this, because root is never not allowed". And sure I very much dislike my computer telling me "Nay I cannot do that", hence why I have no windows anymore at home.
But there is some stuff that seemingly doesn't have any legitimate use case on a server. And even if protections from that stuff keep me from fixing some situations, I can still nuke and rebuild it in an hour or so.
Only some parts of proc are "read only." /proc/sys is filled with writable controls.
> my first impulse is "Why do we allow this?"
The user is allowed to do whatever they like with their machine. It's the reason I use linux. It never puts me in a position where "system policies" or other default "security theater" nonsense disadvantages me on my own hardware.
If you're that concerned you can easily add a policy framework, like SELinux, or others, which would prevent this from happening or raise an exception if it does.
> that seemingly doesn't have any legitimate use case on a server.
There are dozens of other ways to achieve this same effect that rely on mechanisms that have legitimate use cases. In particular if you are root you will not struggle to find ways to hide processes. In this case you can just observe "/proc/mounts" to see that something perfidious is occurring.
> I can still nuke and rebuild it in an hour or so.
As long as there is no important data at rest within the server. This isn't always the case.
—
ProcSubset=
Takes one of "all" (the default) and "pid". If "pid", all files and directories not directly associated with process management and introspection are made invisible in the /proc/ file system configured for the unit's processes. This controls the "subset=" mount option of the "procfs" instance for the unit. For further details see The /proc Filesystem². Note that Linux exposes various kernel APIs via /proc/, which are made unavailable with this setting. Since these APIs are used frequently this option is useful only in a few, specific cases, and is not suitable for most non-trivial programs.
2. The /proc Filesystem: <https://docs.kernel.org/filesystems/proc.html#mount-options>
Because, the amount of different contexts linux is being used in, and the different threat levels are vastly different.
For example, I'm aware that the industrial and embedded world does wild things at times. Because it's hard to establish redundancy and replacability there. Because the system is attached to a $750k lathe. However, that thing is not networked, and physical access is controlled by people with guns. Do whatever you need to keep this thing running, as horrid as it may be.
On the other hand, I have a fleet of loadbalancers and their job is to accept traffic from all criminals in this world, and then some legitimate users as well. I can reset them to base linux and have them back operational in 10 minutes or so. Things modifying loaded code in memory outside of some very specific situations like service startup on these systems is terrifying and entirely not necessary.
So I would be very happy with a switch to turn that off, even though some other use cases wouldn't need it or wouldn't be able to use it at all.
One can imagine having a special code which checks for mounts for /proc, but this turns ugly pretty quick. Disallow all mounts on /proc? Not going to work, the PC I am typing the comment on has a mount at /proc/sys/fs/binfmt_misc. Maybe just disallow bind mounts only? This breaks "create chroot/container and bind-mount host fs" use case, plus attacker can mount tmpfs anyway.
You have to design some sort of rules for where mounting is allowed and where not, and then ensure they are correct and up-to-date. This is a non-trivial amount of work -- and for what? A method which is super obvious to detect (mount table entries!) and can only fool the beginner defenders?
Instead, Linux provides generic "LSM" hook mechanism that can restrict any operations, including mounts. If someone thinks such mount restrictions are a good idea, they are welcome to write kmod (kernel module) to do so, or configure one of the existing ones to reject those operations. But I expect that by the time people get knowledgeable enough to write kmods, they are knowledgeable enough to come up with a better protection against rogue root user.
Personally, my stance is to just blindly trust whatever /proc tells you, except in really unusual security models. Users can only end up hurting themselves by putting nonsensical things in there. (The same way no one should bother checking that /dev/null isn't a regular file, even though root can easily make it one.)
Concealing Namespaces Within a File Descriptor | https://tmpout.sh/3/06.html
Instead, you can do something like "cat /proc/$$/mounts" - that will check the mounts file directly, from location like /proc/14102/mounts. That location is much harder to bind-mount over, as there are many processes and process IDs are hard to predict.
That said, to bind-mount, malware must have a root; and if malware has a root, it can do much better than playing silly tricks with bind-mounting over /proc - it can load a kernel rootkit to hide itself very effectively. That's why all investigation of potentially compromised machines must be done from known-clean OS.
Unfortunately, yes. 'bind' allows mount to bind over individual files and not just directories. Which is a little bit insane.
In any case, if you are suspicious, 'umount /proc/mounts'. It either returns ok or it returns "umount: /proc/mounts: not mounted."