We abused Slacks TURN servers to gain access to internal services
Publish date: Apr 6, 2020
Executive summary (TLDR)
Slack’s TURN server allowed relaying of TCP connections and UDP packets to internal Slack network and meta-data services on AWS. And we were awarded $3,500 for our bug-bounty report on HackerOne.
A very brief introduction to the TURN protocol
The Wikipedia page for this protocol is somewhat handy because it explains that:
Traversal Using Relays around NAT (TURN) is a protocol that assists in traversal of network address translators (NAT) or firewalls for multimedia applications. It may be used with the Transmission Control Protocol (TCP) and User Datagram Protocol (UDP). It is most useful for clients on networks masqueraded by symmetric NAT devices. TURN does not aid in running servers on well known ports in the private network through a NAT; it supports the connection of a user behind a NAT to only a single peer, as in telephony, for example.
TURN is specified by RFC 5766. An update to TURN for IPv6 is specified in RFC 6156. The TURN URI scheme is documented in RFC 7065.
It might be also useful to note that TURN is actually an extension to the STUN (Session Traversal Utilities for NAT) protocol rather than a network protocol that stands on its own.
TURN servers can get peers behind NAT connected by acting as a relay, as it is called in the RFCs, or a proxy from the perspective of a pentester. In the case of TCP relaying, TURN servers make use of a connect message method 0x000A in RFC 6062 while with UDP, a send indication message method 0x006 in RFC 5766 is used. For UDP, the channel method can also be used and has a similar function.
With that out of the way, one might ask, how is this related to WebRTC?
Introduction to TURN in the WebRTC infrastructure context
With WebRTC, as well as VoIP in general, one of the more painful complications has been getting the media stream (i.e. RTP packets carrying audio and video) of two or more parties to reach each other. This tends to be a problem because of NAT, which is widely known to have inflicted a great deal of pain on human nature (at least that subculture which develops real-time communications software). The problem has to do with finding the IP and port tuple of each media stream which, when either or both hosts are behind NAT, tends to be less obvious. In many cases, this has been solved with STUN and when that fails, the TURN extension which tends to be the last resort before failing to get the media stream working. Here we should mention that the ICE protocol (Interactive Connectivity Establishment) is what ties in STUN and TURN. In fact, TURN has been designed to work with ICE.
Therefore, for many WebRTC systems, one key element is to have a TURN server to relay messages between peers when direct media traffic between peers is not allowed by a firewall or NAT device.
How Slack uses TURN
When we tested Slack, we noticed that TURN was always used for establishing the media which is passed over SRTP. This has been described extensively by the webrtcHacks blog in an article called Is Slack’s WebRTC Really Slacking? (Yoshimasa Iwase) way back in 2016, and so we will not repeat the same explanation over here. But one thing that we should highlight is that the way that Slack uses its TURN server puts it in a critical position within its infrastructure, rather than it being a measure of last resort.
What we found when testing Slack’s TURN servers
Our tests showed that Slack’s TURN servers can be abused to relay TCP and UDP traffic to the TURN server itself and also internal addresses on Slack’s AWS infrastructure. For the webapp-sort of penetration testers out there, this sounds familiar because that is how SSRF (server-side request forgery) vulnerabilities are usually abused. However, there is an important difference in that abuse of this vulnerability is not limited to just HTTP-based protocols (or targets that somehow respond to HTTP requests). Instead, we see it as closer to abusing an open proxy (e.g. a socks proxy or a web proxy with the CONNECT method).
What could one do by abusing Slack’s TURN servers?
Connect to the AWS meta-data services at http://169.254.169.254 and obtain IAM temporary credentials
Connect to open ports on localhost that are usually not exposed to the Internet (e.g. node exporter): 22, 25, 53, 443, 515, 5666, 8500, 8888, 9090 and 9100
Port-scan the Slack AWS infrastructure on 10.41.0.0/16 and find server management applications; possibly abuse such “trusted” services
Our methodology for testing for open TURN relay abuse
At this point, one might get the wrong impression that TURN servers do not have any authentication or authorization but the truth is that they do make use of authentication. In fact, each time there is a WebRTC session, new temporary TURN credentials are generated and returned by the system. An attacker must therefore retrieve these credentials. We used the following steps to do so:
configure our web browser to use Burp proxy
in the Proxy > HTTP history tab, filter for the keyword screenhero
start a call by pressing the call button
observe the TURN details returned in the call to /api/screenhero.rooms.create which include the temporary username and password, TURN hostname and ports
these details are then passed to our tool stunner that was written to abuse this vulnerability
Stunner is an internal tool that we developed to test STUN, and by extension, TURN for various protocol vulnerabilities. The first subcommand of interest here is turn peer scanner, which runs a port scan through a TURN relay targeting a particular peer address. In the video demonstration we show the turn peer httpproxy subcommand that implemented an HTTP proxy so that web browsers could be configured to pass through stunner, which then proxies HTTP requests and responses to the TURN server speaking its protocol. Finally, the TURN server relays this HTTP traffic back and forth to stunner.
And the rest, as they say, is a historic video:
The video shows:
How to obtain the TURN credentials
Testing relaying to the Internet through the TURN server by checking our IP address
Connecting to internal network and meta-data services on Slacks AWS infrastructure
How to fix an open TURN relay to address this vulnerability
To address this issue, we recommend placing access control rules on the TURN server itself to block non-public addresses from being specified as the XOR-PEER-ADDRESS in the TURN messages. In practical terms, most systems, including Slack’s, make use of Coturn. Our recommendation is to make use of the following options:
We would like to extend our gratitude to the Slack security team who handled our report and provided us with test systems to check their security fixes. And many thanks to Alfred Farrugia for his work on stunner and reproducing this vulnerability reliably.
Who first discovered the TURN open relay abuse vulnerability?
From public records, it looks like that would be Cisco, who released an advisory for Cisco Meeting Server back in 2017 September 13.
We properly identified this issue separately, apparently in late 2016, by reading the TURN RFC and eventually proving the actual vulnerability by adding features within our internal toolset, stunner, to abuse this vulnerability. Since then, we have discovered various instances of the same vulnerability during our WebRTC Penetration Test engagements.