记一次服务器排查挖矿病毒

背景

服务器本来是用来开 mc 服的,8.4开好服务器后搁置了,8.9凌晨告警,紧急关机,排查后发现是挖矿病毒

时间线

八月五日 17点52分23秒,德国 ip 192.109.206.11 爆破 ssh 成功,登录 rootimg

98566d448e0840a0e9b154a29302a8ae

八月五日 17点53分22秒,攻击者通过 root 创建用户 titu,权限为 root (该用户作用目前不明确);通过 root 添加挖矿程序,路径为 /dev/shm/syswatchd (后来发现路径并不固定,每次启动服务都会将原程序重命名移动到另一路径),通过 root 创建系统服务 mem-tracker.service,该服务于八月九日凌晨启动挖矿程序,同时 cpu 占用爆满

image-20250809104906944

image-20250809105123640

image-20250809104325001

image-20250809110700033

八月九日 2点2分左右,紧急关机

八月九日 8点33分左右,开始排查

八月九日 10点32分左右,排查出挖矿服务并停止服务

复现排查过程

启动服务器,发现 cpu 占用很快爆满,使用 top 命令和 ps 命令无法查询

image-20250809112647208

查看定时任务 crontab -l

image-20250809114813695

查看正在运行的系统服务 systemctl list-units --type=service --all | grep -iE "(enable|running)"

image-20250809115132165

查看 ssh 记录 sudo grep "sshd" /var/log/auth.log | grep -iE "accepted|failed",发现 192.109.206.11 在 八月五日爆破 ssh 成功,同时发现八月七日 192.109.206.173 也进行了爆破,但是爆破失败,二者均为德国ip

image-20250809115507707

image-20250809115637738

使用 ss -tunap 查看是否有外连

image-20250809112904172

发现本地 192.168.5.203:44278 连接到了 5.223.46.169:443,使用 Shodan 查询,该 ip 位于新加坡,服务器开启了 22 和 443 两个端口,猜测这是矿池ip

image-20250809113233493

查看 /proc/net/tcp,最后一条即为可疑外连,inode 为 105723841

image-20250809114052815

image-20250809114138965

使用 ss -tpne | grep <inode> 查询,发现来自服务 /system.slice/mem-tracker.service

image-20250809114341811

查看服务状态,发现目标进程为/usr/bin/udeb/tmp/syswatchd

image-20250809114447031

停止服务,cpu 占用降低至正常

image-20250809114646620

异常进程排查结束

挖矿进程分析

syswatchd(rcu_scheb)

ida 查看字符串,发现 xmrig ,这是一个用于挖取门罗币的开源 CPU 挖矿程序

image-20250809120149437

尝试直接运行该程序,会由于缺少配置文件而无法运行(文件名和路径不固定)

image-20250809135029783

udeb

直接运行该文件,cpu占用爆满

程序没有加壳,主要功能根据函数名即可推断

image-20250809144610163

Dropper

发现字符串 http://dudiito.dev/iu/tools.tar/usr/local/lib/libsimplesshd.soimage-20250809135540990

image-20250809135934190

发现从 http://dudiito.dev/iu/tools.tar 下载了一个 tools.tar 压缩包,以及一个路径 /usr/local/lib/mslog,但是无法直接访问该链接下载文件

image-20250809140032459

注意到路径 /usr/local/lib/mslog ,发现里面正是 tool.tar,包含三个文件

image-20250809140135366

image-20250809140149029

Loader

其中,udebrcu_scheb 分别为 /usr/bin/udeb 和 挖矿程序,另一个 .so 文件在函数 main_addToLdPreload() 中加载

image-20250809143023457

函数 main_checkAndLaunchMiner(string locBig) 检查挖矿程序是否启动,如果没有启动,那么执行 main_prepareAndLaunchMiner(string locBig)

image-20250809150340402

函数 main_prepareAndLaunchMiner(string locBig) 准备好一系列变量,最后调用函数 main_launchMinerWithRandomName(string locBig)

image-20250809150015960

main_launchMinerWithRandomName(string locBig) 将挖矿程序复制到随即路径后,启动程序

image-20250809150638744

libsimplesshd.so

在 tool.tar 中额外发现了该文件

在字符串中发现如下内容

image-20250809141105067

跟进,该函数作用为判断程序名是否在过滤列表中

image-20250809141122570

在函数列表发现 readdirreaddir64

image-20250809143232397

image-20250809143535303

readdir() 是libc中的函数,作用为读取目录,获取目录下所有文件和 inode。这里将该函数劫持,跳过了 processes_to_filter 中的文件名,导致 processes_to_filter 中文件名不会被读取到,从而在 top ps 中隐藏了挖矿程序

钱包、矿池分析

前面已经提到,挖矿程序运行需要配置文件,或者在启动时传参,但是通过 find 命令无法找到配置文件,在 udeb 启动挖矿程序时中也没有查到参数,猜测参数是直接硬编码到挖矿程序中

尝试使用 strings 命令,得到了三个矿池链接

image-20250809153059421

