Black Hat USA 2020
I had a pleasure to be a part of Black Hat USA 2020. Due to the current pandemic, this year’s conference was held as a virtual event. It lacked lots of typical social interactions – all presentations were prerecorded, but sometimes one couldn’t hear or see the speaker due to a network lag. On the other hand, it was much easier to stay on the schedule (one click on the link and you’re set), switch between tracks and presentations if you didn’t like the first 5 minutes, or peek through the entire arsenal toolkit. The best thing, though, is that all presentations are now available to the attendees and within the next 30 days I can watch them as many times as I want to. Overall, I had a very positive experience.
In the series of short blog posts, I will try to cover the most interesting topics from the conference (at least in my opinion!). I will try to summarize the researchers’ work and add a few words of comment from myself. The scope will vary, expect topics around web pentesting, infrastructure pentesting, Windows internals, exploit development, and application security. As I am watching new videos, additional topics, such as WiFi security, may end up on the list as well.
#1 When TLS Hacks You
Let’s start with a novel, cross-platform way of leveraging TLS to target internal services. The attack technique was presented by Joshua Maddux @joshmdx. He found a way to mix DNS rebinding with the ability to reflect arbitrary payload inside TLS handshake packets. As a result, it’s possible to construct SSRF primitive and interact with some services that ignore invalid data.
Sounds a bit enigmatic? Let’s take a few steps back and start from the beginning. I will briefly cover some terms to make sure we are all on the same page.
SSRF stands for Server-Side Request Forgery. It’s a quite common vulnerability in various web applications, where the attacker can forge network requests on behalf of the server. Imagine having the following URL: https://example.cq/?ping=/log.php. What can we deduce from it? It surely sounds like a
ping parameter communicating somehow with the
/log.php endpoint. Maybe it downloads the file, maybe it sends some other HTTP request to it. Seeing such URL, the attacker would likely check if other files can be accessed this way (e.g.
index.php or, with path traversal, various system files). The attacker would also check if the path can be extended with a full hostname, e.g.
ping=http://127.0.0.1/. This would result in a connection to the local IP address – an interface that is not accessible from the outside world, but since the attacker forged the request on behalf of a web server, such a request is perfectly fine. This attack could result in various outcomes – including the ability to perform local network port scanning, accessing internal login panels (often not protected with strong credentials or MFA), or possibility to interact with services available only on the localhost. In the attack demonstrated by Joshua, we will benefit the most from the third outcome.
If the attacker is lucky, there will not be any mitigation in place, and it might be possible to access local files using
file:///C:/windows/win.ini syntax or benefit from old and weird protocols such as
gopher://. Often though, the only allowed scheme would be
https:// where it’s hard to inject arbitrary commands into the traffic.
Another needed piece is DNS rebinding attack. It is yet another technique that may result in the attacker breaching the private network. When visiting our example domain https://example.cq, what the victim’s web browser does, is asking the operating system to resolve the hostname into an IP address. To do that, the DNS query is sent to the name server(s) associated with the domain (via
NS record). The attacker, controlling the domain and associated name sever, controls all replies as well. The initial reply returns the correct IP address and has a very low TTL (time-to-live) value. A low TTL value makes the DNS reply valid only for a brief period of time (technically 0 seconds is also a valid answer, but browsers will ignore very low TTL values and use a safe alternative). The attacker’s DNS intentionally replied with a valid IP address for the first time. This way it is possible to build a sort of trusted relationship in the victim’s application (e.g. browser will record origin information and create secure context around it). Each time the domain needs to be resolved, the TTL value is being checked. If TTL > 0, the cached value can be reused. If TTL is expired, the DNS server will be contacted again – this time though, it will reply with a different IP address, coming from the local network or pointing explicitly to
127.0.0.1. Since the victim’s browsers work on domain level (because the victim used domain name, not IP, to visit the page) – it will continue operating within the same context as if nothing changed. In reality, though, the context changed and the same request to https://example.cq/ will now reach the webserver running on the victim’s localhost.
This implicitly breaks the same-origin policy within the browser and also gives access to resources inside the victim’s internal network.
TLS Session Resumption
Finally, time for TLS – a modern encryption protocol designed to secure Internet communications. Most of the time, when you hear SSL, it really means TLS. If not, you are in trouble. Describing how TLS works is way too complex for this brief article, instead, we need to look just at the TLS handshake. Handshake is being exchanged between two communicating sides when they initiate the TLS session. During the handshake, both sides verify each other and establish encryption algorithms along with session keys. Once completed, encrypted communication continues. This seems like a lot of work to send maybe just a few bytes of information. To save time and resources (negotiating and creating session keys takes a lot of CPU power), the server sends a so-called session ID to the client. Reconnecting clients can provide this session ID during the
ClientHello message and reuse previously established session keys. This is called session resumption and significantly speeds up the encrypted communication as both sides already negotiated what algorithm and keys to use. What matters to us, is that during the handshake, the client reflects the session ID value provided by the server.
Some servers need to handle millions of unique clients – storing session information would require significant resources and would have a bad impact on scalability. To solve that issue – session storage is outsourced to the clients. The entire session blob is first encrypted using a server-side key, then send as a session ID to the client. The server has to only keep server-side keys private and with them decrypt any session ID sent by the client willing to resume the session. This functionality doesn’t have a direct impact on Joshua’s technique, but it ensures that pretty much any data can be used as a session identifier. The TLS session ID is further described in RFC-5077.
Besides session IDs, which are typically limited to 32 bytes, the implementation may also use session tickets which are very similar in nature, but may offer up to 65k bytes of payload space. That’s plenty of space.
Having all that explained, let’s mix it all together.
Joshua’s technique can be used to attack victims that initially connected to the attacker’s HTTP servers through TLS. The session ID sent by the attacker’s server contains not typical session blob, but arbitrary payload. The payload should be a part of some valid communication protocol accepted by non-encrypted services. A good example would be IRC, SMTP, or FTP servers, as they are all text-based and will not (well, should not) crash on invalid commands. By using DNS rebinding, the browser (or other application) would connect to a new service on the localhost (or another interesting endpoint) and send the payload as part of the TLS
ClientHello message. The victim’s application would still believe that it talks with a regular HTTPS service, thus returned that would probably not make much sense and result in an error, however, the attacker-controlled data would be send just fine. Please note, that prior to a Session ID, some other data is sent to the server, hence the attacked service needs to somehow ignore that without crashing. Likely, prefixing and ending payload with
fetch API may be used to initiate the attack. The entire communication was also summarized on the UML diagram:
Joshua demonstrated a couple of successful attacks, including arbitrary emails sent via local SMTPs, and an attack on the Memcached service used by Django. Memcached is a general-purpose distributed memory caching system that has a single interesting property – it supports commands that allow code execution. Django uses it during deserialization. As you can expect from a good talk, calc was popped during the demo.
Not every application implements TLS caching in the same manner, but fortunately, the presenter provided a handy list of affected implementations.
Joshua already published POC on his Github: https://github.com/jmdx/TLS-poison. You can build the components and reproduce the attack in your own environment.
The presented technique is very promising, I will definitively try it next time I see promising SSRF target. The TLS, and especially 1.3 version, may have many more interesting things to play with. Especially, less common extensions, may introduce additional ways of data injection.
If you liked the technique, make sure to also check brilliant SSRF techniques from A New Era of SSRF – Exploiting URL Parser in Trending Programming Languages!. It describes a similar attack using
SNI field of TLS packet, but it’s much more limited in terms of payload content and scenarios.
That’s all! Let us know in the comments if you found other interesting topics, such as DNS rebinding, and you would like to read more about them too.
Adrian Denkiewicz, Cybersecurity Specialist at CQURE, Ethical Hacker, Penetration Tester, Red Teamer, Software Developer, and Trainer. Holder of OSCE, OSCP, OSWP, and CRTE certificates. Adrian is deeply interested in the offensive side of security, ranging from modern web attacks, through operating system internals, to low level exploit development. Twitter: @a_denkiewicz