Где на компьютере хранятся пароли и как их просмотреть в случае необходимости?
То, что пользователи достаточно часто забывают пароли от всевозможных программ, интернет-сайтов или даже те комбинации, которые используются для входа в систему, знают все. Поэтому и возникает проблема их быстрого восстановления. Но где хранятся все вводимые на компьютере пароли? Как их найти и посмотреть в случае необходимости? Увы, все далеко не так просто. В самом простом случае можно узнать пароли для интернет-ресурсов, а вот с локальными или сетевыми паролями возникает множество проблем, тем более что средствами Windows просмотреть их не представляется возможным, а использование специализированного программного обеспечения освоить могут далеко не все рядовые пользователи. Но для понимания общей картины некоторую ясность внесет представленный ниже материал.
Где на компьютере хранятся пароли: общая информация
Для начала следует отметить тот факт, что какого-то единого и универсального места сохранения парольных комбинаций нет. Основная проблема состоит в том, что операционная система использует собственные хранилища в виде недоступных пользователю и защищенных от просмотра зашифрованных файлов. Некоторые программы могут сохранять пользовательские данные в собственных файлах настроек. А вот если разбираться в том, где на компьютере хранятся пароли браузеров, тут знание местонахождения не нужно, поскольку просмотреть все сохраненные комбинации можно прямо в них самих. Но об этом чуть позже.
В каком виде и где хранятся сохраненные на компьютере пароли, относящиеся ко входу в систему и сетевым настройкам?
Но давайте отталкиваться от того, что нам для начала нужно узнать именно локацию, в которой сохраняется файл с паролями пользователей, а не просмотреть исходную комбинацию. Локальные пользовательские комбинации, относящиеся ко входу в систему или для возможности использования сетевых подключений, сохраняются непосредственно в каталоге каждого пользователя, условно обозначаемого как User SID. В версии ХР в качестве локации используется папка Credentials, а в «Висте» и выше таким местом выбран подкаталог Random ID.
В ветке реестра HKU локациям файлов паролей соответствуют ключи в виде длинных комбинаций, начинающиеся со значений «S-1-5-21». Но это в большинстве случаев только указание на сами файлы, поскольку просмотреть сохраненные комбинации невозможно ни в самих файлах, ни даже в реестре, хотя изменить исходные хранящиеся на компьютере пароли можно совершенно элементарно через соответствующие настройки управления сетевыми подключениями или учетными записями пользователей, которые доступны в графическом интерфейсе.
Для администраторских паролей входа в систему можно обратить внимание на раздел реестра SAM.
Для VPN- и Dial-Up-подключений в ветке реестра HKLM имеются разделы Secrets и SECURITY с ключами вроде RasDialParams, но и они ровным счетом никакой особой информации обычному юзеру не дают. Другое дело, что просмотреть и изменить пароль сетевого доступа можно либо в настройках Windows, либо прямо на маршрутизаторе. Кстати сказать, по схожему принципу сохраняются и парольные комбинации для большинства встроенных в систему почтовых клиентов или утилит от сторонних разработчиков, если они представлены именно в виде отдельных приложений, что не относится к интернет-сервисам вроде почты Mail.Ru или чего-то подобного.
Место сохранения паролей для программы Skype и проблемы просмотра искомых комбинаций
Достаточно часто приходится выяснять, где на компьютере хранятся пароли от установленных программ. В частности, это касается популярного приложения Skype, с которым в последнее время у многих пользователей наблюдаются проблемы входа в собственные аккаунты.
Установленное приложение хранит пользовательскую комбинаций в специальном XML-файле, где паролю соответствует значение хэша (). Да, но здесь пароль представлен в 16-ричном виде и просто так просмотреть его не получится. Поэтому для таких целей необходимо использовать HEX-редактор. Но и применение таких утилит без соответствующих знаний результата может не дать.
Просмотр паролей в браузерах
Теперь посмотрим, где на компьютере хранятся пароли, сохраняемые непосредственно в веб-обозревателях, которые используются для работы в интернете. Собственно, как уже было сказано выше, само местоположение файлов нас не интересует.
А вот просмотреть пароли можно прямо в браузере, если в разделе основных настроек перейти к пункту управления сохраненными паролями, где в списке будут представлены все ресурсы, для которых такие комбинации были сохранены. Далее нужно всего нажать на кнопку или ссылку показа пароля, после чего забытую комбинацию можно перенести в текстовый файл или просто записать.
Специализированные программы для «вытаскивания» всех вводимых паролей
Но можно предположить, что пользователю мало знать, где на компьютере хранятся пароли, а нужно еще их как-то «вытащить» из системы для просмотра. Для выполнения таких операций в самих Windows-системах средств нет, зато без проблем можно воспользоваться всевозможным и сторонними программами наподобие Password Recovery Tool, PSexec, входящей в состав пакета PSTools, PasswordSpy или аналогичными.
В них необходимо всего лишь активировать сканирование системных компонентов на предмет обнаружения сохраненных паролей, а затем задать их извлечение и преобразование в читабельный вид.
Послесловие
Как видим, все, что касается места и формы сохранения парольных комбинаций, даже многим опытным пользователям может показаться достаточно сложным. Но вот в случае их изменения или просмотра особых трудностей возникнуть не должно, поскольку для этого сгодятся и некоторые стандартные средства системы, и сторонние приложения, которые очень просты в использовании. Впрочем, знать именно место хранения в виде конкретного каталога или зашифрованного файла в этом случае совершенно необязательно.
Хранение и шифрование паролей Microsoft Windows / Habr
V-блок
Windows до версии Vista по умолчанию хранила пароль в двух разных хэшах — LM и NT. В висте и выше LM-хэш не хранится. Для начала посмотрим где искать эти хэши, а потом разберемся что из себя они представляют. Пароли пользователей, а так же много другой полезной информации хранится в реестре по адресу HKLMSAMSAMDomainsAccountusers[RID]V
, известном как V-блок. Раздел SAM находится в соответствующем файле c:WindowsSystem32configSAM
. RID — уникальный идентификатор пользователя, его можно узнать, например заглянув в ветку HKLMSAMSAMDomainsAccountusersnames
(параметр Default, поле — тип параметра). Например, RID учетной записи «Администратор» всегда 500 (0x1F4), а пользователя «Гость» — 501 (0x1f5). Доступ к разделу SAM по умолчанию возможен только пользователю SYSTEM, но если очень хочется посмотреть — запускаем regedit c правами системы: PsExec.exe -s -i -d regedit.
Чтобы наблюдать V-блок в удобном виде можно, например, экспортировать его в текстовый файл (File-Export в Regedit). Вот что мы там увидим: От 0x0 до 0xCC располагаются адреса всех данных, которые находятся в V-блоке, их размеры и некоторая дополнительная информация о данных. Чтобы получить реальный адрес надо к тому адресу, что найдем прибавить 0xCC. Адреса и размеры хранятся по принципу BIG ENDIAN, т.е понадобится инвертировать байты. На каждый параметр отводится по 4 байта, но фактически все параметры умещаются в одном-двух байтах. Вот где искать: Адрес имени пользователя — 0xС Длина имени пользователя — 0x10 Адрес LM-хэша — 0x9с Длина LM-хэша — 0xa0 Адрес NT-хэша — 0xa8 длина NT-хэша — 0xac В данном случае имя пользователя найдется по смещению 0xd4 + 0xcc и его длина будет 0xc байт. NT-хэш будет располагаться по смещению 0x12c + 0xcc и его размер (всегда один и тот же) = 0x14. Еще одна деталь, касающаяся хранения паролей — как к NT- так и к LM-хэшу всегда добавляются спереди 4 байта, назначение которых для меня загадка. Причем 4байта будут присутствовать даже если пароль отключен. В данном случае видно, что длина LM хэша =4 и если посмотреть на его адрес, можно эти 4 байта увидеть несмотря на то что никакого LM-хэша нет. Поэтому при поиске смещений хэшей смело прибавляем 4 байта к адресу, а при учете размеров — вычитаем. Если удобнее читать код — вот примерно так будет выглядеть поиск адресов с учетом инверсии, лишних четырех байтов и прибавления стартового смещения 0xcc (код C#) int lmhashOffset = userVblock[0x9c] + userVblock[0x9d] * 0x100 + 4 + 0xcc;
rn int nthashOffset = userVblock[0xa8] + userVblock[0xa9] * 0x100 + 4 + 0xcc;
rn int lmhashSize = userVblock[0xa0] + userVblock[0xa1] * 0x100 - 4;
rn int nthashSize = userVblock[0xac] + userVblock[0xad] * 0x100 - 4;
rn int usernameOffset = userVblock[0xc] + userVblock[0xd] * 0x100 + 0xcc;
rn int usernameLen = userVblock[0x10] + userVblock[0x1a] * 0x100;
userVblock — значение HKLMSAMSAMDomainsAccountusers\V в виде массива байт. Еще про V-блок можно почитать тут.
Алгоритмы
Теперь разберемся в алгоритмах шифрования. Формирование NT-хэша
: 1. Пароль пользователя преобразуется в Unicode-строку. 2. Генерируется MD4-хэш на основе данной строки. 3. Полученный хэш шифруется алгоритмом DES, ключ составляется на основе RID пользователя. Формирование LM-хэша
: 1. Пароль пользователя преобразуется в верхний регистр и дополняется нулями до длины 14 байт. 2. Полученная строка делится на две половинки по 7 байт и каждая из них по отдельности шифруется алгоритмом DES. В итоге получаем хэш длиной 16 байт (состоящий из двух независимых половинок длиной по 8 байт). 3. Полученный хэш шифруется алгоритмом DES, ключ составляется на основе RID пользователя.4.
В windows 2000 и выше оба полученых хэша дополнительно шифруются алоритмом RC4 с помощью ключа, известного как «системный ключ» или bootkey, сгенерированого утилитой syskey, и шифруются довольно хитрым образом. Рассмотрим общую последовательность действий для получения исходного пароля и каждый шаг в отдельности 1. Получаем bootkey, генерируем на его основе ключи для RC4, расшифровываем хэши с помощью RC4 2. Получаем ключи для DES из RID’ов пользователей, расшифровываем хэши DES’ом 3. Полученые хэши атакуем перебором.
Bootkey
Системный ключ (bootkey) разбит на 4 части и лежит в следующих разделах реестра: Раздел system находится в файле c:WindowsSystem32configsystem Следует отметить, что раздел CurrentControlSet является ссылкой на один из разделов controlset и создается в момент загрузки системы. Это значит что не получится его найти в файле system, если система неактивна. Если вы решили искать ключ в файле — необходимо узнать значение ContolSet по умолчанию в HKLMSYSTEMSelectdefault. например если HKLMSYSTEMSelectdefault = 1 — вместо HKLMSystemCurrentControlSet
ищем в HKLMSystemcontrolset001
У каждого ключа реестра есть некий скрытый атрибут, известный как «class». Regedit его так просто не покажет, однако его можно увидеть, например, если экспортировать эти ключи реестра в текстовые файлы. В winapi для получения этого атрибута есть функция RegQueryInfoKey. Фрагменты хранятся в строковом представлении шестнадцатеричных чисел, причем по принципу BIG ENDIAN (т.е не строка задом наперед, а число). Например мы обнаружили вот такие записи:Key Name: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsaJD
rn Class Name: 46003cdb = {0xdb,0x3c,0x00,0x46}
rn Key Name: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsaSkew1
rn Class Name: e0387d24 = {0x24,0x7d,0x38,0xe0}
rn Key Name: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsaGBG
rn Class Name: 4d183449 = {0x49,0x34,0x18,0x4d}
rn Key Name: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsaData
rn Class Name: 0419ed03 = {0x03,0xed,0x19,0x04}
Собраный из четырех частей ключ будет массивом байт: scrambled_key = {0xdb,0x3c,0x00,0x46,0x24,0x7d,0x38,0xe0,0x49,0x34,0x18,0x4d,0x03,0xed,0x19,0x04};
Далее элементы этого массива переставляются на основе некоторого константного массива pint[] p = { 0xb, 0x6, 0x7, 0x1, 0x8, 0xa, 0xe, 0x0, 0x3, 0x5, 0x2, 0xf, 0xd, 0x9, 0xc, 0x4 };
Элементы в этом массиве определяют позиции для перестановок, т.е.key[i] = scrambled_key[p[i]];
rn
В нашем примере получится массив: key[] = {0x4d,0x38,0xe0,0x3c,0x49,0x18,0x19,0xdb,0x46,0x7d,0x00,0x04,0xed,0x34,0x03,0x24 };
этот массив и есть так называемый bootkey
. Только в шифровании паролей будет учавствовать не он а некий хэш на основе bootkey, фрагментов f-блока и некоторых констант. Назовем его Hashed bootkey.
Hashed bootkey
для получения Hashed bootkey нам понадобятся 2 строковые константы (ASCII): string aqwerty = "!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%";
rn string anum = "0123456789012345678901234567890123456789";
Также понадобится F-блок пользователя (HKLMSAMSAMDomainsAccountusers\F), а именно его 16 байт: F[0x70:0x80]
На основе этих значений, склееных в один большой массив формируем MD5 хэш, который будет являться ключем для шифрования RC4rc4_key = MD5(F[0x70:0x80] + aqwerty + bootkey + anum).
Последним шагом для получения hashed bootkey будет rc4 шифрование( или дешифрование — в rc4 это одна и та же функция) полученым ключем фрагмента F-блока F[0x80:0xA0]
;hashedBootkey = RC4(rc4_key,F[0x80:0xA0])
Hashed bootkey у нас в руках, осталось научиться с ним правильно обращаться.
Дешифруем пароли с помощью Hashed Bootkey
для паролей LM и NT нам понадобятся еще 2 строковые константы — string almpassword = "LMPASSWORD";
rn string antpassword = "NTPASSWORD";
а так же RID пользователя в виде 4х байт (дополненый нулями) и первая половина Hashed Bootkey (hashedBootkey[0x0:0x10]
); Все это склеивается в один массив байт и считается MD5 по правилам:rc4_key_lm = MD5(hbootkey[0x0:0x10] +RID + almpassword);
rn rc4_key_nt = MD5(hbootkey[0x0:0x10] +RID + antpassword);
полученый md5 хэш — ключ для rc4, которым зашифрованы LM и NT хэши в V-блоке пользователяuserLMpass = RC4(rc4_key_lm,userSyskeyLMpass);
rn userNTpass = RC4(rc4_key_lm,userSyskeyNTpass);
rn
На этом этапе мы получили пароли пользователя в том виде в каком они хранились бы без шифрования syskey, можно сказать, что самое сложное позади. Переходим к следующему шагу
DES
На основе четырех байт RID’а пользователя с помощью некоторых перестановок и побитовых операций создаем 2 ключа DES. Вот функции, которые осуществляют обфускацию (С#):private byte[] str_to_key(byte[] str) {
rn byte[] key = new byte[8];
rn key[0] = (byte)(str[0] >> 1);
rn key[1] = (byte)(((str[0] & 0x01) <> 2));
rn key[2] = (byte)(((str[1] & 0x03) <> 3));
rn key[3] = (byte)(((str[2] & 0x07) <> 4));
rn key[4] = (byte)(((str[3] & 0x0F) <> 5));
rn key[5] = (byte)(((str[4] & 0x1F) <> 6));
rn key[6] = (byte)(((str[5] & 0x3F) <> 7));
rn key[7] = (byte)(str[6] & 0x7F);
rn for (int i = 0; i < 8; i++) {
rn key[i] = (byte)(key[i] << 1);
rn }
rn des_set_odd_parity(ref key);
rn return key;
rn }
rn
rn private byte[] sid_to_key1(byte[] rid) {
rn byte[] s = new byte[7];
rn s[0] = (byte)(rid[0] & 0xFF);
rn s[1] = (byte)(rid[1] & 0xFF);
rn s[2] = (byte)(rid[2] & 0xFF);
rn s[3] = (byte)(rid[3] & 0xFF);
rn s[4] = s[0];
rn s[5] = s[1];
rn s[6] = s[2];
rn
rn return str_to_key(s);
rn }
rn
rn private byte[] sid_to_key2(byte[] rid) {
rn byte[] s = new byte[7];
rn s[0] = (byte)((rid[3]) & 0xFF);
rn s[1] = (byte)(rid[0] & 0xFF);
rn s[2] = (byte)((rid[1]) & 0xFF);
rn s[3] = (byte)((rid[2]) & 0xFF);
rn s[4] = s[0];
rn s[5] = s[1];
rn s[6] = s[2];
rn
rn return str_to_key(s);
rn }
Ну здесь особо комментировать нечего, кроме функции des_set_odd_parity(ref key)
— это одна из функций библиотеки openssl, задача которой добавить некоторые «биты нечетности», используется для повышения стойкости ключа к атакам. Далее разбиваем NT (или LM) хэш на 2 части по 8 байт и дешифруем DES’ом -одна половина зашифрована ключем сформированым функцией sid_to_key1, вторая — sid_to_key2.obfskey_l = userNTpass[0x0:0x7]
rn obfskey_r = userNTpass[0x8:0xF]
rn byte[] deskey1 = sid_to_key1(RID);
rn byte[] deskey2 = sid_to_key2(RID);
rn byte[] md4hash_l = DES(obfskey_l, deskey1);
rn byte[] md4hash_r = DES(obfskey_r, deskey2);
После склеивания двух половин мы получим md4 хэш -в случае NT, или LanMan (DES) — в случае LM. Полученый хэш полностью готов к атаке перебором. Кстати, md4 Хэш от пустого пароля — 31d6cfe0d16ae931b73c59d7e0c089c0
Исследование проведено на основе исходного кода ophcrack-3.3.1, а так же статьи Push the Red Button:SysKey and the SAM
292