domain fronting. version 1.3

kremlin.ru. Read it – quite intelligibly and interestingly.

https://habr.com/ru/post/475372/ – the first part

https://habr.com/ru/post/477696/ – the second part

When is this TLS feature again went to the people was adopted by malware specialists, engineers from Cloudflare said “oh” hastily closed it (albeit, like last time, leaving it to work for their favorite customers with a corporate subscription). Since 2020, it was no longer possible to hide behind a foreign domain, but the mechanism with ESNI still worked. That is, as part of the SSL client-hello package, there was no longer an open part of the server name, but only a closed part.

And so, either in the spring or summer of 2022, Cloudflare completely removed ESNI support from its servers. They did this not because all malware in the world began to use this mechanism, but because ESNI was replaced by ECH (Encrypted Client Hello). Cloudflare engineers wrote several articles about the principles of this mechanism. There are a lot of innovations, but in short, the essence is about the same – first we request a public key for the domain, and then we encrypt the entire client-hello packet with this key, including the server name field.

Read more about the transition from ESNI to ECH in Russian – https://tcinet.ru/press-center/articles/7563/

Let’s move on to water procedures (practical exercises)

First of all, let’s check in the browser how ECH works. We take the latest Google Chrome (at the time of this writing – 108th) and do a couple of simple configurations with it:

Enable SecureDNS and select a provider

Through the settings, turn on ECH itself

This completes the Chrome configuration. To check, you can open a special project page defo.io (community working on implementing ECH) — https://defo.ie/ech-check.php

The cherished green checkmark tells us that the connection to the server was made using ECH. We accessed the domain defo.ieit was this value that was in the encrypted part of the ClientHello, and the domain was used as a “cover” cover.defo.iewhich can be seen if you look at the traffic in wireshark.

You can also check the work on the Cloudflara website.

As another practical exercise, let’s try to build openssl and curl with ECH support. Fortunately, the guys from the DEFO project have already taken care of us and described in detail how to do it:

https://github.com/sftcd/openssl/blob/ECH-draft-13a/esnistuff/building-curl-openssl-with-ech.md

We just follow the instructions, download the appropriate sources from the github and collect them at our place.
The new curl has a corresponding –echpublic option, which instructs our build regarding the cover domain. Our curl example from previous articles would look like this:

In this case, you first need to obtain ECH keys (so-called ECHConfig) from the DNS server. This can be done by requesting the appropriate entry from the DNS server serving the domain of interest to us. The keys we need are contained in the HTTPS (or TYPE65) DNS resource record and can be obtained, for example, using the dig utility:

You need to get ECHConfig just before making a request, because, as in the case of ESNI, the keys change about once every half hour.
It should also be noted here that cloudflares do not generate separate ECHConfigs for their clients (domains) of the server and do not return them when requested, but ECHConfig for the domain crypto.cloudlare.com will work for any domains created behind Cloudflare. Apparently, even in the cloudflare itself, the ECH implementation process has not yet been “settled down” to the end.

Closer to hacking

So we’ve taken a close look at the new ECH mechanism and how it can be applied in practice. Now let’s adapt some hacker’s tool (curl doesn’t count) for this new technology. Last time we did this with the Rsocks tunneler. Now let’s carry out this operation with another similar tool (also implemented on GO), namely, a tunneler ligolo-ng from French chatlanina developer (https://github.com/nicocha30/ligolo-ng).

Initially, ligolo-ng does not know how to work with websocket. And support for this protocol is required to work through Cloudflare. Adding a websocket to ligolo-ng is out of the scope of this article. Let me just say that nothing particularly new is required here, and for websocket I used the same standard approaches / libraries as for Rsocks.
In order to teach ligolo-ng to work with ECH, you need to use the appropriate fork of GO from Cloudflare, which provides support for ECH (at the time of this writing, this is GO 1.18.3) – https://github.com/cloudflare/go. We download it from github, collect it at our place and use it as GOROOT when compiling ligolo-ng.
After compilation, we get two executable modules: proxy – the server part and agent – the client part of the tunnel.

We start the server as usual, specifying the desired port and the https prefix, which will tell the tunneler to work using the websocket protocol:

We also launch the agent with the -ech flag, the https prefix, and our domain set behind the cloudflare:

We see that the agent has successfully checked in to the server. Everything else is standard. We start tunneling and work like through VPN with pings and UDP protocol. Miracles, and more!

What does it see Roskomnadzor wireshark:

He sees that the request was first sent to dns.google.com (it is through DoH that the agent requests the ECHConfigs keys), and then a request went to the IP address of the cloudflara servers, but there are no server names in these packets.
Basically, it’s pretty good. The smart host only sees IP addresses, not destination domains. However, this is not enough for us. It is necessary to carry out a cover operation so that no one even has the thought of blocking our connection. Therefore, we make a “knight’s move.” Open the src/crypto/tls/ech.go file from the GO fork and find the line

hello.serverName = hostnameInSNI(string(echConfig.rawPublicName))

and change it to something more euphonious real Komsomol member IB-resourcer:

We rebuild the agent, launch it and see what the guys from Roskomnadzor see this time.

And they see that now the most important domain of the country is securely protected by the best CDN in the world, they are a little surprised, of course, but at the same time they reassure themselves with the fact that now “at least something is safe with us.”

Conclusion

In this article, we got acquainted with the new technology for encrypting ClientHello packets of the TLS1.3 protocol and saw that this technology can be used both from the point of view of defensive (protection from surveillance by ILV and the like), and from the point of view of offensive (DomainFronting) . So far, the fork of Ligolo-NG with websocket and ECH capabilities is posted on the author’s github in a separate branch (https://github.com/virusvfv/ligolo-ng/tree/websocket), but a corresponding pull-request has been made and it is quite possible that it will be included in the main branch of the project.

Wangyu, that pretty soon, when this feature with ECH DomainFronting “goes to the people”, the guys from the cloudflara will again say “Oh”, and disable the ability to cover with an arbitrary cleartext SNI (outer server name), as was already the case with ESNI . But still, ECH technology does not stand still, the TLS 1.3 standard, as I believe, will soon become a real standard, other CDNs (Google, Amazon, Microsoft) will start supporting it, and browsers will start working on ECH out of the box. We’ll see what the RKN will do then.

But it will be later. Ahead of winter, I hope not nuclear …

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *