Slacking Off: Hacking Slack and Annoying My Co-Workers

Daniel Ellis
6 min readFeb 12, 2015

--

Disclaimer: I use “hack” in the non-breaking-into-computers way here.

A few weeks ago, my company changed from using campfire to Slack as its communication tool of choice. Overall, I’ve been impressed with Slack, and I’m not surprised with the success they’ve seen. A few nights ago a friend asked me a deep question:

What’s so great about it?

My response was equally deep:

I don’t know.

Seriously though, I really don’t. It just feels right in every single place. I almost never feel as though I’m fighting against the UI. It just… works. Anyway, I’m digressing (and swooning a bit too).

A few weeks ago, I decided to start poking around with Slack to see what all I could make it do programmatically. I was inspired after quite a few abuses of @channel (if you’re a Slack user, you know how controversial these can be):

Yeah, people take this stuff seriously. And where people take things seriously, opportunity for mischief arises. (Granted, it is annoying.)

Reversing the Communication

I began brainstorming a few things I might be able to do, but the first step was to start to learn how the internals actually worked. Thankfully, the client itself is just a wrapper around the web interface, so I was able to use Chrome’s developer tools, which were familiar with me, to explore.

My first question: how was the chat data being transmitted? I opened up the network panel, refreshed the page, and saw this:

I may have gotten a bit obsessive with the blurring…

Nice! The data was basically just json. How about some other actions? What happened if I tried to edit a message?

Turns out that request, along with a few other “maintenance-y” things, are still sent over standard HTTP requests.

Cool. So it was time to start hacking. My first step was to see if I could re-use an existing web-socket URL in Python to try to inject commands into. Unfortunately, it appeared that these websocket URLs were only valid for the initial connection.

I started digging around the Slack JavaScript source code, and found that although the websocket URL was embedded in the page on initial load, if the connection was lost, a request was made with the user’s API token to get the URL to a new session!

Thankfully, tokens are stored right in the page, so it was pretty easy to find:

After a brief search for a websocket library for Python, I combined it with the output from Chrome’s handy Copy as cURL feature, parsed the response, and started a websocket connection.

This was basically all I needed to get up and running (though this process was lengthy, and took a bit longer than I’m letting on). Here are some of the things I created.

The Hacks

Animated Text

I had a Zalgo one, but a change in the last couple of months appears to have broken it:

Slack killed Zalgo :-(

Animated Icons

Since I did this, Slack has now added support for animated icons. Whatever. I did it before it was cool.

Animated Avatars

It has an annoying flashing effect, but using the “crop” option of uploaded images, we can easily animate our avatars as well.

Dammit! It looks like they changed something, and my script isn’t working. I’ve learned my lesson about writing blog posts 2 months after I’ve done the thing I’m writing about. I leave this one as an exercise to the reader.

Changing Notification Text

This one is a bit more tricky and nefarious.

Using a USB rubber ducky:

I was able to create a USB thumb drive that would type a JavaScript command to send a user’s API token to my web server when inserted into a user’s computer (functioning essentially like a really fast-typing keyboard). Then, I could use that to change their notification text to be on something like:

Every time someone said “the”… well, you can guess what happened.

Also, I just want to say this one made me feel uneasy. I’m not sure about the ethics of it. I wasn’t getting anyone’s password at least, and I wasn’t installing anything on their computer.

Other Ideas

Channel Spammer

Given that you can automate the deletion of your messages, you could easily spam @channel and then immediately delete it, giving people notifications without being able to track down where they came from.

The only reason I didn’t follow this through was that my username still pops up in the OSX notification box, so they’d still know what was going on.

Techniques That Helped

JavaScript De-obfuscation

I spent a while searching the internet for a de-obfuscator for JavaScript, before I realized Chrome has one built in! It’s nice and un-assuming:

Yup, those two brackets there. They turn this:

Into this:

Ah, much better!

Breakpointing Inside Closures

After digging through the source code for a while, I found a couple of objects I wanted to play with in the javascript console. The problem? They were defined in anonymous closures. The solution? Breakpoint, and make the objects global!

At this point, I can easily grab any variable accessible to that closure and save it for later use, continuing execution.

If you look closer at that image, you might have a couple of questions. TS stands for TinySpeck. As for that DELEEEEETETEEESTTTT thing, well…

Funny Things I Found

An Easter Egg

If you type in “DELEEEEETETEEESTTTT” to any channel and press Enter, a funny thing happens:

You can’t send it! I’m assuming this is / was used for debugging, and it just so happened to be useful for figuring out the websocket connection process mentioned earlier, since this causes the client to reconnect.

Colorful Comments

Slack oozes style, and the comments in their JavaScript don’t disappoint:

Hacking as Play

You may wonder why I did all of this. There is certainly an element of mischievousness to it all, but that doesn’t explain everything. At it’s core: it’s play. Hacking is play. Creativity is play. In my opinion, the essence of hacking is getting a system to do something that it otherwise wasn’t meant to do. Extending the bounds of it.

A lot of times this overlaps with mischief, but mischief is just the general expression rather than the end goal itself. Doing all of this play without having a target is like a tree falling in the forest with no-one else around to hear it. Having someone hear it in many ways brings the hack to life.

People sometimes laugh, pigeon holing it as a quirky (err, frustrating?) personality trait. But in my mind, it’s the essence of learning, the essence of curiosity. What greater curiosity than to dig deep into a system that you didn’t build, just to learn its inner workings and have fun with it?

--

--