Главная » Форензика » Стиллер паролей для Chrome и Firefox

Стиллер паролей для Chrome и Firefox

Стилер для Chrome и Firefox на C++

Вы наверное знаете о том, что такое стилеры паролей. Их задача — вытащить из операционной системы важные данные, такие как пароли. В сегодняшней статье я расскажу, как хакеры создают стиллер паролей для браузеров Chrome и Firefox.

Весь материал статьи приводится исключительно в образовательных целях и для восстановления личных паролей. Кража чужих учетных или других личных данных без специального письменного соглашения владельца компьютера карается по закону.

Итак, браузеры, в основе которых лежит Google Chrome или Mozilla Firefox, хранят логины и пароли пользователей в зашифрованном виде в базе SQLite. Эта СУБД компактна и распространяется бесплатно по свободной лицензии. Так же, как и рассматриваемые нами браузеры: весь их код открыт и хорошо документирован, что, несомненно, поможет нам в создании стиллера.

В примере модуля стилинга, который я приведу в статье, будет активно использоваться CRT и другие сторонние библиотеки и зависимости, типа sqlite.h. Если вам нужен компактный код без зависимостей, придется его немного переработать, избавившись от некоторых функций и настроив компилятор должным образом.

Все современные и более-менее серьезные вирусы и трояны имеют модульную структуру, каждый модуль в которой отвечает за что-то свое: один модуль находит и собирает пароли, второй препятствует отладке и эмуляции, третий определяет факт работы в песочнице или виртуальной машине, четвертый проводит обфускацию вызовов WinAPI, пятый разбирается со встроенным в ОС файрволом.

Стиллер для Chrome

Начнем с браузера Google Chrome. Для начала давайте получим файл, где хранятся учетные записи и пароли пользователей. В Windows он лежит по такому адресу:

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

Давайте напишем функцию, которая получает путь к базе паролей Chrome. В качестве аргумента ей будет передаваться массив символов с результатом ее работы (то есть массив будет содержать путь к файлу паролей Chrome).

Вызов функции:

Давайте вкратце поясню, что здесь происходит. Мы сразу пишем эту функцию, подразумевая будущее расширение. Один из ее аргументов — поле browser_family, оно будет сигнализировать о семействе браузеров, базу данных которых мы получаем (то есть браузеры на основе Chrome или Firefox).

Если условие browser_family = 0 выполняется, то получаем базу паролей браузера на основе Chrome, если browser_family = 1 — Firefox. Идентификатор CHROME_DB_PATH указывает на базу паролей Chrome. После этого мы получаем путь к базе при помощи функции SHGetFolderPath, передавая ей в качестве аргумента CSIDL значение CSIDL_LOCAL_APPDATA, которое означает:

Функция SHGetFolderPath уже устарела, и в Microsoft рекомендуют использовать вместо нее SHGetKnownFolderPath. Проблема кроется в том, что поддержка этой функции начинается с Windows Vista, поэтому я применил ее более старый аналог для сохранения обратной совместимости. Вот ее прототип:

После этого функция lstrcat совмещает результат работы SHGetFolderPath с идентификатором CHROME_DB_PATH.

База паролей получена, теперь приступаем к работе с ней. Как я уже говорил, это база данных SQLite, работать с ней удобно через SQLite API, которые подключаются с заголовочным файлом sqlite3.h. Давайте скопируем файл базы данных, чтобы не занимать его и не мешать работе браузера.

Теперь подключаемся к базе командой sqlite3_open_v2. Ее прототип:

Первый аргумент — наша база данных; информация о подключении возвращается во второй аргумент, дальше идут флаги открытия, а четвертый аргумент определяет интерфейс операционной системы, который должен использовать это подключение к базе данных, в нашем случае он не нужен. Если эта функция отработает корректно, возвращается значение SQLITE_OK, в противном случае возвращается код ошибки.

Обратите внимание: при некорректной отработке функции нам все равно необходимо самостоятельно закрыть подключение к базе и удалить ее копию.

Теперь начинаем непосредственно обрабатывать данные в базе. Для этого воспользуемся функцией sqlite3_exec().

Эта функция имеет такой прототип:

Первый аргумент — наша база паролей, второй — это команда SQL, которая вытаскивает URL файла, логин, пароль и имя пользователя, третий аргумент — это функция обратного вызова, которая и будет расшифровывать пароли, четвертый — передается в нашу функцию обратного вызова, ну а пятый аргумент сообщает об ошибке.

Давайте остановимся подробнее на callback-функции, которая расшифровывает пароли. Она будет использоваться к каждой строке из выборки нашего запроса SELECT. Ее прототип — int (*callback)(void*,int,char**,char**), но все аргументы нам не понадобятся, хотя объявлены они должны быть. Саму функцию назовем crack_chrome_db, начинаем писать и объявлять нужные переменные:

В этом цикле формируем BLOB (то есть большой массив двоичных данных). Далее выделяем память, читаем блоб и инициализируем поля DATA_BLOB:

А теперь приступим непосредственно к дешифровке паролей. База данных Chrome зашифрована механизмом Data Protection Application Programming Interface (DPAPI). Суть этого механизма заключается в том, что расшифровать данные можно только под той учетной записью, под которой они были зашифрованы. Другими словами, нельзя вытащить базу данных паролей, а потом расшифровать ее уже на своем компьютере (об этом мы писали в статье «Где в Chrome хранятся пароли»). Для расшифровки данных нам потребуется функция CryptUnprotectData.

После этого выделяем память и заполняем массив passwds расшифрованными данными.

Собственно, на этом все! После этого passwds будет содержать учетные записи пользователей и URL. Можно эту информацию вывести на экран или сохранить в файл и отправить куда-нибудь.

Стиллер для Firefox

Переходим к Firefox. Это будет немного посложнее. Для начала давайте получим путь до базы данных паролей Firefox. Помните, в нашей универсальной функции get_browser_path мы передавали параметр browser_family? В случае Chrome он был равен нулю, а для Firefox установим 1.

В случае с Firefox мы не сможем, как в Chrome, сразу указать путь до каталога пользователя. Дело в том, что имя каталога пользовательского профиля генерируется случайным образом. Но это не помеха, ведь известно начало пути (\\Mozilla\\Firefox\\Profiles\\). Достаточно поискать в нем объект «папка» и проверить наличие в ней файла \\logins.json«. Именно в этом файле хранятся данные логинов и паролей. Разумеется, в зашифрованном виде. Реализуем все это в коде.

В самом конце переменная db_loc, которую мы передавали в качестве аргумента в нашу функцию, содержит полный путь до файла logins.json, а функция возвращает 1, сигнализируя о том, что она отработала корректно.

Теперь получим хендл файла паролей и выделим память под данные. Для получения хендла используем функцию CreateFile, как советует MSDN.

Все готово, но в случае с Firefox все не будет так просто, как с Chrome, — мы не сможем просто получить нужные данные обычным запросом SELECT, да и шифрование не ограничивается одной-единственной функцией WinAPI.

Network Security Services (NSS)

Браузер Firefox активно использует функции Network Security Services для реализации шифрования своей базы паролей. Эти функции находятся в динамической библиотеке, которая лежит по адресу:

Все интересующие функции придется получать из этой DLL. Сделать это можно стандартным образом, при помощи LoadLibrary\GetProcAdress. Код однообразный и большой, поэтому я просто приведу список функций, которые нам понадобятся:

  • NSS_Init;
  • PL_Base64Decode;
  • PK11SDR_Decrypt;
  • PK11_Authenticate;
  • PK11_GetInternalKeySlot;
  • PK11_FreeSlot.

Это функции инициализации механизма NSS и расшифровки данных. Давайте напишем функцию расшифровки, она небольшая. Я добавлю комментарии, чтобы все было понятно.

Теперь осталось парсить файл logins.json и применять нашу функцию расшифровки. Для краткости кода я буду использовать регулярные выражения и их возможности в C++ 11.

Защита от стиллера паролей

Мы разобрались, как хранятся пароли в разных браузерах, и узнали, что нужно делать, чтобы их извлечь. Можно ли защититься от подобных методов восстановления сохраненных паролей? Да, конечно. Если установить в браузере мастер-пароль, то он выступит в качестве криптографической соли для расшифровки базы данных паролей. Без ее знания восстановить данные будет невозможно.

Еще по теме: Исохдники вирусов

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *