August 26, 2007

Breaking SQL Server 2005 hashes

Yes, I`m still alive

and yes, this is an old known topic . The only reason made me post about it was that I found no good note about this on security community.

Back to SQL Server 2000 and based on published paper on it`s hashing mechanism , we learned how to gain and crack these hashes. In SQL Server 2005 how ever , things changed a bit.
Let`s have a quick review of password hashes in SQL Server 2000 before we continue.

In order to dump hash of 'SA' account we used to query :
SELECT password from master.dbo.sysxlogins where name='sa'
And the result :

If we break given hash into smaller sections ( [6][8][40][40] ) we`ll have :
0x0100 -->(Constant value)
34767D5C -->(Salt)
0CFA5FDCA28C4A56085E65E882E71CB0ED250341 -->(Case sensitive SHA hash)
2FD54D6119FFF04129A1D72E7C3194F7284A7F3A -->(Upper case SHA hash)

Above is result of "Test" beeing the clear-text password, generated by pwdencrypt() . To make it more clear , here's the result of pwdencrypt() for clear-text password beeing "TEST" which is all uppercase password :

select pwdencrypt('TEST');

Now you know how things works. So how to crack these hashes ? well, there are tons of free and commercial tools already released for auditing ( read cracking ) SQL Server 2000 passwords . My favorite commercial one is NGSSqlcrack and as always CAIN being the freeware choice. Non of them are best in performance, but they both work well. Let`s try CAIN for cracking "Test" from SQL Server 2000 case :

And passwords cracked:

Now let`s move to SQL Server 2005. As you may already know in many cases SQL Server 2005 stopped backward compatibility with older versions of the product, and mixed in many security options and features that are beyond scope of this post . The only thing we`ll focus is the way SQL 2005 saves password hashes .
First of all , there`s no more a 'sysxlogins' out there , and you have to query a pre-defined view named [sql_logins] to gain access to usernames and their stored hash values , and this is only accessible for sysadmins . Second note about SQL 2005 we care here is the way it stores hash of password.
Let`s try and see how things changed :

In order to get hash of the password for account 'SA' we query :

SELECT password_hash FROM sys.sql_logins where name='sa'

And the result will be :


As you see, length of the hash is reduced . A closer look to string (comparing to SQL 2000) and referring to SQL 2005 documents, you`ll notice that the upper case hash has been removed from the string . The reason is obvious; making it harder to guess passwords, but still possible. as nothig changed about the algorithm we can simply use SQL 2000 methods and tools for breaking the hash . so , clear-text password being "Test" we have :

0x0100 -->(Constant value)
993BF231 -->(Salt)
5F36CC441485B35C4D84687DC02C78B0E680411F -->(Case sensitive SHA hash)
[ removed in SQL 2005! ] -->(Upper case SHA hash)

Looks pretty simple, right ? And how we`ll crack this new hash ?
Turning back to CAIN as our cracker , we'll insert hash and salt value from interface as following. the only change since SQL 2000 is that you have to leave "Uppercase Hash" box empty and continue:

And the expected result after successful crack :

That`s it ! the only remaining note you should remember is that if you want to try either brute force or dictionary attack the hash using CAIN , you must use "MixCASE Hash" from menu, or you`ll fail as there`s no "UpperCase Hash" .

Now let's wait and see when Mao ( ) update his great CAIN to support SQL 2005 and dumping hashes through ODBC connections ;)
cheers to him for such a great project, and keeping it FREE.