Linux 下如何隐藏自己不被发现?

可能在某些情况下,自己运行的程序不想或者不方便被其他人看到,就需要隐藏运行的进程。或者某些攻击者采用了本文介绍的隐藏技术,也可以让大家看到如何进行对抗。

隐藏有两种方法:

  1. kernel 层面,不对用户层暴露该进程的信息,进程不被看见;
  2. 用户层可以看到该进程信息,但不是以真实的身份出现,而是伪造成别的程序出现,达到隐藏自己的目的。

方法一是需要修改内核,本文主要是讲第二种方法。

常用获取进程信息工具

在 Linux 环境下,主要是通过 top、ps 等工具来查看当前运行的进程,他们主要是通过读取 /proc/ 文件系统来获取进程信息,读取哪些内容,我们可以通过 strace (该工具用于监控系统调用和信号) 工具查看,我们以 296277 进程为例。

top 获取进程信息

296277 进程信息

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 296277 wangshu+  20   0    2272   1380   1300 S   0.0   0.0   0:00.00 bash

top 查看到 296277 进程的信息,我们一般主要关心的是最后一列,进程名。

strace 跟踪结果

stat("/proc/296277", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
openat(AT_FDCWD, "/proc/296277/stat", O_RDONLY) = 9
read(9, "296277 (bash) S 296271 296271 23"..., 1024) = 322
close(9)                                = 0
openat(AT_FDCWD, "/proc/296277/statm", O_RDONLY) = 9
read(9, "568 355 335 2 0 78 0\n", 1024) = 21
close(9)

从上面可以看到,主要是读取了 /proc/296277/stat 和 /proc/296277/statm 文件。

  • /proc/296277/stat 内容
296277 (bash) S 296271 296271 230491 34840 296271 4194304 94 155 0 0 0 0 0 0 20 0 1 0 94413592 2326528 345 18446744073709551615 94055941185536 94055941191257 140723269084624 0 0 0 0 4096 0 0 0 0 17 11 0 0 0 0 0 94055941201384 94055941202080 94055956852736 140723269087783 140723269087820 140723269087820 140723269091283 0
  • /proc/296277/statm 内容
568 345 325 2 0 78 0

可以看到 top 中的进程名是使用 /proc/296277/stat 中的第二项 (bash)。

ps -aux 获取进程信息

296277 进程信息

wangshu+  296277  0.0  0.0   2272  1380 pts/24   S+   18:59   0:00 /bin/bash

ps -aux 查看到 296277 进程的信息,最后一列是 bash 的完整路径名。

strace 跟踪结果

stat("/proc/296277", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
openat(AT_FDCWD, "/proc/296277/stat", O_RDONLY) = 6
read(6, "296277 (bash) S 296271 296271 23"..., 2048) = 322
close(6)                                = 0
openat(AT_FDCWD, "/proc/296277/status", O_RDONLY) = 6
read(6, "Name:\tbash\nUmask:\t0022\nState:\tS "..., 2048) = 1095
close(6)                                = 0
openat(AT_FDCWD, "/proc/296277/cmdline", O_RDONLY) = 6
read(6, "/bin/bash\0", 131072)          = 10
read(6, "", 131035)                     = 0
close(6)                                = 0
stat("/dev/pts24", 0x7ffe4ce31630)      = -1 ENOENT (No such file or directory)
stat("/dev/pts/24", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x18), ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=545, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=545, ...}) = 0
write(1, "wangshu+  296277  0.0  0.0   227"..., 104) = 104

从上面可以看到,主要是读取了 /proc/296277/stat、/proc/296277/status 和 /proc/296277/cmdline。

  • /proc/296277/cmdline 内容
/bin/bash

ps -aux 中进程名可以看到是从 /proc/296277/cmdline 读取到的。

上面列出来proc信息,可以从proc文件内容介绍获取更详细的介绍。

小结

从上面实验中可以看到,进程名主要是通过 /proc/进程号/stat 和 /proc/进程号/cmdline 文件中获取。

隐藏技术实现

/proc/进程号/stat 和 /proc/进程号/cmdline 这些接口都是内核实现的,通过阅读内核代码得到:

  • /proc/进程号/stat 中的进程名对应的可执行文件的文件名;
  • /proc/进程号/cmdline 内容对应的是启动该进程的使用的路径,对应的是入口函数 main(int argc, char *argv[]) 中的 argv[0]。

