记一次GPU服务器挖矿事件应急响应

举报
亿人安全 发表于 2025/02/28 23:59:32 2025/02/28
【摘要】 一、背景2024年12月26日,我司收到托管机房的网络安全通报,认为我司服务器有挖矿行为,需要当天完成整改。二、影响范围同一内网的10台GPU服务器,版本均为ubuntu 20.04。三、排查过程从通报里面知道以下IP为异常IP,从这两个信息开始进行排查,查看威胁情报得知均为德国IP:209.38.180.198:443 德国矿池138.68.113.5:80 德国IP3.1 进程分析先把云...


一、背景

2024年12月26日,我司收到托管机房的网络安全通报,认为我司服务器有挖矿行为,需要当天完成整改。

二、影响范围

同一内网的10台GPU服务器,版本均为ubuntu 20.04。

三、排查过程

从通报里面知道以下IP为异常IP,从这两个信息开始进行排查,查看威胁情报得知均为德国IP:

209.38.180.198:443 德国矿池

138.68.113.5:80 德国IP

3.1 进程分析

先把云安全中心高级版装上,运行全盘扫描,并且等待扫描过程中手工排查服务器,使用ss -ta命令发现服务器有和恶意IP连接

图片


执行netstat -tnlpu | grep 209.38.180.198,想查看PID,结果未返回相关结果,反而过了10秒后出现阿里云告警:

图片


怀疑netstat命令被黑客篡改,使用stat /usr/bin/netstat收集篡改时间,可以看到最后一次修改文件属性的时间是2024年9月19日 17:49。询问运维这台服务器什么时候购买的,是在几个月之前,因此基本可以推断入侵时间是在2024年9月19日左右。

图片


为避免阿里云安全中心误报,把/usr/bin/netstat下载后丢到威胁情报进行查询,结果依然是报毒:

图片


查看行为,有很多grep -v反向过滤矿池IP,导致无法使用netstat -tnlpu查看pid

图片


接着阿里云不断报出了新的告警systemctl、top命令全部被篡改,基本可以确定不能继续使用系统命令进行排查

图片图片


下载busybox进行应急

cd /root
wget https://www.busybox.net/downloads/binaries/1.35.0-x86_64-linux-musl/busybox
chmod u+x ./busybox
mv ./busybox /usr/bin/busybox

执行busybox top查看CPU占用最高的进程,发现存在异常进程/9ac8a281

图片


查看根目录,不存在/9ac8a281,怀疑文件已经被删掉了,恶意程序应该在内存里运行

cat /9ac8a281
cat: /9ac8a281: No such file or directory
cd /proc/4022388/
ls -al | grep exe

恶意文件/9ac8a281果然被删除了

图片


找运维从其他机器上拷贝了一个干净的systemctl到中毒机上,排查守护进程,发现异常服务63f55525.service

./systemctl list-units --type=service
 UNIT      LOAD      ACTIVE     SUB          DESCRIPTION                                                                     >63f55525.service    not-found failed     failed       63f55525.service                                                                
……

执行./systemctl status 63f55525.service,看到加载恶意文件/9ac8a281

图片


查看这个守护进程的具体配置,找到恶意文件的位置/usr/bin/9ac8a28120cf5089

cat /usr/lib/systemd/system/63f55525.service

[Service]
Type=simple
User=root
TimeoutStartSec=1200
ExecStart=/usr/bin/9ac8a28120cf5089 9ac8a281

Restart=always
RestartSec=4h
KillMode=process

## 全局查找是否还有恶意文件
find / -name "9ac8a28*"

查看开机启动项、定时任务、系统账号、挂载,无异常

cat /var/spool/cron/crontabs
cat /etc/passwd
df -h
cat /proc/mounts
cat /etc/rc.local
cat: /etc/rc.local: No such file or directory
(base) root@gpua15:/var/spool/cron/crontabs# systemctl status rc-local
● rc-local.service - /etc/rc.local Compatibility
     Loaded: loaded (/lib/systemd/system/rc-local.service; static; vendor preset: enabled)
    Drop-In: /usr/lib/systemd/system/rc-local.service.d
             └─debian.conf
     Active: inactive (dead)
       Docs: man:systemd-rc-local-generator(8)

