Friday, 6 July 2007

SourceSafe Password Encryption

Well it was fun getting administrative access to SourceSafe in my previous article, and if anyone ever forgot their password at least they could gain access to the tool, but it doesn't really provide a full solution because we still haven't got the password for the administrators account.

So my next challenge was to see if I could decrypt the administrator password, and to start down this road I needed to work out how the password is encrypted.

You might remember from my previous article, 'Is SourceSafe "Safe"', this call in SSAPI:
3DCE6 CALL SSAPI.3E6D0

And this seemed to take the password off the stack ("Password" in the above case) and set the value of EAX to a number (0x6A10 in this case).


I also notice that the comparison at 3DCEE compares this with the value 0x6DAF (which I assume is the coded version of the password "adad").

Well the only reasonable thing to do is see what is happening in the proc at 3E6D0.

I won't list the proc here (there's not much point - you can look yourself) but there are a few things to note in it:
  1. Whatever password I have entered is converted into upper case (at 3E6F2)
  2. The password must be 15 characters - if the entered password is shorter then letters from the string "BrianDavidHarry" will be appended to the end (see 3E6F7 to 3F70C). So if I entered "password", this will be changed to "PASSWORDBrianDa"
  3. If the password is empty, the full string "BrianDavidHarry" will be used
  4. The appended "BrianDavidHarry" string is not converted to upper case

So, now we get to 3E714, and this is where the actual codification takes place:
3E714 XOR EAX, EAX
-- 3E716 MOVSX DX, BYTE PTR SS:[ESP+EAX+8]
/ 3E71C XOR EDX, 0x96
/ 3E722 LEA ECX, DWORD PTR DS:[EAS+1]
/ 3E725 IMUL EDX, ECX
/ 3E728 ADD ESI, EDX
/ 3E72A INC EAX
/ 3E72B CMP EAX, 0xF
-- 3E72E JL SHORT SSAPI.3E716

So immediately you will see that there is a loop is betwen 3E716 and 3E72E, the counter is stored in EAX and there are 15 steps.

In 3E716, the next character value is read from the password and stored in DX.

The character value (in EDX) is the XORed with 0x96 (150) although I have no idea why.

In the next two lines the value in EDX is multiplied by the counter + 1.

The resulting value in EDX is then added to the value in ESI (which is, of course, 0 at the first loop iteration).

After we drop out of the loop, we see the value 0x6A10 in ESI, which is moved into EAX before the proc returns... as we expected from the call at 3DCE6!

So, the password code is encrypted in the following way:
Sum (char_position(char XOR 0x96))

In my opinion, hardly a fantastic way of securing the passwords. I know I have used XOR myself in the past to attempt to hide password data, but I wouldn't ever recommend it as a secure way of hiding anything.

In the case of SourceSafe though, I guess it is sufficient. Or is it...?

No comments: