GPU挖矿分析与处理

1 现象

显卡资源断断续续地被占用,nvidia-smi看不到进程号,指定gpu卡设备(nvidia-smi -i 0)能看到对应进程号:

曾经截图发现的进程:

进程中带有octopus、stratum关键字,以此作为进程线索。

2  排查过程

2.1  开启系统调用审计

因为只有进程的关键字,也不知道挖矿进程出现频率,而且挖矿时,/proc/目录下对应挖矿进程的可执行文件显示deleted,因此并不知道来源是哪里,所以先对系统调用开启审计,具体方式:

修改auditd的审计配置/etc/audit/auditd.conf,增加日志文件数量与日志大小:

# 10M
max_log_file = 10
# 100个
num_logs = 100

重启auditd服务:

systemctl restart auditd

之后添加审计规则:

auditctl -a always,exit -F arch=b64 -S execve -F key=virus

大概意义是对每个execve系统调用都开启审计追踪(linux程序执行基本都是fork+exec),这样在日/var/log/audit/audit.log中就能观察到木马的频率了。

过一阵子,对审计日志进行观察,确实发现有木马相关进程的执行,并且也记录了所有执行的参数:

分析时间规律:

grep 'octopus' /var/log/audit/audit.log* | awk '{print $2}' | awk -F ':' '{print $1}' | awk -F '(' '{print $2}' |xargs -I{} date -d @{} +"%Y-%m-%d %H:%M:%S" | sort

时间大概是6-7分钟一次,但具体秒数具有随机性,可能是木马程序故意为之,因此并没有直接去相关定时任务中查看异常。

不过此时没法定位来源,只能确切地知道挖矿进程间断性出现,没有具体的现场,难以分析。

2.2  暂停进程

因为挖矿进程经常性断断续续出现,没法一直保留进程现场,因此方式是采用SIGSTOP信号,将进程设置为T状态,使得进程HUNG住而不退出,编写如下脚本catch-virus.sh

#!/usr/bin/env bash
while true;do
  ps aux|grep 'octopus' | grep -v grep | awk '{print $2}' | xargs kill -19 2>/dev/null
  if [ $? -eq 0 ]; then
    echo 'I catch the virus!!!!' && exit 0
  fi
  sleep 1
done

实际意义表示,每秒钟检测一次进程,一出现octopus相关的进程便直接kill -19(即发送SIGSTOP信号),并提示'I catch the virus!!!'

2.3  进程隐藏处理

理论上来讲,上一步能在挖矿进程出现时,直接给抓取到进程,不让其退出。但是在实际后面过程中发现,服务器还是出现了挖矿现象,而上面暂停进程的方法并没有生效。

也就意味着,挖矿进程出现时,并没有在ps命令列表里出现,也就是出现了进程隐藏现象,隐藏进程一般会有两种方式:

1.  ps命令被篡改

这种情况,如果系统命令本身不可信任,那么需要采用应急处理,安装busybox:apt install -y busybox,后续执行命令时,加busybox前缀,如busybox ps aux

但实际上也没有抓到,因此并不是ps命令篡改。

2.  动态链接劫持

通过修改LD_PRELOAD环境变量或/etc/ld.so.preload文件,配置动态链接库,实现将其注入到目标进程中。

当前服务器上,查看/etc/ld.so.preload文件(已经重命名为.bak的新文件),确实有一条.so文件内容:

因此进程隐藏大概率是通过ld.so.preload文件中加载的动态链接库实现的,所以解决方式是将该文件移除或重命名:mv /etc/ld.so.preload /etc/ld.so.preload.bak

2.4  再次暂停进程

此时再次执行catch-virus.sh,后面便成功抓到了,ps命令显示进程已经变成了T状态,现场得以保留,隐藏进程的手段被成功打破:

但实际上去查看进程相关信息的时候,也没得到很多有价值的东西,/proc对应进程目录下,只能看到当前目录是根目录/,当前可执行文件显示deleted。不过从/proc/进程号/ns目录下能看到,当前的namespace空间是宿主机的空间(由lsns -p 1查看得出),并非某个docker容器的namespace,这样至少能定位到是宿主机上的问题

2.5 排查定时任务

既然进程隐藏的问题解决了,也定位到是宿主机的问题,而且之前也观察到挖矿进程有一定的时间频率规律,那么接下来排查方向应该是关注宿主机的异常进程以及定时任务,这里先主要排查定时任务:

首先执行crontab -l,无有价值输出。

再去/etc/下的各种cron相关目录下查看相关任务:ls -ltr /etc/cron*

其中发现一个可疑的/etc/cron.d下,3月27号修改时间的defunct文件:

查看文件内容:

执行其中部分内容echo L3Jvb3QvLmNvbmZpZy9odG9wL2RlZnVuY3QK|base64 -d

可以看到,实际上是去执行/root/.config/htop/defunct文件,也的确在该目录下发现该文件(已经重命名):

该文件是个二进制文件,无法查看具体执行了什么,此时选择手动执行该文件,同时用strace追踪该文件启动时的系统调用过程:

strace -ff /root/.config/htop/defunct

查看文件内容,发现几处可疑:

1、访问/etc/ld.so.preload

2、新打开一个/tmp/下的临时文件,并将该文件描述符设置为1:

3、往该文件描述符1中写入一些看不懂的二进制数据:

4、将该文件权限设为755,并切换到根目录/,执行该文件,并显示为[kworker/00:0],这是linux内核线程的表现形式:

5、删除该文件:

很显然,该进程的作用其实就是启动一个名为[kworker/00:0]的进程,伪装成内核线程在宿主机上,并且利用ld.so.preload加载动态链接库,隐藏进程并加以进一步的伪装,以致于极其难以发现。从系统调用过程也能看出来,chdirunlinkat就是程序所在执行目录是根目录/,并且文件显示deleted的原因。

3 恢复措施

已经定位到该进程名,刚好此时在宿主机上执ps auxfww发现如下进程关系:

可以看到[kworker/00:0]下有个python3的子进程,也即我们最初发现的挖矿进程。

因此,实际挖矿现象产生本质原因,就是[kworker/00:0]进程定期去fork一个python3的挖矿进程,只不过这个期限应该是在程序内部随机在7分半钟左右。

因此只需要避免[kworker/00:0]这个伪装出来的进程再次产生就行了,从上面的来源可以看到,实际上就是定时任务每天去执行/root/.config/htop/defunct文件,那么只需要先将已有的进程kill掉,并将/root/.config/htop/defunct重命名即可。

进一步清理,应该是删除/etc/ld.so.preload文件,以及其中的库文件/lib64/libnss.so,删除/etc/cron.d/defunct文件,删除/root/.config/htop/defunct文件,不过先可以观察几天再删。

此时也仍然需要在后台执行catch-virus.sh,并查看/var/log/audit/文件下的日志,看是否有挖矿进程的产生,以便验证是否生效,没有任何结果输出就说明木马程序确实消失了。

作者:隆吟风原文地址:https://www.cnblogs.com/longyinfeng/p/18824728

%s 个评论

要回复文章请先登录注册