diff --git a/common/initialize.go b/common/initialize.go index f879463..fbebf84 100644 --- a/common/initialize.go +++ b/common/initialize.go @@ -13,9 +13,10 @@ initialize.go - 统一初始化入口 // InitResult 初始化结果 type InitResult struct { - Config *Config - State *State - Info *HostInfo + Config *Config + State *State + Info *HostInfo + Session *ScanSession } // Initialize 统一初始化函数 @@ -39,10 +40,13 @@ func Initialize(info *HostInfo) (*InitResult, error) { return nil, fmt.Errorf("输出初始化失败: %w", err) } + session := NewScanSession(cfg, state, GetFlagVars()) + return &InitResult{ - Config: cfg, - State: state, - Info: info, + Config: cfg, + State: state, + Info: info, + Session: session, }, nil } diff --git a/common/session.go b/common/session.go new file mode 100644 index 0000000..2ddf340 --- /dev/null +++ b/common/session.go @@ -0,0 +1,101 @@ +package common + +import ( + "context" + "fmt" + "net" + "strings" + "sync" + "time" + + "github.com/shadow1ng/fscan/common/proxy" +) + +// ScanSession 封装单次扫描的全部上下文 +// 一次扫描一个 session,并发扫描各自独立 +type ScanSession struct { + Config *Config // 不可变,创建后只读 + State *State // 可变,原子操作,每会话独立 + Params *FlagVars // 原始参数,只读 + + // 每会话 dialer(懒初始化,取决于代理配置) + dialerOnce sync.Once + dialer proxy.Dialer + dialerErr error +} + +// NewScanSession 从已构建的 Config、State 和 FlagVars 创建会话 +func NewScanSession(config *Config, state *State, params *FlagVars) *ScanSession { + return &ScanSession{ + Config: config, + State: state, + Params: params, + } +} + +// DialTCP 创建 TCP 连接,内含限速检查、代理、计数 +func (s *ScanSession) DialTCP(ctx context.Context, network, address string, timeout time.Duration) (net.Conn, error) { + // 检查发包限制 + if ok, err := CanSendPacketWith(s.Config, s.State); !ok { + LogError(fmt.Sprintf("TCP连接 %s 受限: %s", address, err.Error())) + return nil, fmt.Errorf("发包受限: %s", err.Error()) + } + + // 获取 dialer + dialer, err := s.getDialer(timeout) + if err != nil { + LogError(fmt.Sprintf("获取代理拨号器失败: %v", err)) + s.State.IncrementTCPFailedPacketCount() + return nil, err + } + + conn, err := dialer.DialContext(ctx, network, address) + if err != nil { + s.State.IncrementTCPFailedPacketCount() + LogDebug(fmt.Sprintf("连接 %s 失败: %v", address, err)) + return nil, err + } + + s.State.IncrementTCPSuccessPacketCount() + return conn, nil +} + +func (s *ScanSession) getDialer(timeout time.Duration) (proxy.Dialer, error) { + s.dialerOnce.Do(func() { + cfg := s.createProxyConfig(timeout) + manager := proxy.NewProxyManager(cfg) + s.dialer, s.dialerErr = manager.GetDialer() + }) + return s.dialer, s.dialerErr +} + +func (s *ScanSession) createProxyConfig(timeout time.Duration) *proxy.ProxyConfig { + cfg := proxy.DefaultProxyConfig() + cfg.Timeout = timeout + cfg.LocalAddr = s.Config.Network.Iface + + // 优先 SOCKS5 + if s.Config.Network.Socks5Proxy != "" { + cfg.Type = proxy.ProxyTypeSOCKS5 + socks5URL := s.Config.Network.Socks5Proxy + if !strings.HasPrefix(socks5URL, "socks5://") { + socks5URL = "socks5://" + socks5URL + } + cfg.Address, cfg.Username, cfg.Password = parseProxyURL(socks5URL, s.Config.Network.Socks5Proxy) + return cfg + } + + // 其次 HTTP + if s.Config.Network.HTTPProxy != "" { + if strings.HasPrefix(s.Config.Network.HTTPProxy, "https://") { + cfg.Type = proxy.ProxyTypeHTTPS + } else { + cfg.Type = proxy.ProxyTypeHTTP + } + cfg.Address, cfg.Username, cfg.Password = parseProxyURL(s.Config.Network.HTTPProxy, s.Config.Network.HTTPProxy) + return cfg + } + + cfg.Type = proxy.ProxyTypeNone + return cfg +} diff --git a/core/alive_scanner.go b/core/alive_scanner.go index 47999be..9062d1c 100644 --- a/core/alive_scanner.go +++ b/core/alive_scanner.go @@ -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() diff --git a/core/local_scanner.go b/core/local_scanner.go index ee67a2b..c132a8d 100644 --- a/core/local_scanner.go +++ b/core/local_scanner.go @@ -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 准备本地扫描目标 diff --git a/core/scanner.go b/core/scanner.go index fb25133..200ee62 100644 --- a/core/scanner.go +++ b/core/scanner.go @@ -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 { // 保存成功的扫描结果到文件 diff --git a/core/scanner_test.go b/core/scanner_test.go index a3fbf78..5f91517 100644 --- a/core/scanner_test.go +++ b/core/scanner_test.go @@ -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) { diff --git a/core/service_scanner.go b/core/service_scanner.go index 113b4c5..cd9122c 100644 --- a/core/service_scanner.go +++ b/core/service_scanner.go @@ -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) } } diff --git a/core/web_scanner.go b/core/web_scanner.go index bd63869..f921cad 100644 --- a/core/web_scanner.go +++ b/core/web_scanner.go @@ -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目标列表 diff --git a/main.go b/main.go index 8f391d1..9c598c1 100644 --- a/main.go +++ b/main.go @@ -67,5 +67,5 @@ func main() { defer func() { _ = common.Cleanup() }() // 执行扫描 - core.RunScan(context.Background(), *result.Info, result.Config, result.State) + core.RunScan(context.Background(), *result.Info, result.Session) } diff --git a/plugins/init.go b/plugins/init.go index 3aee1ad..23188ea 100644 --- a/plugins/init.go +++ b/plugins/init.go @@ -11,7 +11,7 @@ import ( // Plugin 统一插件接口 type Plugin interface { Name() string - Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *Result + Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *Result } // BasePlugin 基础插件结构,提供通用的name字段 @@ -62,7 +62,7 @@ type Result struct { // Exploiter 利用接口 type Exploiter interface { - Exploit(ctx context.Context, info *common.HostInfo, creds Credential, config *common.Config) *ExploitResult + Exploit(ctx context.Context, info *common.HostInfo, creds Credential, session *common.ScanSession) *ExploitResult } // ExploitResult 利用结果 diff --git a/plugins/local/avdetect.go b/plugins/local/avdetect.go index ff5f1cb..8b3225e 100644 --- a/plugins/local/avdetect.go +++ b/plugins/local/avdetect.go @@ -53,7 +53,7 @@ func NewAVDetectPlugin() *AVDetectPlugin { } // Scan 执行AV/EDR检测 - 直接、有效 -func (p *AVDetectPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *AVDetectPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { var output strings.Builder var detectedAVs []string diff --git a/plugins/local/cleaner.go b/plugins/local/cleaner.go index 6d11682..d843a97 100644 --- a/plugins/local/cleaner.go +++ b/plugins/local/cleaner.go @@ -32,7 +32,7 @@ func NewCleanerPlugin() *CleanerPlugin { } // Scan 执行系统痕迹清理 - 直接、简单 -func (p *CleanerPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *CleanerPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { var output strings.Builder var filesCleared, dirsCleared, sysCleared int diff --git a/plugins/local/crontask.go b/plugins/local/crontask.go index 612a8bc..eaf84cd 100644 --- a/plugins/local/crontask.go +++ b/plugins/local/crontask.go @@ -35,7 +35,8 @@ func NewCronTaskPlugin() *CronTaskPlugin { } // Scan 执行计划任务持久化 - 直接实现 -func (p *CronTaskPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *CronTaskPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config var output strings.Builder if runtime.GOOS != "linux" { diff --git a/plugins/local/dcinfo.go b/plugins/local/dcinfo.go index 3eccf6e..55d448e 100644 --- a/plugins/local/dcinfo.go +++ b/plugins/local/dcinfo.go @@ -41,7 +41,9 @@ func NewDCInfoPlugin() *DCInfoPlugin { } // Scan 执行域控信息收集 - 直接实现 -func (p *DCInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *DCInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder output.WriteString("=== 域控制器信息收集 ===\n") diff --git a/plugins/local/downloader.go b/plugins/local/downloader.go index 1684ac8..a4afeb3 100644 --- a/plugins/local/downloader.go +++ b/plugins/local/downloader.go @@ -35,7 +35,8 @@ func NewDownloaderPlugin() *DownloaderPlugin { } // Scan 执行文件下载任务 - 直接实现 -func (p *DownloaderPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *DownloaderPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config var output strings.Builder // 从config获取配置 diff --git a/plugins/local/envinfo.go b/plugins/local/envinfo.go index fdcf46c..7c2c9d3 100644 --- a/plugins/local/envinfo.go +++ b/plugins/local/envinfo.go @@ -30,7 +30,7 @@ func NewEnvInfoPlugin() *EnvInfoPlugin { } // Scan 执行环境变量收集 - 直接、有效 -func (p *EnvInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *EnvInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { var output strings.Builder var sensitiveVars []string diff --git a/plugins/local/fileinfo.go b/plugins/local/fileinfo.go index 0462df7..708c1d5 100644 --- a/plugins/local/fileinfo.go +++ b/plugins/local/fileinfo.go @@ -33,7 +33,7 @@ func NewFileInfoPlugin() *FileInfoPlugin { } // Scan 执行本地文件扫描 - 直接、简单、有效 -func (p *FileInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *FileInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { var foundFiles []string // 扫描关键敏感文件位置 - 删除复杂的配置系统 diff --git a/plugins/local/forwardshell.go b/plugins/local/forwardshell.go index 5918501..9a571bd 100644 --- a/plugins/local/forwardshell.go +++ b/plugins/local/forwardshell.go @@ -37,7 +37,9 @@ func NewForwardShellPlugin() *ForwardShellPlugin { } // Scan 执行正向Shell服务 - 直接实现 -func (p *ForwardShellPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *ForwardShellPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/local/keylogger.go b/plugins/local/keylogger.go index 18c07d1..0354cdd 100644 --- a/plugins/local/keylogger.go +++ b/plugins/local/keylogger.go @@ -36,7 +36,8 @@ func NewKeyloggerPlugin() *KeyloggerPlugin { } // Scan 执行键盘记录 - 直接实现 -func (p *KeyloggerPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *KeyloggerPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config var output strings.Builder // 从config获取配置 diff --git a/plugins/local/ldpreload.go b/plugins/local/ldpreload.go index 33af08a..2d879c0 100644 --- a/plugins/local/ldpreload.go +++ b/plugins/local/ldpreload.go @@ -33,7 +33,8 @@ func NewLDPreloadPlugin() *LDPreloadPlugin { } // Scan 执行LD_PRELOAD持久化 - 直接实现 -func (p *LDPreloadPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *LDPreloadPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config var output strings.Builder if runtime.GOOS != "linux" { diff --git a/plugins/local/minidump.go b/plugins/local/minidump.go index cffd3fc..61acdb0 100644 --- a/plugins/local/minidump.go +++ b/plugins/local/minidump.go @@ -83,7 +83,9 @@ func NewMiniDumpPlugin() *MiniDumpPlugin { } // Scan 执行内存转储 - 直接实现 -func (p *MiniDumpPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *MiniDumpPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State defer func() { if r := recover(); r != nil { common.LogError(i18n.Tr("minidump_panic", r)) diff --git a/plugins/local/reverseshell.go b/plugins/local/reverseshell.go index ac7f695..3a6e99f 100644 --- a/plugins/local/reverseshell.go +++ b/plugins/local/reverseshell.go @@ -40,7 +40,9 @@ func NewReverseShellPlugin() *ReverseShellPlugin { // GetName 实现Plugin接口 // Scan 执行反弹Shell - 直接实现 -func (p *ReverseShellPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *ReverseShellPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/local/shellenv.go b/plugins/local/shellenv.go index 936d2fc..0f29d6f 100644 --- a/plugins/local/shellenv.go +++ b/plugins/local/shellenv.go @@ -33,7 +33,8 @@ func NewShellEnvPlugin() *ShellEnvPlugin { } // Scan 执行Shell环境变量持久化 - 直接实现 -func (p *ShellEnvPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *ShellEnvPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config var output strings.Builder if runtime.GOOS != "linux" { diff --git a/plugins/local/socks5proxy.go b/plugins/local/socks5proxy.go index d24d075..0342e8b 100644 --- a/plugins/local/socks5proxy.go +++ b/plugins/local/socks5proxy.go @@ -36,7 +36,9 @@ func NewSocks5ProxyPlugin() *Socks5ProxyPlugin { } // Scan 执行SOCKS5代理扫描 - 直接实现 -func (p *Socks5ProxyPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *Socks5ProxyPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/local/systemdservice.go b/plugins/local/systemdservice.go index 525232e..2a6081b 100644 --- a/plugins/local/systemdservice.go +++ b/plugins/local/systemdservice.go @@ -33,7 +33,8 @@ func NewSystemdServicePlugin() *SystemdServicePlugin { } // Scan 执行系统服务持久化 - 直接实现 -func (p *SystemdServicePlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *SystemdServicePlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config var output strings.Builder if runtime.GOOS != "linux" { diff --git a/plugins/local/systeminfo.go b/plugins/local/systeminfo.go index 0ac0d9f..3eab92b 100644 --- a/plugins/local/systeminfo.go +++ b/plugins/local/systeminfo.go @@ -33,7 +33,7 @@ func NewSystemInfoPlugin() *SystemInfoPlugin { } // Scan 执行系统信息收集 - 直接、简单、有效 -func (p *SystemInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *SystemInfoPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { var output strings.Builder output.WriteString("=== 系统信息收集 ===\n") diff --git a/plugins/local/types.go b/plugins/local/types.go index 010fbaf..8e18cd0 100644 --- a/plugins/local/types.go +++ b/plugins/local/types.go @@ -10,7 +10,7 @@ import ( // Plugin 本地插件接口 - 不需要端口概念 type Plugin interface { Name() string - Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result + Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result } // RegisterLocalPlugin 注册本地插件 - 自动标记local类型 diff --git a/plugins/local/winregistry.go b/plugins/local/winregistry.go index cdaabbb..35413d6 100644 --- a/plugins/local/winregistry.go +++ b/plugins/local/winregistry.go @@ -32,7 +32,9 @@ func NewWinRegistryPlugin() *WinRegistryPlugin { } // Scan 执行Windows注册表持久化 - 直接实现 -func (p *WinRegistryPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *WinRegistryPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder if runtime.GOOS != "windows" { diff --git a/plugins/local/winschtask.go b/plugins/local/winschtask.go index f0a5bb2..fa3bef0 100644 --- a/plugins/local/winschtask.go +++ b/plugins/local/winschtask.go @@ -33,7 +33,9 @@ func NewWinSchTaskPlugin() *WinSchTaskPlugin { } // Scan 执行Windows计划任务持久化 - 直接实现 -func (p *WinSchTaskPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *WinSchTaskPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/local/winservice.go b/plugins/local/winservice.go index 59c0359..564413a 100644 --- a/plugins/local/winservice.go +++ b/plugins/local/winservice.go @@ -33,7 +33,9 @@ func NewWinServicePlugin() *WinServicePlugin { } // Scan 执行Windows服务持久化 - 直接实现 -func (p *WinServicePlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *WinServicePlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/local/winstartup.go b/plugins/local/winstartup.go index 1b341e3..9e59e41 100644 --- a/plugins/local/winstartup.go +++ b/plugins/local/winstartup.go @@ -33,7 +33,9 @@ func NewWinStartupPlugin() *WinStartupPlugin { } // Scan 执行Windows启动文件夹持久化 - 直接实现 -func (p *WinStartupPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *WinStartupPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/local/winwmi.go b/plugins/local/winwmi.go index effe0e2..1ca2e98 100644 --- a/plugins/local/winwmi.go +++ b/plugins/local/winwmi.go @@ -33,7 +33,9 @@ func NewWinWMIPlugin() *WinWMIPlugin { } // Scan 执行Windows WMI事件订阅持久化 - 直接实现 -func (p *WinWMIPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *WinWMIPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State var output strings.Builder // 从config获取配置 diff --git a/plugins/services/activemq.go b/plugins/services/activemq.go index a1bff9f..d3a2b71 100644 --- a/plugins/services/activemq.go +++ b/plugins/services/activemq.go @@ -25,7 +25,9 @@ func NewActiveMQPlugin() *ActiveMQPlugin { } } -func (p *ActiveMQPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *ActiveMQPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/cassandra.go b/plugins/services/cassandra.go index 39f1ae2..a54ae1c 100644 --- a/plugins/services/cassandra.go +++ b/plugins/services/cassandra.go @@ -24,7 +24,9 @@ func NewCassandraPlugin() *CassandraPlugin { } } -func (p *CassandraPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *CassandraPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/elasticsearch.go b/plugins/services/elasticsearch.go index 8706763..9fd3464 100644 --- a/plugins/services/elasticsearch.go +++ b/plugins/services/elasticsearch.go @@ -25,7 +25,9 @@ func NewElasticsearchPlugin() *ElasticsearchPlugin { } } -func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/findnet.go b/plugins/services/findnet.go index 9bdd009..4f1da3e 100644 --- a/plugins/services/findnet.go +++ b/plugins/services/findnet.go @@ -36,7 +36,9 @@ func NewFindNetPlugin() *FindNetPlugin { // GetPorts 实现Plugin接口 // Scan 执行FindNet扫描 - Windows网络信息收集 -func (p *FindNetPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *FindNetPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() // 检查是否为RPC端口 diff --git a/plugins/services/ftp.go b/plugins/services/ftp.go index a9c04a5..8e14788 100644 --- a/plugins/services/ftp.go +++ b/plugins/services/ftp.go @@ -24,7 +24,9 @@ func NewFTPPlugin() *FTPPlugin { } } -func (p *FTPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *FTPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State if config.DisableBrute { return p.identifyService(info, config, state) } diff --git a/plugins/services/kafka.go b/plugins/services/kafka.go index 64fe65e..7635639 100644 --- a/plugins/services/kafka.go +++ b/plugins/services/kafka.go @@ -24,7 +24,9 @@ func NewKafkaPlugin() *KafkaPlugin { } } -func (p *KafkaPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *KafkaPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State if config.DisableBrute { return p.identifyService(ctx, info, config, state) } diff --git a/plugins/services/ldap.go b/plugins/services/ldap.go index c5c650c..5e44ef8 100644 --- a/plugins/services/ldap.go +++ b/plugins/services/ldap.go @@ -23,7 +23,9 @@ func NewLDAPPlugin() *LDAPPlugin { } } -func (p *LDAPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *LDAPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State if config.DisableBrute { return p.identifyService(ctx, info, config, state) } diff --git a/plugins/services/memcached.go b/plugins/services/memcached.go index 1e1b9a6..3160767 100644 --- a/plugins/services/memcached.go +++ b/plugins/services/memcached.go @@ -24,7 +24,9 @@ func NewMemcachedPlugin() *MemcachedPlugin { } } -func (p *MemcachedPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *MemcachedPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/mongodb.go b/plugins/services/mongodb.go index 5a3875f..d4074e0 100644 --- a/plugins/services/mongodb.go +++ b/plugins/services/mongodb.go @@ -28,7 +28,9 @@ func NewMongoDBPlugin() *MongoDBPlugin { } } -func (p *MongoDBPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *MongoDBPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/ms17010.go b/plugins/services/ms17010.go index 0c22b4f..dd773bb 100644 --- a/plugins/services/ms17010.go +++ b/plugins/services/ms17010.go @@ -34,7 +34,9 @@ func NewMS17010Plugin() *MS17010Plugin { // GetPorts 实现Plugin接口 // Scan 执行MS17-010扫描 -func (p *MS17010Plugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *MS17010Plugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State // 如果禁用暴力破解,也禁用漏洞检测 if config.DisableBrute { return &ScanResult{ diff --git a/plugins/services/mssql.go b/plugins/services/mssql.go index 0cb533c..93055ec 100644 --- a/plugins/services/mssql.go +++ b/plugins/services/mssql.go @@ -25,7 +25,9 @@ func NewMSSQLPlugin() *MSSQLPlugin { } } -func (p *MSSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *MSSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State if config.DisableBrute { return p.identifyService(ctx, info, config, state) } diff --git a/plugins/services/mysql.go b/plugins/services/mysql.go index 543f3a2..892d4c5 100644 --- a/plugins/services/mysql.go +++ b/plugins/services/mysql.go @@ -36,7 +36,9 @@ func NewMySQLPlugin() *MySQLPlugin { } } -func (p *MySQLPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *MySQLPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State if config.DisableBrute { return p.identifyService(info, config) } diff --git a/plugins/services/neo4j.go b/plugins/services/neo4j.go index 5160b49..7e884f2 100644 --- a/plugins/services/neo4j.go +++ b/plugins/services/neo4j.go @@ -25,7 +25,9 @@ func NewNeo4jPlugin() *Neo4jPlugin { } } -func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/netbios.go b/plugins/services/netbios.go index 1bef760..2e8423b 100644 --- a/plugins/services/netbios.go +++ b/plugins/services/netbios.go @@ -29,7 +29,9 @@ func NewNetBIOSPlugin() *NetBIOSPlugin { // GetPorts 实现Plugin接口 // Scan 执行NetBIOS扫描 - 收集Windows主机和域信息 -func (p *NetBIOSPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *NetBIOSPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() // 检查端口类型 diff --git a/plugins/services/oracle.go b/plugins/services/oracle.go index 4125ea9..fa80398 100644 --- a/plugins/services/oracle.go +++ b/plugins/services/oracle.go @@ -24,7 +24,9 @@ func NewOraclePlugin() *OraclePlugin { } } -func (p *OraclePlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *OraclePlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/postgresql.go b/plugins/services/postgresql.go index e5ecc69..d7edf57 100644 --- a/plugins/services/postgresql.go +++ b/plugins/services/postgresql.go @@ -25,7 +25,9 @@ func NewPostgreSQLPlugin() *PostgreSQLPlugin { } } -func (p *PostgreSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *PostgreSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/rabbitmq.go b/plugins/services/rabbitmq.go index d19a4b4..7329f19 100644 --- a/plugins/services/rabbitmq.go +++ b/plugins/services/rabbitmq.go @@ -26,7 +26,9 @@ func NewRabbitMQPlugin() *RabbitMQPlugin { } } -func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/rdp.go b/plugins/services/rdp.go index e144760..ee4145f 100644 --- a/plugins/services/rdp.go +++ b/plugins/services/rdp.go @@ -28,7 +28,9 @@ func NewRDPPlugin() *RDPPlugin { } // Scan 执行RDP扫描 - 系统指纹识别 + 真实暴力破解 -func (p *RDPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *RDPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() // 配置grdp日志级别 diff --git a/plugins/services/redis.go b/plugins/services/redis.go index 35565dd..dd2b842 100644 --- a/plugins/services/redis.go +++ b/plugins/services/redis.go @@ -31,7 +31,9 @@ func NewRedisPlugin() *RedisPlugin { } // Scan 执行Redis扫描 -func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() // 如果禁用暴力破解,只做服务识别 diff --git a/plugins/services/rsync.go b/plugins/services/rsync.go index e7f84e2..b63fe52 100644 --- a/plugins/services/rsync.go +++ b/plugins/services/rsync.go @@ -28,7 +28,9 @@ func NewRsyncPlugin() *RsyncPlugin { } } -func (p *RsyncPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *RsyncPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/smb.go b/plugins/services/smb.go index fa0c4e2..278b90d 100644 --- a/plugins/services/smb.go +++ b/plugins/services/smb.go @@ -24,7 +24,9 @@ func NewSmbPlugin() *SmbPlugin { } } -func (p *SmbPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *plugins.Result { +func (p *SmbPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result { + config := session.Config + state := session.State target := info.Target() // 检查端口 diff --git a/plugins/services/smtp.go b/plugins/services/smtp.go index e3dbd2c..7d61eea 100644 --- a/plugins/services/smtp.go +++ b/plugins/services/smtp.go @@ -25,7 +25,9 @@ func NewSMTPPlugin() *SMTPPlugin { } } -func (p *SMTPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *SMTPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/ssh.go b/plugins/services/ssh.go index 2a843b3..d98effc 100644 --- a/plugins/services/ssh.go +++ b/plugins/services/ssh.go @@ -34,7 +34,9 @@ func NewSSHPlugin() *SSHPlugin { } // Scan 执行SSH扫描 -func (p *SSHPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *SSHPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() // 如果指定了SSH密钥,优先使用密钥认证 diff --git a/plugins/services/telnet.go b/plugins/services/telnet.go index 00b96f6..48ff181 100644 --- a/plugins/services/telnet.go +++ b/plugins/services/telnet.go @@ -50,7 +50,9 @@ func NewTelnetPlugin() *TelnetPlugin { } } -func (p *TelnetPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *TelnetPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() if config.DisableBrute { diff --git a/plugins/services/types.go b/plugins/services/types.go index 139d550..a3b1afb 100644 --- a/plugins/services/types.go +++ b/plugins/services/types.go @@ -10,7 +10,7 @@ import ( // 插件接口定义 - 统一命名风格 type Plugin interface { Name() string - Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult + Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult } type ScanResult = plugins.Result diff --git a/plugins/services/vnc.go b/plugins/services/vnc.go index 69f279d..ff0024a 100644 --- a/plugins/services/vnc.go +++ b/plugins/services/vnc.go @@ -24,7 +24,9 @@ func NewVNCPlugin() *VNCPlugin { } } -func (p *VNCPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult { +func (p *VNCPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult { + config := session.Config + state := session.State target := info.Target() // 检查未授权访问 diff --git a/plugins/web/types.go b/plugins/web/types.go index 9e296df..7882ec4 100644 --- a/plugins/web/types.go +++ b/plugins/web/types.go @@ -10,7 +10,7 @@ import ( // WebPlugin Web插件接口 - 使用智能HTTP检测,不需要预定义端口 type WebPlugin interface { Name() string - Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *WebScanResult + Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *WebScanResult } // WebScanResult Web扫描结果类型别名 diff --git a/plugins/web/webpoc.go b/plugins/web/webpoc.go index 1bbb5a5..3b43e0b 100644 --- a/plugins/web/webpoc.go +++ b/plugins/web/webpoc.go @@ -87,7 +87,8 @@ func NewWebPocPlugin() *WebPocPlugin { // Scan 执行Web POC扫描 // 注意:非全量模式下,POC扫描由webtitle插件在指纹识别后触发,此插件不执行 // 全量模式(-full)下,此插件独立执行全量POC扫描 -func (p *WebPocPlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *WebScanResult { +func (p *WebPocPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *WebScanResult { + config := session.Config if config.POC.Disabled { return &WebScanResult{ Success: false, diff --git a/plugins/web/webtitle.go b/plugins/web/webtitle.go index d4cf3a8..599aab5 100644 --- a/plugins/web/webtitle.go +++ b/plugins/web/webtitle.go @@ -39,7 +39,8 @@ func NewWebTitlePlugin() *WebTitlePlugin { } // Scan 执行WebTitle扫描 -func (p *WebTitlePlugin) Scan(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *WebScanResult { +func (p *WebTitlePlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *WebScanResult { + config := session.Config title, status, length, server, fingerprints, url, err := p.getWebTitle(ctx, info, config) if err != nil { return &WebScanResult{ diff --git a/web/api/scan.go b/web/api/scan.go index 7337c4e..9cf1b68 100644 --- a/web/api/scan.go +++ b/web/api/scan.go @@ -206,9 +206,12 @@ func (h *ScanHandler) runScan(req ScanRequest) { fv.DisableSave = true // Web模式不保存到文件 fv.Silent = true // 静默模式 - // 构建Config,同步到全局实例供 network/限速等模块使用 + // 构建Config和Session config := common.BuildConfigFromFlags(fv) state := common.NewState() + session := common.NewScanSession(config, state, fv) + + // 过渡桥:全局状态同步(待 Phase 5 移除) common.SetGlobalConfig(config) common.SetGlobalState(state) @@ -221,7 +224,7 @@ func (h *ScanHandler) runScan(req ScanRequest) { }) // 执行扫描 - core.RunScan(ctx, info, config, state) + core.RunScan(ctx, info, session) } // Stop 停止扫描