As a penetration tester at Coalfire Labs, I frequently use exploitation frameworks such as Metasploit or PowerShell Empire to perform post-exploitation actions on compromised endpoints. While anti-virus (AV) bypass and detection avoidance is often trivial in all but the most mature environments, detections from AV have caused me to look toward custom tooling to mitigate the risk of being detected by both traditional AV as well as security operations teams relying on network indicators. Over the past year I’ve been slowly developing my own tooling to deal with these challenges.
Today I will open-source this tool, which I have dubbed “Slackor.” Slackor is a post-exploitation implant written in Golang, which uses Slack as a command and control (C2) channel. Initially inspired by Twittor, this implant attempts to avoid detection by security teams by using an existing legitimate web service as a way to relay commands and files to a compromised host. It provides concealment by using a very popular and legitimate web service as a C2 mechanism, as many enterprise organizations already have legitimate Slack traffic originating from their endpoints. This service also makes use of Transport Layer Security (TLS), which provides an additional layer of cover if the client is not terminating TLS.
Slack was chosen as the C2 channel, as its use in enterprise environments has grown dramatically over the past several years and has become the dominant workplace collaboration tool.
Source: https://techcrunch.com/2018/05/08/slack-hits-8-million-daily-active-users-with-3-million-paid-users/
This, combined with the easy-to-use API, made it a prime candidate for a covert C2 channel. Another distinct advantage of Slack is specific to its implementation of the API. All Slack API URLs come in the form of https://slack.com/api/[METHOD]. This is useful, as unencrypted DNS queries only show resolution of slack.com, making it difficult to differentiate Slack API usage from normal web browsing. HTTP proxy logs would also only log the FQDN and could not inspect the full URL. This is not the case for other web service-based C2 tools, which call out to an API-specific endpoint. Another important feature of Slack is the ease in creating workspaces and associated API access tokens. The entire process takes about a minute.
Both the Slackor implant and client-side component only communicate with Slack via the API, never directly
Slackor is not the first (nor the last) tool to take advantage of the Slack API for command and control. The earliest tool of this type I found was SlackShell from 2017, which was written in PowerShell. Recently a blog post by Praetorian detailed how to set up a Slack workspace and released a PoC tool called slack-c2bot. Trend Micro has also recently published a blog post on a backdoor named “SLUB,” which uses GitHub and Slack to communicate and was believed to be part of a targeted attack campaign.
While the Slack API did prove to be easy to use, it wasn’t without its limitations. The first and most common issue I ran into was API rate limiting. The rate limits differ between the various features; however, nearly all of them enforce sending less than one request per second. This became an issue when many implants were calling back to the same workspace. To compensate for this, Slackor has an adjustable beacon interval for implants.
Another limitation was the number of characters per message, which was only 4,000 characters. A single POST request to the chat.postMessage method could allow up to 40,000 characters by creating a multi-part message. Because of this, Slackor has limited the amount of output that can be returned after running a command. For example, a directory listing on C:\Windows\System32\ would exceed the character limit. While Slack can also make use of snippets for larger messages, it uses the files.upload API method with a stricter rate limit. Slackor reserves the use of the files.upload method for upload/download functionality.
One concern I had with the Slack C2 tools I found online is that none of them seemed to utilize any crypto aside from TLS. This concerned me as data retrieved from the implant would be posted unencrypted in the Slack workspace. I wanted to make sure that any data retrieved by Slackor would be unreadable by anyone who managed to access only the raw data. Slackor encrypts all command output and file uploads from the implant with AES. Encrypted data can only be decrypted with a symmetric key shared by the Golang implant and the client-side Python component that runs on the operator’s system. This key is generated during the initial setup process of Slackor. While Slackor lacks an asymmetric key exchange process, it still provides some meaningful protection for data residing within the Slack workspace. Knowing this limitation, a Slack workspace should never be shared between multiple disparate targets, as reversing an implant could allow an analyst to gain access to the workspace and decrypt the data within.
Typical Slackor message as seen in the channel
When developing Slackor, I had originally created both the client-side component and the implant in Python. While I enjoy and prefer writing in Python, it is far from the best language from which to develop an implant. Because of the ease of development and general proliferation of python-based malware, many tools for compiling Python scripts to Portable Executables (PE) for Windows such as Pyinstaller or Py2exe are instantly seen as suspicious and sometimes immediately detected as malware regardless of context. AVs such as AVG, McAfee, Windows Defender, and Symantec have all been observed doing this. Knowing this, I opted to use Golang as my language of choice. While not the best language for writing Windows malware (I believe C# currently has this honor), Golang is highly capable and relatively easy to learn. I had never written a single line on Golang before creating Slackor, and what I do know now I learned exclusively from the development of the Slackor implant.
Simplified Agent Logic
When writing Slackor, my primary goal was to avoid detection, thus, much of the code in Slackor was written from scratch and attempted to avoid using known malicious open-source tooling as part of its modules. Most of Slackor functionality is pure Golang, and usage of powershell.exe or cmd.exe was avoided as much as possible. Common system functions such as reading files, changing directories, enumerating network interfaces and listing directory contents are performed by Slackor without starting a new cmd.exe process.
Operational Security (OPSEC) was a major consideration, and as such, any module that writes to disk, executes cmd.exe/powershell.exe, or otherwise modifies the system will present an OPSEC warning before continuing. By default, Slackor will beacon every five seconds, however this can be re-configured dynamically. A built-in jitter factor of 20% is applied to the beacon interval. This adds a random level of ambiguity into the beacon frequency.
Slackor also makes heavy use of LOLBins, or “Living Off the Land Binaries.” When Slackor duplicates itself or persists on a system, it starts as a child process of a built-in Microsoft binary. Usage of LOLBins can be a double-edged sword as far as detection, however. While making use of these binaries can aid in avoiding detection, a mature defensive team may also be monitoring execution of these binaries specifically. Slackor favors LOLbins, as many of them can execute data stored in Alternate Data Streams (ADS), which Slackor uses when persisting on disk. ADS can be used to hide malicious files inside legitimate files or folders. Years ago, Microsoft removed the ability of cmd.exe to execute files contained in ADS. Despite this, many LOLbins retained this functionality.
While Slackor boasts many features such as command execution, upload/download, shellcode execution, keylogging and credential harvesting, it lacks utility for lateral movement, has relatively high latency, and does not handle scale. For this reason, I find the primary usage of Slackor to be a long-haul C2 implant. Slackor works best when dropped on a small subset of systems to retain a foothold if the short-haul C2 were to get burned.
Slackor is released open source to the information security industry for legitimate and lawful purposes.
Slackor is live at: https://github.com/Coalfire-Research/Slackor.