Sunday, February 15, 2009

Classic Bug: Windows 95/98/ME share password bypass (part 1)

Another oldie, this time MS00-072: bypassing Windows 95/98/ME share level passwords. In Windows ME and earlier, you could share a folder and put a password on it, so only people in possession of the password could access your shared files over the network.

This vulnerability is interesting because this authentication could by bypassed completely. Furthermore, you could use it to recover the actual password. The function to verify the password probably looked something like this pseudo code:

bool verifyPassword(int givenLength, char * givenPassword, char * realPassword){
for(int i=0; i<length; i++){
if (givenPassword[i] != realPassword[i]){
return false;
}
}
return true;
}


The code does not look so bad at first glance. It takes three parameters, the supplied password and its length and the actual share password. Both passwords are NULL-terminated. The password length includes the NULL byte, so the password ‘12345’ would have a length of 6. It then starts to compare the two byte-by-byte. If any of bytes in the two passwords differ, the verification fails and access is denied.

As I mentioned in the above paragraph, the supplied length of the password includes the NULL byte, so even an empty password would have a length of 1 (the NULL byte itself). This is where the problem lies. The relevant part of a legitimate authentication packet would look like this (password could be empty):

[password length+1][password][NULL byte]


So for an empty password, password length = 1 and the above function would simply compare 1 byte (the NULL byte). If the actual password is also empty (e.g. consists of only a NULL byte), access is granted.

Now you might wonder what happens if the password length is set to 0 (this should never happen, as there is always a NULL byte). What happens is we bypass authentication. Looking at the above function, if givenLength is equal to 0, we never enter the for loop. Thus, we never compare any characters and authentication is always successful.

In part 2 I will describe how an exploit called pqWak uses this bug to determine the password remotely.

No comments: