fscan/Common/config/ScanOptions.go
ZacharyZcR 5b1dde0a59 refactor: 重构配置系统为模块化架构
- 将Config相关文件重构为独立的config模块
- 创建config/Types.go定义核心配置数据结构
- 新增config/ServiceDict.go管理服务认证字典(线程安全)
- 新增config/PortMapping.go管理端口探测器映射(线程安全)
- 新增config/ScanOptions.go提供扫描选项管理(线程安全)
- 新增config/Manager.go统一配置管理器
- 新增Variables.go作为向后兼容桥接层
- 重构Config.go为兼容入口点,委托给新模块
- 删除原有的单体配置文件
- 修复用户字典和密码字典初始化问题
- 保持完全向后兼容性,现有API无需修改
- 提升代码组织性和可维护性
2025-08-05 02:42:17 +08:00

433 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package config
import (
"sync"
"time"
)
// ScanOptionsManager 扫描选项管理器
type ScanOptionsManager struct {
mu sync.RWMutex
options *Config
}
// NewScanOptionsManager 创建扫描选项管理器
func NewScanOptionsManager() *ScanOptionsManager {
return &ScanOptionsManager{
options: NewConfig(),
}
}
// GetConfig 获取完整配置
func (som *ScanOptionsManager) GetConfig() *Config {
som.mu.RLock()
defer som.mu.RUnlock()
// 返回深拷贝,避免外部修改
return som.copyConfig(som.options)
}
// SetConfig 设置完整配置
func (som *ScanOptionsManager) SetConfig(config *Config) {
som.mu.Lock()
defer som.mu.Unlock()
if config != nil {
som.options = som.copyConfig(config)
som.options.LastUpdated = time.Now()
}
}
// UpdateScanTarget 更新扫描目标配置
func (som *ScanOptionsManager) UpdateScanTarget(target *ScanTargetConfig) {
som.mu.Lock()
defer som.mu.Unlock()
if target != nil {
som.options.ScanTarget = target
som.options.LastUpdated = time.Now()
}
}
// UpdateCredential 更新认证配置
func (som *ScanOptionsManager) UpdateCredential(credential *CredentialConfig) {
som.mu.Lock()
defer som.mu.Unlock()
if credential != nil {
som.options.Credential = credential
som.options.LastUpdated = time.Now()
}
}
// UpdateScanControl 更新扫描控制配置
func (som *ScanOptionsManager) UpdateScanControl(control *ScanControlConfig) {
som.mu.Lock()
defer som.mu.Unlock()
if control != nil {
som.options.ScanControl = control
som.options.LastUpdated = time.Now()
}
}
// UpdateWebScan 更新Web扫描配置
func (som *ScanOptionsManager) UpdateWebScan(webScan *WebScanConfig) {
som.mu.Lock()
defer som.mu.Unlock()
if webScan != nil {
som.options.WebScan = webScan
som.options.LastUpdated = time.Now()
}
}
// UpdateDisplay 更新显示配置
func (som *ScanOptionsManager) UpdateDisplay(display *DisplayConfig) {
som.mu.Lock()
defer som.mu.Unlock()
if display != nil {
som.options.Display = display
som.options.LastUpdated = time.Now()
}
}
// UpdateOutput 更新输出配置
func (som *ScanOptionsManager) UpdateOutput(output *OutputConfig) {
som.mu.Lock()
defer som.mu.Unlock()
if output != nil {
som.options.Output = output
som.options.LastUpdated = time.Now()
}
}
// SetDefaults 设置默认值
func (som *ScanOptionsManager) SetDefaults() {
som.mu.Lock()
defer som.mu.Unlock()
// 设置扫描控制默认值
if som.options.ScanControl.ThreadNum <= 0 {
som.options.ScanControl.ThreadNum = 600
}
if som.options.ScanControl.ModuleThreadNum <= 0 {
som.options.ScanControl.ModuleThreadNum = 10
}
if som.options.ScanControl.Timeout <= 0 {
som.options.ScanControl.Timeout = 3
}
if som.options.ScanControl.GlobalTimeout <= 0 {
som.options.ScanControl.GlobalTimeout = 300 // 5分钟
}
// 设置Web扫描默认值
if som.options.WebScan.WebTimeout <= 0 {
som.options.WebScan.WebTimeout = 5
}
// 设置暴力破解默认值
if som.options.BruteForce.MaxRetries <= 0 {
som.options.BruteForce.MaxRetries = 3
}
// 设置显示默认值
if som.options.Display.LogLevel == "" {
som.options.Display.LogLevel = "SUCCESS"
}
if som.options.Display.Language == "" {
som.options.Display.Language = "zh"
}
// 设置输出默认值
if som.options.Output.OutputFormat == "" {
som.options.Output.OutputFormat = "txt"
}
if som.options.Output.Outputfile == "" {
som.options.Output.Outputfile = "result.txt"
}
// 设置网络默认值
if som.options.Network.UserAgent == "" {
som.options.Network.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}
if som.options.Network.Accept == "" {
som.options.Network.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
}
if som.options.Network.PocNum <= 0 {
som.options.Network.PocNum = 20
}
som.options.LastUpdated = time.Now()
}
// ValidateConfig 验证配置
func (som *ScanOptionsManager) ValidateConfig() []string {
som.mu.RLock()
defer som.mu.RUnlock()
var warnings []string
// 验证线程数配置
if som.options.ScanControl.ThreadNum > 1000 {
warnings = append(warnings, "线程数过大,可能影响系统性能")
}
// 验证超时配置
if som.options.ScanControl.Timeout > som.options.WebScan.WebTimeout {
warnings = append(warnings, "Web超时时间大于普通超时时间可能导致不期望的行为")
}
// 验证超时配置合理性
if som.options.ScanControl.Timeout < 1 {
warnings = append(warnings, "超时时间过短,可能导致误报")
}
if som.options.WebScan.WebTimeout < 1 {
warnings = append(warnings, "Web超时时间过短可能导致误报")
}
// 验证全局超时
if som.options.ScanControl.GlobalTimeout < 60 {
warnings = append(warnings, "全局超时时间过短,扫描可能提前终止")
}
return warnings
}
// GetSummary 获取配置摘要
func (som *ScanOptionsManager) GetSummary() map[string]interface{} {
som.mu.RLock()
defer som.mu.RUnlock()
return map[string]interface{}{
"scan_mode": som.options.ScanControl.ScanMode,
"thread_num": som.options.ScanControl.ThreadNum,
"timeout": som.options.ScanControl.Timeout,
"web_timeout": som.options.WebScan.WebTimeout,
"disable_ping": som.options.ScanControl.DisablePing,
"local_mode": som.options.ScanControl.LocalMode,
"log_level": som.options.Display.LogLevel,
"output_format": som.options.Output.OutputFormat,
"has_proxy": som.options.WebScan.HttpProxy != "" || som.options.WebScan.Socks5Proxy != "",
"has_credentials": som.options.Credential.Username != "" || som.options.InputFile.UsersFile != "",
"last_updated": som.options.LastUpdated,
}
}
// ResetToDefaults 重置为默认配置
func (som *ScanOptionsManager) ResetToDefaults() {
som.mu.Lock()
defer som.mu.Unlock()
som.options = NewConfig()
som.SetDefaults()
}
// ClearConfig 清空配置
func (som *ScanOptionsManager) ClearConfig() {
som.mu.Lock()
defer som.mu.Unlock()
// 清空所有配置项但保持结构
som.options.ScanTarget.Ports = ""
som.options.ScanTarget.ExcludePorts = ""
som.options.ScanTarget.ExcludeHosts = ""
som.options.ScanTarget.AddPorts = ""
som.options.ScanTarget.HostPort = nil
som.options.Credential.Username = ""
som.options.Credential.Password = ""
som.options.Credential.AddUsers = ""
som.options.Credential.AddPasswords = ""
som.options.Credential.Domain = ""
som.options.Credential.HashValue = ""
som.options.Credential.HashValues = nil
som.options.Credential.HashBytes = nil
som.options.Credential.HashFile = ""
som.options.Credential.SshKeyPath = ""
som.options.InputFile.HostsFile = ""
som.options.InputFile.UsersFile = ""
som.options.InputFile.PasswordsFile = ""
som.options.InputFile.PortsFile = ""
som.options.WebScan.TargetURL = ""
som.options.WebScan.URLsFile = ""
som.options.WebScan.URLs = nil
som.options.WebScan.HttpProxy = ""
som.options.WebScan.Socks5Proxy = ""
som.options.LastUpdated = time.Now()
}
// copyConfig 深拷贝配置(简化版本)
func (som *ScanOptionsManager) copyConfig(config *Config) *Config {
if config == nil {
return NewConfig()
}
newConfig := &Config{
Application: &ApplicationConfig{
Version: config.Application.Version,
ProgressBar: config.Application.ProgressBar, // 指针共享
},
ScanTarget: &ScanTargetConfig{
Ports: config.ScanTarget.Ports,
ExcludePorts: config.ScanTarget.ExcludePorts,
ExcludeHosts: config.ScanTarget.ExcludeHosts,
AddPorts: config.ScanTarget.AddPorts,
},
Credential: &CredentialConfig{
Username: config.Credential.Username,
Password: config.Credential.Password,
AddUsers: config.Credential.AddUsers,
AddPasswords: config.Credential.AddPasswords,
Domain: config.Credential.Domain,
HashValue: config.Credential.HashValue,
HashFile: config.Credential.HashFile,
SshKeyPath: config.Credential.SshKeyPath,
},
ScanControl: &ScanControlConfig{
ScanMode: config.ScanControl.ScanMode,
ThreadNum: config.ScanControl.ThreadNum,
ModuleThreadNum: config.ScanControl.ModuleThreadNum,
Timeout: config.ScanControl.Timeout,
GlobalTimeout: config.ScanControl.GlobalTimeout,
LiveTop: config.ScanControl.LiveTop,
DisablePing: config.ScanControl.DisablePing,
UsePing: config.ScanControl.UsePing,
EnableFingerprint: config.ScanControl.EnableFingerprint,
LocalMode: config.ScanControl.LocalMode,
},
InputFile: &InputFileConfig{
HostsFile: config.InputFile.HostsFile,
UsersFile: config.InputFile.UsersFile,
PasswordsFile: config.InputFile.PasswordsFile,
PortsFile: config.InputFile.PortsFile,
},
WebScan: &WebScanConfig{
TargetURL: config.WebScan.TargetURL,
URLsFile: config.WebScan.URLsFile,
WebTimeout: config.WebScan.WebTimeout,
HttpProxy: config.WebScan.HttpProxy,
Socks5Proxy: config.WebScan.Socks5Proxy,
},
VulnExploit: &VulnExploitConfig{
PocPath: config.VulnExploit.PocPath,
PocInfo: config.VulnExploit.PocInfo,
DisablePocScan: config.VulnExploit.DisablePocScan,
RedisFile: config.VulnExploit.RedisFile,
RedisShell: config.VulnExploit.RedisShell,
DisableRedis: config.VulnExploit.DisableRedis,
RedisWritePath: config.VulnExploit.RedisWritePath,
RedisWriteContent: config.VulnExploit.RedisWriteContent,
RedisWriteFile: config.VulnExploit.RedisWriteFile,
Shellcode: config.VulnExploit.Shellcode,
},
BruteForce: &BruteForceConfig{
DisableBrute: config.BruteForce.DisableBrute,
MaxRetries: config.BruteForce.MaxRetries,
},
Display: &DisplayConfig{
DisableSave: config.Display.DisableSave,
Silent: config.Display.Silent,
NoColor: config.Display.NoColor,
LogLevel: config.Display.LogLevel,
ShowProgress: config.Display.ShowProgress,
ShowScanPlan: config.Display.ShowScanPlan,
SlowLogOutput: config.Display.SlowLogOutput,
Language: config.Display.Language,
},
Output: &OutputConfig{
Outputfile: config.Output.Outputfile,
OutputFormat: config.Output.OutputFormat,
},
Network: &NetworkConfig{
UserAgent: config.Network.UserAgent,
Accept: config.Network.Accept,
DnsLog: config.Network.DnsLog,
PocNum: config.Network.PocNum,
PocFull: config.Network.PocFull,
Cookie: config.Network.Cookie,
},
LastUpdated: config.LastUpdated,
}
// 拷贝切片
if len(config.ScanTarget.HostPort) > 0 {
newConfig.ScanTarget.HostPort = make([]string, len(config.ScanTarget.HostPort))
copy(newConfig.ScanTarget.HostPort, config.ScanTarget.HostPort)
}
if len(config.Credential.HashValues) > 0 {
newConfig.Credential.HashValues = make([]string, len(config.Credential.HashValues))
copy(newConfig.Credential.HashValues, config.Credential.HashValues)
}
if len(config.Credential.HashBytes) > 0 {
newConfig.Credential.HashBytes = make([][]byte, len(config.Credential.HashBytes))
for i, b := range config.Credential.HashBytes {
if len(b) > 0 {
newConfig.Credential.HashBytes[i] = make([]byte, len(b))
copy(newConfig.Credential.HashBytes[i], b)
}
}
}
if len(config.WebScan.URLs) > 0 {
newConfig.WebScan.URLs = make([]string, len(config.WebScan.URLs))
copy(newConfig.WebScan.URLs, config.WebScan.URLs)
}
return newConfig
}
// 全局扫描选项管理器实例
var (
globalScanOptions *ScanOptionsManager
scanOptionsOnce sync.Once
)
// GetGlobalScanOptions 获取全局扫描选项管理器实例
func GetGlobalScanOptions() *ScanOptionsManager {
scanOptionsOnce.Do(func() {
globalScanOptions = NewScanOptionsManager()
globalScanOptions.SetDefaults()
})
return globalScanOptions
}
// SetGlobalScanOptions 设置全局扫描选项管理器实例
func SetGlobalScanOptions(manager *ScanOptionsManager) {
globalScanOptions = manager
}
// 便利函数,直接使用全局实例
// GetGlobalConfig 获取全局配置
func GetGlobalConfig() *Config {
return GetGlobalScanOptions().GetConfig()
}
// SetGlobalConfig 设置全局配置
func SetGlobalConfig(config *Config) {
GetGlobalScanOptions().SetConfig(config)
}
// SetGlobalDefaults 设置全局默认值
func SetGlobalDefaults() {
GetGlobalScanOptions().SetDefaults()
}
// ValidateGlobalConfig 验证全局配置
func ValidateGlobalConfig() []string {
return GetGlobalScanOptions().ValidateConfig()
}
// GetGlobalSummary 获取全局配置摘要
func GetGlobalSummary() map[string]interface{} {
return GetGlobalScanOptions().GetSummary()
}