Index
1.原理
在Linux下,一切皆文件。所有的进程信息,都存放在/proc/目录下,每一个pid一个目录。一般来说,遍历检查进程的方法,就是遍历检查/proc目录,检查所有名称是数字的子目录,检查其中的status等文件的内容,可以获得进程的相关信息:命令行、运行状态、程序路径、父进程pid等等。
那么,如何进行进程隐藏呢?
让别的进程看不到“/proc/[需要隐藏的进程pid]”这个目录就可以了。
2.目前比较常见的Linux进程隐藏方法
1.1.注入preload挂钩readdir
制作一个libxxx.so文件,在里面仿照系统接口制作一个readdir函数,然后修改系统的配置/etc/ld.so.preload,将这个libxxx.so文件的绝对路径配置上去。
这样,所有动态编译的程序在启动时,会优先加载这个libxxx.so库文件,然后再加载libc相关的so,这样一来,先入为主,libxxx.so中的readdir就顶替了libc中的readdir。
在我们仿冒的readdir中,调用libc的readdir获取结果并进行过滤,把需要隐藏的pid目录过滤掉然后返回。这样一来,ps/ls/top等系统命令都无法发现隐藏的进程了。
缺点:
- 需要修改系统配置/etc/ld.so.preload,比较容易被发现。
- 对静态编译的程序无效。
- 全局挂钩,稳定性需要考虑好。
1.2.直接替换ls/ps等系统程序
这个方法更直接,直接把ls/ps等直接替换掉,想给调用者显示什么就显示什么,就是这么任性。
缺点:
- 替换系统程序很敏感,很容易被发现。
3.fanotify是什么?
关于fanotify的写得很全面的介绍:fanotify 监控文件系统
fanotify在Linux内核2.6.37引入,相对inotify来说,其最大的特点是可以对文件的OPEN/ACCESS操作进行审核,换句话说:任何进程尝试打开/访问你关注的文件,你可以获得通知,并且知道是哪个进程在做这个事,然后你可以选择放行或者拒绝。
这个听起来很牛的功能,按照一些文章的介绍,是发明者给杀毒软件留下的好东东,在用户尝试打开某个文件时,杀软先收到通知,进行检查,然后做出动作。(和Windows下的杀软行为也确实很像)。
4.使用fanotify进行进程隐藏
结合第1节和第3节,相信已经有人猜出来我们要干什么了。
没错,我们要用fanotify来监控“/proc/[需要隐藏的进程pid]”这个目录,针对其下的所有访问,不是授权进程统统拒绝。
先来看看测试程序的效果:
编译和运行:
示例程序stealth.cpp编译为可执行程序stealth,他启动后,会打印自己的pid,然后使用fanotify对/proc/下自己的目录进行监视,拒绝所有访问请求。
从上图中可以看出stealth进程的pid是2596。
下面我们来进行测试:
可以看到ps/lsof都无法发现这个进程,我们列取/proc目录,可以看到有2596这个目录,但是尝试列取其中的内容或尝试查看其中的文件内容,皆提示:Operation not permitted。
最后,上代码:
#include <stdio.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/fanotify.h>
//#include "fanotify-syscalllib.h"
//#include "fanotify.h"
static int _fafd = 0;
static bool _working = true;
static bool _thread_created = false;
static pthread_t _reader_thread;
static void fanotify_callback(struct fanotify_event_metadata* metadata)
{
if ((FAN_OPEN_PERM & metadata->mask) != 0 || (FAN_ACCESS_PERM & metadata->mask) != 0)
{
bool allow = true;
do
{
if