为了实现隐藏,我们将伪造为 bash 进程, bash 进程比较常见,并且一般不会被过多关注。所以需要进行的操作有:

  1. 文件名修改为 bash;
  2. 运行时将 argv[0] 修改成 /bin/bash;
  3. 为了防止从 /proc/进程号/maps 中发现没有包含 /bin/bash,我们将 /bin/bash 文件 mmap 进我们的进程中。

{:.warning}

2中 Android 环境中不能直接拿到argv[0] 怎么办? 在 Unix 环境下,有定义全局变量 __progname_full, 该变量指向了 argv[0],可以直接使用 __progname_full 进行修改,当然在 Linux 下同样适用。

代码示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

extern const char *__progname_full; // 引入该变量

int main(int argc, char **argv)
{
	int pid = getpid();
	printf("current pid: %d\n", pid);
	char buffer[100] = {0};
	char cmdline[100] = {0};
	sprintf(cmdline, "cat /proc/%d/cmdline", pid);
	system(cmdline);
	printf("\n");
	scanf("%s", &buffer);
	printf("%d change the name: %s\n", getpid(), buffer);

	//int size = strlen(__progname_full);      // 使用 __progname_full 进行修改 cmdline
	//printf("name len: %d\n", size);
	//memset((char *)__progname_full, 0, size);
	//strcpy((char *)__progname_full, buffer);

	int size = strlen(argv[0]);   // 使用 argv[0] 进行修改 cmdline
	printf("name len: %d\n", size);
	memset((char *)argv[0], 0, size);
	strcpy((char *)argv[0], buffer);

	int fd = open(buffer, O_RDONLY);     // 打开伪造后的可执行文件, mmap 到我们进程中
	if (fd < 0) {
		printf("not found the file:%s\n", buffer);
		return -1;
	}
	struct stat st;
	fstat(fd, &st);
	void *addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); // 可读 map
	if (addr == MAP_FAILED) {
		printf("mmap failed\n");
	}
	void *addr1 = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); // 读写 map
	if (addr1 == MAP_FAILED) {
		printf("mmap1 failed\n");
	}
	void *addr2 = mmap(NULL, st.st_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0); // 读可执行 map
	if (addr2 == MAP_FAILED) {
		printf("mmap2 failed\n");
	}
	system(cmdline);
	printf("\n");
	scanf("%s", &buffer);
	munmap(addr, st.st_size);
	munmap(addr1, st.st_size);
	munmap(addr2, st.st_size);
	close(fd);

	return 0;
}

执行结果

current pid: 301929  # 当前进程
/home/f/doing/linux/change_name/bash  # 伪造前 cmdline
/bin/bash # 要伪造的可执行文件
301929 change the name: /bin/bash
name len: 36
/bin/bash # 伪造后的 cmdline

工具查看结果

ps -aux 查看

top 查看

可以看到都已经是 bash。

技术对抗

上述隐藏方式可以骗过 ps 和 top 工具,但是只是修改了名字,但可执行文件等信息没有改变,所以从其他信息可以推断出是进程名是伪造的,下面阐述几种方式。

/proc/进程名/exe

在 /proc/进程名/exe 中保存的真正执行的可执行文件,所以可以将该文件和伪造后的 /bin/bash 文件对比,若发现不同可以证明进程名是伪造的,但此时还不能确认真正的可执行文件,只能和文件系统中的其他可执行文件对比进行确认。

/proc/进程名/maps

Linux 中内存的布局是有一定的规律的,如下图,地址从低到高,分别是ELF可执行文件、Data和Bss区域、HEAP、memory map区域、stack等。我们可以根据这些信息来确认真正的可执行文件。

来看下伪造进程的内存布局:

从上面可以看出来,红色框是ELF可执行文件、Data和Bss区域,其实就是进程的真正可执行文件,接着是 HEAP,后面是我们 mmap 伪造的 bash 文件,所以通过 /proc进程名/maps 可以确认出真正的可执行文件为 /home/f/doing/linux/change_name/bash。

小结

上面中 /proc/进程名/exe 能简单判断出进程名是否伪造,但不能确认真正的可执行文件,而通过 /proc/进程名/maps 可以非常直观的看到可执行文件的信息。除了这两种方式外,可能还有其他方法,比如 /proc/进程名/status 中 VmExe 字段,该字段是记录 text 段大小,和显示的可执行文件进行对比,确认是否有伪造。

总结

