Hola, chicos,
¡Buenas noches!
En esta publicación, demostraré cómo identificar contraseñas débiles, vacías o con el mismo nombre de usuario en SQL Server. Esto es especialmente útil para que los administradores de bases de datos eviten ataques por descuidos de los usuarios a la hora de elegir sus contraseñas.
Introducción
Para realizar esta comprobación utilizaremos la función PWDCOMPARE, presente en SQL Server desde 2008, pero lamentablemente está marcada como obsoleta y será descontinuada en alguna versión futura de SQL Server (aunque no he identificado ninguna otra alternativa para esto). Esta función es muy simple, donde ingresa la contraseña que desea probar, el hash de comparación y la función devuelve un valor booleano (0 o 1) si la contraseña que intentó coincide con el hash ingresado.
Si bien esta función es pública, es decir, cualquier usuario de la instancia puede utilizarla, esto no representa una amenaza a la seguridad de la base de datos, ya que la columna contraseña_hash de la vista sys.sql_logins solo es visible para los usuarios con privilegio CONTROL SERVER en la instancia, que imagino que son muy pocos usuarios, todos ellos DBA. De lo contrario, sería muy fácil para un usuario malintencionado realizar ataques de fuerza bruta para intentar adivinar las contraseñas, pero esto no es posible debido a esta restricción de permisos (aunque sí es posible para un usuario DBA).
Otro punto importante a mencionar es que esta técnica sólo aplica para usuarios con autenticación de SQL Server. Los usuarios con autenticación de Active Directory (Windows AD) tienen el valor de la columna contraseña_hash como NULL, incluso para los usuarios administradores de sistemas.
Identificar el hash de contraseña del usuario (password_hash)
Un paso importante para poder identificar estas frágiles contraseñas es poder descubrir el hash de la contraseña del usuario. Necesitaremos este hash para usarlo en la función PWDCOMPARE e identificar la contraseña actual del usuario.
Recuperar este hash de usuario es muy simple, simplemente use una de las 2 consultas siguientes:
SELECT
password_hash
FROM
sys.sql_logins
WHERE
[name] = 'Usuario'
SELECT LoginProperty('Usuario', 'PasswordHash')

Identificar contraseñas débiles
Ahora que hemos identificado cómo recuperar el hash_contraseña, comprobemos qué tan frágiles son las contraseñas de nuestros usuarios en el banco. Para hacer esto, crearé una tabla de contraseñas débiles que probaré y luego probaré cada contraseña, en cada usuario, para encontrar cuál coincide.
Script de creación de tabla de contraseñas:
Con el siguiente script, crearé una tabla con las contraseñas que usaré para intentar identificar la contraseña actual del usuario. No dude en cambiar este script y agregar sus intentos de contraseña.
En este script puedes crear fácilmente una lista con todas las posibilidades y realizar un ataque de fuerza bruta, si eres un usuario con privilegios de DBA, has perdido la contraseña de un usuario y realmente necesitas descubrir una determinada contraseña (porque es mucho más fácil simplemente cambiarla, si ese es el caso).
IF (OBJECT_ID('tempdb..#Senhas') IS NOT NULL) DROP TABLE #Senhas
CREATE TABLE #Senhas (
Senha VARCHAR(100)
)
-- Inserindo senhas mais comuns (pesquisei no google)
INSERT INTO #Senhas
VALUES
('teste'), ('TESTE'), ('password'), ('qwerty'),
('football'), ('baseball'), ('welcome'), ('abc123'),
('1qaz2wsx'), ('dragon'), ('master'), ('monkey'), ('letmein'),
('login'), ('princess'), ('qwertyuiop'), ('solo'), ('passw0rd'),
('starwars'), ('teste123'), ('TESTE123'), ('deuseamor'), ('jesuscristo'),
('iloveyou'), ('MARCELO'), ('jc2512'), ('maria'), ('jose'), ('batman'),
('123123'), ('123123123'), ('FaMiLia'), (''), (' '), ('sexy'),
('abel123'), ('freedom'), ('whatever'), ('qazwsx'), ('trustno1'), ('sucesso'),
('1q2w3e4r'), ('1qaz2wsx'), ('1qazxsw2'), ('zaq12wsx'), ('! qaz2wsx'),
('!qaz2wsx'), ('123mudar'), ('gabriel'), ('102030'), ('010203'), ('101010'), ('131313'),
('vitoria'), ('flamengo'), ('felipe'), ('brasil'), ('felicidade'), ('mariana'), ('101010')
-- Números repetidos
DECLARE
@Contador INT = 1,
@Total INT = 10,
@Contador2 INT = 1,
@Total2 INT = 10
WHILE(@Contador < @Total)
BEGIN
WHILE(@Contador2 < @Total2)
BEGIN
INSERT INTO #Senhas
SELECT REPLICATE(CAST(@Contador AS VARCHAR(100)), @Contador2)
SET @Contador2 += 1
END
SET @Contador += 1
SET @Contador2 = 1
END
SET @Contador = 12
SET @Contador2 = 1
-- Letras repetidos
WHILE(@Contador <= 126)
BEGIN
WHILE(@Contador2 <= @Total2)
BEGIN
INSERT INTO #Senhas
SELECT REPLICATE(CHAR(@Contador), @Contador2)
SET @Contador2 += 1
END
SET @Contador += 1
SET @Contador2 = 1
END
-- Sequências
DECLARE @Atual VARCHAR(100) = ''
SET @Contador = 0
WHILE(@Contador <= @Total)
BEGIN
SET @Atual = @Atual + CAST((CASE WHEN @Contador = 10 THEN 0 ELSE @Contador END) AS VARCHAR(100))
INSERT INTO #Senhas
SELECT @Atual
SET @Contador = @Contador + 1
END
SET @Contador = 1
SET @Atual = ''
WHILE(@Contador <= @Total)
BEGIN
SET @Atual = @Atual + CAST((CASE WHEN @Contador = 10 THEN 0 ELSE @Contador END) AS VARCHAR(100))
INSERT INTO #Senhas
SELECT @Atual
SET @Contador = @Contador + 1
END
-- Logins
INSERT INTO #Senhas
SELECT [name]
FROM sys.sql_logins
INSERT INTO #Senhas
SELECT LOWER([name])
FROM sys.sql_logins
INSERT INTO #Senhas
SELECT UPPER([name])
FROM sys.sql_logins
INSERT INTO #Senhas
SELECT DISTINCT REVERSE(Senha)
FROM #Senhas
Y ahora intentamos identificar contraseñas débiles en la instancia:
SELECT
A.[name],
B.Senha
FROM
sys.sql_logins A
CROSS APPLY #Senhas B
WHERE
PWDCOMPARE(B.Senha, A.password_hash) = 1

En el informe anterior se muestran todos los usuarios donde fue posible identificar la contraseña, con sus respectivas contraseñas encontradas.
Lo ideal es que en la siguiente configuración de contraseña actives la opción “Aplicar política de contraseñas” (https://msdn.microsoft.com/en-us/library/ms161959.aspx), para garantizar que sus contraseñas sean sólidas y seguras.

Espero que hayas disfrutado del post y hasta luego.
Comentários (0)
Carregando comentários…