web-dev-qa-db-fra.com

Comment décrypter un mot de passe depuis le serveur SQL?

J'ai cette requête dans SQL Server 2000:

select pwdencrypt('AAAA')

qui génère une chaîne chiffrée de 'AAAA':

 0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D12625EF019E157120D58DD46569AC7BF4118455D 

Comment puis-je convertir (décrypter) la sortie de son origine (qui est 'AAAA')?

16
sef

Je crois que pwdencrypt utilise un hachage, vous ne pouvez donc pas vraiment inverser la chaîne hachée - l'algorithme est conçu de sorte qu'il est impossible.

Si vous vérifiez le mot de passe qu'un utilisateur a entré, la technique habituelle consiste à le hacher, puis à le comparer à la version hachée de la base de données.

Voici comment vérifier une table saisie par l'utilisateur

SELECT password_field FROM mytable WHERE password_field=pwdencrypt(userEnteredValue)

Remplacez userEnteredValue par (grosse surprise) la valeur entrée par l'utilisateur :)

16
Svet

L'algorithme de hachage de mot de passe SQL Server:

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

Par exemple, pour hacher le mot de passe "agrafe de batterie de cheval correcte" . D'abord, nous générons du sel aléatoire:

fourByteSalt = 0x9A664D79;

Et puis hachez le mot de passe (encodé en UTF-16) avec le sel:

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

La valeur stockée dans la table syslogins est la concaténation de:

[en-tête] + [sel] + [hachage]
0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

Que vous pouvez voir dans SQL Server:

SELECT 
   name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins
WHERE name = 'sa'

name  PasswordHash
====  ======================================================
sa    0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
  • En-tête de version: 0100
  • Sel (quatre octets): 9A664D79
  • Hachage: 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 (SHA-1 est de 20 octets; 160 bits)

Validation

Vous validez un mot de passe en effectuant le même hachage:

  • récupérez le sel du PasswordHash: 0x9A664D79 enregistré

et recommencez le hachage:

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

qui sortira sur le même hachage, et vous savez que le mot de passe est correct.

Ce qui était bon autrefois est faible

L'algorithme de hachage introduit avec SQL Server 7, en 1999, était bon pour 1999.

  • Il est bon que le hachage du mot de passe soit salé.
  • Il est bon de ajouter le sel au mot de passe, plutôt que ajouter celui-ci.

Mais aujourd'hui, elle est dépassée. Il n'exécute le hachage qu'une seule fois, où il devrait l'exécuter plusieurs milliers de fois, afin de contrecarrer les attaques par force brute.

En fait, Baseline Security Analyzer de Microsoft tentera, dans le cadre de ses vérifications, de forcer les mots de passe par bruteforce. S'il en devine, il signale les mots de passe comme faibles. Et il en obtient.

Forçage brutal

Pour vous aider à tester certains mots de passe:

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 et SHA-512

Depuis SQL Server 2012, Microsoft est passé à l'utilisation de SHA-2 512 bits:

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

Modification du préfixe de version en 0x0200:

SELECT 
   name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins

name  PasswordHash
----  --------------------------------
xkcd  0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
  • Version: 0200 (SHA-2 256 bits)
  • Sel: 6A80BA22
  • Hachage (64 octets): 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

Cela signifie que nous hachons le mot de passe encodé UTF-16, avec le suffixe salt:

  • SHA512 ( "agrafe de batterie de cheval correcte" + 6A80BA22)
  • SHA512 (63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500 + 6A80BA22)
  • 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
20
Ian Boyd

Vous vous rendez compte que vous fabriquez peut-être une tige pour votre propre dos pour l'avenir. Les fonctions pwdencrypt () et pwdcompare () sont des fonctions non documentées et pourraient ne plus se comporter de la même manière dans les futures versions de SQL Server.

Pourquoi ne pas hacher le mot de passe en utilisant un algorithme prévisible tel que SHA-2 ou mieux avant de frapper la base de données?

12
Kev

Vous ne devriez pas vraiment décrypter les mots de passe.

Vous devez chiffrer le mot de passe entré dans votre application et le comparer avec le mot de passe chiffré de la base de données.

Modifier - et si cela est dû au fait que le mot de passe a été oublié, configurez un mécanisme pour créer un nouveau mot de passe.

4
Dynite

Un rapide google indique que pwdencrypt () n'est pas déterministe, et votre déclaration sélectionnez pwdencrypt ('AAAA') renvoie une valeur différente sur mon installation!

Voir également cet article http://www.theregister.co.uk/2002/07/08/cracking_ms_sql_server_passwords/

1
devio

Vous ne pouvez plus déchiffrer ce mot de passe mais il existe une autre méthode nommée "pwdcompare". Voici un exemple d'utilisation de la syntaxe 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
1
Anheledir