- Linux: скрываем процессы от других пользователей
- Познакомимся с опцией hidepid
- Защита ядра Linux: скрываем процессы от других пользователей
- Пример
- Подсказка: что делать с программами, которые падают при включении защиты.
- Linux hide processes from other users and ps command
- Linux hide processes from other users using hidepid option
- Get the list of current processes on Linux
- Linux kernel protection: Hiding processes from other users
- Hiding Linux processes for fun + profit
- Introduction
- The Baseline Behavior
- How ps works
- Hiding the process
- Sysdig
- Final notes
Linux: скрываем процессы от других пользователей
Я работаю в многопользовательской системе. Большинство пользователей получают доступ к своим ресурсам с помощью ssh-клиента. Как я могу при этом предотвратить утечку информации, которая происходит из-за того, что все пользователи могут видеть все запущенные в системе процессы, даже если они им не принадлежат?
Если вы используете ядро версии 3.2+ (или RHEL/CentOS версии v6.5+), вы можете скрывать процессы от других пользователей. Только root может видеть все процессы, а каждый пользователь может видеть только свои процессы. Все это можно сделать, если перемонтировать файловую систему /proc с опцией ядра «hidepid».
Познакомимся с опцией hidepid
Эта опция определяет объем информации о процессах, который мы хотим сделать доступным для других пользователей. Она может иметь следующие значения:
1. hidepid=0 — любой пользователь может читать все файлы в /proc/PID/* (значение по умолчанию).
2. hidepid=1 — пользователи имеют доступ только к своим собственным директориям в /proc/. Важные файлы, такие как cmdline, sched*, не защищены от других пользователей.
3. hidepid=2 — это значит hidepid=1 плюс все файлы в /proc/PID/ невидимы для других пользователей. Это усложняет возможность проникновения в систему или сбор информации о запущенных процессах — работают ли какие-то демоны с повышенными привилегиями, запустил ли другой пользователь важную программу и так далее.
Защита ядра Linux: скрываем процессы от других пользователей
Введите следующую команду:
Отредактируйте файл /etc/fstab:
Измените строку для proc, как показано ниже, чтобы защита включалась автоматически при загрузке системы:
Сохраните и закройте файл.
Пример
В этом примере я авторизуюсь как vivek@cbz-test:
Пример вывода (просмотрите до конца этот демо-ролик):
Подсказка: что делать с программами, которые падают при включении защиты.
Вам необходимо использовать опцию gid=VALUE_HERE:
gid=XXX определяет группу, которая будет в состоянии собирать всю информацию о процессах (как при hidepid=0). Эта группа должна использоваться вместо помещения обычного пользователя в файл sudoers. Однако ненадежные пользователи (демоны и т.п.), для которых нет оснований, что они должны мониторить задачи во всей системе, не должны добавляться в эту группу.
Поэтому добавьте пользователя по имени monapp в группу (например admin), которой вы хотите дать доступ к информации о процессах, и отредактируйте fstab:
Источник
Linux hide processes from other users and ps command
I run a multi-user system. Most users access resources using SSH client. How can I stop leaking process information to all users on Linux operating systems? How do I prevent users from seeing processes that do not belong to them on a Debian/Ubuntu/RHEL/CentOS Linux server? Is there any way to hide other users process when running ps command?
If you are using Linux kernel version 3.2+ (or RHEL/CentOS v6.5+ above) you can hide process from other users. Only root can see all process and user only see their own process. All you have to do is remount the /proc filesystem with the Linux kernel hardening hidepid option. This hides process from all other commands such as ps, top, htop, pgrep and more.
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | Yes |
Requirements | Linux kernel v3.2+ |
Est. reading time | 3 minutes |
Linux hide processes from other users using hidepid option
This option defines how much info about processes we want to be available for non-owners. The values are as follows:
- hidepid=0 – The old behavior – anybody may read all world-readable /proc/PID/* files (default).
- hidepid=1 – It means users may not access any /proc/
/ directories, but their own. Sensitive files like cmdline, sched*, status are now protected against other users.
Get the list of current processes on Linux
The ps command displaying the root user process and I am logged in as a regular user
Linux kernel protection: Hiding processes from other users
Type the following mount command:
# mount -o remount,rw,nosuid,nodev,noexec,relatime,hidepid=2 /proc
Edit /etc/fstab using a text editor such as nano command/vim command, enter:
# vi /etc/fstab
Update/append/modify proc entry as follows so that protection get enabled automatically at server boot-time:
Источник
Hiding Linux processes for fun + profit
Introduction
The other day I was looking at the output of top on my machine, and I wondered: how hard would it be to hide specific processes and/or network connections from traditional monitoring tools like ps , top , lsof , …? I decided to kill a couple hours and try to hack together a solution. In this post, I’ll show you some of the answers I came up with, and some proof of concept code to implement this. I’ll also show that sysdig is not susceptible to my hack, and explain why.
The goal that I want to achieve is to deliberately hide a simple and malicious Python script (I’ll call it evil_script.py ) that does some damage to my system, saturating CPU and network by sending UDP packets towards a poor victim:
The Baseline Behavior
I’ll start by running this:
If you run it, you’ll see it will quickly saturate your system resources. Perfect use case for starting the analysis. Let’s confirm that the process is there and eating my CPU, using ps :
Yep. I can also look at the network connections opened by the process by using lsof :
So the process is there, doing network activity. If I want to hide this information, the first thing I have to do is understand how ps and similar tools can actually extract the information about my process.
How ps works
Tools like ps leverage the /proc file system, a Linux construct that we explained at a high level in a previous post. Let’s dig into the details now using sysdig :
This perfectly highlights how ps works: first, the directory /proc is opened via the openat() system call. Then, the process calls getdents() on the opened directory, which is a system call that returns the list of files/directories contained in a specific directory ( /proc in this case). If you’ve ever run ls /proc , you noticed that there is a subdirectory for every running process in the system, and each directory is named after the PID of the process itself. So, ps will just grab the list from getdents() , and then iterate over a fixed set of files in each subdirectory. These files, as you can see from the event list, are named /proc/PID/status , /proc/PID/stat , and /proc/PID/cmdline , and contain all the information that ps shows in the output.
It’s worth noticing (as it will be useful in the next section), that the process itself doesn’t directly call openat() and getdents() , as those are system calls that are abstracted by the C standard library ( libc ). If you ever cared to read the libc documentation, libc provides two different functions, opendir() and readdir() , and they take care of calling the system calls themselves, providing a somewhat simpler API to the developer. So these last ones are the functions that are directly called from ps .
Hiding the process
After this quick digression on how ps works, it seems fairly obvious that if we want to hide our process, we need a way to prevent these tools from accessing the proper files under /proc/PID/ . What are the options? There are various methods worth mentioning:
- Using a proper framework: there are a bunch of very good frameworks, like SELinux and Grsecurity that do, among other things, exactly this. In a production system, I would absolutely consider these, although today I want to get my hands dirty and have fun creating something from scratch.
- Modify top/ps/… binaries: I could grab the source code of each of these tools, implement my own “hiding linux processes” logic, recompile, and replace the binaries. Very inefficient and time consuming.
- Modify libc : I could modify the readdir() function inside libc and input the code to exclude the access to some /proc files. But recompiling libc is a burden, not to mention the libc code tends to be very hard to understand.
- Modify the system calls in the kernel: This is the most advanced, and it would work by intercepting and modifying the getdents() system call directly in the kernel with a custom module. It’s definitely tempting, but I won’t follow this route today because I’m already very familiar with how the system call interception works in sysdig, so I want to do something new.
I decided to go for an intermediate solution, one that is interesting and simple enough to implement in an hour or so: it’s a variant of “modifying libc ” based on a tricky feature offered by the Linux dynamic linker (the component that takes care of loading the various libraries needed by a program at runtime), called preloading.
With preloading, Linux is kind enough to give us the option to load a custom shared library before the other normal system libraries are loaded. This means that, if the custom library exports a function with the same signature of one found in a system library, we are literally able to override it with the custom code in our library, and all the processes will automatically pick our custom one!
This sounds like a solution to my problem, because I could write a very simple custom library that overrides libc ’s readdir() , and write the logic to hide the process! The logic would be fairly straightforward too: every time I see that the /proc/PID directory (where PID is the PID of the process having the name “evil_script”) is being read, I just block that access in a clean way, thus hiding the entire directory! I went ahead and implemented these thoughts in code. You can get the sources at https://github.com/gianlucaborello/libprocesshider/blob/master/processhider.c (it’s actually less than 100 lines of code including comments, so go read it!). Once the code is written, let’s compile it as a shared library, and install it in the system path:
Now, I just need to tell the dynamic linker to actually use it. I want to install it system-wide, so that every new process in the system can pick this up automatically. This is done by simply writing my library path into a configuration file:
Done! From this moment on, every new binary that I’ll launch will execute my custom code when iterating through directories via readdir() . So let’s go back and try this executing ps and lsof while the evil script is running:
It works! My process is now running in invisible mode, even when the tools are run as root. I also repeated this with pstree , top and htop , and none of them were able to show my process anymore.
This is just a simple example, but we could also spoof more information, for example:
- Modify the global CPU usage counters: /proc/stat contains those statistics, so I could intercept all the read operations to that file and return a custom one, faking a 0% global CPU usage.
- Modify the connection list: for example, netstat uses the /proc/net/tcp file to get the list of TCP connections. Just intercept the reads to the file and hide a specific connection.
Good exercises for the reader 🙂
Note that this method won’t work if the binaries are statically linked against libc . I’ve seen some niche distributions extremely focused on security, where all the binaries dependencies are statically linked. This has the huge disadvantage that the binaries tend to get pretty big, and shipping an update for a library forces shipping new binaries of every program that depends on it, so usually it’s not done for mainstream distributions.
4 different ways of hiding a #Linux process
Sysdig
Let’s see if sysdig can be tricked as well, starting by CPU usage:
And network activity:
With sysdig, we’re still able to see it all! This is because sysdig doesn’t necessarily rely on /proc to look for system activity (although it uses it if available). Sysdig inspects every system call, and in this data the malicious process is still clearly visible, along with all its used resources. Hiding system calls is a much more challenging task that can’t be done in a couple hours. In fact, sysdig can see everything:
As a bonus, sysdig is also showing me that the dynamic linker is loading my custom library before libc . This is what happens when ps executes after the preload change:
/usr/local/lib/libprocesshider.so is automatically loaded (with open() and read() ) before /lib/x86_64-linux-gnu/libc.so.6 , without having to change the ps code or the libc code.
In theory, I could have used strace/ltrace to attach to the process and see what it was doing in a similar way, but if you remember I completely hid the malicious process PID from /proc , so how would we find it? Those tools require the exact PID to attach in order to work. I could have brute-forced the entire PID range, but that doesn’t seem like a very attractive alternative. Also, those tools just provide a flat list of events, whereas sysdig, with chisels, can aggregate the events and show me exactly what I care about (in this case CPU/network consumption).
Final notes
As one last consideration, it’s worth clarifying that although it might be possible to get your machine compromised in this exact way (I know there are rootkits out there who rely on this easy and effective method), that is certainly not the point of this post. I just enjoyed it as a thought experiment, and hopefully this demonstrates a simple and powerful method that can be used by application developers to solve real problems in certain circumstances. I think this also proves that monitoring the system usage can be done from different perspectives, and getting data from system calls can be as good as extracting it from the /proc file system. And at the end of the day, I think we’re all very lucky to have Linux and the /proc file system with its useful metrics exported in plain-text files, ready to be read and inspected without any custom tools!
As always, we’d love to hear from you. If you have any thoughts or questions, please let us know in the comments or on @sysdig. Thanks!
Источник