I described how a zero length password could bypass the authentication, but what if we want to know the actual password? This could be handy as the password may be used on other systems or if we want to use non-modified software to access the share after extracting the password.
To accomplish this we simply try to guess the password one character at the time. Let me explain: instead of using a zero length password, we use the following:
[password length=1][password=A]
Notice we do not NULL terminate our password, and do not add one to the password length. Lets revisit our verifyPassword function:
bool verifyPassword(int givenLength, char * givenPassword, char * realPassword){
for(int i=0; i<length; i++){
if (givenPassword[i] != realPassword[i]){
return false;
}
}
return true;
}
When we supply a password with a length of one, the function will compare our one character password ('A') with the first character of the actual password. If they match, authentication is successful, if they do not, authentication fails. We can use this to determine the first character of the actual password. If authentication fails, we simply try the password 'B' and so on.
When we have found the first character (say it’s 'P'), we add another character to the password and try ‘PA’ with a length of 2. When we found the second character we add a third one and so on. If we want to know if we have the full password we simply add a NULL byte instead of a character and if authentication succeeds, we have the complete password.
This process is automated by the tool pqWak, which can be found here.
So is this bug still relevant? Well I think so, as it certainly isn’t the only one of its kind. In 2004 a very similar bug was found in MySQL (advisory), you could access a MySQL server without actually knowing the password.