diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 93c4609..09dc1de 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -72,7 +72,8 @@ body: attributes: label: fscan 版本 options: - - 2.2.0-rc (dev) + - 2.2.0 + - 2.2.0-rc - 2.1.3 - 2.1.2 - 2.1.0 diff --git a/.github/ISSUE_TEMPLATE/false_positive.yml b/.github/ISSUE_TEMPLATE/false_positive.yml index 883903d..d201dec 100644 --- a/.github/ISSUE_TEMPLATE/false_positive.yml +++ b/.github/ISSUE_TEMPLATE/false_positive.yml @@ -94,7 +94,8 @@ body: attributes: label: fscan 版本 options: - - 2.2.0-rc (dev) + - 2.2.0 + - 2.2.0-rc - 2.1.3 - 2.1.2 - 2.1.0 diff --git a/.github/RELEASE.md b/.github/RELEASE.md index be3d4fb..0711d12 100644 --- a/.github/RELEASE.md +++ b/.github/RELEASE.md @@ -12,6 +12,7 @@ gh workflow run release.yml -f snapshot=true # 3. 确认版本号一致 grep "version" common/globals.go grep "版本" README.md +grep "Version" README_EN.md ``` ## 发版 @@ -20,7 +21,7 @@ grep "版本" README.md # 1. 确认 release notes 已就绪 cat .github/release-notes/v.md -# 2. 打 tag(在 dev 分支打 RC,在 main 分支打正式版) +# 2. 打 tag(RC 手动打;正式版合并到 main 后由 CI 自动打 tag) git tag v git push origin v @@ -47,18 +48,14 @@ git push origin v ## 正式版发布(RC → 正式) ```bash -# 1. 合并 dev 到 main -git checkout main -git merge dev -git push - -# 2. 更新版本号去掉 -rc +# 1. 在 dev 分支准备正式版内容 # common/globals.go, README.md, README_EN.md - -# 3. 准备正式版 release notes # .github/release-notes/v2.2.0.md -# 4. 打 tag -git tag v2.2.0 -git push origin v2.2.0 +# 2. 创建 dev -> main PR +gh pr create --base main --head dev + +# 3. 合并 PR +# main push 会自动读取 common/globals.go 中的版本号,创建 v tag +# tag push 会触发 GoReleaser 构建并创建 GitHub Release ``` diff --git a/.github/conf/.goreleaser.yml b/.github/conf/.goreleaser.yml index 18ebff3..426b6d7 100644 --- a/.github/conf/.goreleaser.yml +++ b/.github/conf/.goreleaser.yml @@ -1,3 +1,5 @@ +version: 2 + project_name: "fscan" before: @@ -135,17 +137,17 @@ builds: upx: - ids: [fscan, fscan-nolocal, fscan-web] enabled: true - goos: [windows, linux, freebsd] - goarch: [amd64, "386", arm, arm64, mips, mipsle] - compress: best + goos: [windows, linux] + goarch: [amd64, "386", arm64] + compress: "6" brute: false lzma: false archives: # 标准版归档 - id: fscan - builds: [fscan] - format: binary + ids: [fscan] + formats: [binary] allow_different_binary_count: true name_template: >- fscan_{{ .Version }}_ @@ -158,8 +160,8 @@ archives: # 无本地插件版归档 - id: fscan-nolocal - builds: [fscan-nolocal] - format: binary + ids: [fscan-nolocal] + formats: [binary] allow_different_binary_count: true name_template: >- fscan-nolocal_{{ .Version }}_ @@ -172,8 +174,8 @@ archives: # WebUI版归档 - id: fscan-web - builds: [fscan-web] - format: binary + ids: [fscan-web] + formats: [binary] allow_different_binary_count: true name_template: >- fscan-web_{{ .Version }}_ @@ -238,7 +240,7 @@ release: **完整更新日志**: https://github.com/{{ .Env.GITHUB_OWNER }}/{{ .Env.GITHUB_REPO }}/compare/{{ .PreviousTag }}...{{ .Tag }} snapshot: - name_template: "{{ incpatch .Version }}-dev-{{ .ShortCommit }}" + version_template: "{{ incpatch .Version }}-dev-{{ .ShortCommit }}" metadata: mod_timestamp: "{{ .CommitTimestamp }}" diff --git a/.github/release-notes/v2.2.0.md b/.github/release-notes/v2.2.0.md new file mode 100644 index 0000000..0a7ace6 --- /dev/null +++ b/.github/release-notes/v2.2.0.md @@ -0,0 +1,129 @@ +# fscan v2.2.0 + +v2.2.0 是 v2.2 系列首个正式版,基于 v2.1.3 之后的 RC 测试和 Issue 反馈整理发布。 + +本版本重点提升大规模扫描稳定性、POC 扫描可靠性、非标准端口服务识别、插件隔离和嵌入式 SDK 能力。 + +--- + +## 重点变化 + +### 嵌入式 Scanner SDK + +新增 `pkg/fscan`,fscan 从纯 CLI 工具扩展为可嵌入的 Go 扫描引擎: + +- 支持在 Go 程序内直接调用扫描能力 +- Scanner 实例拥有独立 `config` / `state` / `session` +- 全局状态迁移到 session,改善多实例并发隔离 +- 补充 SDK 结果转换、配置校验和并发扫描测试 + +### 大规模扫描稳定性 + +- 新增流式 Host Iterator,大 CIDR 不再一次性展开到内存 +- 移除 MaxHosts 硬限制,大网段不再被静默截断 +- 新增自适应并发调度,基于 RTT、丢包率、fd limit 自动推导扫描参数 +- 线程池升级为 AIMD + 慢启动,遇到资源耗尽时自动降速 +- `-gt` 全局超时正式生效,超时后会取消扫描任务 +- 新增 `-nsp`,可禁用网段预筛 + +### 服务识别与插件调度 + +- 修复非标准端口服务无法匹配插件的问题 +- 新增服务缓存和指纹驱动插件匹配 +- `-full` 模式下 Web 插件可覆盖所有开放端口 +- 不确定服务增加 HTTP 回退探测 +- 移除误导性的“无可用插件”日志 +- 用户指定 `-p` 时 UDP 插件按端口交集正确调度 + +### Web / POC 扫描 + +- 修复默认扫描 POC 结果缺失 +- 修复 `-hf` 批量扫描时 POC 缺失 +- 修复 HTTPS 端口误用 HTTP 扫描 POC +- 修复 POC 结果文件只显示 `vulnerable` 不显示漏洞名称 +- POC 加载按 `pocpath` 隔离缓存,多 session 不再互相覆盖 +- 修复 CEL、reverseCheck、正则缓存等稳定性问题 +- `-nopoc` 禁用 POC 时不再输出误导性错误日志 + +### 新增协议插件 + +新增多种原生协议插件,覆盖邮件、Java 调试、文件共享、带外管理、UDP 和工控场景: + +| 插件 | 用途 | +|------|------| +| IMAP / POP3 | 邮件服务器检测 | +| JDWP | Java Debug 端口检测 | +| NFS / RMI | 文件共享 / Java 远程调用 | +| IPMI | 服务器带外管理 | +| SNMP / DNS / BACnet / Modbus | 网络设备、DNS、工控协议检测 | + +### Web 版 + +- 拆分 CLI / Web 入口 +- Web 版结果存储改为 SQLite 持久化 +- Web API 版本号改为动态读取 + +--- + +## Bug 修复摘要 + +- 修复 #586 默认扫描 POC 结果缺失 +- 修复 #587 `-hf` 批量扫描 POC 缺失 +- 修复 #588 非标准端口服务插件匹配问题 +- 修复 #590 Telnet Cisco MOTD 横幅误判 shell prompt +- 修复 #591 HTTPS POC 协议错误与结果名称缺失 +- 修复 #592 service probe 空指针 panic +- 修复 #593 `-ehf` 排除主机未生效,支持 IP / CIDR / range +- 修复 UDP 插件阻塞导致扫描无法结束 +- 修复 SSH goroutine 泄漏和握手 deadline 问题 +- 修复 Redis exploit 超时和非超时错误处理 +- 修复 MongoDB SCRAM、Cassandra、Oracle 等协议问题 +- 修复 SOCKS5 代理认证、LM:NT hash、逗号分隔密码等参数问题 +- 修复非终端输出 ANSI 控制码覆盖结果 +- 修复 CSV / NDJSON / TXT 输出若干字段问题 +- 修复 ARM 32 位原子计数器对齐问题 + +--- + +## 升级注意 + +- WebUI 仍建议视为实验性能力 +- 本地后渗透插件仅用于授权环境 +- v2.2.0 改动较大,建议从 v2.1.3 升级的用户先在测试环境验证扫描参数 +- 如依赖旧版本输出格式,请重点检查 POC、SERVICE、VULN 结果字段 + +--- + +## 版本说明 + +| 版本 | 说明 | +|------|------| +| **fscan** | 标准版,包含全部插件(推荐) | +| **fscan-nolocal** | 精简版,不含本地模块(体积更小) | +| **fscan-web** | WebUI 版,带 Web 管理界面(主流平台) | + +## 平台支持 + +| 平台 | 架构 | +|------|------| +| Linux | x64, x32, arm64, armv5/6/7, mips, mips64, mipsle | +| Windows | x64, x32 | +| macOS | x64, arm64 | +| FreeBSD | x64, x32, arm64, armv5/6/7 | +| Solaris | x64 | + +--- + +## 校验 + +本版本已通过: + +- `go test ./...` +- 近期 Issue 回归验证 +- 本地 HTTP / HTTPS POC 扫描验证 +- `-hf` 批量 POC 扫描验证 +- `-ehf` IP / CIDR 排除验证 + +完整变更记录见: + +https://github.com/shadow1ng/fscan/compare/v2.1.3...v2.2.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e7b8dc7..cc149e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,8 @@ name: 发布 on: push: + branches: + - main tags: - 'v*' workflow_dispatch: @@ -22,7 +24,60 @@ env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: + auto-tag: + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + tag: ${{ steps.version.outputs.tag }} + + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 读取版本号 + id: version + shell: bash + run: | + VERSION=$(sed -n 's/^[[:space:]]*version = "\(.*\)"/\1/p' common/globals.go) + if [ -z "$VERSION" ]; then + echo "❌ 无法从 common/globals.go 读取版本号" + exit 1 + fi + TAG="v${VERSION}" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + echo "准备发布 ${TAG}" + + - name: 创建发布标签 + shell: bash + run: | + TAG="${{ steps.version.outputs.tag }}" + + if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/tmp/tag-ref 2>/dev/null; then + git fetch --force origin "refs/tags/${TAG}:refs/tags/${TAG}" + TAG_COMMIT=$(git rev-list -n 1 "${TAG}") + HEAD_COMMIT=$(git rev-parse HEAD) + if [ "$TAG_COMMIT" = "$HEAD_COMMIT" ]; then + echo "✅ ${TAG} 已指向当前提交,跳过创建" + exit 0 + fi + echo "❌ ${TAG} 已存在,但不指向当前提交" + echo "tag: ${TAG_COMMIT}" + echo "head: ${HEAD_COMMIT}" + exit 1 + fi + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git tag -a "${TAG}" -m "Release ${TAG}" + git push origin "${TAG}" + release: + needs: [auto-tag] + if: ${{ always() && (startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.auto-tag.result == 'success')) }} runs-on: ubuntu-latest timeout-minutes: 90 @@ -32,10 +87,32 @@ jobs: with: fetch-depth: 0 + - name: 解析发布标签 + id: release_tag + shell: bash + env: + AUTO_TAG: ${{ needs.auto-tag.outputs.tag }} + SNAPSHOT: ${{ inputs.snapshot }} + run: | + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + TAG="${GITHUB_REF_NAME}" + elif [ "${GITHUB_EVENT_NAME}" = "push" ] && [ "${GITHUB_REF}" = "refs/heads/main" ]; then + TAG="${AUTO_TAG}" + git fetch --force origin "refs/tags/${TAG}:refs/tags/${TAG}" + elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "${SNAPSHOT}" = "true" ]; then + TAG="${GITHUB_REF_NAME}" + else + echo "❌ 非 snapshot 手动发布必须从 tag 触发" + exit 1 + fi + + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV" + - name: 准备 Release Notes if: ${{ !inputs.snapshot }} run: | - TAG="${GITHUB_REF_NAME}" + TAG="${RELEASE_TAG}" NOTES_FILE=".github/release-notes/${TAG}.md" if [ -f "$NOTES_FILE" ]; then @@ -61,7 +138,7 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - TAG="${GITHUB_REF_NAME}" + TAG="${RELEASE_TAG}" NOTES_FILE="${RELEASE_NOTES_FILE}" if [ -s "$NOTES_FILE" ]; then diff --git a/README.md b/README.md index 2564245..64ad461 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 内网综合扫描工具,一键自动化漏扫。 -**版本**: 2.2.0-rc.1 +**版本**: 2.2.0 ## 功能特性 diff --git a/README_EN.md b/README_EN.md index d55b95d..cbb55aa 100644 --- a/README_EN.md +++ b/README_EN.md @@ -4,7 +4,7 @@ Comprehensive intranet scanning tool for automated vulnerability assessment. -**Version**: 2.2.0-rc.1.1 +**Version**: 2.2.0 ## Features diff --git a/common/globals.go b/common/globals.go index 7a1626c..0ed94e7 100644 --- a/common/globals.go +++ b/common/globals.go @@ -69,7 +69,7 @@ const ( // 版本信息,通过 ldflags 注入 var ( - version = "2.2.0-rc.1" + version = "2.2.0" commit = "unknown" date = "unknown" )