Clash实现IP秒级切换(含简易源码分析)

免责声明 本文所提供的程序(方法)可能带有攻击性,仅供安全研究与教学之用。文章作者无法鉴别判断读者使用信息及工具的真实用途,若读者将文章中的工具或信息做其他用途,由读者承担全部法律及连带责任,segmentfault和本文作者不承担任何法律及连带责任。
注:此文章适用于对Clash有一定使用经验的读者??不再对基础配置说明
0x00 意外 一直以来都使用酸酸乳自带的负载均衡功能配合Airport实现IP秒切
主要用途是对站点进行渗透测试时路径爆破和扫描端口
Clash实现IP秒级切换(含简易源码分析)
文章图片

直到有一天Airport跑路了
兜兜转转换了一家??发现他们使用Clash作为客户端
Clash实现IP秒级切换(含简易源码分析)
文章图片

为方便使用??我选择了Clash-For-Windows简称CFW
Clash支持跨平台??后文以Clash进行分析(主要是CFW不开源)
Clash实现IP秒级切换(含简易源码分析)
文章图片

拿到机场配置文件导入??简单配置下就能正常使用了
但是却始终没有找到和负载均衡有关的设置
百度一下??找到了负载均衡的配置样例

# load-balance: The request of the same eTLD+1 will be dial to the same proxy. - name: "load-balance" type: load-balance proxies: - ss1 - ss2 - vmess1 url: 'http://www.gstatic.com/generate_204' interval: 300

按照样例配置好负载均衡??拿起dirsearch跑一跑??然后就被封了
Clash实现IP秒级切换(含简易源码分析)
文章图片

用VPS起个WEB服务扫描看一看??原来IP根本就没变!
Clash实现IP秒级切换(含简易源码分析)
文章图片

0x01 深入 继续翻文档??最终把目光停留在这个注释上
# load-balance enables the same eTLD requests on the same proxy

eTLD没接触过??补个课先
Top-level domains (TLDs) ,顶级域名,例如.com、.net、.cn、.tw、.top等。
effective TLDs(eTLDs),有效顶级域名,对于如.com.cn或.github.io这样的域名,仅仅使用.jp或.io的顶级域名是不够细化的,不足以识别 "同一个网站",目前没有统一的标准确定某个顶级域名的可注册等级。这就是为什么创建了一个 "有效顶级域名"(eTLDs)的列表。 (eTLDs列表在publicsuffix.org/list上维护)
举例:给定的URL是https://my-project.github.io,则eTLD是.github.io,eTLD+1是my-project.github.io
换句话说,eTLD+1是有效的顶级域名和域名之前的部分。
eTLD的概念主要应用于同源跨域的判断上,在页面转换、fetch()请求、cookies、打开弹出窗口、嵌入式资源和iframe的应用较多。
引用自web.dev/same-site-same-origin
根据注释推测是使用了eTLD的原因
那么让负载均衡不使用eTLD就可以在扫描的时候实现秒切IP了?
0x02 分析 打开Clash-1.6.5源码??全局搜索etld
运气不错??只有loadbalance.go在一个函数内部声明了etld
Clash实现IP秒级切换(含简易源码分析)
文章图片

继续分析??首先声明了变量etld
调用publicsuffix.EffectiveTLDPlusOne()方法对metadata.Host进行处理并赋值给etld
然后定义了一个函数getKey()来接收处理后的metadata.Host
Clash实现IP秒级切换(含简易源码分析)
文章图片

