文章
技术

Lisa大神能不能帮忙解释下这两个问题?

https://pincong.rocks/article/17023

这个是什么原理?

https://pincong.rocks/question/22222

这个可行么?

菜单
  1. v2rayuser  

    第二个其实可以做成这样https://hidester.com/proxy/ 做成一个通用的online web proxy,不需要一个一个的网站去做反代。大部分这种online web proxy本身就被墙了,但如果配合cdn+doh+esni,就可以像直连pincong那样,通过online web proxy去访问各种被墙的网站。

  2. 霏艺Faye 图书管理员
    霏艺Faye   图书管理员

    第一个问题

    就是这次GitHub的中间人攻击,原理一模一样。不建议使用这个方式,很容易被中间人攻击。

    第二个问题

    反向代理肯定可以,但是GFW可以主动嗅探。你的反向代理服务器马上就会被墙。不可行!

  3. 张怀义  

    @立紗Lisa #2 lisa大神,可以说的细一些么?好抽象啊,我不懂

    第一个问题,说是中间人攻击,能不能解释下怎么攻击?第二个问题,主动嗅探是怎么工作的,原理说下?

  4. 霏艺Faye 图书管理员
    霏艺Faye   图书管理员

    @张怀义 #3

    第一个问题,本地浏览器发起TLS请求,代理软件截获。删掉了SNI,转发给服务器。服务器返回了证书,但是会有告警,代理软件忽略了告警,所以可以上网。也因为忽略了告警,如果出现GitHub那样的伪造的证书,也会被许可,这样就被中间人攻击了。

    第二个问题,GFW会模拟正常的浏览器访问这些反向代理服务器,根据应答报文,就能知道这个是代理服务器了。就是GFW扫描流量,发现可疑TLS连接,就会模拟浏览器去尝试访问。所以v2ray模拟websocket的时候,才会伪造一个网站,因为GFW会自己嗅探

  5. solids   Ñøñë

    @立紗Lisa #2 证书和密钥都是本地生成的,我觉得没什么问题

  6. v2rayuser  

    @立紗Lisa #4 加了DOH+ESNI,主动探测到了也墙不了的。就像现在pincong.rocks一直可以通过这种方式直连一样。 不过最近GFW似乎把firefox默认的DOH的DNS给墙了,但只要换个DOH的DNS就行了。 除非GFW再进一步把所有cloudflare的CDN给墙了,或者把ESNI的包都给reset掉,那就是更进一步了。

  7. 霏艺Faye 图书管理员
    霏艺Faye   图书管理员

    @solids #5

    仅考虑代理软件,代理软件会去向目标网站申请证书。而且没有校验证书是不是有效。

    如果这个时候被GFW中间人攻击,代理软件会忽略,导致中间人攻击。

    https://github.com/URenko/Accesser/ 官网写的 支持python3.7版本

    https://docs.python.org/3/library/ssl.html

    ssl.match_hostname 这段 Changed in version 3.7: The function is no longer used to TLS connections. Hostname matching is now performed by OpenSSL.

    同时 Verifying certificates When calling the SSLContext constructor directly, CERT_NONE is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you’re talking to. Therefore, when in client mode, it is highly recommended to use CERT_REQUIRED. However, it is in itself not sufficient; you also have to check that the server certificate, which can be obtained by calling SSLSocket.getpeercert(), matches the desired service. For many protocols and applications, the service can be identified by the hostname; in this case, the match_hostname() function can be used. This common check is automatically performed when SSLContext.check_hostname is enabled.

    Changed in version 3.7: Hostname matchings is now performed by OpenSSL. Python no longer uses match_hostname().


    然后开始看代码201-204行

            if self.host in setting.config['alert_hostname']:
                server_hostname = setting.config['alert_hostname'][self.host]
            else:
                server_hostname = None
    

    人话版本:如果代理软件认为域名 在 https://github.com/URenko/Accesser/blob/master/template/pac 文件的domains里的话,同时,域名不在https://github.com/URenko/Accesser/blob/master/config.json.default 的alert_hostname的话,则把SNI信息去除,否则改用 json里的域名

    也就是说,代码是删除了SNI信息来完成规避SNI RST,这样GFW伪造一个证书,就可以骗过代理,因为代理不会检查证书

  8. 霏艺Faye 图书管理员
    霏艺Faye   图书管理员

    @v2rayuser #6 以下是我的个人理解:

    v2ex上很多人会联系我,说自己的VPS 的IP被封了。其实64,两会期间,封IP更猖獗。既然共产党连私人翻墙的VPS的IP都封杀,为什么不封杀品葱的ip呢

    我觉得对共产党来说,封杀一个品葱IP,是非常简单的事情

    两种可能:

    1.共产党高层,觉得品葱只是BBC CNN VOACHINESE 级别,给个SNI RST待遇就很给面子了

    2.GFW内部,有我们的同志,所以不封杀品葱IP


    关于CDN,我觉得你有误解。品葱没有使用前置域名,所以不需要封杀CDN的ip,封杀品葱ip就可以了。

    关于前置域名用法,参考迷雾通

    			revProx := &httputil.ReverseProxy{
    				Director: func(req *http.Request) {
    					log.Println("reverse proxying", req.Method, req.URL)
    					req.Host = binderHost
    					req.URL.Scheme = binderURL.Scheme
    					req.URL.Host = binderURL.Host
    					req.URL.Path = binderURL.Path + "/" + req.URL.Path
    				},
    

    req.URL.Host = binderURL.Host 这个是前置域名,req.Host = binderHost 这个才是真实地址。

    如果我是GFW,只要 TCP RST 所有品葱IP的443端口就可以了。不需要墙掉所有的CDN IP地址。


    回到反向代理,我经常上反向代理网站,Google会提示这个是钓鱼网站。连Google都可以识别反向代理网站,我觉得GFW做不到,我反正不信。

    最好的方法其实是v2ray的websocket,就是你配置一个随机的websocket path,因为GFW是猜不到这个path的,如果是你path是/ 那么大概率被墙.。。建议path 是一个随机的地址 /psdfjklsadfaksdlhgdjkas

    类似这样的

  9. v2rayuser  

    @立紗Lisa #8 品葱是上了cf的cdn的,cdn的一个ip实际上是有很多网站的,如果直接封杀的话这个ip上所有网站都会受影响。所以从封ip来看,(至少目前)根本不是一个可行的办法。

    所以现在GFW对pincong的封杀方式也就是限制在DNS污染和SNI重置上,但是这两点都被DOH+ESNI解决了。所以目前来说,GFW要么把支持DOH的DNS给全部墙掉,要么把cf的CDN大量给墙掉,要么就是把esni的包都给reset掉,但无论是那种方法,都必定会误杀大量网站。

  10. 小二   默认开启批量屏蔽受限用户发言功能,可在设置中手动取消。

    @立紗Lisa #8 品葱和2049bbs都使用了 cf 的cdn,真实ip是不对外的,所以不存在封杀ip一说。

  11. 霏艺Faye 图书管理员
    霏艺Faye   图书管理员

    @小二 #10 cf的CDN,其实是反向代理。这么做为的是v2rayuser说的,和其他网站共享IP,导致GFW不敢冒然封IP。

    至于不公开真实IP,是为了防止共产党对自己的服务器进行DDoS,因为暴露了真实IP,共产党就可以对这个IP进行DDoS。你想想,DoH返回的是CDN的地址,封不封你的IP,墙内不都可以正常访问2049么?

    @v2rayuser #9 你和小二说得对。因为开了CF的CDN,和其他网站共享了IP,GFW是不能随便封IP。

    回到你说的GFW手段上。对GFW最棘手的是ESNI。但是却特别好破解,只要封掉所有的DoH服务器就可以了。

    使用传统的DNS服务器,无法做到ESNI,我已经写了代码讲解,说明了原因。

    公开的DoH服务器全封杀了就可以了。如果是自己搭DoH服务器,说明自己在墙外有服务器,既然有服务器,直接v2ray就可以一次性搞定,也没有必要v2ray和doh都部署了。

    和DoH服务器的TLS连接,是SNI方式的,不是ESNI。我也解释过了。所以,DoH部署到CDN上,也可以根据SNI精确RST掉。

    当然了,可以使用IP方式直接访问DoH服务器,这样会导致GFW直接封杀1.1.1.1这个IP。

  12. abc123  

    为什么GFW至今不封1.1.1.1这个IP?

  13. 张怀义  

    @abc123 #12 6楼不是说被墙了么?我这里也连不上1.1.1.1

  14. solids   Ñøñë

    @霏艺Faye #2290348 代码那部分只是定义Accesser如何修改发出的SNI。验证的部分是给OpenSSL处理。

    我刚才测试了 badssl.com 上的一些示例域名,测试之前将其SNI加入 config.json 以指示 Accesser 不去除 SNI。对于有问题的TLS证书处理不同。

    https://expired.badssl.com/ (过期)

    终止连接

    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1129)
    

    https://wrong.host.badssl.com/ (host不匹配)

    没有终止连接

    https://self-signed.badssl.com/(自签)

    终止连接

    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1129)
    

    https://untrusted-root.badssl.com/ (CA不可信)

    终止连接

    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)
    

    后面的 revoked 和 punning-test 是有问题的,但是我的浏览器也没有警告,所以不再测试。


    由此可见GFW要完成MITM只能获取有效的其他网站的证书和私钥。并非自签就可以。