mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-25 12:41:53 +08:00
refactor: 引入 ScanSession,替代全局状态穿透扫描管道 (Phase 1-3)
- 新增 common/session.go: ScanSession 结构体封装 Config/State/Params/Dialer - RunScan/Strategy/ExecuteScanTasks/executeScanTask 全部接收 session - Plugin 接口从 Scan(ctx, info, config, state) 改为 Scan(ctx, info, session) - 48 个插件实现统一更新签名 - Web API 构建 ScanSession 传给 RunScan - CLI 模式通过 Initialize() 创建 session
This commit is contained in:
@@ -54,17 +54,15 @@ func (s *AliveScanStrategy) Description() string {
|
||||
}
|
||||
|
||||
// Execute 执行存活探测扫描策略
|
||||
func (s *AliveScanStrategy) Execute(_ context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func (s *AliveScanStrategy) Execute(_ context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
// 验证扫描目标(需要同时检查 -h 和 -hf 参数)
|
||||
fv := common.GetFlagVars()
|
||||
if info.Host == "" && fv.HostsFile == "" {
|
||||
if info.Host == "" && session.Params.HostsFile == "" {
|
||||
common.LogError(i18n.GetText("parse_error_target_empty"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 执行存活探测
|
||||
s.performAliveScan(info, config, state)
|
||||
s.performAliveScan(info, session.Config, session.State)
|
||||
|
||||
// 输出统计信息
|
||||
s.outputStats()
|
||||
|
||||
@@ -42,7 +42,9 @@ func (s *LocalScanStrategy) Description() string {
|
||||
}
|
||||
|
||||
// Execute 执行本地扫描策略
|
||||
func (s *LocalScanStrategy) Execute(ctx context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func (s *LocalScanStrategy) Execute(ctx context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
config := session.Config
|
||||
|
||||
// 输出扫描开始信息
|
||||
s.LogScanStart()
|
||||
|
||||
@@ -67,7 +69,7 @@ func (s *LocalScanStrategy) Execute(ctx context.Context, config *common.Config,
|
||||
targets := s.PrepareTargets(info)
|
||||
|
||||
// 执行扫描任务
|
||||
ExecuteScanTasks(ctx, config, state, targets, s, ch, wg)
|
||||
ExecuteScanTasks(ctx, session, targets, s, ch, wg)
|
||||
}
|
||||
|
||||
// PrepareTargets 准备本地扫描目标
|
||||
|
||||
+15
-8
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
// ScanStrategy 定义扫描策略接口
|
||||
type ScanStrategy interface {
|
||||
Execute(ctx context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup)
|
||||
Execute(ctx context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup)
|
||||
GetPlugins(config *common.Config) ([]string, bool)
|
||||
IsPluginApplicableByName(pluginName string, targetHost string, targetPort int, isCustomMode bool, config *common.Config) bool
|
||||
}
|
||||
@@ -73,10 +73,13 @@ func selectStrategy(config *common.Config, state *common.State, info common.Host
|
||||
}
|
||||
|
||||
// RunScan 执行整体扫描流程
|
||||
func RunScan(ctx context.Context, info common.HostInfo, config *common.Config, state *common.State) {
|
||||
func RunScan(ctx context.Context, info common.HostInfo, session *common.ScanSession) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
config := session.Config
|
||||
state := session.State
|
||||
|
||||
// 初始化HTTP客户端(静默,无需日志)
|
||||
if err := lib.Inithttp(config); err != nil {
|
||||
common.LogError(i18n.Tr("http_client_init_failed", err))
|
||||
@@ -91,7 +94,7 @@ func RunScan(ctx context.Context, info common.HostInfo, config *common.Config, s
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
// 执行策略
|
||||
strategy.Execute(ctx, config, state, info, ch, &wg)
|
||||
strategy.Execute(ctx, session, info, ch, &wg)
|
||||
|
||||
// 等待所有扫描完成
|
||||
wg.Wait()
|
||||
@@ -142,7 +145,9 @@ func finishScan(config *common.Config, state *common.State) {
|
||||
}
|
||||
|
||||
// ExecuteScanTasks 任务执行通用框架
|
||||
func ExecuteScanTasks(ctx context.Context, config *common.Config, state *common.State, targets []common.HostInfo, strategy ScanStrategy, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func ExecuteScanTasks(ctx context.Context, session *common.ScanSession, targets []common.HostInfo, strategy ScanStrategy, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
config := session.Config
|
||||
|
||||
// 获取要执行的插件
|
||||
pluginsToRun, isCustomMode := strategy.GetPlugins(config)
|
||||
|
||||
@@ -174,7 +179,7 @@ func ExecuteScanTasks(ctx context.Context, config *common.Config, state *common.
|
||||
|
||||
// 检查插件是否适用于当前目标
|
||||
if strategy.IsPluginApplicableByName(pluginName, target.Host, targetPort, isCustomMode, config) {
|
||||
executeScanTask(ctx, config, state, pluginName, target, ch, wg)
|
||||
executeScanTask(ctx, session, pluginName, target, ch, wg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,7 +210,9 @@ var longRunningPlugins = map[string]bool{
|
||||
}
|
||||
|
||||
// executeScanTask 执行单个扫描任务
|
||||
func executeScanTask(ctx context.Context, config *common.Config, state *common.State, pluginName string, target common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func executeScanTask(ctx context.Context, session *common.ScanSession, pluginName string, target common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
state := session.State
|
||||
|
||||
// 检查取消
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -218,7 +225,7 @@ func executeScanTask(ctx context.Context, config *common.Config, state *common.S
|
||||
go func() {
|
||||
plugin := plugins.Get(pluginName)
|
||||
if plugin != nil {
|
||||
plugin.Scan(ctx, &target, config, state)
|
||||
plugin.Scan(ctx, &target, session)
|
||||
}
|
||||
}()
|
||||
return
|
||||
@@ -257,7 +264,7 @@ func executeScanTask(ctx context.Context, config *common.Config, state *common.S
|
||||
|
||||
plugin := plugins.Get(pluginName)
|
||||
if plugin != nil {
|
||||
result := plugin.Scan(ctx, &target, config, state)
|
||||
result := plugin.Scan(ctx, &target, session)
|
||||
if result != nil {
|
||||
if result.Success {
|
||||
// 保存成功的扫描结果到文件
|
||||
|
||||
@@ -215,7 +215,7 @@ type mockStrategy struct {
|
||||
applicablePlugins map[string]bool // pluginName -> isApplicable
|
||||
}
|
||||
|
||||
func (m *mockStrategy) Execute(_ context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func (m *mockStrategy) Execute(_ context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
}
|
||||
|
||||
func (m *mockStrategy) GetPlugins() ([]string, bool) {
|
||||
|
||||
@@ -113,10 +113,11 @@ func (s *ServiceScanStrategy) Description() string {
|
||||
}
|
||||
|
||||
// Execute 执行服务扫描策略
|
||||
func (s *ServiceScanStrategy) Execute(ctx context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func (s *ServiceScanStrategy) Execute(ctx context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
config := session.Config
|
||||
|
||||
// 验证扫描目标(需要同时检查 -h 和 -hf 参数)
|
||||
fv := common.GetFlagVars()
|
||||
if info.Host == "" && fv.HostsFile == "" {
|
||||
if info.Host == "" && session.Params.HostsFile == "" {
|
||||
common.LogError(i18n.GetText("parse_error_target_empty"))
|
||||
return
|
||||
}
|
||||
@@ -134,13 +135,13 @@ func (s *ServiceScanStrategy) Execute(ctx context.Context, config *common.Config
|
||||
s.LogPluginInfo(config)
|
||||
|
||||
// 执行主机扫描流程
|
||||
s.performHostScan(ctx, config, state, info, ch, wg)
|
||||
s.performHostScan(ctx, session, info, ch, wg)
|
||||
}
|
||||
|
||||
// performHostScan 执行主机扫描的完整流程
|
||||
func (s *ServiceScanStrategy) performHostScan(ctx context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func (s *ServiceScanStrategy) performHostScan(ctx context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
// 发现目标主机和端口
|
||||
targetInfos, err := s.discoverTargets(info.Host, info, config, state)
|
||||
targetInfos, err := s.discoverTargets(info.Host, info, session.Config, session.State)
|
||||
if err != nil {
|
||||
common.LogError(err.Error())
|
||||
return
|
||||
@@ -148,7 +149,7 @@ func (s *ServiceScanStrategy) performHostScan(ctx context.Context, config *commo
|
||||
|
||||
// 执行漏洞扫描
|
||||
if len(targetInfos) > 0 {
|
||||
ExecuteScanTasks(ctx, config, state, targetInfos, s, ch, wg)
|
||||
ExecuteScanTasks(ctx, session, targetInfos, s, ch, wg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -304,7 +304,7 @@ func (s *WebScanStrategy) Description() string {
|
||||
}
|
||||
|
||||
// Execute 执行Web扫描策略
|
||||
func (s *WebScanStrategy) Execute(ctx context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
func (s *WebScanStrategy) Execute(ctx context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
||||
// 输出扫描开始信息
|
||||
s.LogScanStart()
|
||||
|
||||
@@ -315,13 +315,13 @@ func (s *WebScanStrategy) Execute(ctx context.Context, config *common.Config, st
|
||||
}
|
||||
|
||||
// 准备URL目标
|
||||
targets := s.PrepareTargets(info, state)
|
||||
targets := s.PrepareTargets(info, session.State)
|
||||
|
||||
// 输出插件信息
|
||||
s.LogPluginInfo(config)
|
||||
s.LogPluginInfo(session.Config)
|
||||
|
||||
// 执行扫描任务
|
||||
ExecuteScanTasks(ctx, config, state, targets, s, ch, wg)
|
||||
ExecuteScanTasks(ctx, session, targets, s, ch, wg)
|
||||
}
|
||||
|
||||
// PrepareTargets 准备URL目标列表
|
||||
|
||||
Reference in New Issue
Block a user