那么函数getKey()返回的值可以是目的IP??也可以是eTLD(eTLD+1)
(其实分析到这里??已经隐约感觉到问题没有出在eTLD
继续搜索??发现函数strategyConsistentHashing()调用了getKey()
根据函数名判断strategyConsistentHashing()是一致性哈希算法策略
Clash实现IP秒级切换(含简易源码分析)
文章图片

一致性哈希算法是负载均衡调度算法的其中一种
以Nginx负载均衡的算法进行类比??相当于ip_hashurl_hash的结合
ip_hash:每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。
url_hash:按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。如果需要这种调度算法,则必须安装Nginx的hash软件包。
分析到这步??基本可以确定IP秒切失败的原因是使用了一致性哈希调度算法导致的
那么只要使用轮询调度算法来分配每次请求??就可以实现IP秒切效果
轮询调度(Round-Robin,RR):最简单的调度算法,LB按照顺序将请求依次转发给后端的RS,并没有考量后端RS的状态(处理速度以及响应时间)。
带权重的轮询调度(Weighted Round-Robin,WRR):在轮询算法的基础上加上权重设置,权重越高的RS被分配到的请求越多。
上下随便翻翻??发现函数strategyConsistentHashing()上方已经写好了Round-Robin调度算法
本来还想尝试写一个呢hhh??既然如此??那就来看下两个函数之间的差异
直接的原因就在于变量idx的值??而idx的值又是由两种算法决定的
一致性哈希会把同一个IP/URL的请求分配到同一个代理上??idxgetKey()的返回值相关
轮询调度会把每一次请求分配到不同的代理上??idx仅和代理的数量相关
两者在策略失效的情况下??都会默认选择第1个代理
Clash实现IP秒级切换(含简易源码分析)
文章图片

调度算法已经有了??现在只要找到哪里调用了strategyRoundRobin()
粗略读一下代码??发现函数NewLoadBalance()对调度算法进行了分支选择
Clash实现IP秒级切换(含简易源码分析)
文章图片

继续跟进 函数parseStrategy()从字典config[]strategy键值对读取解析策略
推测字典对象config[]对应Clash的配置文件*.yaml
如果在字典中没有读取到strategy键值对??就会默认使用consistent-hashing作为解析策略
(后续经过测试strategy键值对要写在配置文件load-balance的内部才会生效)
Clash实现IP秒级切换(含简易源码分析)
文章图片

那么这里就有两种解决方法:
  1. 将函数parseStrategy()的默认返回值由consistent-hashing更改为round-robin
  2. 在配置文件里新增键值对strategy并赋值为round-robin
显然方法2更加便捷灵活
(安福仔一枚基本不接触开发 分析缺陷的地方还请师傅们多指教)
(RR是作者后期增加的一个调度算法??早期的配置文档里没有样例??所以才有了这篇文章)
0x03 调试 将配置文件修改以后??简单进行一下测试
Clash实现IP秒级切换(含简易源码分析)
文章图片

使用浏览器连接代理访问cip.cc??通过不断刷新页面来观察IP的切换情况
然而在每次刷新之后IP依旧固定不变
Clash实现IP秒级切换(含简易源码分析)
文章图片

再三阅读代码确认没有问题之后??在一次测试中无意间点开了CFW的连接
原来在访问网站之后??TCP连接没有立即断开??而是处于保持连接状态
Clash实现IP秒级切换(含简易源码分析)
文章图片

F12呼出控制台 --> 刷新??果然??请求和响应头部都被设置了Connection: keep-alive
Clash实现IP秒级切换(含简易源码分析)
文章图片

Clash实现IP秒级切换(含简易源码分析)
文章图片

突然想到Burpsuite默认会把Connection字段值改写为close
于是起Burp --> 挂代理 --> 抓包 --> 重放 --> 重放 --> 重放??OK
Clash实现IP秒级切换(含简易源码分析)
文章图片

Clash实现IP秒级切换(含简易源码分析)
文章图片

Clash实现IP秒级切换(含简易源码分析)
文章图片

最后??VPS起个WEB服务??拿dirsearch跑一跑验证效果
Clash实现IP秒级切换(含简易源码分析)
文章图片

【Clash实现IP秒级切换(含简易源码分析)】这样又可以放心大胆的干活了

    推荐阅读