-
Notifications
You must be signed in to change notification settings - Fork 912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Another method for bypassing DPI #71
Comments
Unfortunately it's impossible to change domain name inside HTTPS request without SSL termination on GoodbyeDPI side. Modifying SNI requires SSL re-encrypting. Most probably this won't be implemented, I consider this outside of GoodbyeDPI scope. |
This would happen at the first request only. Before an encrypted communication is established. Isn't that correct? This is what I meant: https://hal.inria.fr/hal-01202712v1/document |
SNI is included in ClientHello packet, which is later hashed to make sure it hasn't been modified. Changing SNI (or any other fields in ClientHello packet) requires HTTPS inspection. |
I see. Thanks! |
The author in the @aaomidi referred paper proposes that it is possible to create socket connection to the original site and send a client hello packet with a fake SNI object in server_name var. Then after the negotiations are completed, the Host header is sent with the right URL address. I think it does not require any SSL inspection. Waiting for your reply! |
Yes it does require termination. I can write this in c++ but the problem is, you intercept all the responsibility of managing the http (and protocols built atop it) stack. This is why for my proxy I moved to c# because I just bundle Microsoft's kestrel server and let them manage compliance with that all that. |
If simply tweaking the tls hello is enough actually you may not need termination. You'd just have to push packets into a fifo buffer and detect and modify them. I could do some experiments and publish a proof of concept based on WinDivert if you'd like. |
What if we make this a socks proxy in something like go and try to modify the actual bytes going through it? |
See my last comment. I'll do a proof of concept in c#. I wrapped WinDivert in c# because I got tired of writing everything from scratch in c/c++ land. Then it's up to gdpi author to port it. |
I've never heard of the sni portion being hashed. Afaik this is called domain fronting and apparently Google and Amazon actively reject it. |
SNI is hashed. It's not possible to just change SNI in ClientHello packet without re-encryption. I already have SNI modification code in my private branch which I wrote as a concept, before realizing that it won't work as expected. |
Ah interesting. Are you sure it's not that it's being mitigated against by the server you're testing on? Because from what reading I've done, this is not a new idea, and it's being counteracted in the server or termination endpoint. |
Absolutely. ClientHello packet is fully signed by TLS specification, no client/server/website/etc should permit that. |
How does the client sign it? What key does it use? |
It uses randomly generated ephemeral key stored in RAM. More information is available in TLS specification. I didn't dig too deep. |
I'm so confused, what's the point of signing if the server has no way to verify the signature? I'll read more on it. |
The client generates random key and signs ClientHello packet hash with it. The server also generates another random key, hashes concatenated ClientHello hash and ServerHello hash. When client gets ServerHello with mismatch hash, it drops the connection because the connection has been tampered. |
I gotta say this is all news to me, and I've written software that intercepts TLS w/ SNI. The only key exchange I ever had to handle was generating ECDH keys for the actual session negotiation. However, OpenSSL certainly could be something like this I missed. By reading up on domain fronting, the description of this historical practice would seem to contradict anything about the hello being hashed or secured. In fact the remarks around the development of ESNI (encrypted SNI) are meant to address the fact that it's a huge privacy leak that is filled with security holes because it can be tampered with to steal sessions. Anyway on that note I don't think it matters, because ESNI is on the way and all these content inspection guys are going to lose this ability to filter secured connections in the way we're discussing here. |
I just realized we actually have a working version of ESNI. Made this tweet, feel free to share with your friends from Iran, Russia, etc. https://twitter.com/aaomidi/status/1055282490888331266 |
Thats awesome. |
https://blog.cloudflare.com/esni/ |
@aaomidi ESNI is not working on Fortiguard firewall here in my university network on the Firefox Nightly build. I have accessed Cloudflare backed websites but their TLS connection is interrupted by the firewall. @ValdikSS & @TechnikEmpire can you provide me with some resources where I can find more about the things that you are talking about. It will be very helpful. I want to dig deep in this area. I have read RFC 5246, 8446 & 4346 but I can't find the things that you guys mentioned. |
Efficiently Bypassing SNI-based HTTPS Filtering (PDF) |
I don't know about rfc's on this topic. Look at sni-proxy on GitHub though. In his code he cites the RFC that he based his sni parsing algorithm on. As far as that paper yeah, it seems to confirm that tampering with sni is a thing. That was my other suggestion, to strip the extension and modify the cipher advertisement to fake being a legacy client that doesn't support SNI. Anyway. That sucks that ESNI is being blocked by a firewall. Not sure what to say about that. The protocol probably looks unregonizable to the firewall or it knows exactly what it is and is blocking for either reason. |
For a start: ...and maybe Encrypted SNI Comes to Firefox Nightly: https://blog.mozilla.org/security/2018/10/18/encrypted-sni-comes-to-firefox-nightly/ Related: openssl/openssl#7482 |
@Atavic @TechnikEmpire Thanks for your help. I am thinking of implementing the idea mentioned in on the windows environment. I think it should be implementable and then it can easily bypass the firewalls like fortiguard which uses SNI server_name var to block the site. @TechnikEmpire also SNI proxy can only help in bypassing IP based filtering or DNS requests but in my case and IMO in other major cases of DPI, the firewall will not block either. Instead, it blocks the ClientHello packets. |
@mohdluqman I was talking about this project: https://github.com/dlundquist/sniproxy Only about getting the referenced RFC's in the source code. |
ESNI uses another TLS option ID and does not include SNI or SNI field. Current firewalls will detect packets with ESNI as a handshake without SNI, which in case of Russia are usually get blocked if the connection is initiated to the blocked domain's IP address as DPI can't distinguish whether this connection is being established to the blocked domain or not. |
@TechnikEmpire If you want to change SNI, you must server the TLS connection and re-send it with a changed SNI by yourself. That is a MITM process. |
Thanks for the additional information. I have a new appreciation both for the work people like you are putting into this problem, and for the freedom I often take for granted. |
@SeaHOH I build MITM proxies for a living. I know. I was only referring to sni-proxy because I remembered that it manually parses the SNI extension by performing a peek read on new tls socket connections. As such, it references RFC's from which the author created his algorithm. Was not referencing it for any other reason. Can you guys not get away with using Tor or something similar? |
A misunderstanding :) , I am not good at English.
I am not demand using Tor for the time being. |
@ValdikSS @TechnikEmpire @aaomidi @SeaHOH .. Guys, is it possible that client hello negotiation takes place from the secondary network interface and the rest of transmission from the primary interface i.e. the filtered interface. If it is possible, then there is no need for any SNI modifications. we can use VPN as a secondary network interface. VPN can be slow sometimes so only use it for SSL negotiations and then use the acquired SSL handshake for full transmission from the primary network interface. |
This is possible. First do full handshake and send/receive some data, then close the connection, switch to another network interface, at last, send data with in client hello by session resumption (it not safe with forward secrecy). This method use in TLS1.3, in TLS 1.2, session resumption use session ID or session ticket. Cause requires a lot of extra coordination work, not recommended. |
@mohdluqman just use ReQrypt |
For clarification my specialty is more in proxying and content classification and filtering. The author of WinDivert and @ValdikSS are much more qualified to answer these questions. Just wanted to clear that up cause I was tagged. |
Thanks. I will look into it to explore some more info. |
Iran uses DPI to detect youtube.com from host header to block it. Providing a host replacement system based on keyword would allow Iranians to bypass this system of DPI.
For example, if you replace youtube.com with google.com, the DPI system will fail. Google doesn't care about the SNI since they use a SAN certificate.
So I propose adding a file that has something like this:
Alongside adding a usage for:
Where once the host with that value is encountered, it just replaces it with the other value.
The text was updated successfully, but these errors were encountered: