Abusing Slack for Offensive Operations: Part 2

When I first started diving into offensive Slack access, one of the best public resources I found was a blog post by Cody Thomas from back in 2020 (which I highly recommend giving a read). This follow-up post aims to take a look at changes Slack has implemented since Cody’s post and reexamine avenues to achieving Slack access from ceded access on both macOS and Windows hosts.

What’s Changed Since 2020?

The biggest change Slack has made since Cody’s original post involves cookie encryption (at least on macOS). Back in 2020, the macOS Slack cookies database contained cleartext cookies, which meant an attacker with disk access could steal the database file and place it on another host where the attacker’s local Slack application could replay the cookies.

On macOS, the cookie values are now encrypted with a key named Slack Safe Storage, which is stored in the user’s login Keychain. On Windows, the cookies are encrypted by a data protection API (DPAPI) key.

The SQLite cookies database can be found at:

  • %APPDATA%\Slack\Network\Cookies (Windows)
  • ~/Library/Application Support/Slack/Default/Cookies (macOS)

Additionally, some of the files containing Slack user metadata have been consolidated into a single file:

  • %APPDATA%\Slack\storage\root-state.json (Windows, Figure 1)
  • ~/Library/Application Support/Slack/storage/root-state.json (macOS)
Figure 1 –Root-State Workspace Info

This file contains JSON content detailing Slack UI settings, metadata for files downloaded through Slack, and workspaces the user is signed into.

Cookie Theft on Windows Hosts

I’m All Ears

Since Slack stores its cookies in a SQLite database with the same database schema as Chrome, it shouldn’t be too hard to modify a tool like SharpDPAPI’s SharpChrome to accommodate Slack cookie retrieval (shoutout to Lee Christensen for doubling back and actually implementing Slack support in this pull request). However, unlike the Chrome cookies database, which is likely storing many cookies we care about, the Slack cookies database only contains a single cookie we’re interested in.

To log into a user’s Slack without their password (regardless of multi-factor authentication [MFA]) we just need the d cookie — a value with the static prefix xoxd-. Using Process Hacker, we can actually identify the cookie within memory of a running slack.exe process:

  1. Open the parent slack.exe process (on occasion, you may need to check the child Slack processes)
  2. On the “Memory” tab, click “Strings” (and subsequently “OK” to gather results)
  3. Click “Filter” and return only results that contain or start with the string xoxd- (Figure 2)
Figure 2 — Strings for the Win!

How can we make use of this discovery operationally on a red team engagement? Immediately, the office_tokens beacon object file (BOF) from TrustedSec’s CS-Remote-OPs-BOF repository comes to mind. This BOF simply reads the memory of a remote Office process and searches the returned buffer for JSON web tokens (JWTs) related to Microsoft services. The following snippet contains the BOF code iterating through the buffer and trying to find a match to a specific JWT prefix, eyJ0eX:

for (index = 0; index < (address_sz/2)-8; index++)
{
if(buffer[index] == L'e' && buffer[index+1] == L'y' && buffer[index+2] == L'J' && buffer[index+3] == L'0' && buffer[index+4] == L'e' && buffer[index+5] == L'X')
{
BeaconPrintf(CALLBACK_OUTPUT, "Office Token: %ls", buffer + index);
index += MSVCRT$wcslen(buffer + index);
}
}

With just a few modifications to this code, we can leverage any command and control (C2) framework with BOF support to steal Slack cookies from running slack.exe processes (or browser processes, if the target isn’t using the desktop app) (Figure 3).

Figure 3 — Same Cookie Retrieved via BOF

In addition to not having to deal with DPAPI complexities, this approach doesn’t require us to load any .NET tooling. The slack_cookie BOF and updated aggressor script can be found in this pull request to the CS-Remote-OPs-BOF repo.

After stealing the cookie, open up a browser and visit Slack or your target’s workspace URL. Use the browser’s developer tools or the EditThisCookie extension to add a new cookie with the name d and your stolen cookie value. Ensure the cookie’s domain is set to .slack.com — in some instances, I found leaving this to the default app.slack.com or <workspace>.slack.com wouldn’t work (Figure 4).

Figure 4 — Loading Cookie… 

Refresh the page and it should now say you’re signed into the target space! Click “open” and now you can interact with your new Slack account on the web or in the desktop app (Figure 5).

Figure 5 –Signed into the BloodHoundGang Slack!

Cookie Theft on macOS Hosts

No So Fast…

Since we can’t just read remote process memory on macOS (modern versions of Slack are protected by the hardened runtime, part of Apple’s notarization process), the cross-process cookie theft we demonstrated on Windows won’t fly. With the cookie decryption key stored in the user’s login Keychain, this line from Cody’s blog still mostly holds true:

At least in macOS, this means that an attacker doesn’t just need access as the user account, but also needs to know the user’s plaintext password to decrypt the login Keychain to access the appropriate key.

While in the process of writing this blog, Cody pointed me to some recent Keychain research he released at Objective by the Sea 5. In it, he presents a unique tactic to retrieve Slack’s decryption key from the login Keychain without knowledge of the user’s password. Check out his presentation or slides for more details.

In other cases, it’s likely you’re going to need the Slack Safe Storage key from the Keychain (Figure 6).

Figure 6 — Slack’s Keychain Entry

The user’s password is required to extract the key from the login Keychain. There are a few potential routes to obtain the user’s password:

  • Download the user’s login Keychain from ~/Library/Application Support/keychains/login.keychain-db, extract the user’s password hash with chainbreaker, and crack it with Hashcat (-m 23100)
  • Use Apfell’s or Poseidon’s prompt command to coerce the user into submitting their password (similar to the Windows AskCreds BOF technique)
  • Phishing and other social engineering techniques
  • Monitoring the clipboard through Poseidon’s clipboard_monitor command (the clipboard is not protected by transparency consent and control [TCC], unlike keystrokes)

This is the biggest hurdle to clear — assuming you’ve accomplished this step, you can retrieve the Slack Safe Storage key from the login Keychain with chainbreaker (Figure 7).

Figure 7 –Slack Safe Storage Key Decryption

Now we can finally decrypt that Slack cookie! ChatGPT quickly converted this ChromeCookieDecryptor project to Python for me and with only a few slight tweaks, I had plaintext cookies (Figure 8)!

Figure 8 — SQLite Cookies Database Decryption

The decryption script can be found in this gist.

Conclusion

Slack has followed the cookie storage blueprint used by browsers, like Google Chrome, making existing tooling and techniques adaptable for Slack exploitation. Windows hosts present a relatively easy opportunity for Slack compromise, opposed to macOS, where current tradecraft requires some additional work (or luck).

Abusing Slack for Offensive Operations: Part 2 was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.

Article Link: https://posts.specterops.io/abusing-slack-for-offensive-operations-part-2-19fef38cc967?source=rss----f05f8696e3cc---4