When you detect brute force attempts on your SQL Server's 'sa' account, take these immediate actions:
-- Disable SA account if not already done
ALTER LOGIN sa DISABLE;
GO
-- View failed login attempts (SQL Server 2016+)
SELECT * FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND status = 'sleeping'
ORDER BY login_time DESC;
Implement these network security measures:
-- Restrict SQL Server port access via firewall
netsh advfirewall firewall add rule name="SQL Server Restricted" dir=in action=allow protocol=TCP localport=1433 remoteip=192.168.1.0/24,10.0.0.0/8
Beyond just disabling the SA account:
-- Rename the SA account (SQL Server 2016+)
ALTER LOGIN sa WITH NAME = [obscure_name];
-- Implement login auditing
USE master;
GO
CREATE SERVER AUDIT SQL_Login_Audit
TO FILE (FILEPATH = 'C:\Audits\')
WITH (QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE);
GO
Consider these enterprise-level security features:
-- Enable SQL Server Advanced Threat Protection (Azure SQL)
-- Configure Threat Detection in Azure portal
-- For on-premises, consider:
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'remote login timeout', 30;
RECONFIGURE;
Set up proactive monitoring:
-- Create login failure trigger
CREATE TRIGGER tr_login_attempts
ON ALL SERVER
FOR LOGON
AS
BEGIN
IF (SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND program_name LIKE '%hack%') > 5
BEGIN
ROLLBACK;
ALTER DATABASE [YourDB] SET OFFLINE WITH ROLLBACK IMMEDIATE;
END
END;
Move away from SQL authentication:
-- Enable Windows Authentication only
USE [master]
GO
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'LoginMode', REG_DWORD, 1
GO
When you notice multiple failed login attempts targeting the SQL Server 'sa' account, it's clear someone is attempting a brute force attack. While having the 'sa' account disabled is a good first step, there are several additional security measures you should implement.
First, check your SQL Server logs to determine the source IP addresses of these attacks:
SELECT
login_time,
host_name,
program_name,
client_net_address
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
ORDER BY login_time DESC;
Use Windows Firewall or your network firewall to block the attacking IPs. For persistent threats, consider implementing a script to automatically block IPs after multiple failed attempts:
-- Create a table to track failed logins
CREATE TABLE FailedLogins (
IPAddress VARCHAR(50),
AttemptCount INT,
LastAttempt DATETIME
);
-- Create a trigger to track failed logins
CREATE TRIGGER track_failed_logins
ON ALL SERVER FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN() = 'sa' AND IS_SRVROLEMEMBER('sysadmin') = 0
BEGIN
-- Log the failed attempt
INSERT INTO FailedLogins (IPAddress, AttemptCount, LastAttempt)
VALUES (CONNECTIONPROPERTY('client_net_address'), 1, GETDATE())
ON DUPLICATE KEY UPDATE
AttemptCount = AttemptCount + 1,
LastAttempt = GETDATE();
-- Block IP after 5 attempts
IF (SELECT AttemptCount FROM FailedLogins
WHERE IPAddress = CONNECTIONPROPERTY('client_net_address')) >= 5
BEGIN
EXEC xp_cmdshell 'netsh advfirewall firewall add rule name="Block SQL Attacker" dir=in action=block remoteip=' + CONNECTIONPROPERTY('client_net_address');
END
END
END;
Beyond disabling the 'sa' account, implement these security measures:
- Enable Windows Authentication mode instead of Mixed Mode
- Implement account lockout policies
- Require strong passwords for all SQL logins
- Regularly audit SQL logins and permissions
Set up an Extended Events session to monitor login attempts in real-time:
CREATE EVENT SESSION [Security_Audit] ON SERVER
ADD EVENT sqlserver.login(
WHERE ([result]=(5))), -- Failed login
ADD EVENT sqlserver.login_failed,
ADD EVENT sqlserver.login_success
ADD TARGET package0.event_file(SET filename=N'C:\Audits\Security_Audit.xel')
WITH (MAX_MEMORY=4096 KB, MAX_DISPATCH_LATENCY=30 SECONDS);
Consider these network security enhancements:
- Change the default SQL Server port from 1433
- Implement VPN access for remote connections
- Use SSL encryption for all connections
- Restrict access to the SQL Server port at the firewall level
Schedule regular security checks with this PowerShell script:
Import-Module SqlServer
$serverName = "YourServerName"
$auditResults = Invoke-Sqlcmd -ServerInstance $serverName -Query "
SELECT
name AS LoginName,
type_desc AS LoginType,
is_disabled AS IsDisabled,
create_date,
modify_date
FROM sys.server_principals
WHERE type IN ('S', 'U')
ORDER BY name"
$auditResults | Export-Csv -Path "C:\Audits\SQL_Logins_Audit_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation