Skip to content
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

Closed
aaomidi opened this issue Apr 4, 2018 · 37 comments
Closed

Another method for bypassing DPI #71

aaomidi opened this issue Apr 4, 2018 · 37 comments

Comments

@aaomidi
Copy link

aaomidi commented Apr 4, 2018

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:

youtube.com google.com
*.youtube.com google.com

Alongside adding a usage for:

goodbyedpi.exe --replacement-file [value] 

Where once the host with that value is encountered, it just replaces it with the other value.

@ValdikSS
Copy link
Owner

ValdikSS commented Apr 7, 2018

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.

@aaomidi
Copy link
Author

aaomidi commented Apr 7, 2018

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

@ValdikSS
Copy link
Owner

ValdikSS commented Apr 8, 2018

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.

@aaomidi
Copy link
Author

aaomidi commented Apr 8, 2018

I see. Thanks!

@aaomidi aaomidi closed this as completed Apr 8, 2018
@mohdluqman
Copy link

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!

@TechnikEmpire
Copy link

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.

@TechnikEmpire
Copy link

TechnikEmpire commented Oct 23, 2018

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.

@aaomidi
Copy link
Author

aaomidi commented Oct 23, 2018

What if we make this a socks proxy in something like go and try to modify the actual bytes going through it?

@TechnikEmpire
Copy link

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.

@TechnikEmpire
Copy link

I've never heard of the sni portion being hashed. Afaik this is called domain fronting and apparently Google and Amazon actively reject it.

@ValdikSS
Copy link
Owner

ValdikSS commented Oct 24, 2018

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.

@TechnikEmpire
Copy link

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.

@ValdikSS
Copy link
Owner

Absolutely. ClientHello packet is fully signed by TLS specification, no client/server/website/etc should permit that.

@aaomidi
Copy link
Author

aaomidi commented Oct 24, 2018

How does the client sign it? What key does it use?

@ValdikSS
Copy link
Owner

It uses randomly generated ephemeral key stored in RAM. More information is available in TLS specification. I didn't dig too deep.

@aaomidi
Copy link
Author

aaomidi commented Oct 24, 2018

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.

@ValdikSS
Copy link
Owner

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.

@TechnikEmpire
Copy link

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.

@aaomidi
Copy link
Author

aaomidi commented Oct 25, 2018

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

@TechnikEmpire
Copy link

Thats awesome.

@SeaHOH
Copy link

SeaHOH commented Oct 25, 2018

https://blog.cloudflare.com/esni/
ESNI only works on cloudflare cdn now.

@mohdluqman
Copy link

@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.

@SeaHOH
Copy link

SeaHOH commented Oct 25, 2018

Efficiently Bypassing SNI-based HTTPS Filtering (PDF)
This is the method how escape DPI with fake sni name. You can only use in your own application code.

@TechnikEmpire
Copy link

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.

@Atavic
Copy link

Atavic commented Oct 25, 2018

For a start:
Transport Layer Security RFC5246
Server Name Indication RFC 6066

...and maybe
DNS in TLS RFC7858

Encrypted SNI Comes to Firefox Nightly: https://blog.mozilla.org/security/2018/10/18/encrypted-sni-comes-to-firefox-nightly/
https://tools.ietf.org/html/draft-ietf-tls-sni-encryption-03
https://github.com/tlswg/sniencryption

Related: openssl/openssl#7482

@mohdluqman
Copy link

@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.

@TechnikEmpire
Copy link

@mohdluqman I was talking about this project:

https://github.com/dlundquist/sniproxy

Only about getting the referenced RFC's in the source code.

@ValdikSS
Copy link
Owner

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.

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.

@SeaHOH
Copy link

SeaHOH commented Oct 26, 2018

@TechnikEmpire
It is just a reverse proxy which use SNI or hostname to connect to the backend servers.
It can not change the SNI values, so can not escape DPI too.

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.

@TechnikEmpire
Copy link

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.

@TechnikEmpire
Copy link

TechnikEmpire commented Oct 26, 2018

@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?

@SeaHOH
Copy link

SeaHOH commented Oct 26, 2018

A misunderstanding :) , I am not good at English.

Can you guys not get away with using Tor or something similar?

I am not demand using Tor for the time being.

@mohdluqman
Copy link

mohdluqman commented Nov 10, 2018

@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.

@SeaHOH
Copy link

SeaHOH commented Nov 10, 2018

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.

@ValdikSS
Copy link
Owner

@mohdluqman just use ReQrypt

@TechnikEmpire
Copy link

TechnikEmpire commented Nov 10, 2018

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.

@mohdluqman
Copy link

@mohdluqman just use ReQrypt

Thanks. I will look into it to explore some more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants