We abused Slack's TURN servers to gain access to internal services
rtcsec.com
rtcsec.com
For fun, read that last paragraph out loud to a non-techy near by and watch their eyes...
"Our recommendation here is to make use of the latest coturn which by default, no longer allows peering with 127.0.0.1 or ::1. In some older versions, you might also want to use the no-loopback-peers."
> So Slack's VoIP uses WebRTC, which connects via UDP/TCP to always send SRTP packets through a TURN proxy (which extends STUN via ICE) to work around usual NAT problems. These guys scanned the TURN and found an SSRF which allowed them to connect to Slack's VPC on AWS using IAM temporary credentials. Interesting.
https://webrtchacks.com/slack-webrtc-slacking/
Given that the latest coturn has this vulnerability mitigated by default, perhaps all this boils down to is "Slack runs outdated software, we exploited it."?
I'm guessing its actually the latter as everyone is so fond of the 1:1 VM/container->service model. Meaning its likely a config problem with the denied-peer-ips the parent here links.
(This just seems to be one of those bugs that every proxy goes through at some point, just like pretty much any attempt to write a web server that serves files off disk will have at least one directory traversal bug.)
Fun fact 2, this only blocks 127.0.0.1.
(side note: if you don't mind breaking license compliance on your personal pc, you can use this to remote desktop into other user accounts on the same pc for a nice separation of work spaces (or just move to linux))
Ask me about CALs, I can tell you all about them.
It's still technically breaking the license to override TERMSERV.dll's protections on home/professional PCs not allowing somebody to be logged in while somebody else is already logged in.
ie, a home or professional licensed pc can not support 1 user on remote desktop, and 1 user sitting down in front of it at the same time, you have to pay for a server license to get that functionality. This technical limitation is considered a DRM measure and also protected by the DMCA anti-circumvention provision.
if you don't mind breaking the law, I was pointing out how you could use abuse 127.0.0.2 to connect remote desktop to localhost in other to do seperate user accounts for seperate tasks, (such as putting your job hunting activities in a seperate account so you don't get distracted by discord/chrome desktop notifications and reddit in your new tab page)
But running coturn in its default-config isn't a good idea anyway.
November 2017: added TURN abuse to our stunner toolset
December 2017: discovered and reported TURN vulnerability in private customer of Enable Security
February 2018: briefly tested Slack and discovered the vulnerability
April 2018: submitted our report to Slack, helped them reproduce and address the issue through various rounds of testing
May 2018: Slack pushed patch to live servers which was retested by Enable Security
January 2020: asked to publish report
February 2020: disclosure delayed by HackerOne/Slack
March 2020: report published
I'm still developing on it a bit but my solution is open source [1]. If anybody want to use this I'm happy to provide answers to questions, and quick bug fixes (as this directly benefits my work right now). If you're using kubernetes this is a pretty easy drop in for your pod. It's part of our default setup now.
Yes, Istio was the service mesh I referenced above that we can't install for different reasons:
>> It was a huge PITA tho without a service mesh (which we can't use for different reasons)
If you have Istio then you don't need MeTaLS (unless your client comes from outside the cluster or something, and even then I think there are ways to make it work).
I don't know that I would agree that it is "for free" as Istio still needs to be configured, and it isn't trivial from my experience. I could also see situations where something like MeTaLS where you place a few env vars for certs and you're done is nice to have. I would definitely recommend Istio if you can use it though.
MeTaLS won't provide you with client-related stuff, but most clients and client libs make it easy to set a certificate/key with a request.
For example, I have Grafana backed by Postgres, and they both understand this authentication scheme out of the box. Postgres is happy to be provided with a cert to present to connecting applications, and is happy to check the cert that applications present against the CA cert.
The main problem with my setup is that I use a ClusterIssuer CA, so really anyone in the cluster can get a valid certificate. This is not amazingly secure and things like Istio do a bit more provenance checking of the application before issuing a cert, which I like. But this is simple, and does protect against the attack this article covers -- as long as you don't go out of your way to present the application's cert when proxying a connection. (Which is probably an easy mistake to make, so be careful.)
I'm not sure if any of the PSK modes manage to work with perfect forward secrecy though. Otherwise, leaking the PSK would also allow decrypting any previously-sniffed traffic.
If you're exclusively interested in mitigating SSRF, a more targeted solution is to run your connections (HTTP or TCP) through a proxy that enforces network-level rules. That seems like it would have worked here. For HTTP SSRF, Stripe has a good tool, Smokescreen.
What is the advantage over simply routing the media streams through application servers (i.e. user A connects to server which links to user B) which can then perform application-specific authentication, enforce restrictions on payloads, etc... Performance?
I'm assuming, perhaps incorrectly, that most of these RTC connections are happening over NAT and therefore usually go over TURN rather than by connecting directly. Even if that's not the case, why not try direct p2p connection first then fall back to routing through an application-specific proxy, which can have tighter controls on who connects to who and what payloads they send?
Rather than falling back from p2p to STUN to TURN, why not replace TURN with something more application/protocol-specific?
Perhaps a webrtc-only proxy that performs authentication and can perform authorization along the lines of: user A is (only) allowed to connect to user B using protocol WebRTC.
In addition, only a fraction of users will need TURN; the rest can use direct peer connections with the aid of NAT traversal; the two kinds of connection are more or less the same to higher layers. Conversely, if the application depended on an application server to process data, chances are you wouldn't implement a second version of the same protocol that works without the server.
So a single TURN server can handle a lot more traffic than an application server, is potentially more secure, and is more easily shared between different applications, and even different owners.
If you want it geo-distributed for latency, the ability to share the same TURN servers between different applications and owners gives you cost-latency advantages too.
Is there actually any data on this or is it mostly anecdotal? Because I've done my own experiments on hole punching before and its almost impossible with today's routers, almost all of which it seems implement symmetric NAT (impossible to match the ports after initial contact with the STUN sever cause it becomes assigned randomly). Compound this with the fact that some ISPs have more than 1 layer of NAT, I have trouble believing that the majority of Slack users either have a direct public IP or a convenient way to conduct NAT traversal successfully.
Google's libjingle documentation[1] alludes to a statistic that says that "8% of connection attempts require an intermediary relay server".
This will obviously depend on the user demographic, I would guess that users on corporate connections are probably less likely to form successful p2p connections.
[1]: https://developers.google.com/talk/libjingle/important_conce...
However, many firewalls block port ranges, or even UDP entirely. What you really want is a way to let people speak WebRTC over a common port (443 TCP is almost never blocked.) TURN facilitates this. Sometimes it's built into SFUs, sometimes not, and requires coturn in front of it. In Slack's case (and the project I work on as well) they are running Janus, which does not have TURN built in, and hence, run coturn to facilitate TURN.
Slacks's approach is particularly interesting because they always push people through TURN, instead of allowing direct connectivity to their SFU. Hard to say why exactly, but probably it's a mix of locking down SFU onto the private network for some reasons, being able to push TURN to edge but keep SFU on private LAN, etc. Typically you don't do this I don't think, you run TURN and SFU both with public IPs, and the client connects to one or the other depending on what ICE candidates win (which is a function of their firewall rules: your browser tries to pick the 'best' candidate it can get to, ideally one over UDP without a TURN hop.)
Someone is doing this right now for Pion, really excited to see it. I am especially excited to see what it means for deploys, right now asking people to expose port ranges adds so much overhead vs 1 UDP and 1 TCP for media.
With an SFU you end up having thousands of remote peers each with their own port on your server. However you could easily listen on a single port and then handle the inbound packet depending on what the remote 3-tuple is (clients ip/port/protocol). Effectively you would just be running all your ICE Agents on one port, but doing one additional step of processing.
I need to fill out [1] more to fully explain the idea, but I think it could make a huge difference when making it easier to deploy WebRTC SFUs.
Let's put it another way: The team who discovered this has skills WELL worth 350k for a year's worth a work. How many security issues would they have to catch for it to be "worth it"? Maybe more than 1, but 100 show stopping vulnerabilities for 350k is crazy to me.
edit: ESPECIALLY slack, if it was possible to use this to get access to any chat logs.
November 2017: added TURN abuse to our stunner toolset
December 2017: discovered and reported TURN vulnerability in private customer of Enable Security
February 2018: briefly tested Slack and discovered the vulnerability
April 2018: submitted our report to Slack, helped them reproduce and address the issue through various rounds of testing
May 2018: Slack pushed patch to live servers which was retested by Enable Security
January 2020: asked to publish report
February 2020: disclosure delayed by HackerOne/Slack
March 2020: report published
Just add extra linebreaks