Clash实现IP秒级切换(含简易源码分析)
免责声明
本文所提供的程序(方法)可能带有攻击性,仅供安全研究与教学之用。文章作者无法鉴别判断读者使用信息及工具的真实用途,若读者将文章中的工具或信息做其他用途,由读者承担全部法律及连带责任,segmentfault和本文作者不承担任何法律及连带责任。
注:此文章适用于对Clash有一定使用经验的读者??不再对基础配置说明
0x00 意外
一直以来都使用酸酸乳自带的负载均衡功能配合Airport实现IP秒切
主要用途是对站点进行渗透测试时路径爆破和扫描端口
文章图片
直到有一天Airport跑路了
兜兜转转换了一家??发现他们使用Clash作为客户端
文章图片
为方便使用??我选择了Clash-For-Windows
简称CFWClash
支持跨平台??后文以Clash
进行分析(主要是CFW不开源)
文章图片
拿到机场配置文件导入??简单配置下就能正常使用了
但是却始终没有找到和负载均衡有关的设置
百度一下??找到了负载均衡的配置样例
# 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跑一跑??然后就被封了
文章图片
用VPS起个WEB服务扫描看一看??原来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
文章图片
继续分析??首先声明了变量
etld
调用
publicsuffix.EffectiveTLDPlusOne()
方法对metadata.Host
进行处理并赋值给etld
然后定义了一个函数
getKey()
来接收处理后的metadata.Host
文章图片
那么函数
getKey()
返回的值可以是目的IP??也可以是eTLD(eTLD+1)(其实分析到这里??已经隐约感觉到问题没有出在
eTLD
)继续搜索??发现函数
strategyConsistentHashing()
调用了getKey()
根据函数名判断
strategyConsistentHashing()
是一致性哈希算法策略文章图片
一致性哈希算法是负载均衡调度算法的其中一种
以Nginx负载均衡的算法进行类比??相当于
ip_hash
和url_hash
的结合ip_hash:每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。分析到这步??基本可以确定IP秒切失败的原因是使用了
url_hash:按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。如果需要这种调度算法,则必须安装Nginx的hash软件包。
一致性哈希调度算法
导致的那么只要使用
轮询调度算法
来分配每次请求??就可以实现IP秒切效果轮询调度(Round-Robin,RR):最简单的调度算法,LB按照顺序将请求依次转发给后端的RS,并没有考量后端RS的状态(处理速度以及响应时间)。上下随便翻翻??发现函数
带权重的轮询调度(Weighted Round-Robin,WRR):在轮询算法的基础上加上权重设置,权重越高的RS被分配到的请求越多。
strategyConsistentHashing()
上方已经写好了Round-Robin调度算法本来还想尝试写一个呢hhh??既然如此??那就来看下两个函数之间的差异
直接的原因就在于变量
idx
的值??而idx
的值又是由两种算法决定的一致性哈希会把同一个IP/URL的请求分配到同一个代理上??
idx
和getKey()
的返回值相关轮询调度会把每一次请求分配到不同的代理上??
idx
仅和代理的数量相关两者在策略失效的情况下??都会默认选择第1个代理
文章图片
调度算法已经有了??现在只要找到哪里调用了
strategyRoundRobin()
粗略读一下代码??发现函数
NewLoadBalance()
对调度算法进行了分支选择文章图片
继续跟进 函数
parseStrategy()
从字典config[]
的strategy
键值对读取解析策略推测字典对象
config[]
对应Clash的配置文件*.yaml
如果在字典中没有读取到
strategy
键值对??就会默认使用consistent-hashing
作为解析策略(后续经过测试
strategy
键值对要写在配置文件load-balance
的内部才会生效)文章图片
那么这里就有两种解决方法:
- 将函数
parseStrategy()
的默认返回值由consistent-hashing
更改为round-robin
- 在配置文件里新增键值对
strategy
并赋值为round-robin
(安福仔一枚基本不接触开发 分析缺陷的地方还请师傅们多指教)
(RR是作者后期增加的一个调度算法??早期的配置文档里没有样例??所以才有了这篇文章)
0x03 调试 将配置文件修改以后??简单进行一下测试
文章图片
使用浏览器连接代理访问
cip.cc
??通过不断刷新页面来观察IP的切换情况然而在每次刷新之后IP依旧固定不变
文章图片
再三阅读代码确认没有问题之后??在一次测试中无意间点开了CFW的
连接
原来在访问网站之后??TCP连接没有立即断开??而是处于保持连接状态
文章图片
F12呼出控制台 --> 刷新??果然??请求和响应头部都被设置了
Connection: keep-alive
文章图片
文章图片
突然想到Burpsuite默认会把
Connection
字段值改写为close
于是起Burp --> 挂代理 --> 抓包 --> 重放 --> 重放 --> 重放??OK
文章图片
文章图片
文章图片
最后??VPS起个WEB服务??拿dirsearch跑一跑验证效果
文章图片
【Clash实现IP秒级切换(含简易源码分析)】这样又可以放心大胆的干活了
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM