SeaHOH / GotoX

本地自动代理,修改自 goagent。
722 stars 147 forks source link

在伪造SNI配置中配置了host为none,但程序仍验证返回的证书是否过期 #278

Closed gulut closed 3 months ago

gulut commented 3 months ago

问题描述: 即使在伪造sni配置中设置了host为none,GotoX仍然验证证书的有效期

GotoX 版 本 : 3.9.3.dev (python/3.11.4 gevent(libev-cext-4.33)/22.10.2 pyOpenSSL/23.2.0)

Commit: 93624e024f10731bfc384d54a9626607a1e737af

更新方式: 从3.9.2覆盖升级

修改内容: 按照#267 中 https://github.com/SeaHOH/GotoX/issues/267#issuecomment-1605560725 的办法添加了memimport_exclude_modules文件

配置:

注:下面的网址NSFW

在ActionFilter.ini中的[0-fakecert]配置了

thisvid.com = none@none
.thisvid.com = none@none

日志:

17:34:02 D query qname='thisvid.com' reply iplist={'remote': ['88.208.3.194']}
17:34:02 T 127.0.0.1:5350 dns_remote_resolve 已缓存:3/1024,耗时:1 毫秒,thisvid.com = ['88.208.3.194']
17:34:02 D request_headers={'Host': 'thisvid.com', 'Connection': 'keep-alive', ...}
17:34:03 W 88.208.3.194 _create_ssl_connection 'thisvid.com' 返回 CertificateError(-1, ('time expired: 20211015235959Z', 0)),重试
17:34:03 W L4:50598->88.208.3.194 do_DIRECT "GET https://thisvid.com/" 证书验证失败,返回 522

request_headers因包含部分敏感信息,已做删减处理

复现截图:

0

预期行为: 根据 https://github.com/SeaHOH/GotoX/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E4%BC%AA%E9%80%A0-SNI-%E7%9A%84%E5%8A%9F%E8%83%BD#%E5%9C%A8-gotox-%E4%B8%AD%E8%AF%A5%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%92%8C%E4%BF%AE%E6%94%B9-sni Wiki的提示,当host设置为none时,应当不验证 Host 头域是否匹配证书,事实上有部分网站在没有SNI下的默认证书是过期的。如果host设置为none时能够不验证证书的有效期会更好。

附加信息:

在使用OpenSSL 1.1.1l命令行访问时可见,不携带sni时确实会返回过期证书

openssl s_client -connect 88.208.3.194:443 -showcerts

CONNECTED(00000140)
Can't use SSL_get_servername
depth=3 C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
verify error:num=19:self signed certificate in certificate chain
verify return:1
depth=3 C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
verify return:1
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.thisvid.com
verify error:num=10:certificate has expired
notAfter=Oct 15 23:59:59 2021 GMT
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.thisvid.com
notAfter=Oct 15 23:59:59 2021 GMT
verify return:1
---
Certificate chain
 0 s:OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.thisvid.com
   i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
-----BEGIN CERTIFICATE-----
(省去证书内容)
-----END CERTIFICATE-----
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
   i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
-----BEGIN CERTIFICATE-----
(省去证书内容)
-----END CERTIFICATE-----
 2 s:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
   i:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
-----BEGIN CERTIFICATE-----
(省去证书内容)
-----END CERTIFICATE-----
 3 s:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
   i:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
-----BEGIN CERTIFICATE-----
(省去证书内容)
-----END CERTIFICATE-----
---
Server certificate
subject=OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.thisvid.com

issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 6183 bytes and written 378 bytes
Verification error: certificate has expired
---
New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-CHACHA20-POLY1305
    Session-ID: 1E208FB7FBA43C4E066F5FC2083576D5A16D39ADEB9A41232B8A3B0C76804FA6
    Session-ID-ctx:
    Master-Key: DE57F56ADDB1090531179C1D5AC243F6EDC399684ED04D65EF5CC58B875CE638CD385CF61FCF9FE2B59EB9799E999C6F
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1716715773
    Timeout   : 7200 (sec)
    Verify return code: 10 (certificate has expired)
    Extended master secret: yes
---

且只有在携带正确sni时才会返回正确的证书

openssl s_client -connect 88.208.3.194:443 -showcerts -servername thisvid.com -proxy 127.0.0.1:7890
CONNECTED(00000130)
depth=1 C = US, O = Let's Encrypt, CN = R3
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = thisvid.com
verify return:1
---
Certificate chain
 0 s:CN = thisvid.com
   i:C = US, O = Let's Encrypt, CN = R3
-----BEGIN CERTIFICATE-----
(省去证书内容)
-----END CERTIFICATE-----
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
-----BEGIN CERTIFICATE-----
(省去证书内容)
-----END CERTIFICATE-----
---
Server certificate
subject=CN = thisvid.com

issuer=C = US, O = Let's Encrypt, CN = R3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2900 bytes and written 443 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.2, Cipher is ECDHE-ECDSA-AES256-GCM-SHA384
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES256-GCM-SHA384
    Session-ID: 50C66898420DFA7EE709AED31A3CF9A9FC839C58999F5BA752CF33AE6AECAD0D
    Session-ID-ctx:
    Master-Key: 6251003D48DDFE06E990F7A64E057762F4DC315D36CE33692909FFF584EEAFC87A871F3003C747342DAACF970AC7D4CA
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1716715957
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: yes
---
SeaHOH commented 3 months ago

如果host设置为none时能够不验证证书的有效期会更好

没有直接这样设置,已经添加了可以调整验证的参数,见 b9c6df0baeb4ae7e5364fba71da09ab3edc1f2d9

另,上例网站好像不需要伪造 SNI,可以直接访问。

gulut commented 3 months ago

在按照 https://github.com/SeaHOH/GotoX/compare/93624e024f10731bfc384d54a9626607a1e737af...9a40687fbac82469bb5300367594a1c45f614470 中的内容,更新到 commit https://github.com/SeaHOH/GotoX/commit/9a40687fbac82469bb5300367594a1c45f614470 后,修改ActionFilter.ini内容为

thisvid.com = none@none;allow expired
.thisvid.com = none@none;allow expired

确实能够请求到了,感谢。