PipelineHttp 源码解析scan4all 中自动升级 HTTP/2 与 HTTP/3 的高性能请求管道【免费下载链接】scan4allOfficial repository vuls Scan: 15000PoCs; 23 kinds of application password crack; 7000Web fingerprints; 146 protocols and 90000 rules Port scanning; Fuzz, HW, awesome BugBounty( ͡° ͜ʖ ͡°)...项目地址: https://gitcode.com/GitHub_Trending/sca/scan4allPipelineHttp 是 scan4all 依赖的一个轻量级 HTTP 请求管道库以 vendor 形式位于 vendor/github.com/hktalent/PipelineHttp/README.md。它的核心价值在于对大量目标做批量请求时自动探测并按需切换 HTTP/1.1、HTTP/2含 h2c Upgrade与 HTTP/3 传输同时内置 403 Bypass 请求头、连接池调优参数与错误熔断机制。读完本文你可以理解它如何被 scan4all 的批量目录探测DoDirs、多文件上传SendFiles所复用并掌握连接池参数的实际配置方法。一、README 给出的定位自动支持 HTTP/2支持 HTTP/3原始 README 非常简短核心功能只有两条auto support HTTP/2.0对目标自动探测并升级无需手工指定协议support HTTP/3.0当响应中出现Alt-Svc: h3...或服务端返回 101 Switching Protocols 时切换到 QUIC/HTTP3 传输。README 同时给出了命令行的安装与用法go get -u ./... go build -o ppHttp cmd/main.go ln -s $PWD/ppHttp $HOME/go/bin/ppHttp # go install github.com/hktalent/PipelineHttp/cmd/latestppHttp https://xx1.com https://b1.xx2.comREADME 中还附有一条速度参考http 2.0 18s req 30612 * 2(host) times即在两台主机上共 61224 次请求耗时约 18 秒说明其吞吐能力是为“对少量 Host 打大量请求”的场景设计的——这正契合 scan4all 批量 POC 探测的工作模式。在 scan4all 仓库中该库以 go.mod 第 31 行声明github.com/hktalent/PipelineHttp v0.0.0-20231203113740-b6691386054d引入vendor 目录下只有 5 个文件PipelineHttp.go、http2Imp.go、http3client.go、DoFile.go 和 README结构非常紧凑。二、PipelineHttp 结构体连接池参数与默认值所有可配置项都集中在PipelineHttp结构体中见 PipelineHttp.go 第 28-51 行源码上方有一段中文注释解释了各连接池参数的关系这是调优的关键依据MaxConnsPerHost控制单个 Host 的最大连接总数。默认为 0即不限制连接池里能用就用不能用就新建连接MaxIdleConnsPerHost决定单个 Host 维持的连接池大小是“优先设置”的参数应根据压测结果调整MaxIdleConns跨所有 Host 的空闲连接总数。若客户端连接 n 个 Host 而该值小于n × MaxIdleConnsPerHost会影响按 Host 控制的连接池导致连接重建。嫌麻烦建议设为 0不限制MaxConnsPerHost包含 IdleConns一般应大于等于 MaxIdleConnsPerHost设置过小会 block 请求导致并发下降所以默认不限制。NewPipelineHttp()工厂函数第 53-95 行给出的默认值以nTimeout 5*60秒、nIdle 1000为基准参数默认值说明Timeout600 秒整个请求超时含拨号、TLS 握手应比 IdleConnTimeout 更长KeepAlive300 秒TCP Keep-Alive 探测周期MaxIdleConns1000所有 Host 的空闲连接总数MaxIdleConnsPerHost1000单 Host 空闲连接数MaxConnsPerHost0不限制单 Host 最大连接数IdleConnTimeout300 秒连接空闲超过该时间即关闭ResponseHeaderTimeout300 秒读取响应头的超时TLSHandshakeTimeout300 秒TLS 握手超时ExpectContinueTimeout00 表示不等待 100-continue立即发送正文ErrLimit10相同目标累计错误 10 次即停止熔断ReTry3拨号失败重试次数UseHttp2/TestHttpfalse协议升级开关参数通过 variadic 参数传入内部用 JSON 序列化/反序列化覆盖字段第 85-91 行因此调用方传map[string]interface{}即可字段名即 JSON tag。scan4all 正是这样使用的lib/util/util.go 第 103-134 行的GetClient()在默认参数下传入了map[string]interface{}{ max_idle_conns_per_host: 50, max_conns_per_host: 50, max_idle_conns: 50, err_limit: 90000, }即把单 Host 连接数收敛到 50、把错误熔断阈值放大到 9 万次POC 探测中大量 404/超时属正常噪音并将 client 按schemehost写入内存缓存复用避免每个目标重建连接池。三、连接建立重试拨号与 Transport 构造Dial()第 102-123 行是对net.Dialer的封装按ReTry次数重试拨号开启了KeepAlive与DualStack同时支持 IPv4/IPv6。源码注释特别指出不能开启Dialer.Timeout和conn.SetReadDeadline否则会触发dial tcp ...: i/i timeout假超时——这是批量扫描场景下的一个实战经验值。GetTransport()第 132-149 行构造 HTTP/1.1 传输几个值得注意的点TLSClientConfig设置了InsecureSkipVerify: true与MinVersion: tls.VersionTLS10即跳过证书校验、兼容 TLS 1.0 起的老服务DisableKeepAlives: false注释明确“false 才会复用连接”Proxy: http.ProxyFromEnvironment支持走系统代理环境各连接池字段直接映射自结构体参数。GetClient()第 151-179 行组装http.Client时有两个细节CheckRedirect返回http.ErrUseLastResponse即不自动跟随重定向3xx 响应原样交给回调处理——这对漏洞扫描判断原始响应至关重要Client.Timeout被刻意留空注释超时为零表示没有超时整体生命周期由 context 与ErrLimit控制。四、自动升级协议HTTP/1.1 → h2c Upgrade → HTTP/2 / HTTP/3这是“auto support HTTP/2.0”的核心实现位于DoGetWithClient4SetHd()第 247-329 行主动尝试 h2c当ver 1、未启用 HTTP/2 且 URL 为 https 前缀时请求头注入Connection: Upgrade, HTTP2-Settings、Upgrade: h2c和一段二进制HTTP2-Settings试探明文/升级通道第 258-261 行升级判断若首次 HTTP/1.1 请求返回非 200将UseHttp2置为 true 并检查响应响应头Alt-Svc含h3或resp.Proto以HTTP/3开头 → 切换为GetClient4Http3()状态码为 101 Switching Protocols → 切换为GetRawClient4Http2()raw HTTP/2 client随后用新 client 对去掉 query 的 URL 重新发起一次请求并把ErrLimit抬到 99999999 防止误熔断。另外testHttp2()第 358-390 行在批量探测入口doDirsPrivate()被调用用 raw HTTP/2 client 先发一次探测请求根据101、Alt-Svc: h3或Proto HTTP/2.0三种情况选定最终 client实现了 README 所说的“自动”。HTTP/2 侧的实现在 http2Imp.goGetTransport4http2()第 102-126 行基于golang.org/x/net/http2ReadIdleTimeout50 秒、PingTimeout15 秒、WriteByteTimeout600 秒并设置StrictMaxConcurrentStreams: true注释说明“true 则全局复用client 时建议全局复用false 则为每一个创建一个链接”dialT()tConn第 13-22 行包装了 TLS 连接把读取到的字节同步写入r.Bufhttp2.Frame消息缓冲配合DoUrl4Http24Frame()的http2.Framer逐帧回调可用于解析原始 HTTP/2 帧数据GetClient4Http2()会把ver置为 2并同样注入环境代理。HTTP/3 侧在 http3client.go基于quic-go的http3.RoundTripperInsecureSkipVerify: true跳过证书校验GetClient4Http3()把ver置为 3。文件内还留有一行注释指向 HTTP/3 在线测试工具作为验证目标是否开启 QUIC 的旁证。五、批量探测 DoDirs 与多文件上传 SendFiles5.1 并发批量请求DoDirs(szUrl, dirs, nThread, fnCbk)第 354-452 行是 scan4all 批量探测的主要入口先用带缓冲 channel容量nThread实现信号量限流每个 goroutine 拼出szUrl dir后调用DoGetWithClient全程响应r.Ctx.Done()取消信号一旦IsClosed立即退出。DoDirs4Http2则是强制 HTTP/2 的变体。请求执行时的其他行为随机 User-Agent未显式设置 UA 时生成Chrome/92.xxxxx格式的随机版本号 UA第 286-288 行403 BypassDoGetWithClient()第 208-231 行在byPass403()对 URL 尾部做随机变形如追加...;/、%20/、?随机数、连续等并注入一组伪造来源头X-Forwarded-For、X-Original-URL、X-Rewrite-URL、X-Originating-IP、X-Remote-IP、X-Client-IP、X-Forwared-Host注意源码中 Host 头被固定为127.0.0.1、X-Custom-IP-Authorization等源码注释注明这是参考 403 bypass 技巧实现的。错误熔断任何错误都会r.ErrCount达到ErrLimit且未开启NoLimit时调用Close()终止整个管道第 304-308 行若错误信息匹配dial tcp: ...: no such hostDNS 解析失败直接关闭第 309-313 行。Close()第 336-347 行会分别按 Transport 类型关闭http3.RoundTripper或http.Transport的空闲连接并取消 context。scan4all 仓库中确实有多处直接引用该库如 pocs_go/log4j/check.go 与 pocs_go/VMware/vCenter/c_21972.go 都调用了SendFiles构造 multipart 上传。5.2 multipart 多文件上传DoFile.go 提供PostFileData{ContentType, Name, FileName, FileData}结构SendFiles()第 23-76 行支持“表单字段 多个文件”混合上传表单值以 JSON 序列化写入multipart.NewWriter文件部分逐段CreatePart并设置Content-Disposition默认 Content-Type 为text/plain; charsetUTF-8最后用Content-Type: multipart/related; boundary...发起 POST并显式写入Content-Length。源码注释说明了为何不用io.Pipe无法提前预知发送数据的总长度因此先整体缓冲到bytes.Buffer。六、在 scan4all 中的接入方式scan4all 没有直接暴露 PipelineHttp 的命令行而是把它封装成全局 client 缓存供各扫描模块调用统一入口在 lib/util/util.goGetClient(szUrl, pms...)第 103 行按 Host 命中缓存则直接复用未命中则用NewPipelineHttp(pms...)创建并写入缓存GetClient4Cc / PutClientCc按schemehost维度的缓存读写CloseHttpClient / CloseAllHttpClient第 136-149 行先调用PipelineHttp的Close()释放连接再从缓存中删除。这意味着 scan4all 的目录爆破、POC 探测、指纹识别等模块对同一 Host 共享同一个连接池与协议升级状态——目标一旦被判定支持 HTTP/2 或 HTTP/3后续该 Host 上的全部请求都会走升级后的通道这正是 README 中 18 秒 6 万请求量级吞吐的来源。小结PipelineHttp 以不到 700 行 Go 代码覆盖了批量扫描请求管道的几个关键工程点连接池四参数MaxIdleConns / MaxIdleConnsPerHost / MaxConnsPerHost / IdleConnTimeout的显式可调与注释级调优指南、h2c Upgrade 与 Alt-Svc 驱动的 HTTP/2/HTTP/3 自动升级、基于错误计数与 DNS 失败的两级熔断、403 Bypass 请求头注入以及可预测 Content-Length 的 multipart 多文件上传。在 scan4all 中它通过 lib/util/util.go 的 per-host client 缓存被全局复用是 pocs_go、webScan 等扫描模块共同的底层请求基础设施。适用前提该库跳过 TLS 证书校验且不跟随重定向行为面向漏洞扫描而非通用客户端若要在其他项目复用建议按自身场景重设Timeout、ErrLimit并评估InsecureSkipVerify的安全影响。【免费下载链接】scan4allOfficial repository vuls Scan: 15000PoCs; 23 kinds of application password crack; 7000Web fingerprints; 146 protocols and 90000 rules Port scanning; Fuzz, HW, awesome BugBounty( ͡° ͜ʖ ͡°)...项目地址: https://gitcode.com/GitHub_Trending/sca/scan4all创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