使用unhide工具检查隐藏进程,发现上百个隐藏进程

apt install unhide
unhide proc

Used options: 
[*]Searching for Hidden processes through /proc stat scanning

Found HIDDEN PID: 5043
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 5044
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 5045
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 5046
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 5047
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 5048
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 6461
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/

Found HIDDEN PID: 6462
        Cmdline: "/9ac8a281"
        Executable: "/9ac8a281 (deleted)"
        Command: "9ac8a281"
        $USER=root
        $PWD=/
…………

3.2 遏制过程

##杀掉恶意进程
kill -9 4022388
kill -9 6462   #删除1个恶意隐藏进程后,其他也会消失,原理未知

##删除守护进程
./systemctl stop 63f55525.service
./systemctl disable 63f55525.service
rm -rf /usr/bin/9ac8a28120cf5089

重复3.1 进程分析步骤,未发现有新的恶意进程启动,服务器暂时恢复正常

3.3 恢复过程

1.删除后门,查看云安全中心,发现有异常可执行文件/etc/ssh/ssh_host_dsa_key.pub
图片


丢沙箱查看,是一个后门

图片


ping example.servidor.world,解析出来IP是138.68.113.5,跟通报文件里的恶意IP吻合,从情报和行为可以判断这是远控服务器的IP,而且可以看到还有另外一个远控IP 185.125.188.58

图片


清理后门,发现被锁定了,无法删除、移动、改权限,可以判断攻击者用chattr锁定了文件

图片


使用chattr -ia /etc/ssh/ssh_host_dsa_key.pub解锁,结果报错不存在该命令,提示让我使用vmlinux1来代替chattr执行(此处漏了截图),由于怕中毒,不敢用vmlinux1命令

下载/usr/bin/vmlinux1,上传到沙箱,结果为正常文件,但保守起见还是不敢用vmlinux1来代替chattr命令

图片


使用lsattr /etc/ssh/ssh_host_dsa_key.pub命令查看,结果lsattr命令也被黑客删除了

从干净的服务器上下载chattr和lsattr文件,上传到中毒服务器,再用lsattr查看,果然后门文件是被锁定了禁止变更

chmod +x ./chattr
chmod +x ./lsattr
mv ./lsattr /usr/bin
mv ./chattr /usr/bin
lsattr /etc/ssh/ssh_host_dsa_key.pub

图片


解锁并删除vmlinux1和后门文件

chattr -ia /usr/bin/vmlinux1
chattr -ia /etc/ssh/ssh_host_dsa_key.pub
rm -rf /usr/bin/vmlinux1
rm -rf /etc/ssh/ssh_host_dsa_key.pub

2.  恢复系统命令

根据云安全中心的扫描结果,得出以下文件均被替换

/usr/bin/uptime
/usr/bin/netstat
/usr/bin/top
/usr/bin/systemctl
/bin/systemctl
/sbin/runlevel

从干净的服务器上下载如上命令文件,打包并上传到中毒服务器进行替换即可

unzip 1.zip
cd 1
chattr -ia /usr/bin/netstat
chattr -ia /usr/bin/top
chattr -ia /usr/bin/uptime
chattr -ia /bin/systemctl
chattr -ia /usr/bin/systemctl
rm -rf /usr/bin/netstat
rm -rf /usr/bin/top
rm -rf /usr/bin/uptime
rm -rf /sbin/runlevel
rm -rf /bin/systemctl
rm -rf /usr/bin/systemctl
cp /root/1/netstat /usr/bin
cp /root/1/top /usr/bin
cp /root/1/uptime /usr/bin
chmod u+x /usr/bin/netstat
chmod u+x /usr/bin/top
chmod u+x /usr/bin/uptime
cp /root/1/systemctl /bin
cp /root/1/systemctl /usr/bin
chmod u+x /usr/bin/systemctl
chmod u+x /bin/systemctl
ln -s /bin/systemctl /sbin/runlevel

