Decrypting Stolen Slack Cookies with SharpChrome

Slack is a productivity platform used by many businesses for team chats and communication. There’s a great article about abusing Slack for offensive operations that gives a detailed overview of the platform and how it can be leveraged. Then there’s a Part 2 article that gets into the more recent changes in Slack’s cookie encryption and discusses how to dump Slack cookies from the running process on a target machine.

Recently, I was on an engagement and had the opportunity to grab Slack cookies from an end-user workstation via SMB share. I had cracked the user’s password hash and they were a local admin on their workstation so I was able to copy the files through the admin share. Slack now uses Windows data protection API (DPAPI) to encrypt their SQLite cookies file, similar to the way Chrome encrypts its cookies database. I could find information about decrypting Chrome cookies but nothing about decrypting Slack cookies from flat files to a different machine, like I had to do. This post outlines the process I worked out to import a target’s Slack session onto another machine.

The Situation

You have plaintext domain credentials for a user and access to their Windows workstation file system where Slack is being used but no shell access on the target system.

Machine Prep

Because Slack uses Windows APIs to encrypt the file, we’ll need a Windows VM to decrypt the file. To make things easier, this VM only needs internet access for Slack to login and does not need to be on the target’s internal network. Antivirus needs to be disabled or an exclusion set for the working folder containing the files we’re using.

This VM also needs the compiled binaries for SharpChrome. These are not provided in the repo so you will have to compile them yourself and copy them into the VM. Be sure you place them in the AV exclusion folder from above because Windows Defender will flag SharpChrome.

The Windows VM also needs a web browser and the Slack desktop client installed. The desktop client doesn’t need to be used for browsing Slack after the session hijacking, but SharpChrome checks those folder paths for decryption automatically so it makes the process simpler. There’s also a switch to pass SharpChrome an arbitrary folder path to run against but I did not explore this option.

With a clean Slack install and no sign-ins, running SharpChrome only returns a “b” entry in the Cookies file.

.\SharpChrome.exe cookies /browser:slack

Figure 1: SharpChrome finds no logins on a clean install

Decrypting Slack Cookies

Now that the environment is prepared, we can start decrypting the target’s Slack cookies. There is one value in the Cookies database that saves the user’s session, so we only need to obtain the value of the “d” key. This value is prefixed with “xoxd-” which makes identification easy.

Slack uses the “Local State” file and the “Cookies” file to save the session state and encrypt it using the user’s master keys. The Slack workspace domains will also be needed and can be found in the root-state.json file. In order to decrypt, we need these following three files from the target user’s profile folder:

  • %appdata%\Slack\Local State
  • %appdata%\Slack\Network\Cookies
  • %appdata%\Slack\storage\root-state.json

The user’s master keys from the %appdata%\Microsoft\Protect folder are also needed. There will be a subfolder named with the user’s SID. If browsing with Explorer, the folder will appear empty and needs the Options > View > Show hidden files, folders, and drives button enabled and Options > View > Hide protected operating system files checkbox disabled to view these files.

Paste the target’s Local State and Cookies files into their respective folders on the Windows VM, overwriting the existing files.

Figure 2: Paste and overwrite Cookies file
Figure 3: Paste and overwrite “Local State” file

Also paste the contents of the user’s SID folder into the existing SID folder on the Windows VM. This adds the user’s master keys into the pool for SharpChrome to utilize.

Figure 4: Adding target’s master keys into VM current user’s SID folder

Open a PowerShell/command prompt window as Administrator and navigate to the folder containing your SharpChrome binary. SharpChrome needs switches set to target cookies and the Slack application, as well as a password to decrypt the additional master keys with. The following command will run SharpChrome with these parameters and decrypt the target’s Slack Cookies file we copied into our Slack install earlier:

.\SharpChrome.exe cookies /browser:slack /password:<UserPassword>

If everything goes right, SharpChrome will spit out the contents of the decoded Cookies file. The “d” key beginning with “xoxd-” is the string we need.

Figure 5: SharpChrome output of decoded Cookies file

Open the web browser and go to https://slack.com/workspace-signin. The target’s workspace can be found toward the end of the root-state.json file. Open it in your favorite text editor and search “workspace”. One instance will have a “domain” value with the target’s workspace domain name.

Figure 6: Identifying the workspace domain from the root-state.json file

Use this domain to begin the sign-in process to Slack.com. Open up the browser’s developer tools and go to the cookie storage section (the exact location will vary by browser). There should be several keys in the <workspacedomain>.slack.com cookie already, but no “d” value. The domain of the cookie should match the target workspace.

If these multiple keys aren’t present, you may have to change how you’re attempting to sign in (i.e., load the sign-in page from the Slack home page, load the sign-in page from the “Sign In With Email” option, or load the sign-in page from “Login to Workspace URL” page). When recreating this on my test account for screenshots, it took a few attempts before loading the full set of data into the cookie. Once this is all set by the browser session, add a new value into the cookie with the “d” name and paste in the xoxd- string returned by SharpChrome as the value.

Figure 7: Adding the magic d key to the website cookie

Refreshing the page and will prompt to launch the Slack desktop client and then load the target’s account, all signed in. We successfully hijacked the target’s Slack session by copying their files to another machine, decrypting the session key, and importing that into a clean Slack install.

Figure 8: The target’s hijacked Slack session

Side note: It is also possible to use the web client after this point by clicking the Open button under the “You’re already signed in to…” section on the sign-in page. The browser cookie saves the “d” value and recognizes that it is already signed into that workplace. Being helpful, Slack generously offers to load the workspace and save some hassle.

Figure 9: Slack recognizes the hijacked session key and tries to be helpful

Conclusion

While Slack technically does encrypt its session cookie, the decryption process is quick once the target’s password is known. Even if the credentials are not known, it would be easy to create a PowerShell script to run through a wordlist and brute-force a common password. From my research into Slack’s (and Chrome’s) responses to this decryption vulnerability, their position is that all data is considered compromised once an attacker has access to the target’s file system, regardless of encryption or not. While this is true to some extent, this stance means that a few minutes of LLMNR poisoning and a weak password can result in the compromise of that user’s Slack account. A strong domain password remains the best defense against this type of attack because SharpChrome needs a plaintext password to decrypt the user’s master keys. Without a cracked password, this attack vector falls flat.