Hackers have been taking advantage of Graphical Processing Units (GPUs or Video Cards) for some time now to leverage their ‘massively parallel’ processing power as a way to much more efficiently attempt password cracking. To that end, it’s no surprise that hackers can use modern GPUs to generate literally billions of password ‘guesses’ per second.
As outlined a while back by ZDNET, while CPUs might take hours or even days to ‘chew’ through NTLM passwords, GPUs can chew through them in minutes or even seconds. (For example, the password “fh0GH5h” might take a CPU 4 days to ‘guess’ while a mid-range GPU could do so in just under 18 minutes. Throw a couple of higher-end GPUs together and I’m guessing you could tear that password down in just a few minutes.)
Now, to be clear, when it comes to cracking NTLM password by brute-force, there’s one huge problem that hackers are going to run into – which is that they’re NOT going to be able to generate billions of guesses per second – simply because I’m going to assume that after just a handful of guesses the account that they’re trying to crack will end up getting locked out. As such, we’re pretty much safe from hackers wiring up multiple GPUs and cracking their way into systems via brute-force.
In other words, the password ‘cracking’ times mentioned in the article I linked above were not true ‘brute force’ attacks against Windows Logins in the wild. Instead, they’re geared towards allowing unfettered access at underlying logins in order to enable password recovery.
But, throw in some rainbow tables or combine the ‘massively parallel’ nature of modern GPUs and give them access to attempt logins WITHOUT some sort of control mechanism that detects brute-force attacks and correspondingly shuts down accounts and you’ve got a recipe for potential disaster.
While attempts to crack Windows passwords in a production environment are going to run afoul of account lockout policies, SQL Server Authentication isn’t so lucky.
In fact, SQL Server Authentication has absolutely no provision that allows it to detect when passwords are being brute forced.
Furthermore, since SQL Server is so adept and performant when it comes to evaluating SQL Server authentication credentials (i.e., usernames and passwords) SQL Server can easily handle aggressive, repeated, attempts to brute-force passwords WITHOUT the slightest indicator in terms of system slow down or negative overall performance.
Meaning, of course, that SQL Server Authentication is RIPE for password cracking via brute-force means.
Which, quite frankly, means that I’m really surprised that script kiddies out there haven’t generated some sort of tool or script that finds SQL Servers and try brute-forcing their way in to internet-facing SQL Server. Or, similarly, in cases where SQL Server Authentication is being used internally, similar tools could be used by malicious employees for a variety of different reasons (IP or customer theft, sabotage, etc).
“When possible, use Windows Authentication” and
“Windows Authentication is the default authentication mode, and is much more secure than SQL Server Authentication".”
Consequently, your first line of defense against brute force attacks is merely to not be exposed to them by using Windows Authentication alone (i.e., disabling SQL Server Authentication).
This change alone is enough to protect you from brute force attacks because authentication then needs to be handled by windows which will (or SHOULD) have account lockout policies in place. (Obviously you may want to verify that you’ve got account lockout policies in place that suspend a given Windows account after x password failures.)
Second, if you DO need to use SQL Server Authentication (and there are reasons where you’ll need to accept the security limitations/trade-offs imposed by SQL Server Auth in order to allow access via certain users or apps), then try to put your SQL Server behind a well-defined firewall if at all possible. If SQL Server Auth is enabled on your server (i.e. if it’s running in ‘Mixed’ mode) and you put it behind a firewall, you WILL be protecting yourself from rogue or random attacks from the internet, but you’ll still need to address worries about internal attacks (from potentially compromised systems or malicious employees).
I’m sure I’ll catch hell for recommending this, but the ability to specify a Password Policy within SQL Server for SQL Server Authentication accounts is more hassle than it’s worth.
Typically password policies do two things:
1) Needlessly complicate security and interactions. (Once you impose a password policy that requires that passwords be changed regularly, for example, you have to make sure that all of your apps have SOME way to do this – either natively or via some special new functionality that you expose in your apps)
2) Make end-users hate security.
And that second point is a BIG concern. When security is important, you want end-users on your side. Because if you don’t have end-users on your side, and you enforce draconian policies, you end up with complex passwords that are written on sticky-notes that are either placed under keyboards or on the sides of monitors.
Instead, what I’ve recommended for years is pass-phrases. They achieve MUCH greater cryptographic entropy, and are MUCH easier for end-users to remember – as clearly illustrated by xkcd’s brilliant comic:
Consequently, go ahead AND use password policy for your SQL Server Logins – but skip the ugly stuff and just ensure that passwords are greater than 15-20 characters and you’re typically going to be just fine.
If you’ve got an internet facing server (or are worried about internal attacks), then renaming and/or removing the SA account is a great option – because password cracking only works when hackers are trying to brute-force the password for an account that exists and is enable. Take away the account or disable it, and you’ve stopped the ability of hackers to log in with the account they’re trying to crack their way into.
A common recommendation in security circles for SQL Server installations is to turn on Failed Login Auditing.
This IS something you’ll want to do. However, the problem with this is really two fold.
First, turning this on doesn’t DO anything if you’re not regularly checking your SQL Server logs to see which accounts are regularly failing the login process. and
Second, if you’re allowing SQL Server Authentication and even if you’re checking your logs every hour (yeah, right), you STILL run the risk that hackers might find your SQL Server and mount a brute-force attack against it with ‘just perfect’ timing to the point where you might discover their activities too late – especially if you’re dealing with an internet-facing server. Consequently, auditing IS a key security best-practice. But it’s not as important as mitigating the potential risk for SQL Server brute-force attacks by switching to Windows Auth mode (only – i.e, non-mixed) if possible, removing internet access to your SQL Server whenever and where ever possible, and using SECURE passphrases with sufficient entropy that they can’t be easily cracked.
In fact, the TRUE role of auditing is to make sure that WHEN you’ve done everything else and STILL need to have internet facing servers with SQL Server Auth enabled that you’re CHECKING to make sure that hackers haven’t mounted a ‘three day’ attack against a login and aren’t in the process of trying to brute-force their way on to your server.
The fact that SQL Server Authentication has no means at all of disabling accounts after n failed logins is a HUGE security problem – because it means that, eventually, ALL SQL Server passwords can be hacked (if SQL Auth is being allowed). Effectively, this means that password cracking against SQL Server Auth passwords is MERELY a matter of time. If your passphrases are long enough, you’re effectively safe. If they’re not, you’re effectively doomed the first time someone puts serious effort against your box.
I’d love to see Microsoft address this in the future – but Microsoft already recommends against using SQL Auth in cases where data security is of utmost importance, so I’m not holding my breath on this one.
That, and I’m guessing that TONS of the servers that might be IMPACTED by this limitation are already out in the field and MIGHT not be getting patched as regularly as we’d all like.
To that end I spent a bit of time a few weeks ago playing around with a simple .NET application that reads in SQL Server logs, scans them for ‘login failed’ errors, aggregates those failure messages against the accounts in question, and provides some simple information on failure rates (i.e., x failures total, and y failures within a given time-span).
This .NET app is a work in progress – but my plan/idea is to turn it into a simple class library that can easily be consumed as a stand-alone .NET app that you could configure to send out email/sms alerts if/when you reached a certain threshold of suspicious activity, or which could also be used as a SQL CLR sproc, or even from within PowerShell.
So, if that’s something that sounds interesting, just spout of in the comments or drop me a line and I’ll put some attention towards building it out into something that people can use if wanted.