Cómo descifrar una contraseña del servidor SQL?

Tengo esta consulta en sql server 2000:

select pwdencrypt('AAAA') 

que emite una cadena cifrada de ‘AAAA’:

 0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D12625EF019E157120D58DD46569AC7BF4118455D

¿Cómo puedo convertir (descifrar) la salida de su origen (que es ‘AAAA’)?

Creo que pwdencrypt está usando un hash, por lo que no se puede invertir la secuencia hash, el algoritmo está diseñado por lo que es imposible.

Si está verificando la contraseña que ingresó un usuario, la técnica habitual es usar hash y luego compararla con la versión hash en la base de datos.

Así es como se puede verificar una tabla ingresada usered

 SELECT password_field FROM mytable WHERE password_field=pwdencrypt(userEnteredValue) 

Reemplace userEnteredValue con (gran sorpresa) el valor que el usuario ingresó 🙂

El algoritmo de hashing de contraseñas de SQL Server:

 hashBytes = 0x0100 | fourByteSalt | SHA1(utf16EncodedPassword+fourByteSalt) 

Por ejemplo, para cifrar la contraseña “grapa correcta de batería de caballo” . Primero generamos sal al azar:

 fourByteSalt = 0x9A664D79; 

Y luego hash la contraseña (codificada en UTF-16) junto con la sal:

  SHA1("correct horse battery staple" + 0x9A66D79); =SHA1(0x63006F007200720065006300740020006200610074007400650072007900200068006F00720073006500200073007400610070006C006500 0x9A66D79) =0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 

El valor almacenado en la tabla syslogins es la concatenación de:

[encabezado] + [sal] + [hash]
0x0100 9A664D79 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

Que puedes ver en SQL Server:

 SELECT name, CAST(password AS varbinary(max)) AS PasswordHash FROM sys.syslogins WHERE name = 'sa' name PasswordHash ==== ====================================================== sa 0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 
  • Encabezado de la versión: 0100
  • Sal (cuatro bytes): 9A664D79
  • Hash: 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 (SHA-1 tiene 20 bytes; 160 bits)

Validación

Valida una contraseña realizando el mismo hash:

  • agarra la sal del PasswordHash guardado: 0x9A664D79

y realizar el hash de nuevo:

 SHA1("correct horse battery staple" + 0x9A66D79); 

que saldrá con el mismo hash, y usted sabe que la contraseña es correcta.

Lo que una vez fue bueno, pero ahora es débil

El algoritmo hash introducido con SQL Server 7, en 1999, fue bueno para 1999.

  • Es bueno que la contraseña hash salada.
  • Es bueno agregar la sal a la contraseña, en lugar de anteponerla .

Pero hoy está desactualizado. Solo ejecuta el hash una vez, donde debe ejecutarlo unas mil veces, para frustrar los ataques de fuerza bruta.

De hecho, el Baseline Security Analyzer de Microsoft, como parte de sus controles, intentará crear contraseñas de fuerza bruta. Si adivina alguno, informa las contraseñas como débiles. Y consigue algo.

Fuerza bruta

Para ayudarte a probar algunas contraseñas:

 DECLARE @hash varbinary(max) SET @hash = 0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 --Header: 0x0100 --Salt: 0x9A664D79 --Hash: 0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 DECLARE @password nvarchar(max) SET @password = 'password' SELECT @password AS CandidatePassword, @hash AS PasswordHash, --Header 0x0100 + --Salt CONVERT(VARBINARY(4), SUBSTRING(CONVERT(NVARCHAR(MAX), @hash), 2, 2)) + --SHA1 of Password + Salt HASHBYTES('SHA1', @password + SUBSTRING(CONVERT(NVARCHAR(MAX), @hash), 2, 2)) 

SQL Server 2012 y SHA-512

A partir de SQL Server 2012, Microsoft cambió a usar SHA-2 de 512 bits:

 hashBytes = 0x0200 | fourByteSalt | SHA512(utf16EncodedPassword+fourByteSalt) 

Cambiar el prefijo de versión a 0x0200 :

 SELECT name, CAST(password AS varbinary(max)) AS PasswordHash FROM sys.syslogins name PasswordHash ---- -------------------------------- xkcd 0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38 
  • Versión: 0200 (SHA-2 de 256 bits)
  • Sal: 6A80BA22
  • Hash (64 bytes): 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

Esto significa que hash la contraseña codificada UTF-16, con el sufijo salt:

  • SHA512 ( “grapa correcta de la batería del caballo” + 6A80BA22 )
  • SHA512 ( 63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500 + 6A80BA22 )
  • 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

Se da cuenta de que puede estar haciendo una barra para su propia espalda para el futuro. Pwdencrypt () y pwdcompare () son funciones no documentadas y es posible que no se comporten igual en futuras versiones de SQL Server.

¿Por qué no hash la contraseña usando un algoritmo predecible como SHA-2 o mejor antes de llegar a la base de datos?

Realmente no deberías estar descifrando las contraseñas.

Debería cifrar la contraseña ingresada en su aplicación y compararla con la contraseña cifrada de la base de datos.

Editar – y si esto se debe a que se olvidó la contraseña, configure un mecanismo para crear una nueva contraseña.

No puede descifrar esta contraseña nuevamente, pero hay otro método llamado “pwdcompare”. Aquí hay un ejemplo de cómo usarlo con syntax SQL:

 USE TEMPDB GO declare @hash varbinary (255) CREATE TABLE tempdb..h (id_num int, hash varbinary (255)) SET @hash = pwdencrypt('123') -- encryption INSERT INTO tempdb..h (id_num,hash) VALUES (1,@hash) SET @hash = pwdencrypt('123') INSERT INTO tempdb..h (id_num,hash) VALUES (2,@hash) SELECT TOP 1 @hash = hash FROM tempdb..h WHERE id_num = 2 SELECT pwdcompare ('123', @hash) AS [Success of check] -- Comparison SELECT * FROM tempdb..h INSERT INTO tempdb..h (id_num,hash) VALUES (3,CONVERT(varbinary (255), 0x01002D60BA07FE612C8DE537DF3BFCFA49CD9968324481C1A8A8FE612C8DE537DF3BFCFA49CD9968324481C1A8A8)) SELECT TOP 1 @hash = hash FROM tempdb..h WHERE id_num = 3 SELECT pwdcompare ('123', @hash) AS [Success of check] -- Comparison SELECT * FROM tempdb..h DROP TABLE tempdb..h GO 

Un Google rápido indica que pwdencrypt () no es determinista, y su instrucción de selección pwdencrypt (‘AAAA’) devuelve un valor diferente en mi instalación.

Ver también este artículo http://www.theregister.co.uk/2002/07/08/cracking_ms_sql_server_passwords/