Compromise with PowerUpSQL – SQL Attack
Completely Owning MS SQL Server
If what you’re after is a toolkit to own Microsoft SQL Server from end to end, then what you need is PowerUpSQL. Implemented in PowerShell and as complete as they come, PowerUpSQL has tools to discover, compromise, elevate, target, and own just about any SQL system. It’s the whole kill chain in one tool. Just as I could have run all the initial discovery and compromise through metasploit but chose to break it up, I chose to use PowerUpSQL for this middle piece and not the whole series so you may see several ways to approach the challenges. As one reader pointed out, I could have even just done nmap for the initial steps but chose to also give you a flavor of medusa to expand the tool bag. If you are a PowerShell maven, then you can skip the rest of these steps and simply focus here on PowerUpSQL.
However, I did find some very mixed results with the system I was using. I was on a very vanilla version of MS SQL 2012. However, there were not many things I could accomplish through the PowerShell route without already having access to system admin rights. Like many others, the SQL admin rights were granted to the local and domain admins. Users with those rights essentially already own the system. They only need to target the right data and take it. If you need tips on how to grab system level admin rights, you can see our previous blogs on attacks against Active Directory – like attacking core AD infrastructure, leveraging AD service accounts to attack, attacking AD with misconfigured permissions, and our series on Mimikatz attacks. I’ll be sure to highlight where my results varied with and without system admin rights.
Quick Look At Discovery & Compromise
PowerUpSQL really does have everything. That includes the means to find and perform a compromise on a SQL Server. Finding all the SQL on a domain is as easy as one cmdlet, Get-SQLInstanceDomain:
There is also Get-SQLInstanceLocal, which will perform the same sort of discovery but only on the local instance. The domain version is noisier, but if you only have one place from which to attack on the network will do what you need. If you own a lot more of the network and you want to give off less signal, running the Local version on each system will do the trick. In this case, I was able to get similar results when I was a normal user (srogers) or a domain admin.
One of the disappointments when playing with PowerUpSQL was the very powerful Invoke-SQLEscalatePriv never worked for me. I tried different users, hosts, local and remote execution, different kinds of rights, but it would never escalate my user. From my reading, the reason seems to be the newer defaults in MS SQL 2012 Enterprise Edition. Here’s what I saw when running as my non-Admin user:
When I run as my admin I get the correct but unexciting:
Reading online, it seems this does work for many others. That highlights a very important vulnerability in many MS SQL Server environments. Due to requirements from applications, many people are disabling built in security or weakening best practices meant to protect SQL Server. There is only one way this will ever stop. We as the users (and the STEALTHbits products use MS SQL so it is really *we*) need to pressure application vendors to ensure that they do not require password standards be lowered, admin rights be required for operations that don’t strictly require them, checks in the systems that require a little more diligence in SQL or procedures aren’t turned off due to laziness, and more security isn’t thrown out simply to make their lives easier.
Going Deep Into SQL Server Vulnerabilities
Once you have a number of MS SQL systems you with to target – or if you have many and you’re trying to sort out which ones are the best targets – you may want to find out more about each. That’s where Get-SQLServerInfo comes in. This will give you a snapshot of useful information about your potential target:
Two interesting things to note about this. This was another example where I seemed to need my admin rights to get any good results (hence the jonathan user). The other interesting part of this example is it shows off one of the best features of PowerUpSQL. It’s been built to support piping. You see we take Get-SQLInstanceLocal and pipe its results into Get-SQLServerInfo. If there had been any number of SQL instances on this box, I would have gotten results for all of them with one command. Because PowerUpSQL supports this, you can easily build up large cracking scripts that run through complicated operations reasonably quickly and easily.
Using what we learn from Get-SQLServerInfo, we may simply go to the standard libraries of threats and vulns and grab something with which to exploit this system. But why do that? PowerUpSQL again has a powerful trick up its sleeve. The Invoke-SQLAudit cmdlet will literally do all the cracking for you. It checks pretty much every standard way to break into a database, find sensitive information, and exfiltrate it to a form you can carry away. When you first invoke it, you start seeing a outpouring of results like this:
That’s just Invoke-SQLAudit getting started. After it runs through all the permissions level checks, it begins to check for specific, known vulnerabilities one by one. Then it gives reports on what it finds for each:
Reading through the results of this cmdlet, regardless of how vulnerable your target may have been, is like a master class in SQL Server exploits. And as you can easily see from reading the format, the authors have left the toolkit open for extension as new vulnerabilities and exploits are found. So we should expect to see this list only grow over time. And that’s not all. Once its done with vulnerabilities, it tries to find data you may want to steal:
These slightly redacted for obvious reasons results were just two of dozens and dozens found in my target. The authors are even eating their own dogfood as they do this. These results were found using the “Invoke-SQLAuditSampleDataByColumn -Instance APP02.sbcloudlab.com -Exploit” cmdlet – as it states in the results.
You can easily imagine using this audit as a means to get a sense of what you want to hit. Then zeroing in after that. When I envision using this seriously, I would build a script, liberally taking advantage of the piping, to find where I have maximum rights, then move in on sensitive data on each of those locations. I’m always thinking in terms of exfiltration, but maybe your goals are system ownership? PowerUpSQL offers you paths to that as well, but we will really look at how to do that in the next post.
What Do You Do To Prevent This?
There is so much in PowerUpSQL, I could keep going on and on for a lot longer. However, the authors have already done a good job covering their tools so I won’t. Instead let’s ask what we can do to stop some of this from affecting you. The bad news for my fun was good news for all of our data: many of the things in PowerUpSQL seemed to need admin rights already in hand with MS SQL 2012 Enterprise Edition’s default security posture. While that’s good, system admin is so easy to crack in most shops these days it seems like a small barrier to overall success. There are some positive steps you can take to help protect yourselves:
Look for opportunities to enforce a least privilege model for MS SQL server. Do the local and domain admins really need to be database and sys admins in SQL as well? If so, make sure there a stated policy reason as to why and when that policy is not applicable prevent this. Keeping these administrative functions technologically distinct will prevent compromise of one leading to compromise of the other.Make sure SQL system settings changes demanded by applications are fully investigated for security impact. Many times applications are asking for changes to security settings only to spare themselves a few steps. Those steps may make the difference between safety and compromise. Applying the PowerUpSQL audit before and after such changes in test systems and comparing the results is one way to illustrate this.If you must have sensitive information in MS SQL objects “ensure that all passwords and sensitive data are masked, hashed, or encrypted” – as the audit results state verbatim. If the bad guys are after data, this is your best way to stop them from getting it in the end. Systems will always be crackable, but decent encryption is a brick wall for all but the most sophisticated foe. If that sort of enemy is after your data, then you have higher order concerns.Avoid risky configurations like database ownership chaining when at all possible. Like the settings being changed, database level features like this are often only used to save developers some time. Make sure there is at least a consideration of risks when these things are being considered. Often the most challenging part of that is finding where and when those conversations are happening and influencing them.Finally, the most tired but true advice in security: ensure your systems are fully patched at all times when at all possible. Many of the vulnerabilities tested for here are simply a matter of patching things. Patches don’t solve all your security problems, but they do prevent that really big pit in your stomach when things go badly and you know it may have been or was absolutely due to some missing patch.