How to Secure SQL Server Against ‘sa’ Account Brute Force Attacks: Best Practices & Code Examples


2 views

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