net4people / bbs

Forum for discussing Internet censorship circumvention
3.38k stars 80 forks source link

a new idea of passing GFW (PoC) #123

Open SekiBetu opened 2 years ago

SekiBetu commented 2 years ago

https://github.com/ihciah/shadow-tls https://v2ex.com/t/875975

Trojan 将 payload 基于一个伪装的 TLS 连接承载,但它部署起来略微麻烦,主要在于需要证书签发上;并且最近中国部分地区开始采用域名白名单策略,这种方式不再适用了。

Trojan bases the payload on a disguised TLS connection, but it is slightly cumbersome to deploy, mainly because it requires a certificate to be issued; and with the recent adoption of domain whitelisting policies in some parts of China, this approach is no longer applicable.

那么一个 idea 就是:作为 server 不再自己处理握手,而是将握手流量转发至一个可信的域名上。当握手结束则立刻跳车开始向自己的服务器中转流量。这样中间人看到的就是和 www.gov.xx 的合法握手(观测到的证书也是合法的),而这显然是个白名单域名,这时中间人就会标记这个连接为合法连接。

Then one idea is that instead of handling the handshake itself, the server forwards the handshake traffic to a trusted domain. When the handshake ends, it immediately jumps the train and starts relaying traffic to its own server. This way the man in the middle sees a legitimate handshake with www.gov.xx (the observed certificate is also legitimate), which is obviously a whitelisted domain, and the man in the middle then marks the connection as legitimate.

Translated with www.DeepL.com/Translator (free version)

update: Full design doc is here.

wkrp commented 2 years ago

Thank you for the link @SekiBetu. Can you write a few sentences saying what is special about this approach? What are you looking for, users to test, comments, code review, new ideas?

You can consider setting the censorship-circumvention topic on the repository.

wkrp commented 2 years ago

Then one idea is that instead of handling the handshake itself, the server forwards the handshake traffic to a trusted domain. When the handshake ends, it immediately jumps the train and starts relaying traffic to its own server. This way the man in the middle sees a legitimate handshake with www.gov.xx (the observed certificate is also legitimate), which is obviously a whitelisted domain, and the man in the middle then marks the connection as legitimate.

Based on this description, it sounds similar to the "mask sites" proposed by Conjure. See https://github.com/net4people/bbs/issues/18#issuecomment-561336149:

One of the possible covert proxy protocols, new in this work, is "mask sites" (§4.2.3, §5.3.2, §7.1). The overall idea is that the Conjure station forwards phantom-addressed TLS traffic to some actual web site running at its own address—until the Conjure station discovers that the client is using a special prearranged key, at which point the station hijacks the connection and begins forwarding it to an application proxy instead. The motivation here is that TLS makes a good covert channel, but has a few caveats: in order to look like a genuine TLS connection, the server needs to present a valid CA-signed certificate (not a problem with TLS 1.3), and the client needs to present a plausible SNI (even with TLS 1.3, at least until ESNI arrives). By always forwarding at least the first part of the TLS connection to a real site, the client is able to provide a plausible SNI (that of the mask site) and the Conjure station is able to provide a genuine certificate that matches that SNI (forwarded from the mask site).

ghost commented 2 years ago

The archive of orginal v2ex page https://web.archive.org/web/20220828235743/https://v2ex.com/t/875975

klzgrad commented 2 years ago

I haven't checked the code of ShadowTLS, but from the description there is an obvious issue that gives away the TLS parrot. The author claims this can tunnel architrary TCP payload, but if clear text or some form of low entropy data appears in TLS Application Data record, it is obvious that this is a TLS parrot. To fix this, the tunneled data after handshake must appear as a legal TLS Application Data record and conforms to TLS 1.2 or 1.3 depending on the forwarded handshakes. And also it must respond correctly to active probes with forged or replay data designed to verify its behavior with TLS close_notify.

I think Conjure maybe also has issue with active probing for behaviors with TLS close_notify, but I haven't checked closely. Anyway it's all about how to be a good TLS parrot and not get spotted.

klzgrad commented 1 year ago

Drawing some comparison, Shadow-tls seems to be solving two classes of problems: 1. Adding SNI and certificate authenticity using a mask site, similar to Conjure; 2. TLS-in-TLS double encryption overhead.

Mimicking the mask site may make the TLS handshakes more trustworthy, but the Conjure paper did note that it takes careful considerations to select and mimic a mask site. I think in practice this mimicking opens up a lot of space for parrot detecting features (e.g. differences in application servers, TLS stacks, TCP stacks) that takes significant amount of engineering and operational effort to reduce.

Removing TLS-in-TLS double encryption is a tempting mistake to pursue. XTLS had report (https://github.com/XTLS/Go/issues/16) that shows TLS 1.2 payload with cleartext GCM nonce gives away the parrot. Conjure does require encryption of TLS application data. I'm not seeing specification for encrypting TLS application data in Shadow-tls.

Lastly, both XTLS and Conjure did not discuss in depth (e.g. https://github.com/XTLS/Go/issues/12) what happens when active probes replay or inject invalid data. Conjure did note that it's out of scope for the threat model:

Finally, we assume the censor can replay or preplay any connections that it suspects involve phantom hosts (or their registration) in an attempt to confirm. However, the censor wishes to avoid disrupting any connections before it knows for certain they are from Conjure clients, lest they disrupt legitimate connections. This means that injecting false data or corrupting TLS sessions is outside the scope of the censor [...]

But somehow Conjure is able to claim replay resistance. I do hope there was more discussion here about the definition of replay resistance because it must resist not only invalid data, but also probes that try to distinguish parrots, which means when a certain TLS application data record fails to decrypt, the custom crypto stack must generate appropriate TLS alerts depending on the TLS version of the mask site. The error handling in TLS must be mimicked perfectly, including scenarios that could result in close_notify, unexpected_message, bad_record_mac, record_overflow, etc.

The destructive probes would not be the first line ones, but could be used to confirm after the censor has accumulated from other channels a certain degree of confidence about the profile of the parrot. Also, the disruption caused by the probes would not be hugely visible because of retries, so the collateral damage of this is probably overestimated to date.