看了许多mitmproxy.org的文档,有了点思路
为了解密TLS,我们需要MITM,自己伪装成root ca来签发证书
以mitmproxy为例,mit开启http代理,监听 8080 端口
- 当收到 client hello之后,通过 SO_ORIGINAL_DST 获得原始二元组,然后用TLS连接server,获得证书,找到证书域名回身签发假证书给client,成功欺骗,之后可以SSLLOGFILE获得 masterkey,wireshark解密TLS(直接用fiddler,mitmproxy也可以)
- 使用上述我们封装的代理,获得二元组,找到证书,然后回身签发
但由于 subject alternative name的存在,client想要连接的不一定是证书上签发的,可能是 SAN 中的,所以我们需要在证书中嗅探出 SAN,伪造证书的时候一起加上
还有一个需要注意的是TLS的 server name indication 扩展
这个扩展允许一台主机托管多个ssl网站,client通过 SNI 指明想要访问的域名,然后server返回正确的证书,为了在这种情况下伪造证书,我们需要收到SNI之后和server 进行 TLS
取得正确的证书之后签发,欺骗 client
SAN使得同一个证书可以授予多个域名
而SNI使得服务器可以托管多个https网站(virtual hosting)
由于SNI在client hello阶段,所以第三方可以嗅探出要访问的域名,所以出现了一个TLS1.3的扩展,允许将SNI加密传输
https://blog.cloudflare.com/encrypted-sni/
简单来说,client hello阶段将SNI加密,server解密出来之后根据域名返回对应的证书
那为什么必须要求TLS1.3?
在1.3中,由于使用DH算法,所以server
收到client hello
之后就可以利用自己的私钥与client hello
中的key
推导出masterkey
,server
可以直接解密 SNI
,而1.2版本masterkey在第三阶段获得,但却在第一阶段收到SNI
典型的先有鸡还是先有蛋
之前记着 v2ray 也支持 透明代理,刚找了下
也是通过iptables完成的,普通应用没有能力去对流经协议栈的流量进行过滤
https://docs.mitmproxy.org/stable/concepts-howmitmproxyworks/
mitmproxy整个官网的文档都推荐阅读,涉及到TLS协议本身的特性,对整个网络路由也能有理解.
还想再写点东西
这个我没有试验过,不知道是否可行,只是根据上面的想法和经验推测的.
稀奇古怪的想法
client 使用 TLS与 example.com:8443 通讯,如何在不使用iptables等内核特性的情况下解密TLS
这种方式需要已知拦截域名,自定义DNS解析
为了能够拦截example.com的流量,需要将example.com的DNS解析到本地,进行DNS欺诈
- 修改host,将example.com 指向 127.0.0.1,然后我们的代理直接监听 8443 端口,这样 client的请求直接指向了我们的代理
- 由于是TLS通讯,代理进行SNI嗅探,获得域名
- 为了避免代理解析example.com的时候被host定向,我们需要指定DNS解析服务,获得ip之后SNI获得服务器证书,代理回身签发假的证书
最后再加点东西,
当内核启用IP转发之后,整个OS也就成了路由器.
默认情况下destination ip不指向自身时内核会将流量丢弃,如果需要实现对任意流量的透明代理,首先需要接受任意流量,然后利用iptables进行NAT重写.
后后记
今天看文章 https://vvl.me/2018/06/09/from-ss-redir-to-linux-nat/ 学到的.
既然软件层面问题的解决通过看代码,那么内核上的问题也可以看代理解决.
这里可以搜索内核源码树,快速定位到我们想要的符号 :)
https://elixir.bootlin.com/linux/latest/source
No comments:
Post a Comment