Files
ZacharyZcR 35f3cf1960
测试构建 / 代码检查 (push) Has been cancelled
测试构建 / 单元测试和构建 (push) Has been cancelled
测试构建 / 构建验证 (push) Has been cancelled
docs: release notes 移除实测验证章节
2026-06-14 23:01:39 +08:00

6.4 KiB
Raw Permalink Blame History

fscan v2.2.0-rc.1

⚠️ 这是预发布版本 (Release Candidate),可能存在未发现的问题。 如果你在使用中遇到任何异常,请积极通过 Issue 反馈,帮助我们尽快稳定正式版。 生产环境建议继续使用 v2.1.3


与 v2.2.0-rc 的变更

本版本基于大量实机测试反馈,修复 30+ 个问题,新增自适应扫描系统。183 个文件变更。


🚀 新功能

自适应并发调度

扫描前自动探测网络环境(RTT、丢包率、fd limit),基于探测数据推导关键参数,替代硬编码默认值:

  • Timeout: median_RTT + 4σ(覆盖 99.9% 正常连接),下限 1s,上限 10s
  • ModuleThreadNum: ThreadNum / 30,下限 5,上限 50
  • MaxRetries: 基于丢包率推导,保证全失败概率 <1%
  • ICMPRate / PocNum: 跟随环境和并发自动调整

线程池升级为 AIMD + 慢启动:慢启动阶段 500ms 翻倍,稳态 AIMD(健康 +5%,拥塞 ×0.5),双信号(资源耗尽率 + RTT 趋势)驱动。

协议级超时下限(ModuleTimeout

新增 Config.ModuleTimeout() 方法,保证插件级交互超时不低于 3s。自适应系统将端口扫描超时压到 1s 时,SSH 握手、SNMP 探测、数据库认证等多轮交互协议不再受影响。全部 44 个服务插件已迁移。

限流错误分类(ErrorTypeThrottle

新增 ErrorTypeThrottle 错误类型,区分服务端限流(SSH MaxStartups 等)和真正的网络不可达。限流错误不计入连续失败计数,触发 500ms 退避后继续,避免误判目标不可达而提前放弃。

Web 版独立入口

  • 拆分 main.gomain_cli.gomain_web.go
  • Web 版结果存储从内存替换为 SQLite 持久化(纯 Go 零 CGO

🐛 Bug 修复

插件调度(#586 #587 #588

  • 非标准端口服务无法匹配插件 — SSH 在 8881 端口,端口匹配失败导致插件不执行。新增服务名称缓存 + 指纹驱动回退匹配 (#588)
  • 移除误导性的"无可用插件"日志 — 预检基于静态端口匹配,不代表实际不执行 (#588)
  • 默认扫描 POC 结果缺失executeRules 返回空 vulName 导致检测结果被丢弃 (#586)
  • 批量扫描(-hfPOC 缺失 — 并发压力下 HTTP 请求瞬时失败未重试,跳过指纹识别和 POC 触发。加入指数退避重试 (#587)
  • UDP 插件在 -p 指定端口时被跳过 — 现在按用户指定端口过滤并正确调度
  • -full 模式下 Web 插件跳过 IsMarkedWebService 检查
  • 不确定服务补做 HTTP 回退探测,覆盖自定义 HTTP 框架漏网场景

UDP 插件

  • UDP 插件阻塞导致扫描无法结束conn.Read() 在目标不响应时无限阻塞。所有 UDP 插件(SNMP/BACnet/DNS/IPMI/TFTP)统一使用 context timeout + conn.Close 双保险
  • SNMP community 爆破混入通用密码字典 — 57 个通用密码串行探测导致 10 分钟阻塞,精简为 8 个专用 community

SSH

  • SSH goroutine 泄漏ssh.NewClientConn 不接受 contextcontext 取消后底层 TCP 连接未关闭,大规模扫描时泄漏数万 goroutine
  • SSH 握手无 TCP deadline 兜底 — 在 NewClientConn 前设置 deadline,握手成功后清除
  • SSH 爆破并发过高 — 从 30 降至 3,避免触发 OpenSSH MaxStartups 限流

Redis

  • Redis exploit 无超时保护 — exploit 阶段移除了全部 deadline,改为 30s 超时
  • Redis readReply 吞没非超时错误 — 现在仅对 timeout 类型错误做容忍

POC 引擎

  • DetectPocFormat 误判含 transport 的 fscan POC 为 xray 格式 — 修复后 388 个 POC 全部正确加载(之前 8 个失败)
  • CEL clustersend 结果判断错误 — 从字符串比较改为类型断言
  • CEL wait() 函数 nil Reverse 指针 panic
  • reverseCheck 无超时 — 加 10s 超时防止 ceye API 阻塞
  • 正则编译结果未缓存doSearch/bmatches 缓存到 sync.Map

参数与输出

  • -gt 全局超时参数是死代码 — 现在真正生效,超时后取消所有扫描任务
  • -nopoc 禁用 POC 时仍输出错误日志 — 已修复
  • -debug 日志文件写入失败applyLogLevel 重建 Logger 时丢失 DebugLogFile 配置
  • -hash 不支持 LM:NT 格式 — 现在支持 aad3b435b51404ee:31d6cfe0d16ae931... 标准格式
  • -pwd 不支持逗号分隔多个密码 — 现在 -pwd "123,456,root" 正确拆分
  • -nobr 跳过了 Redis 未授权检测 — 未授权是服务探测不是爆破,不受 -nobr 影响
  • 非终端输出时 ANSI 控制码覆盖扫描结果 — 管道/重定向时自动禁用进度条和颜色
  • 静默模式 NDJSON banner 过长 — Redis INFO ~5KB 截断至 200 字符
  • CSV 漏洞 Type 列为空 — 补全 type 字段
  • SNMP 探测成功但终端无输出 — 补充 session.LogVuln 调用

其他

  • service_probe 连接丢失后静默成功Write/ReadConn=nil 时返回明确错误
  • MongoDB readMongoMsg 未设置读超时
  • TXTWriter.Close Sync 失败后未关闭文件
  • MySQL 3306 服务名误识别为 genetec-5400 — nmap 指纹库误匹配,通过 banner 特征校正
  • gmtls stdout 竞态 — 移除 os.Stdout 非同步重定向

🏗️ 架构优化

  • 统一服务缓存webServiceCache 扩展为通用 serviceCache,下沉到 per-session State,消除多实例缓存串台
  • CEL 表达式编译缓存 — 同一 POC 的所有规则共享编译后的 Program
  • POC 全局状态消除allPocs 全局变量改为 pocStore 按 PocPath 缓存,并发场景不再互相覆盖
  • 进度条竞态修复isActive 改为 atomic.Bool
  • Lint 全量修复 — cassandra/ipmi/mongodb/webscan 的 ineffassign、unused、errcheck

反馈与贡献