虽然原理上比较简单,但是提醒我们有这么一种方式,可以简单的骗过我们通过ps和top看到的信息。若发现系统中有异常,也可以通过技术对抗中提到的方式,确认是否有恶意程序存在。

PS

关注公众号,了解更多信息!

原文地址:https://www.cnblogs.com/liwugang/p/12701360.html

时间: 2024-09-29 11:53:08

Linux 下如何隐藏自己不被发现?的相关文章

linux下显示隐藏目录或隐藏文件占用空间大小

du -sh .[!.]* cd .pyenv du -sh * cd versions/ [email protected]:/# cd /data/home/wangting/ [email protected]:/data/home/wangting# du -sh . 5.5G    . [email protected]:/data/home/wangting# du -sh * 4.0K    airflow 548K    conf 4.0K    derby.log 582M  

快速建立linux下的vpn服务器做加密代理

原文出处: http://www.xfocus.net/articles/200610/893.html 创建时间:2006-10-27文章属性:原创文章提交:fatb (fatb_at_security.zz.ha.cn) 作者:baoz日期:2006-10-26http://baoz.nethttp://xsec.org1妹儿:perlish(*)gmail.com or [email protected] (有时gmail收不到信或者会被当垃圾邮件过滤掉)欢迎转载任何人任何时候转载到任何地

Linux下挂载iscsi存储

1. 检查系统是否安装iSCSI initiator [[email protected] ~]# rpm -qa|grep iscsi [[email protected] ~]#  [[email protected] ~]# mount /dev/cdrom /mnt/ mount: block device /dev/sr0 is write-protected, mounting read-only [[email protected] ~]# cd /mnt/ [[email pro

基于Linux下的GCC编译器的内部预宏定义与__attribute__属性

***************************************************************************************************************************** 作者:EasyWave                                                                                    时间:2015.02.20 类别:Linux应用-GCC编

Linux下几种文件传输命令

Linux下几种文件传输命令 sz rz sftp scp 最近在部署系统时接触了一些文件传输命令,分别做一下简单记录: 1.sftp Secure Ftp 是一个基于SSH安全协议的文件传输管理工具.由于它是基于SSH的,会在传输过程中对用户的密码.数据等敏感信息进行加密,因此可以有效的防止用户信息在传输的过程中被窃取,比FTP有更高的安全性.在功能方面与FTP很类似,不仅可以传输文件数据,而且可以进行远程的文件管理(如建立,删除,查看文件列表等操作).Sftp与ftp虽然只有一字之差,但基于

linux下nginx安装、配置实战

1什么是Nginx Nginx("enginex")是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器,在高连接并发的情况下Nginx是Apache服务器不错的替代品.其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好.目前中国大陆使用nginx网站用户有:新浪.网易.腾讯,另外知名的微网志Plurk也使用nginx. Nginx作为负载均衡服务器,既可以在内部直接支持Rails和PHP程序对外进行服务,也可

Linux下静态编译Qt程序

一般情况下,我们用Qt编译出来的程序是要依赖于系统Qt库的,也就是这个程序移到别的没有安装Qt库的系统上是不能使用的.会提示缺少……库文件之类的错误.这就是动态编译的结果. 但是如果我们想编译一个程序,这个程序在发给别人后,他们可以直接打开,而不需要特别地去先安装Qt库,那就需要采用静态编译了. 在Linux下如何静态编译Qt程序呢? 首先需要先安装静态编译的Qt,也就是静态编译Qt程序首先是需要一个静态编译安装的Qt   1.下载源安装程序,如 qt-x11-opensource-src-4.

Linux下取代top的进程管理工具 htop

一.htop 简介 This is htop, an interactive process viewer for Linux. It is a text-mode application (for console or X terminals) and requires ncurses. Comparison between htop and top In 'htop' you can scroll the list vertically and horizontally to see all

我在GNU/Linux下使用的桌面环境工具组合

为了使GNU/Linux桌面环境下加载的程序较少以节省内存资源和提高启动时间,我目前并不使用重量级的桌面环境KDE和Gnome,甚至连登录窗界面gdm或xdm都不用,而是直接启动到控制台,登录后调用startx进入X视窗环境.所使用的工具组合列举如下: X视窗环境启动:startx 窗口管理器:Sawfish amixer:系统音量设置 键盘与鼠标配置:xmodmap 网络管理器:wicd(需删除NetworkManager) xscreensaver:屏幕保护程序 类似于Windows的底部工