mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
6.8 KiB
6.8 KiB
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.go为main_cli.go和main_web.go - Web 版结果存储从内存替换为 SQLite 持久化(纯 Go 零 CGO)
🐛 Bug 修复
插件调度(#586 #587 #588)
- 非标准端口服务无法匹配插件 — SSH 在 8881 端口,端口匹配失败导致插件不执行。新增服务名称缓存 + 指纹驱动回退匹配 (#588)
- 移除误导性的"无可用插件"日志 — 预检基于静态端口匹配,不代表实际不执行 (#588)
- 默认扫描 POC 结果缺失 —
executeRules返回空vulName导致检测结果被丢弃 (#586) - 批量扫描(-hf)POC 缺失 — 并发压力下 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不接受 context,context 取消后底层 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/Read在Conn=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
📊 实测验证
| 指标 | v2.2.0-rc | v2.2.0-rc.1 |
|---|---|---|
SSH -m ssh 爆破成功率 |
~60% | 100% (10/10) |
| POC 加载成功率 | 380/388 | 388/388 |
UDP 插件 -p 指定端口 |
✗ 跳过 | ✓ 正确调度 |
| SNMP 终端输出 | ✗ 不显示 | ✓ 正常 |
| UDP 扫描耗时(无响应目标) | ∞ 卡死 | 9s 完成 |
| Redis exploit 超时保护 | ✗ 无 | ✓ 30s |
反馈与贡献
- 🐛 发现 Bug → 提交 Bug 报告
- 🎯 结果不准 → 提交误报/漏报
- ✨ 功能建议 → 提交功能请求
- 💬 使用疑问 → Discussions