提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
进程隐藏的应用
进程隐藏,也就在用户不知情的情况下,悄悄执行自己的代码。是病毒、木马等恶意软件能不被发现的重要技术。因此了解进程隐藏的技术就可以在防治病毒的方面起到积极的作用,提高电脑的安全性。
我采用的是Ubuntu15.0.0,linux内核是5.4.0。网上有很多安装方法,要是不会的话可以私信问我。
Strace命令常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
在linux终端输入strace ps 命令(以ps命令为例,top命令操作一样):
可以发现ps的命令是通过readdir函数来访问/proc/pid(进程号id)的状态来显示所有的进程号。既然如此,那我们可以通过cat /proc/pid/stat 的方式来查看一下想查看的进程信息:
想了解具体参数信息的可以自己去CSDN查一下这里就不多说了。
首先进入内核源码(我的版本:/usr/src/linux-source-5.4.0),在PCB增加一个hide字段,用来表示是否要隐藏进程(1表示隐藏,0表示不隐藏),在相关联的函数增加一个判断条件,若是hide字段为1就不做将信息复制到/proc目录下的操作,在fork函数添加一个hide初始化内容,之后添加两个系统调用,用来实现将进程隐藏和显示。
1、在include/linux/sched.h的系统代码中,寻找到task_struct结构体(具体位置会根据使用的系统内核版本不同而有所变化),找到task_struct结构体后,在结构体中找到randomized_struct_fields_end字段。这个字段是linux内核源码提供给用户自定义变量的地方。其余地方是内核代码固定好的不能随便放。
2、修改fs/proc/base.c文件,找到里面proc_pid_readdir() 函数,找到对应的for循环,这个for循环的作用是根据系统内进程动态添加子进程号目录,我们要做的就是在这个循环里增加一个判断当hide字段为0,即不隐藏的状态下是才进行添加操作,否则不进行添加操作。
3、在kernel/fork.c文件中,在task_struct *copy_proccess函数里,在p=dup_task_struct(current,node)字段之下,增加对hide字段的初始化。
4、在kernel/sys.c文件中,添加两个系统调用sys_hide和sys_unhide,这两个系统调用的作用就是将hide字段置为0或者1。(隐藏时为0,不隐藏时为1)。只要将两个系统调用添加在sys.c文件的最底端就可以。
代码如下:
asmlinkage long sys_hide(void)
{
current->hide=1;
return 0;
}
asmlinkage long sys_unhide(void)
{
current->hide=0;
return 0;
}
5、在include/uapi/asm-generic/unistd.h文件中,找到__NR_syscalls字段,在其之上添加所需要的系统调用号(sys_hide为436,sys_unhide为437),并且修改系统调用号的总数(系统调用总数+2,例如此时我的系统调用为436,要修改成438)。
添加内容如下:
#define __NR_hide 436
__SYSCALL(__NR_hide,sys_hide)
#define __NR_unhide 437
__SYSCALL(__NR_unhide,sys_unhide)
//切记一定将低下系统调用总数+2
6、在include/linux/syscalls.h文件中,找到kernel/sys.c字段,声明刚才添加的两个系统调用函数(sys_hide和sys_unhide)
添加内容如下:
asmlinkage long sys_hide(); //my system call
asmlinkage long sys_unhide(); //my system call
7、在系统调用表arch/x86/entry/syscalls/syscall_64.tbl中,在系统调用号为436和437(前面定义的系统调用号)的位置添加对应项
添加内容如下:
436 64 hide sys_hide
437 64 unhide sys_unhide
8、至此所有东西都已经配置好了。开始重新编译内核、重启虚拟机。步骤如下:
sudo make gconfig
sudo make clean
sudo make -j4 //编译内核,可以去打几把游戏,挺久的
sudo make modules_install //安装内核模块
sudo make install //安装内核
reboot //重启
在用户目录下创建一个hide.c文件。
代码如下:
#include
#include
#include
#define __NR_hide 436
#define __NR_unhide 437
int main()
{
printf("Before hide:\n");
system("ps");
syscall(__NR_hide);//调用系统号为436的系统调用
printf("After hide:\n");
system("ps");
syscall(__NR_unhide);
printf("After unhide:\n");
system("ps");
return 0;
}
之后gcc编译.c文件,并运行
编译命令:gcc hide.c -o hide,执行命令:./hide
其实我介绍的隐藏进程的方法比较简单,最折磨人的还是编译内核的各种报错,每次都得等好几个小时,网上还有许多其他隐藏进程的方法,例如在用户态下劫持readdir()函数,让他无法读取/proc/pid的目录、在内核态下直接修改系统自带的proc_pid_lookup函数实现进程隐藏等等。其实万变不离其宗,只要理解了ps的原理,怎么实现看的是个人的理解和能力。
最后,这是我发布的第一篇博客,有逻辑问题的地方希望各位看官多担待!
放一些我参考的内容:(要是不会的可以跟着这几篇走)
安装编译内核:内核编译最新教程+常见问题总结
实现隐藏进程的其余方法:(十分详细,这个博主写的非常好,哪怕不去实现去看看也好。)(渗透测试后期)Linux进程隐藏详解