mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-25 04:31:52 +08:00
feat: v2.1.0 核心重构与功能增强
## 架构重构
- 全局变量消除,迁移至 Config/State 对象
- SMB 插件融合(smb/smb2/smbghost/smbinfo)
- 服务探测重构,实现 Nmap 风格 fallback 机制
- 输出系统重构,TXT 实时刷盘 + 双写机制
- i18n 框架升级至 go-i18n
## 性能优化
- 正则表达式预编译
- 内存优化 map[string]struct{}
- 并发指纹匹配
- SOCKS5 连接复用
- 滑动窗口调度 + 自适应线程池
## 新功能
- Web 管理界面
- 多格式 POC 适配(xray/afrog)
- 增强指纹库(3139条)
- Favicon hash 指纹识别
- 插件选择性编译(Build Tags)
- fscan-lab 靶场环境
- 默认端口扩展(62→133)
## 构建系统
- 添加 no_local tag 支持排除本地插件
- 多版本构建:fscan/fscan-nolocal/fscan-web
- CI 添加 snapshot 模式支持仅测试构建
## Bug 修复
- 修复 120+ 个问题,包括 RDP panic、批量扫描漏报、
JSON 输出格式、Redis 检测、Context 超时等
## 测试增强
- 单元测试覆盖率 74-100%
- 并发安全测试
- 集成测试(Web/端口/服务/SSH/ICMP)
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestPocAdapterExample 演示多格式POC加载
|
||||
func TestPocAdapterExample(t *testing.T) {
|
||||
fmt.Println("\n========== 多格式 POC 适配器演示 ==========")
|
||||
|
||||
// 示例1: fscan原生格式
|
||||
fscanYaml := `
|
||||
name: poc-yaml-test-fscan
|
||||
set:
|
||||
rand: randomInt(10000, 99999)
|
||||
rules:
|
||||
- method: GET
|
||||
path: /api/check?id={{rand}}
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(b"success")
|
||||
detail:
|
||||
author: fscan-dev
|
||||
description: fscan原生格式示例
|
||||
`
|
||||
|
||||
fmt.Println("1. 加载 fscan 原生格式 POC:")
|
||||
fmt.Println(" YAML内容:", fscanYaml[:100], "...")
|
||||
|
||||
poc1, err := LoadUniversalPoc("test-fscan.yml", []byte(fscanYaml))
|
||||
if err != nil {
|
||||
t.Fatalf("加载失败: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf(" ✓ 格式: %s\n", poc1.GetFormat())
|
||||
fmt.Printf(" ✓ 名称: %s\n", poc1.GetName())
|
||||
|
||||
fscanPoc1, _ := poc1.ToFscanPoc()
|
||||
fmt.Printf(" ✓ 规则数: %d\n", len(fscanPoc1.Rules))
|
||||
fmt.Println()
|
||||
|
||||
// 示例2: Nuclei格式
|
||||
nucleiYaml := `
|
||||
id: test-nuclei-sqli
|
||||
info:
|
||||
name: SQL Injection Detection
|
||||
author: pdteam
|
||||
severity: high
|
||||
description: Detects SQL injection vulnerabilities
|
||||
reference:
|
||||
- https://owasp.org/www-community/attacks/SQL_Injection
|
||||
http:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}/api/user?id=1'"
|
||||
- "{{BaseURL}}/search?q=test'"
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "SQL syntax"
|
||||
- "mysql_fetch"
|
||||
condition: or
|
||||
- type: status
|
||||
status:
|
||||
- 500
|
||||
`
|
||||
|
||||
fmt.Println("2. 加载 Nuclei 格式 POC:")
|
||||
fmt.Println(" YAML内容:", nucleiYaml[:100], "...")
|
||||
|
||||
poc2, err := LoadUniversalPoc("test-nuclei.yaml", []byte(nucleiYaml))
|
||||
if err != nil {
|
||||
t.Fatalf("加载失败: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf(" ✓ 格式: %s\n", poc2.GetFormat())
|
||||
fmt.Printf(" ✓ 名称: %s\n", poc2.GetName())
|
||||
|
||||
fscanPoc2, _ := poc2.ToFscanPoc()
|
||||
fmt.Printf(" ✓ 规则数: %d (Nuclei的2个path转为2个rule)\n", len(fscanPoc2.Rules))
|
||||
fmt.Printf(" ✓ 第一条规则表达式: %s\n", fscanPoc2.Rules[0].Expression[:80]+"...")
|
||||
fmt.Println()
|
||||
|
||||
// 示例3: 格式检测
|
||||
fmt.Println("3. 自动格式检测:")
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
yaml string
|
||||
format PocFormat
|
||||
}{
|
||||
{
|
||||
"fscan格式",
|
||||
`name: test
|
||||
rules:
|
||||
- method: GET`,
|
||||
FormatFscan,
|
||||
},
|
||||
{
|
||||
"Nuclei格式",
|
||||
`id: test
|
||||
info:
|
||||
name: test`,
|
||||
FormatNuclei,
|
||||
},
|
||||
{
|
||||
"未知格式",
|
||||
`unknown: field`,
|
||||
FormatUnknown,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
detected := DetectPocFormat([]byte(tc.yaml))
|
||||
status := "✓"
|
||||
if detected != tc.format {
|
||||
status = "✗"
|
||||
}
|
||||
fmt.Printf(" %s %s: 检测为 %s\n", status, tc.name, detected)
|
||||
}
|
||||
|
||||
fmt.Println("\n========== 演示结束 ==========")
|
||||
}
|
||||
|
||||
// TestPocAdapterFeatures 展示适配器特性
|
||||
func TestPocAdapterFeatures(t *testing.T) {
|
||||
fmt.Println("\n========== POC 适配器特性展示 ==========")
|
||||
|
||||
nucleiYaml := `
|
||||
id: features-demo
|
||||
info:
|
||||
name: Feature Demo
|
||||
author: test
|
||||
severity: medium
|
||||
http:
|
||||
- method: POST
|
||||
path:
|
||||
- "{{BaseURL}}/login"
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
body: '{"user":"admin","pass":"test"}'
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "success"
|
||||
- "authenticated"
|
||||
condition: and
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
- 302
|
||||
matchers-condition: and
|
||||
`
|
||||
|
||||
fmt.Println("特性1: Nuclei matcher 转换")
|
||||
poc, _ := LoadUniversalPoc("demo.yaml", []byte(nucleiYaml))
|
||||
fscanPoc, _ := poc.ToFscanPoc()
|
||||
|
||||
fmt.Printf(" 原始: Nuclei format with 2 matchers\n")
|
||||
fmt.Printf(" 转换: fscan expression\n")
|
||||
fmt.Printf(" 结果: %s\n", fscanPoc.Rules[0].Expression)
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println("特性2: 多 path 处理")
|
||||
multiPathYaml := `
|
||||
id: multi-path-demo
|
||||
info:
|
||||
name: Multi Path Demo
|
||||
http:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}/admin"
|
||||
- "{{BaseURL}}/dashboard"
|
||||
- "{{BaseURL}}/config"
|
||||
matchers:
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
`
|
||||
|
||||
poc2, _ := LoadUniversalPoc("multi.yaml", []byte(multiPathYaml))
|
||||
fscanPoc2, _ := poc2.ToFscanPoc()
|
||||
|
||||
fmt.Printf(" 原始: 3个 path\n")
|
||||
fmt.Printf(" 转换: %d 个 rule\n", len(fscanPoc2.Rules))
|
||||
for i, rule := range fscanPoc2.Rules {
|
||||
fmt.Printf(" Rule %d: %s\n", i+1, rule.Path)
|
||||
}
|
||||
|
||||
fmt.Println("\n========== 特性展示结束 ==========")
|
||||
}
|
||||
Reference in New Issue
Block a user