Как расшифровать пароль с сервера SQL? - PullRequest
16 голосов
/ 06 октября 2008

У меня есть этот запрос в SQL Server 2000:

select pwdencrypt('AAAA')

, который выводит зашифрованную строку 'AAAA':

0x0100CF465B7B12625EF019E157120D58DD46569AC7BF4118455D12625EF019E157120D58DD46569AC7BF4118455D

Как я могу преобразовать (расшифровать) вывод из его источника (который является 'AAAA')?

Ответы [ 6 ]

19 голосов
/ 09 августа 2013

Алгоритм хеширования паролей SQL Server:

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

Например, для хэширования пароля "правильный скрепка батареи для лошадей" . Сначала мы генерируем некоторую случайную соль:

fourByteSalt = 0x9A664D79;

А затем хэшируйте пароль (закодированный в UTF-16) вместе с солью:

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

Значение, хранящееся в таблице syslogins, представляет собой конкатенацию:

[заголовок] + [соль] + [хеш]
0x0100 9A664D79 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

Что вы можете увидеть в SQL Server:

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

name  PasswordHash
====  ======================================================
sa    0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
  • Заголовок версии: 0100
  • Соль (четыре байта): 9A664D79
  • Хеш: 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 (SHA-1 составляет 20 байтов; 160 бит)

Проверка

Вы проверяете пароль, выполняя тот же хеш:

  • захватите соль из сохраненных PasswordHash: 0x9A664D79

и снова выполните хеширование:

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

, который получит тот же хеш, и вы знаете, что пароль правильный.

То, что когда-то было хорошо, а сейчас слабо

Алгоритм хеширования, введенный в SQL Server 7 в 1999 году, был хорош для 1999 года.

  • Хорошо, что хеш пароля солен.
  • Хорошо добавить соль к паролю, а не предварять его.

Но сегодня оно устарело. Он запускает хэш только один раз, где он должен запускать его несколько тысяч раз, чтобы предотвратить атаки методом грубой силы.

Фактически, Microsoft Baseline Security Analyzer, в рамках своих проверок, попытается взломать пароли. Если он угадает, он сообщает, что пароли слабые. И это действительно есть.

Перебор

Чтобы помочь вам проверить некоторые пароли:

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

Начиная с SQL Server 2012, Microsoft перешла на использование SHA-2 512-бит:

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

Изменение префикса версии на 0x0200:

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

name  PasswordHash
----  --------------------------------
xkcd  0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
  • Версия: 0200 (256-бит SHA-2)
  • Соль: 6A80BA22
  • Хеш (64 байта): 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

Это означает, что мы хешируем пароль в кодировке UTF-16 с суффиксом соли:

  • SHA512 ( "правильная скоба батареи для лошадей" + 6A80BA22)
  • SHA512 (63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500 + 6A80BA22)
  • 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
16 голосов
/ 06 октября 2008

Я считаю, что pwdencrypt использует хеш, поэтому вы не можете по-настоящему перевернуть хешированную строку - алгоритм разработан так, что это невозможно.

Если вы проверяете пароль, что пользователь ввел обычную технику, это хэширует его, а затем сравнивает с хешированной версией в базе данных.

Так вы можете проверить использованную введенную таблицу

SELECT password_field FROM mytable WHERE password_field=pwdencrypt(userEnteredValue)

Замените userEnteredValue на (большое удивление) значение, введенное пользователем:)

12 голосов
/ 06 октября 2008

Вы понимаете, что, возможно, делаете будущее для своей спины на будущее. Pwdencrypt () и pwdcompare () являются недокументированными функциями и могут не вести себя так же в будущих версиях SQL Server.

Почему бы не хэшировать пароль, используя предсказуемый алгоритм, такой как SHA-2 или лучше, прежде чем попасть в БД?

4 голосов
/ 06 октября 2008

Вы не должны дешифровать пароли.

Вы должны зашифровать пароль, введенный в ваше приложение, и сравнить его с зашифрованным паролем из базы данных.

Изменить - и если это потому, что пароль был забыт, то настройте механизм для создания нового пароля.

1 голос
/ 06 октября 2008

Быстрый google означает, что pwdencrypt () не является детерминированным, и ваш оператор select pwdencrypt ('AAAA') возвращает другое значение в моей установке!

См. Также эту статью http://www.theregister.co.uk/2002/07/08/cracking_ms_sql_server_passwords/

1 голос
/ 06 октября 2008

Вы не можете расшифровать этот пароль снова, но есть другой метод с именем "pwdcompare". Вот пример того, как использовать его с синтаксисом 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
...