直接执行 strings logobserverx | grep -A 200 'config.json'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
"api": {
"id": null,
"worker-id": null
},
"http": {
"enabled": false,
"host": "127.0.0.1",
"port": 0,
"access-token": null,
"restricted": true
},
"autosave": true,
"background": true,
"colors": true,
"title": true,
"randomx": {
"init": -1,
"init-avx2": -1,
"mode": "auto",
"1gb-pages": false,
"rdmsr": true,
"wrmsr": true,
"cache_qos": false,
"numa": true,
"scratchpad_prefetch_mode": 1
},
"cpu": {
"enabled": true,
"huge-pages": true,
"huge-pages-jit": false,
"hw-aes": null,
"priority": null,
"memory-pool": false,
"yield": true,
"max-threads-hint": 100,
"asm": true,
"argon2-impl": null,
"cn/0": false,
"cn-lite/0": false
},
"opencl": {
"enabled": false,
"cache": true,
"loader": null,
"platform": "AMD",
"adl": true,
"cn/0": false,
"cn-lite/0": false
},
"cuda": {
"enabled": false,
"loader": null,
"nvml": true,
"cn/0": false,
"cn-lite/0": false
},
"donate-level": 0,
"donate-over-proxy": 0,
"log-file": null,
"pools": [
{
"algo": null,
"coin": null,
"url": "pool.dudiito.dev:443",
"user": "NEW_ADDRESSS",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
"algo": null,
"coin": null,
"url": "5.223.46.169:443",
"user": "IP-failover",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
"algo": "rx/0",
"coin": null,
"url": "hk.salvium.gfwroute.com:1230",
"user": "SaLvsARaV7D9s3XNreiozaTBLLsJdan6KXCKsCbN1ojtW9ABgKsJtzkgCiQB8e5DkXfqQCPBCatXae4dbJN2ngPvDqTUd2pFyXJ",
"pass": "failSalv",
"rig-id": null,
"nicehash": false,
"keepalive": true,
"enabled": true,
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
"algo": "rx/0",
"coin": null,
"url": "pool.supportxmr.com:3333",
"user": "48wb18tbiori5prH9ad5dbH9UN963XTKhabnUgYJtvzy7LRcAHiP1dA9xHSdwLczGCc7ahsZBx5JxXLMkHrzP5fQPXkkXJk",
"pass": "fail3333",
"rig-id": null,
"nicehash": false,
"keepalive": true,
"enabled": true,
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
"algo": "rx/0",
"coin": null,
"url": "pool.supportxmr.com:7777",
"user": "48wb18tbiori5prH9ad5dbH9UN963XTKhabnUgYJtvzy7LRcAHiP1dA9xHSdwLczGCc7ahsZBx5JxXLMkHrzP5fQPXkkXJk",
"pass": "fail7777",
"rig-id": null,
"nicehash": false,
"keepalive": true,
"enabled": true,
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
"algo": "rx/0",
"coin": null,
"url": "fr-zephyr.miningocean.org:5462",
"user": "ZEPHYR2ysT7Qebc8QLknZo5VyaQDdRHeF7dn7M6d8ra1FUsGpZ1ZpeCKun9XLptPmGCZZCAUjP81qKcYtER3GTUagU15H7btCPa2D",
"pass": "fr-fail",
"rig-id": null,
"nicehash": false,
"keepalive": true,
"enabled": true,
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
}
],
"print-time": 60,
"health-print-time": 60,
"dmi": true,
"retries": 500000,
"retry-pause": 10,
"syslog": false,
"tls": {
"enabled": false,
"protocols": null,
"cert": null,
"cert_key": null,
"ciphers": null,
"ciphersuites": null,
"dhparam": null
},
"user-agent": null,
"verbose": 0,
"watch": true,
"pause-on-battery": false,
"pause-on-active": false

得到信息:

  • 矿池 1

    • 地址: pool.dudiito.dev:443

      user: "NEW_ADDRESSS"

  • 矿池 2

    • 地址: 5.223.46.169:443

      user: "IP-failover"

  • 矿池 3

    • 地址: hk.salvium.gfwroute.com:1230

      钱包 (门罗币): SaLvsARaV7D9s3XNreiozaTBLLsJdan6KXCKsCbN1ojtW9ABgKsJtzkgCiQB8e5DkXfqQCPBCatXae4dbJN2ngPvDqTUd2pFyXJ

  • 矿池 4、5

    • 地址: pool.supportxmr.com (分别使用 33337777 端口)

      钱包 (门罗币): 48wb18tbiori5prH9ad5dbH9UN963XTKhabnUgYJtvzy7LRcAHiP1dA9xHSdwLczGCc7ahsZBx5JxXLMkHrzP5fQPXkkXJk

  • 矿池 6

    • 地址: fr-zephyr.miningocean.org:5462

      钱包 (Zephyr币): ZEPHYR2ysT7Qebc8QLknZo5VyaQDdRHeF7dn7M6d8ra1FUsGpZ1ZpeCKun9XLptPmGCZZCAUjP81qKcYtER3GTUagU15H7btCPa2D

微步检测报告

udeb

libsimplesshd.so

rcu_scheb