3.再次复检

  1. 运行云安全中心,并且再次执行unhide proc进行检查,无任何异常,基本可确定已完成恢复。

  2. 让托管机房监控网络防火墙日志,若还有告警则及时告知。

四、入侵分析

  1. 询问托管机房的网络边界防火墙管理员,确认本地服务器无web端口映射到公网。

  2. 查看进程,发现有frp图片逐个端口访问进行检查,发现一个jupyter server登陆界面。Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算:开发、文档编写、运行代码和展示结果。jupyter_server主要提供后台接口服务,前端应用和后台通信的主要接口,都在jupyter_server中。图片查看了版本后,网上查找是否该版本存在高危漏洞,未找到有用的信息。登陆服务器查找jupyter的登陆日志,结果安装该应用时未开启日志配置,只能放弃。

  3. 查看syslog和auth日志,发现存在大量ssh登陆失败日志,且用户名也不是我司员工姓名拼音,所以用户名应该是字典生成
    图片图片如果说是来自机房内网的SSH爆破导致的入侵,那为什么日志显示的IP是127.0.0.1呢?只能说这个日志很可疑,但无法实锤。
    由于没有保存9月19日左右的日志,很难继续找下去,只能放弃。

  4. cat /root/.ssh/authorized_keys文件,发现内网10台服务器的SSH公钥都加进去了,检查另外9台服务器,也是同样情况,这个作用是让这10台服务器可以互相免密使用root登录。经过验证,的确如此,这是后门维持权限的常用手法。

    图片

  5. 内网执行一次弱口令扫描,发现有5台服务器root存在弱口令。

  6. 继续查看网络防火墙日志,发现有2台服务器外联阿里云OSS的异常流量,询问研发,GPU服务器是要从OSS上拉取文件来进行训练,也就是说OSS里可能有病毒文件。
    图片

综合以上信息的,只能推断出本次事件的2种可能入侵路径,但是缺乏实锤证据:

  1. 攻击者通过托管机房内网其他中毒机器进行了横向移动,并通过弱口令爆破获得了我们其中几台服务器的权限,之后进一步扩大战果。

  2. 研发拉取OSS上的恶意文件后,可能不小心触发了后门/恶意可执行文件,导致服务器直接被控制。

五、经验小结

  1. 209.38.180.198:443是矿池,138.68.113.5:80 是黑客远控服务器,入侵时间是2024年9月19日 17:49之前。

  2. 在排查过程中有一点小小的运气成分,在GPUa15服务器上busybox top一下子就找到挖矿进程和PID了,而其他9台是偶发性的一直不出现。如果没有这个信息作为突破口,遏制过程不会这么顺利。

  3. 使用clamAV扫描以上恶意文件,结果是检测不出来,说明免费的linux杀毒软件能力有限。应急过程还是尽量别用免费的杀软,否则会被误导。

    图片

  4. 由于这批服务器是缺乏监控、日志和安全软件的,加上入侵时间比较早,导致现在难以进行入侵溯源分析,只能完成应急。结合第3点,个人建议安全建设初级阶段的企业,在预算有限的情况下,一定要把资源优先投入到基础设施中去(日志平台、FW、HIDS等),千万不要去追热点、追新技术和新概念。

  5. 企业在建设AI的过程中,一定要有安全意识,需要对训练用到的工具、应用软件、数据进行安全检测和充分的安全评估。

六、IOCs

IP和域名:
209.38.180.198:443
138.68.113.5:80
185.125.188.58
example.servidor.world

恶意文件sha256:
0b4322e157d7880c7b5c516e8511bb9ba44634d44d67ced757669cb6da3db45b
9f514a5486a1be365462790a119df48903235b8082df6bf478845a284faa6313
430337634977213389160c6b9287b0a10aac176ec1c7a74579f0331275a564f6
6f3e8b92ec45372aa64ba9d1873039067002fb84f2c51972b51102edcfd5244a
0f7364dad4c409d48eef8f9c1c29f3a2966ee1c1b5679e5a4692ad6c108bf731
430337634977213389160c6b9287b0a10aac176ec1c7a74579f0331275a564f6

原文链接:https://www.freebuf.com/articles/system/419066.html
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。