目录
在通过https握手rtt识别TCP代理(socks5/http)之后,渐渐的发现这个事情没想象中的靠谱,主要原因分析大概如下:
- iphone在部分情况会有谜之延迟,如果通过设置清楚浏览器缓存和记录,可以稳定得到一个近500ms 的延迟。个人认为客户端在没有https证书缓存的情况下验证会出现这个情况。对应的就是用户第一次访问你的服务器。
- https 几乎都是配合H2或者https/1.1使用,由于链接复用,都很难再次触发重新握手(写这文章时还这么认为),则无法进行多次检测加以验证。
302图片特点
为了规避以上问题,我想到一个简单的方法,就是一个302图片跳转。事实上只要是个302跳转就行,用图片的原因有:
- 图片可以通过img标签引入,页面无需跳转
- img 默认支持302,并且可以视为完整且不易被干扰的过程
- img 默认支持跨域,方便其他人使用
原理
通过https握手rtt发现代理的本质原因是:
- 这是个连续过程
- 有必然来自客户端的数据(密钥交换)
- ack应答包被代理先应答
对比302图片过程
正常情况下
cliet ================== server
1 == img request ==>
2 <= ack ==
3 <= 302 header ==
4 == ack =>
5 ==302img request=>
6 <= ack ==
7 <= img body ==
8 == ack =>
在代理的情况下
cliet ================== proxy ================== server
1 == img request ==>
2 <= ack == == img request =>
3 <= ack ==
4 <= 302 header ==
5 <= 302 header == == ack =>
6 == ack =>
7 ==302img request=>
8 <= ack == ==302img request=>
9 <= ack ==
10 <= img body ==
11 <= img body == == ack =>
12 == ack =>
这是我们也会发现,302图片符合上面提到的原理:
- 这也是一个近乎连续的过程
- 有来自客户端数据(302img request)
- ack包被proxy代理先应答
与https不同的地方
由于302图片过程存在在整个数据中间,并且包并不用于TLS是明文并且可以被简单识别。那么我们需要通过某种方法吧这个过程的包提取出来。
提取关键数据
我是用的方法是通过记录2次img请求到达时间,提取中间的抓到的数据包进行分析。对应上述的过程,则是:
- 不使用代理的步骤 2、3、4、5
- 使用代理的步骤 3、4、5、6、7、8
这时就会发现,关键的点就是 302 header对应的ack应答包已经后续的 302img request。其到达时间间隔则可以视为客户端到代理的延迟。
相比TLS握手优点
- 由于302图片依然可以在https协议下运行,因此,一个302图片可以至少得到2次检测机会
- 302图片可以发起多次请求,在一次检测结束后,在重复加载图片可以在得到一次数据
- 由于http2和http/1.1会话复用,页面多次刷新触发的302图片会让结果更接近真实情况
demo
proxy guess demo