-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Comments
The new version of Chromium has updated new encryption algorithm, prefix v20, the decryption method is under research. Ref: |
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. |
Chrome cookie encrypted_value v20 use 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.
IV:
This will yield the decrypted key, which works exactly as
Here is th PoC |
I am really looking forward to your new method to decrypt chrome, because I have been using your program for many years |
@runassu Great work! As you mentioned:
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 |
@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. |
How can we get the hardcoded key from |
@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 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 |
@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 |
@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 |
wrote my own golang version for those interested (as this is a golang project), big shoutout to the original 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. |
@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. |
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. |
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. |
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 |
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). |
I'm not sure how to construct the aes key for Edge/Brave. Eg. aes_key = decrypted_key[-32:]
iv = decrypted_key[0:12]
ciphertext = decrypted_key[12:12+32]
tag = decrypted_key[12+32:] |
@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"
Let me know if that makes more sense. |
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. |
Thanks! I missed another bit there and your example help me find the issue. pip install -U rookiepy |
Awesome, glad you got it working. |
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! |
Decrypt cookies for all profiles, for both new and old cookies:
|
Very interesting approach to escalate system privileges! |
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) |
Elastic Security Labs has released an article introducing the encryption in version v20. |
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. |
Recently, this program stops working for Microsoft Edge 114.0.1823.67 on Linux. I believe this might be caused by the same decryption issue. With release 0.4.5, I'm getting encrypted result like this: With release 0.4.6, I'm getting the following error message, and empty result:
With latest build from main branch, I'm getting the same empty result.
|
Do we also need a privileges to run code for copy token. All realization i saw needed admin rights for work. And i read it forbidden. Is it real to copy wthout rights? |
Hi |
I had the chance to dig into this problem. |
You need to be running in high integrity for the token duplication of a SYSTEM token. |
Circling back to this, its likely because you would need to duplicate the stolen token and attach it to the whoami spawned process. However, since you're impersonating, the current thread context is running as SYSTEM. |
I'm glad you've come across the assert failing as well, I'm seeing similar behavior on new Chrome builds. It seems to pop up when Chrome is installed fresh. An up-to-date version of Chrome running on a system that's had Chrome installed on it for a while still uses aesgcm for the last decrypt. Would you mind running through how you can across this key and encryption algorithm? Are you opening the elevation service in Ghidra/IDA and running through the code to find the key? |
Actually this key placed near the previous key in the elevation service. Yes, I used IDA opening the elevation service and debugging code to find out what algorithm they using and confirm using the second key. Finding algorithm was not easy. |
Appreciate the info. I'm going to take a look as well. Were you able to successfully decrypt the full Chrome statekey with the new alg and key? |
Just to sum everything down; Had the chance to dig into the Google Chrome's newest state key encryption algorithm, the magic happens in a internally implemented function: https://source.chromium.org/chromium/chromium/src/+/main:chrome/elevation_service/elevator.cc;l=216;bpv=1, as @runassu already explained, the PostProcessData does additional processing to the state key, where the latter was being encrypted using AES-256 GCM with the Key, IV and Nonce parsed from the base64-decoded, system and user DPAPI decrypted appbound encrypted key on Local State. The main change here was the cryptographic function implemented in PostProcessData as explained by @sdemius from AES-256 GCM to ChaCha20Poly1305, this can be confirmed on the function itself found on IDA (elevation_service.exe): The whole flow-of-execution can be easily found by searching this sequence of bytes: E9 8F 37 D7 F4 E1 FA 43 3D 19 30 4D C2 25 80 42 09 0E 2D 1D 7E EA 76 70 D4 1F 73 8D 08 72 96 60 As posted by mentioned user above. This key is used in this function: Where from my analysis it initializes the key for encryption/decryption. The key is stored in three separate variables, which then get summed up and used, in some sort of array: chacha20_key_entry[8] = 0x609672088D731FD4LL;
*((_OWORD *)chacha20_key_entry + 2) = chacha20key;
*((_OWORD *)chacha20_key_entry + 3) = chacha20key2; Bytes are stored in reverse order within each element due to the little-endian representation of the stored data. .rdata:0000000140178C40 chacha20key xmmword 43FAE1F4D7378FE90000000300000002h
.rdata:0000000140178C40 ; DATA XREF: chrome_key_initialization+135↑r
.rdata:0000000140178C50 chacha20key2 xmmword 7076EA7E1D2D0E09428025C24D30193Dh
.rdata:0000000140178C50 ; DATA XREF: chrome_key_initialization+140↑r
.rdata:0000000140178C60 db 0D4h
.rdata:0000000140178C61 db 1Fh
.rdata:0000000140178C62 db 73h ; s
.rdata:0000000140178C63 db 8Dh
.rdata:0000000140178C64 db 8
.rdata:0000000140178C65 db 72h ; r
.rdata:0000000140178C66 db 96h
.rdata:0000000140178C67 db 60h ; ` TL;DR: You just decode the In the case of Brave and Microsoft Edge as mentioned by @abs0lute-i the state key is the DPAPI decrypted content's last 32 bytes. No fancy PostProcessData or anything like that. |
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
The text was updated successfully, but these errors were encountered: