fixup old local state parsing

This commit is contained in:
Lee Chagolla-Christensen
2025-09-29 14:55:09 -07:00
parent 2af2c68c6f
commit 002b8ba910
3 changed files with 15 additions and 18 deletions
+4 -10
View File
@@ -8,8 +8,7 @@ import psycopg
import structlog
from Crypto.Cipher import AES, ChaCha20_Poly1305
from dapr.clients import DaprClient
from impacket.dpapi import DPAPI_BLOB
from impacket.uuid import bin_to_string
from nemesis_dpapi import Blob
logger = structlog.get_logger(module=__name__)
@@ -101,15 +100,10 @@ def detect_encryption_type(encrypted_value: bytes) -> tuple[str, str | None]:
# Check for DPAPI (first 4 bytes are \x01\x00\x00\x00)
if encrypted_value[:4] == b"\x01\x00\x00\x00":
try:
blob = DPAPI_BLOB(encrypted_value)
if blob.rawData is not None:
blob.rawData = blob.rawData[: len(blob.getData())]
masterkey_guid = bin_to_string(blob["GuidMasterKey"]).lower()
return "dpapi", masterkey_guid
blob = Blob.parse(encrypted_value)
return "dpapi", str(blob.masterkey_guid)
except Exception as e:
logger.warning("Failed to parse DPAPI blob", error=str(e))
return "dpapi", None
return "dpapi", None
raise Exception(f"Found DPAPI app bound key, but couldn't parse blob: {str(e)}") from e
# Check for key-based encryption (v10, v11)
if len(encrypted_value) >= 3:
+2 -1
View File
@@ -57,7 +57,7 @@ async def process_chromium_local_state(
with psycopg.connect(conn_str) as pg_conn:
state_key_data = await _insert_state_keys(file_enriched, username, browser, content, pg_conn, dpapi_manager)
logger.warning("Completed processing Chromium Local State", object_id=object_id)
logger.debug("Completed processing Chromium Local State", object_id=object_id)
return state_key_data
@@ -155,6 +155,7 @@ async def _insert_state_keys(
app_bound_key_b64 = os_crypt.get("app_bound_encrypted_key")
app_bound_key_enc = b""
app_bound_key_system_masterkey_guid = None
app_bound_key_user_masterkey_guid = None
if app_bound_key_b64:
logger.debug("Found v2 app bound key encrypted_key in Local State")
+9 -7
View File
@@ -1,7 +1,7 @@
"""Chromium Login Data file parsing and database operations."""
import sqlite3
import asyncio
import sqlite3
import psycopg
import structlog
@@ -109,7 +109,7 @@ def _insert_logins(
try:
password_dec_bytes = asyncio.run(dpapi_manager.decrypt_blob(Blob.parse(password_value)))
if password_dec_bytes:
password_value_dec = password_dec_bytes.decode('utf-8', errors='replace')
password_value_dec = password_dec_bytes.decode("utf-8", errors="replace")
is_decrypted = True
except:
pass
@@ -134,13 +134,15 @@ def _insert_logins(
password_dec_bytes = password_dec_bytes[:-16]
# v20 passwords typically don't have offset like cookies
password_value_dec = password_dec_bytes.decode('utf-8', errors='replace')
password_value_dec = password_dec_bytes.decode("utf-8", errors="replace")
is_decrypted = True
except Exception as e:
logger.debug("Failed to decrypt password with state key",
state_key_id=state_key_id,
encryption_type=encryption_type,
error=str(e))
logger.debug(
"Failed to decrypt password with state key",
state_key_id=state_key_id,
encryption_type=encryption_type,
error=str(e),
)
login_data = {
"originating_object_id": file_enriched.object_id,