diff --git a/Common/Bridge.go b/Common/Bridge.go index 6dc9870..d080391 100644 --- a/Common/Bridge.go +++ b/Common/Bridge.go @@ -19,7 +19,7 @@ import ( "github.com/fatih/color" "github.com/schollz/progressbar/v3" - + "github.com/shadow1ng/fscan/Common/config" "github.com/shadow1ng/fscan/Common/logging" "github.com/shadow1ng/fscan/Common/output" @@ -43,19 +43,6 @@ var ( // PocInfo POC详细信息结构 type PocInfo = config.PocInfo -// 配置相关函数 -func GetVersion() string { return config.GetGlobalVersion() } -func SetVersion(v string) { config.SetGlobalVersion(v) } -func GetProgressBar() *progressbar.ProgressBar { return config.GetGlobalProgressBar() } -func SetConfigProgressBar(pb *progressbar.ProgressBar) { - config.SetGlobalProgressBar(pb) - ProgressBar = pb -} -func GetOutputMutex() *sync.Mutex { return config.GetGlobalOutputMutex() } -func GetConfigManager() *config.Manager { return config.GetGlobalManager() } -func GetFullConfig() *config.Config { return config.GetGlobalConfig() } -func SetFullConfig(cfg *config.Config) { config.SetGlobalManagerConfig(cfg); syncOutputConfig() } - func syncOutputConfig() { cfg := config.GetGlobalConfig() if cfg != nil && cfg.Output != nil { @@ -65,37 +52,28 @@ func syncOutputConfig() { ProgressBar = config.GetGlobalProgressBar() } -func SyncConfigOutputSettings() { - cfg := config.GetGlobalConfig() - if cfg != nil && cfg.Output != nil { - cfg.Output.Outputfile = Outputfile - cfg.Output.OutputFormat = OutputFormat - config.SetGlobalManagerConfig(cfg) - } -} - // ============================================================================= // 日志桥接 (Log.go 功能) // ============================================================================= // 全局日志状态和变量 var ( - status = logging.NewScanStatus() - Num, End int64 - StartTime = time.Now() + status = logging.NewScanStatus() + Num, End int64 + StartTime = time.Now() globalLogger *logging.Logger - loggerOnce sync.Once + loggerOnce sync.Once ) // 日志级别常量 const ( - LogLevelAll = string(logging.LevelAll) - LogLevelError = string(logging.LevelError) - LogLevelBase = string(logging.LevelBase) - LogLevelInfo = string(logging.LevelInfo) - LogLevelSuccess = string(logging.LevelSuccess) - LogLevelDebug = string(logging.LevelDebug) - LogLevelInfoSuccess = string(logging.LevelInfoSuccess) + LogLevelAll = string(logging.LevelAll) + LogLevelError = string(logging.LevelError) + LogLevelBase = string(logging.LevelBase) + LogLevelInfo = string(logging.LevelInfo) + LogLevelSuccess = string(logging.LevelSuccess) + LogLevelDebug = string(logging.LevelDebug) + LogLevelInfoSuccess = string(logging.LevelInfoSuccess) LogLevelBaseInfoSuccess = string(logging.LevelBaseInfoSuccess) ) @@ -115,7 +93,9 @@ func getGlobalLogger() *logging.Logger { }, } globalLogger = logging.NewLogger(config) - if ProgressBar != nil { globalLogger.SetProgressBar(ProgressBar) } + if ProgressBar != nil { + globalLogger.SetProgressBar(ProgressBar) + } globalLogger.SetOutputMutex(&OutputMutex) status = globalLogger.GetScanStatus() }) @@ -123,32 +103,13 @@ func getGlobalLogger() *logging.Logger { } // 日志相关函数 -func InitLogger() { log.SetOutput(io.Discard); getGlobalLogger().Initialize() } -func LogDebug(msg string) { getGlobalLogger().Debug(msg) } -func LogBase(msg string) { getGlobalLogger().Base(msg) } -func LogInfo(msg string) { getGlobalLogger().Info(msg) } -func LogSuccess(result string) { getGlobalLogger().Success(result) } -func LogError(errMsg string) { getGlobalLogger().Error(errMsg) } +func InitLogger() { log.SetOutput(io.Discard); getGlobalLogger().Initialize() } +func LogDebug(msg string) { getGlobalLogger().Debug(msg) } +func LogBase(msg string) { getGlobalLogger().Base(msg) } +func LogInfo(msg string) { getGlobalLogger().Info(msg) } +func LogSuccess(result string) { getGlobalLogger().Success(result) } +func LogError(errMsg string) { getGlobalLogger().Error(errMsg) } func CheckErrs(err error) error { return logging.CheckErrs(err) } -func GetScanStatus() *logging.ScanStatus { return status } -func UpdateScanProgress(completed, total int64) { status.SetCompleted(completed); status.SetTotal(total); End = completed; Num = total } -func SetProgressBar(progressBar ProgressDisplay) { if globalLogger != nil { globalLogger.SetProgressBar(progressBar) } } - -func SetLoggerConfig(enableColor, slowOutput bool, progressBar ProgressDisplay) { - config := &logging.LoggerConfig{ - Level: logging.LevelBaseInfoSuccess, EnableColor: enableColor, SlowOutput: slowOutput, - ShowProgress: true, StartTime: StartTime, - LevelColors: map[logging.LogLevel]color.Attribute{ - logging.LevelError: color.FgBlue, logging.LevelBase: color.FgYellow, - logging.LevelInfo: color.FgGreen, logging.LevelSuccess: color.FgRed, logging.LevelDebug: color.FgWhite, - }, - } - newLogger := logging.NewLogger(config) - if progressBar != nil { newLogger.SetProgressBar(progressBar) } - newLogger.SetOutputMutex(&OutputMutex) - globalLogger = newLogger - status = newLogger.GetScanStatus() -} // ============================================================================= // 输出桥接 (Output.go 功能) @@ -157,14 +118,14 @@ func SetLoggerConfig(enableColor, slowOutput bool, progressBar ProgressDisplay) // 全局输出管理器 var ResultOutput *OutputManager -type OutputManager struct { manager *output.Manager } +type OutputManager struct{ manager *output.Manager } type ResultType = output.ResultType const ( - HOST ResultType = output.TypeHost - PORT ResultType = output.TypePort + HOST ResultType = output.TypeHost + PORT ResultType = output.TypePort SERVICE ResultType = output.TypeService - VULN ResultType = output.TypeVuln + VULN ResultType = output.TypeVuln ) type ScanResult = output.ScanResult @@ -172,15 +133,21 @@ type ScanResult = output.ScanResult func createOutputManager(outputPath, outputFormat string) (*OutputManager, error) { var format output.OutputFormat switch outputFormat { - case "txt": format = output.FormatTXT - case "json": format = output.FormatJSON - case "csv": format = output.FormatCSV - default: return nil, fmt.Errorf(GetText("output_format_invalid"), outputFormat) + case "txt": + format = output.FormatTXT + case "json": + format = output.FormatJSON + case "csv": + format = output.FormatCSV + default: + return nil, fmt.Errorf(GetText("output_format_invalid"), outputFormat) } - + config := output.DefaultManagerConfig(outputPath, format) manager, err := output.NewManager(config) - if err != nil { return nil, err } + if err != nil { + return nil, err + } return &OutputManager{manager: manager}, nil } @@ -189,10 +156,13 @@ func InitOutput() error { LogDebug(GetText("output_init_start")) switch OutputFormat { case "txt", "json", "csv": - default: return fmt.Errorf(GetText("output_format_invalid"), OutputFormat) + default: + return fmt.Errorf(GetText("output_format_invalid"), OutputFormat) } - if Outputfile == "" { return fmt.Errorf(GetText("output_path_empty")) } - + if Outputfile == "" { + return fmt.Errorf(GetText("output_path_empty")) + } + manager, err := createOutputManager(Outputfile, OutputFormat) if err != nil { LogDebug(GetText("output_init_failed", err)) @@ -205,7 +175,9 @@ func InitOutput() error { } func (om *OutputManager) saveResult(result *ScanResult) error { - if om.manager == nil { return fmt.Errorf(GetText("output_not_init")) } + if om.manager == nil { + return fmt.Errorf(GetText("output_not_init")) + } LogDebug(GetText("output_saving_result", result.Type, result.Target)) return om.manager.SaveResult(result) } @@ -218,38 +190,19 @@ func SaveResult(result *ScanResult) error { return ResultOutput.saveResult(result) } -func GetResults() ([]*ScanResult, error) { - if ResultOutput == nil { return nil, fmt.Errorf(GetText("output_not_init")) } - return ResultOutput.manager.GetResults() -} - func CloseOutput() error { - if ResultOutput == nil { return nil } + if ResultOutput == nil { + return nil + } LogDebug(GetText("output_closing")) err := ResultOutput.manager.Close() - if err != nil { return fmt.Errorf(GetText("output_close_failed", err)) } + if err != nil { + return fmt.Errorf(GetText("output_close_failed", err)) + } LogDebug(GetText("output_closed")) return nil } -// 便利函数 -func SaveResultWithDetails(resultType ResultType, target, status string, details map[string]interface{}) error { - result := &ScanResult{Time: time.Now(), Type: resultType, Target: target, Status: status, Details: details} - return SaveResult(result) -} - -func SaveHostResult(target string, isAlive bool, details map[string]interface{}) error { - status := "离线"; if isAlive { status = "存活" } - return SaveResultWithDetails(HOST, target, status, details) -} - -func SavePortResult(target string, port int, isOpen bool, service string, details map[string]interface{}) error { - status := "关闭"; if isOpen { status = "开放" } - if details == nil { details = make(map[string]interface{}) } - details["port"] = port; if service != "" { details["service"] = service } - return SaveResultWithDetails(PORT, fmt.Sprintf("%s:%d", target, port), status, details) -} - // ============================================================================= // 代理桥接 (Proxy.go 功能) // ============================================================================= @@ -265,36 +218,22 @@ func WrapperTcpWithContext(ctx context.Context, network, address string) (net.Co return proxy.DialContextWithProxy(ctx, network, address) } -func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error) { - if err := syncProxyConfig(); err != nil { LogError("proxy_config_sync_failed: " + err.Error()) } - conn, err := proxy.DialWithProxy(network, address) - if err != nil { - LogError(GetText("tcp_conn_failed") + ": " + err.Error()) - return nil, fmt.Errorf(GetText("tcp_conn_failed"), err) - } - return conn, nil -} - -func WrapperTCPWithContext(ctx context.Context, network, address string, forward *net.Dialer) (net.Conn, error) { - if err := syncProxyConfig(); err != nil { LogError("proxy_config_sync_failed: " + err.Error()) } - conn, err := proxy.DialContextWithProxy(ctx, network, address) - if err != nil { - LogError(GetText("tcp_conn_failed") + ": " + err.Error()) - return nil, fmt.Errorf(GetText("tcp_conn_failed"), err) - } - return conn, nil -} - func Socks5Dialer(forward *net.Dialer) (interface{}, error) { - if err := syncProxyConfig(); err != nil { return nil, fmt.Errorf(GetText("socks5_create_failed"), err) } + if err := syncProxyConfig(); err != nil { + return nil, fmt.Errorf(GetText("socks5_create_failed"), err) + } manager := proxy.GetGlobalProxy() dialer, err := manager.GetDialer() - if err != nil { return nil, fmt.Errorf(GetText("socks5_create_failed"), err) } + if err != nil { + return nil, fmt.Errorf(GetText("socks5_create_failed"), err) + } return dialer, nil } func WrapperTlsWithContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (net.Conn, error) { - if err := syncProxyConfig(); err != nil { LogError("proxy_config_sync_failed: " + err.Error()) } + if err := syncProxyConfig(); err != nil { + LogError("proxy_config_sync_failed: " + err.Error()) + } conn, err := proxy.DialTLSContextWithProxy(ctx, network, address, tlsConfig) if err != nil { LogError("tls_conn_failed: " + err.Error()) @@ -305,20 +244,24 @@ func WrapperTlsWithContext(ctx context.Context, network, address string, tlsConf func syncProxyConfig() error { var proxyURL string - if Socks5Proxy != "" { proxyURL = Socks5Proxy } else if HttpProxy != "" { proxyURL = HttpProxy } - + if Socks5Proxy != "" { + proxyURL = Socks5Proxy + } else if HttpProxy != "" { + proxyURL = HttpProxy + } + if proxy.IsProxyEnabledGlobally() { currentAddr := proxy.GetGlobalProxyAddress() - if (proxyURL == "" && currentAddr == "") || - (proxyURL != "" && currentAddr != "" && (Socks5Proxy == currentAddr || HttpProxy == currentAddr)) { + if (proxyURL == "" && currentAddr == "") || + (proxyURL != "" && currentAddr != "" && (Socks5Proxy == currentAddr || HttpProxy == currentAddr)) { return nil } } - + if err := proxy.InitGlobalProxy(proxyURL); err != nil { return fmt.Errorf("初始化代理配置失败: %v", err) } - + if proxyURL != "" { LogBase(fmt.Sprintf("代理已启用: %s %s", proxy.GetGlobalProxyType(), proxy.GetGlobalProxyAddress())) } else { @@ -327,10 +270,6 @@ func syncProxyConfig() error { return nil } -func GetProxyStats() *proxy.ProxyStats { return proxy.GetGlobalProxyStats() } -func IsProxyEnabled() bool { return proxy.IsProxyEnabledGlobally() } -func CloseProxy() error { return proxy.CloseGlobalProxy() } - // ============================================================================= // 初始化函数 // ============================================================================= @@ -338,4 +277,4 @@ func CloseProxy() error { return proxy.CloseGlobalProxy() } func init() { config.SetGlobalVersion(version) syncOutputConfig() -} \ No newline at end of file +} diff --git a/Common/Parse.go b/Common/Parse.go index 2ead8cc..7e520fe 100644 --- a/Common/Parse.go +++ b/Common/Parse.go @@ -69,9 +69,9 @@ func getGlobalParser() *Parser { func Parse(Info *HostInfo) error { // 首先应用LogLevel配置到日志系统 applyLogLevel() - + parser := getGlobalParser() - + // 构建输入参数 input := &AllInputs{ Credential: &parsers.CredentialInput{ @@ -316,168 +316,6 @@ func updateGlobalVariables(config *parsers.ParsedConfig, info *HostInfo) error { return nil } -// 保持原有的独立解析函数以确保向后兼容性 - -// ParseUser 解析用户名配置 - 兼容接口 -func ParseUser() error { - parser := getGlobalParser() - input := &parsers.CredentialInput{ - Username: Username, - UsersFile: UsersFile, - AddUsers: AddUsers, - } - - result, err := parser.credentialParser.Parse(input, parser.options) - if err != nil { - return err - } - - // 更新全局变量 - if len(result.Config.Credentials.Usernames) > 0 { - for serviceName := range Userdict { - Userdict[serviceName] = result.Config.Credentials.Usernames - } - } - - return nil -} - -// ParsePass 解析密码配置 - 兼容接口 -func ParsePass(Info *HostInfo) error { - parser := getGlobalParser() - - // 处理密码 - credInput := &parsers.CredentialInput{ - Password: Password, - PasswordsFile: PasswordsFile, - AddPasswords: AddPasswords, - HashValue: HashValue, - HashFile: HashFile, - } - - credResult, err := parser.credentialParser.Parse(credInput, parser.options) - if err != nil { - LogError(fmt.Sprintf("密码解析失败: %v", err)) - } else if credResult.Config.Credentials != nil { - if len(credResult.Config.Credentials.Passwords) > 0 { - Passwords = credResult.Config.Credentials.Passwords - } - if len(credResult.Config.Credentials.HashValues) > 0 { - HashValues = credResult.Config.Credentials.HashValues - } - if len(credResult.Config.Credentials.HashBytes) > 0 { - HashBytes = credResult.Config.Credentials.HashBytes - } - } - - // 处理URL和主机 - targetInput := &parsers.TargetInput{ - TargetURL: TargetURL, - URLsFile: URLsFile, - Host: Info.Host, - HostsFile: HostsFile, - Ports: Ports, - PortsFile: PortsFile, - AddPorts: AddPorts, - ExcludePorts: ExcludePorts, - } - - targetResult, err := parser.targetParser.Parse(targetInput, parser.options) - if err != nil { - LogError(fmt.Sprintf("目标解析失败: %v", err)) - } else if targetResult.Config.Targets != nil { - if len(targetResult.Config.Targets.URLs) > 0 { - URLs = targetResult.Config.Targets.URLs - } - if len(targetResult.Config.Targets.Hosts) > 0 { - Info.Host = joinStrings(targetResult.Config.Targets.Hosts, ",") - } - if len(targetResult.Config.Targets.Ports) > 0 { - Ports = joinInts(targetResult.Config.Targets.Ports, ",") - } - } - - return nil -} - -// ParseInput 解析输入参数 - 兼容接口 -func ParseInput(Info *HostInfo) error { - parser := getGlobalParser() - - // 网络配置解析 - networkInput := &parsers.NetworkInput{ - HttpProxy: HttpProxy, - Socks5Proxy: Socks5Proxy, - Timeout: Timeout, - WebTimeout: WebTimeout, - DisablePing: DisablePing, - DnsLog: DnsLog, - UserAgent: UserAgent, - Cookie: Cookie, - } - - networkResult, err := parser.networkParser.Parse(networkInput, parser.options) - if err != nil { - return fmt.Errorf("网络配置解析失败: %v", err) - } - - // 更新全局变量 - if networkResult.Config.Network != nil { - HttpProxy = networkResult.Config.Network.HttpProxy - Socks5Proxy = networkResult.Config.Network.Socks5Proxy - if networkResult.Config.Network.Timeout > 0 { - Timeout = int64(networkResult.Config.Network.Timeout.Seconds()) - } - if networkResult.Config.Network.WebTimeout > 0 { - WebTimeout = int64(networkResult.Config.Network.WebTimeout.Seconds()) - } - UserAgent = networkResult.Config.Network.UserAgent - Cookie = networkResult.Config.Network.Cookie - DisablePing = networkResult.Config.Network.DisablePing - DnsLog = networkResult.Config.Network.EnableDNSLog - } - - // 验证配置 - validationInput := &parsers.ValidationInput{ - ScanMode: ScanMode, - LocalMode: LocalMode, - HasHosts: Info.Host != "" || HostsFile != "", - HasURLs: TargetURL != "" || URLsFile != "", - HasPorts: Ports != "" || PortsFile != "", - HasProxy: HttpProxy != "" || Socks5Proxy != "", - DisablePing: DisablePing, - } - - validationResult, err := parser.validationParser.Parse(validationInput, nil, parser.options) - if err != nil { - return fmt.Errorf("参数验证失败: %v", err) - } - - // 报告验证警告 - for _, warning := range validationResult.Warnings { - LogBase(warning) - } - - // 如果有严重错误,返回错误 - for _, validationError := range validationResult.Errors { - LogError(validationError.Error()) - } - - return nil -} - -// 保持原有的工具函数 - -// ReadFileLines 读取文件行 - 兼容接口 -func ReadFileLines(filename string) ([]string, error) { - parser := getGlobalParser() - result, err := parser.fileReader.ReadFile(filename) - if err != nil { - return nil, err - } - return result.Lines, nil -} - // RemoveDuplicate 去重函数 - 保持原有实现 func RemoveDuplicate(old []string) []string { temp := make(map[string]struct{}) @@ -519,23 +357,6 @@ func joinInts(slice []int, sep string) string { return result } -// GetParser 获取解析器实例 - 新增API -func GetParser() *Parser { - return getGlobalParser() -} - -// SetParserOptions 设置解析器选项 - 新增API -func SetParserOptions(options *parsers.ParserOptions) { - globalParser = NewParser(options) -} - -// ClearParserCache 清空解析器缓存 - 新增API -func ClearParserCache() { - if globalParser != nil && globalParser.fileReader != nil { - globalParser.fileReader.ClearCache() - } -} - // showParseSummary 显示解析结果摘要 func showParseSummary(config *parsers.ParsedConfig) { if config == nil { @@ -612,7 +433,7 @@ func applyLogLevel() { if LogLevel == "" { return // 使用默认级别 } - + // 根据LogLevel字符串获取对应的日志级别 var level logging.LogLevel switch LogLevel { @@ -653,15 +474,15 @@ func applyLogLevel() { return // 无效的级别,保持默认 } } - + // 更新全局日志管理器的级别 if globalLogger != nil { config := &logging.LoggerConfig{ - Level: level, - EnableColor: !NoColor, - SlowOutput: SlowLogOutput, + Level: level, + EnableColor: !NoColor, + SlowOutput: SlowLogOutput, ShowProgress: true, - StartTime: StartTime, + StartTime: StartTime, LevelColors: map[logging.LogLevel]color.Attribute{ logging.LevelError: color.FgBlue, logging.LevelBase: color.FgYellow, @@ -670,15 +491,15 @@ func applyLogLevel() { logging.LevelDebug: color.FgWhite, }, } - + newLogger := logging.NewLogger(config) if ProgressBar != nil { newLogger.SetProgressBar(ProgressBar) } newLogger.SetOutputMutex(&OutputMutex) - + // 更新全局日志管理器 globalLogger = newLogger status = newLogger.GetScanStatus() } -} \ No newline at end of file +} diff --git a/Common/Ports.go b/Common/Ports.go index 6afe0c3..130258c 100644 --- a/Common/Ports.go +++ b/Common/Ports.go @@ -1,66 +1,7 @@ package Common -import ( - "sort" - "strconv" - "strings" -) - // 预定义端口组常量 var ( - ServicePorts = "21,22,23,25,110,135,139,143,162,389,445,465,502,587,636,873,993,995,1433,1521,2222,3306,3389,5020,5432,5672,5671,6379,8161,8443,9000,9092,9093,9200,10051,11211,15672,15671,27017,61616,61613" - DbPorts = "1433,1521,3306,5432,5672,6379,7687,9042,9093,9200,11211,27017,61616" - WebPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8005,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10051,10250,12018,12443,14000,15672,15671,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,20880,21000,21501,21502,28018" - AllPorts = "1-65535" - MainPorts = "21,22,23,80,81,110,135,139,143,389,443,445,502,873,993,995,1433,1521,3306,5432,5672,6379,7001,7687,8000,8005,8009,8080,8089,8443,9000,9042,9092,9200,10051,11211,15672,27017,61616" + WebPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8005,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10051,10250,12018,12443,14000,15672,15671,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,20880,21000,21501,21502,28018" + MainPorts = "21,22,23,80,81,110,135,139,143,389,443,445,502,873,993,995,1433,1521,3306,5432,5672,6379,7001,7687,8000,8005,8009,8080,8089,8443,9000,9042,9092,9200,10051,11211,15672,27017,61616" ) - -// IsValidPort 检查端口号是否有效 -func IsValidPort(port int) bool { - return port >= 1 && port <= 65535 -} - -// removeDuplicates 移除重复的端口号并排序 -func removeDuplicates(slice []int) []int { - if len(slice) == 0 { - return slice - } - - // 创建一个map来跟踪已见过的端口 - seen := make(map[int]bool) - var result []int - - for _, port := range slice { - if !seen[port] { - seen[port] = true - result = append(result, port) - } - } - - // 排序 - sort.Ints(result) - return result -} - -// ParsePortsFromString 从逗号分隔的字符串解析端口列表 -func ParsePortsFromString(portsStr string) []int { - if portsStr == "" { - return []int{} - } - - var ports []int - portStrs := strings.Split(portsStr, ",") - - for _, portStr := range portStrs { - portStr = strings.TrimSpace(portStr) - if portStr == "" { - continue - } - - if port, err := strconv.Atoi(portStr); err == nil && IsValidPort(port) { - ports = append(ports, port) - } - } - - return removeDuplicates(ports) -} diff --git a/Common/config/Manager.go b/Common/config/Manager.go index 7153e74..2ef0780 100644 --- a/Common/config/Manager.go +++ b/Common/config/Manager.go @@ -9,29 +9,29 @@ import ( // Manager 配置管理器,统一管理所有配置 type Manager struct { - mu sync.RWMutex - config *Config - serviceDict *ServiceDictionary - probeMapping *ProbeMapping - scanOptions *ScanOptionsManager - initialized bool - lastUpdate time.Time + mu sync.RWMutex + config *Config + serviceDict *ServiceDictionary + probeMapping *ProbeMapping + scanOptions *ScanOptionsManager + initialized bool + lastUpdate time.Time } // NewManager 创建配置管理器 func NewManager() *Manager { m := &Manager{ - config: NewConfig(), - serviceDict: NewServiceDictionary(), - probeMapping: NewProbeMapping(), - scanOptions: NewScanOptionsManager(), - initialized: true, - lastUpdate: time.Now(), + config: NewConfig(), + serviceDict: NewServiceDictionary(), + probeMapping: NewProbeMapping(), + scanOptions: NewScanOptionsManager(), + initialized: true, + lastUpdate: time.Now(), } - + // 设置默认值 m.scanOptions.SetDefaults() - + return m } @@ -39,7 +39,7 @@ func NewManager() *Manager { func (m *Manager) GetConfig() *Config { m.mu.RLock() defer m.mu.RUnlock() - + return m.scanOptions.GetConfig() } @@ -47,7 +47,7 @@ func (m *Manager) GetConfig() *Config { func (m *Manager) SetConfig(config *Config) { m.mu.Lock() defer m.mu.Unlock() - + if config != nil { m.scanOptions.SetConfig(config) m.config = config @@ -59,7 +59,7 @@ func (m *Manager) SetConfig(config *Config) { func (m *Manager) GetServiceDictionary() *ServiceDictionary { m.mu.RLock() defer m.mu.RUnlock() - + return m.serviceDict } @@ -67,7 +67,7 @@ func (m *Manager) GetServiceDictionary() *ServiceDictionary { func (m *Manager) GetProbeMapping() *ProbeMapping { m.mu.RLock() defer m.mu.RUnlock() - + return m.probeMapping } @@ -75,7 +75,7 @@ func (m *Manager) GetProbeMapping() *ProbeMapping { func (m *Manager) GetScanOptions() *ScanOptionsManager { m.mu.RLock() defer m.mu.RUnlock() - + return m.scanOptions } @@ -83,7 +83,7 @@ func (m *Manager) GetScanOptions() *ScanOptionsManager { func (m *Manager) SetProgressBar(pb *progressbar.ProgressBar) { m.mu.Lock() defer m.mu.Unlock() - + if m.config.Application != nil { m.config.Application.ProgressBar = pb m.lastUpdate = time.Now() @@ -94,7 +94,7 @@ func (m *Manager) SetProgressBar(pb *progressbar.ProgressBar) { func (m *Manager) GetProgressBar() *progressbar.ProgressBar { m.mu.RLock() defer m.mu.RUnlock() - + if m.config.Application != nil { return m.config.Application.ProgressBar } @@ -105,7 +105,7 @@ func (m *Manager) GetProgressBar() *progressbar.ProgressBar { func (m *Manager) GetVersion() string { m.mu.RLock() defer m.mu.RUnlock() - + return m.config.Application.Version.Full } @@ -113,7 +113,7 @@ func (m *Manager) GetVersion() string { func (m *Manager) SetVersion(version string) { m.mu.Lock() defer m.mu.Unlock() - + if m.config.Application != nil { m.config.Application.Version.Full = version m.lastUpdate = time.Now() @@ -124,7 +124,7 @@ func (m *Manager) SetVersion(version string) { func (m *Manager) GetOutputMutex() *sync.Mutex { m.mu.RLock() defer m.mu.RUnlock() - + if m.config.Application != nil { return &m.config.Application.OutputMutex } @@ -135,11 +135,11 @@ func (m *Manager) GetOutputMutex() *sync.Mutex { func (m *Manager) SetDefaults() { m.mu.Lock() defer m.mu.Unlock() - + m.scanOptions.SetDefaults() m.serviceDict.ResetToDefaults() m.probeMapping.ResetToDefaults() - + // 设置应用程序默认值 if m.config.Application != nil { m.config.Application.Version = Version{ @@ -149,7 +149,7 @@ func (m *Manager) SetDefaults() { Full: "2.0.2", } } - + m.lastUpdate = time.Now() } @@ -157,14 +157,14 @@ func (m *Manager) SetDefaults() { func (m *Manager) ValidateAll() []string { m.mu.RLock() defer m.mu.RUnlock() - + var warnings []string - + // 验证扫描选项 warnings = append(warnings, m.scanOptions.ValidateConfig()...) - + // 可以添加其他模块的验证逻辑 - + return warnings } @@ -172,16 +172,16 @@ func (m *Manager) ValidateAll() []string { func (m *Manager) GetSummary() map[string]interface{} { m.mu.RLock() defer m.mu.RUnlock() - + summary := m.scanOptions.GetSummary() - + // 添加其他模块信息 summary["service_count"] = len(m.serviceDict.GetServiceNames()) summary["password_count"] = m.serviceDict.GetPasswordCount() summary["mapped_ports_count"] = len(m.probeMapping.GetMappedPorts()) summary["version"] = m.GetVersion() summary["last_updated"] = m.lastUpdate - + return summary } @@ -189,7 +189,7 @@ func (m *Manager) GetSummary() map[string]interface{} { func (m *Manager) Reset() { m.mu.Lock() defer m.mu.Unlock() - + m.config = NewConfig() m.serviceDict.ResetToDefaults() m.probeMapping.ResetToDefaults() @@ -202,7 +202,7 @@ func (m *Manager) Reset() { func (m *Manager) IsInitialized() bool { m.mu.RLock() defer m.mu.RUnlock() - + return m.initialized } @@ -210,7 +210,7 @@ func (m *Manager) IsInitialized() bool { func (m *Manager) GetLastUpdate() time.Time { m.mu.RLock() defer m.mu.RUnlock() - + return m.lastUpdate } @@ -228,28 +228,6 @@ func GetGlobalManager() *Manager { return globalManager } -// SetGlobalManager 设置全局配置管理器实例 -func SetGlobalManager(manager *Manager) { - globalManager = manager -} - -// 便利函数,直接使用全局实例 - -// GetGlobalConfig 获取全局配置 -func GetGlobalManagerConfig() *Config { - return GetGlobalManager().GetConfig() -} - -// SetGlobalManagerConfig 设置全局配置 -func SetGlobalManagerConfig(config *Config) { - GetGlobalManager().SetConfig(config) -} - -// GetGlobalVersion 获取全局版本信息 -func GetGlobalVersion() string { - return GetGlobalManager().GetVersion() -} - // SetGlobalVersion 设置全局版本信息 func SetGlobalVersion(version string) { GetGlobalManager().SetVersion(version) @@ -259,28 +237,3 @@ func SetGlobalVersion(version string) { func GetGlobalProgressBar() *progressbar.ProgressBar { return GetGlobalManager().GetProgressBar() } - -// SetGlobalProgressBar 设置全局进度条 -func SetGlobalProgressBar(pb *progressbar.ProgressBar) { - GetGlobalManager().SetProgressBar(pb) -} - -// GetGlobalOutputMutex 获取全局输出互斥锁 -func GetGlobalOutputMutex() *sync.Mutex { - return GetGlobalManager().GetOutputMutex() -} - -// SetGlobalDefaults 设置全局默认值 -func SetGlobalManagerDefaults() { - GetGlobalManager().SetDefaults() -} - -// ValidateAllGlobal 验证全局配置 -func ValidateAllGlobal() []string { - return GetGlobalManager().ValidateAll() -} - -// GetGlobalManagerSummary 获取全局配置摘要 -func GetGlobalManagerSummary() map[string]interface{} { - return GetGlobalManager().GetSummary() -} \ No newline at end of file diff --git a/Common/config/PortMapping.go b/Common/config/PortMapping.go index 24e8deb..a347075 100644 --- a/Common/config/PortMapping.go +++ b/Common/config/PortMapping.go @@ -178,14 +178,14 @@ func getDefaultPortMap() map[int][]string { func (pm *ProbeMapping) GetProbesForPort(port int) []string { pm.mu.RLock() defer pm.mu.RUnlock() - + if probes, exists := pm.portMap[port]; exists { // 返回副本,避免外部修改 result := make([]string, len(probes)) copy(result, probes) return result } - + // 返回默认探测器 result := make([]string, len(pm.defaultMap)) copy(result, pm.defaultMap) @@ -196,7 +196,7 @@ func (pm *ProbeMapping) GetProbesForPort(port int) []string { func (pm *ProbeMapping) SetProbesForPort(port int, probes []string) { pm.mu.Lock() defer pm.mu.Unlock() - + if len(probes) > 0 { // 创建副本 probesCopy := make([]string, len(probes)) @@ -211,11 +211,11 @@ func (pm *ProbeMapping) SetProbesForPort(port int, probes []string) { func (pm *ProbeMapping) AddProbeToPort(port int, probe string) { pm.mu.Lock() defer pm.mu.Unlock() - + if probe == "" { return } - + if existing, exists := pm.portMap[port]; exists { // 检查是否已存在 for _, p := range existing { @@ -235,7 +235,7 @@ func (pm *ProbeMapping) AddProbeToPort(port int, probe string) { func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) { pm.mu.Lock() defer pm.mu.Unlock() - + if existing, exists := pm.portMap[port]; exists { var result []string for _, p := range existing { @@ -243,7 +243,7 @@ func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) { result = append(result, p) } } - + if len(result) > 0 { pm.portMap[port] = result } else { @@ -256,7 +256,7 @@ func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) { func (pm *ProbeMapping) GetDefaultProbes() []string { pm.mu.RLock() defer pm.mu.RUnlock() - + result := make([]string, len(pm.defaultMap)) copy(result, pm.defaultMap) return result @@ -266,7 +266,7 @@ func (pm *ProbeMapping) GetDefaultProbes() []string { func (pm *ProbeMapping) SetDefaultProbes(probes []string) { pm.mu.Lock() defer pm.mu.Unlock() - + if len(probes) > 0 { defaultCopy := make([]string, len(probes)) copy(defaultCopy, probes) @@ -278,7 +278,7 @@ func (pm *ProbeMapping) SetDefaultProbes(probes []string) { func (pm *ProbeMapping) GetAllPortMappings() map[int][]string { pm.mu.RLock() defer pm.mu.RUnlock() - + result := make(map[int][]string) for port, probes := range pm.portMap { probesCopy := make([]string, len(probes)) @@ -292,12 +292,12 @@ func (pm *ProbeMapping) GetAllPortMappings() map[int][]string { func (pm *ProbeMapping) GetMappedPorts() []int { pm.mu.RLock() defer pm.mu.RUnlock() - + ports := make([]int, 0, len(pm.portMap)) for port := range pm.portMap { ports = append(ports, port) } - + sort.Ints(ports) return ports } @@ -306,7 +306,7 @@ func (pm *ProbeMapping) GetMappedPorts() []int { func (pm *ProbeMapping) HasMappingForPort(port int) bool { pm.mu.RLock() defer pm.mu.RUnlock() - + _, exists := pm.portMap[port] return exists } @@ -315,7 +315,7 @@ func (pm *ProbeMapping) HasMappingForPort(port int) bool { func (pm *ProbeMapping) GetProbeCount(port int) int { pm.mu.RLock() defer pm.mu.RUnlock() - + if probes, exists := pm.portMap[port]; exists { return len(probes) } @@ -326,7 +326,7 @@ func (pm *ProbeMapping) GetProbeCount(port int) int { func (pm *ProbeMapping) ResetToDefaults() { pm.mu.Lock() defer pm.mu.Unlock() - + pm.defaultMap = getDefaultProbeMap() pm.portMap = getDefaultPortMap() } @@ -335,7 +335,7 @@ func (pm *ProbeMapping) ResetToDefaults() { func (pm *ProbeMapping) ClearPortMapping(port int) { pm.mu.Lock() defer pm.mu.Unlock() - + delete(pm.portMap, port) } @@ -343,7 +343,7 @@ func (pm *ProbeMapping) ClearPortMapping(port int) { func (pm *ProbeMapping) ClearAllMappings() { pm.mu.Lock() defer pm.mu.Unlock() - + pm.portMap = make(map[int][]string) } @@ -360,30 +360,3 @@ func GetGlobalProbeMapping() *ProbeMapping { }) return globalProbeMapping } - -// SetGlobalProbeMapping 设置全局探测器映射实例 -func SetGlobalProbeMapping(mapping *ProbeMapping) { - globalProbeMapping = mapping -} - -// 便利函数,直接使用全局实例 - -// GetProbesForPort 获取指定端口的探测器列表(全局函数) -func GetProbesForPort(port int) []string { - return GetGlobalProbeMapping().GetProbesForPort(port) -} - -// GetDefaultProbes 获取默认探测器列表(全局函数) -func GetDefaultProbes() []string { - return GetGlobalProbeMapping().GetDefaultProbes() -} - -// SetProbesForPort 设置指定端口的探测器列表(全局函数) -func SetProbesForPort(port int, probes []string) { - GetGlobalProbeMapping().SetProbesForPort(port, probes) -} - -// GetMappedPorts 获取所有已映射的端口列表(全局函数) -func GetMappedPorts() []int { - return GetGlobalProbeMapping().GetMappedPorts() -} \ No newline at end of file diff --git a/Common/config/ScanOptions.go b/Common/config/ScanOptions.go index def9697..cfd5163 100644 --- a/Common/config/ScanOptions.go +++ b/Common/config/ScanOptions.go @@ -22,7 +22,7 @@ func NewScanOptionsManager() *ScanOptionsManager { func (som *ScanOptionsManager) GetConfig() *Config { som.mu.RLock() defer som.mu.RUnlock() - + // 返回深拷贝,避免外部修改 return som.copyConfig(som.options) } @@ -31,7 +31,7 @@ func (som *ScanOptionsManager) GetConfig() *Config { 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() @@ -42,7 +42,7 @@ func (som *ScanOptionsManager) SetConfig(config *Config) { 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() @@ -53,7 +53,7 @@ func (som *ScanOptionsManager) UpdateScanTarget(target *ScanTargetConfig) { 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() @@ -64,7 +64,7 @@ func (som *ScanOptionsManager) UpdateCredential(credential *CredentialConfig) { 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() @@ -75,7 +75,7 @@ func (som *ScanOptionsManager) UpdateScanControl(control *ScanControlConfig) { 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() @@ -86,7 +86,7 @@ func (som *ScanOptionsManager) UpdateWebScan(webScan *WebScanConfig) { 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() @@ -97,7 +97,7 @@ func (som *ScanOptionsManager) UpdateDisplay(display *DisplayConfig) { 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() @@ -108,7 +108,7 @@ func (som *ScanOptionsManager) UpdateOutput(output *OutputConfig) { func (som *ScanOptionsManager) SetDefaults() { som.mu.Lock() defer som.mu.Unlock() - + // 设置扫描控制默认值 if som.options.ScanControl.ThreadNum <= 0 { som.options.ScanControl.ThreadNum = 600 @@ -122,17 +122,17 @@ func (som *ScanOptionsManager) SetDefaults() { 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" @@ -140,7 +140,7 @@ func (som *ScanOptionsManager) SetDefaults() { if som.options.Display.Language == "" { som.options.Display.Language = "zh" } - + // 设置输出默认值 if som.options.Output.OutputFormat == "" { som.options.Output.OutputFormat = "txt" @@ -148,7 +148,7 @@ func (som *ScanOptionsManager) SetDefaults() { 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" @@ -159,7 +159,7 @@ func (som *ScanOptionsManager) SetDefaults() { if som.options.Network.PocNum <= 0 { som.options.Network.PocNum = 20 } - + som.options.LastUpdated = time.Now() } @@ -167,33 +167,33 @@ func (som *ScanOptionsManager) SetDefaults() { 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 } @@ -201,19 +201,19 @@ func (som *ScanOptionsManager) ValidateConfig() []string { 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, + "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, } } @@ -221,7 +221,7 @@ func (som *ScanOptionsManager) GetSummary() map[string]interface{} { func (som *ScanOptionsManager) ResetToDefaults() { som.mu.Lock() defer som.mu.Unlock() - + som.options = NewConfig() som.SetDefaults() } @@ -230,14 +230,14 @@ func (som *ScanOptionsManager) ResetToDefaults() { 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 = "" @@ -248,18 +248,18 @@ func (som *ScanOptionsManager) ClearConfig() { 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() } @@ -268,7 +268,7 @@ func (som *ScanOptionsManager) copyConfig(config *Config) *Config { if config == nil { return NewConfig() } - + newConfig := &Config{ Application: &ApplicationConfig{ Version: config.Application.Version, @@ -355,18 +355,18 @@ func (som *ScanOptionsManager) copyConfig(config *Config) *Config { }, 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 { @@ -376,12 +376,12 @@ func (som *ScanOptionsManager) copyConfig(config *Config) *Config { } } } - + if len(config.WebScan.URLs) > 0 { newConfig.WebScan.URLs = make([]string, len(config.WebScan.URLs)) copy(newConfig.WebScan.URLs, config.WebScan.URLs) } - + return newConfig } @@ -400,34 +400,7 @@ func GetGlobalScanOptions() *ScanOptionsManager { 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() -} \ No newline at end of file diff --git a/Common/config/ServiceDict.go b/Common/config/ServiceDict.go index caa1e9b..807acb7 100644 --- a/Common/config/ServiceDict.go +++ b/Common/config/ServiceDict.go @@ -7,10 +7,10 @@ import ( // ServiceDictionary 服务字典管理器 type ServiceDictionary struct { - mu sync.RWMutex - userDict map[string][]string - passwords []string - initialized bool + mu sync.RWMutex + userDict map[string][]string + passwords []string + initialized bool } // NewServiceDictionary 创建服务字典管理器 @@ -73,7 +73,7 @@ func getDefaultPasswords() []string { func (sd *ServiceDictionary) GetUserDict(service string) []string { sd.mu.RLock() defer sd.mu.RUnlock() - + service = strings.ToLower(service) if users, exists := sd.userDict[service]; exists { // 返回副本,避免外部修改 @@ -81,7 +81,7 @@ func (sd *ServiceDictionary) GetUserDict(service string) []string { copy(result, users) return result } - + // 返回默认的通用用户名 return []string{"admin", "root", "test", "user"} } @@ -90,7 +90,7 @@ func (sd *ServiceDictionary) GetUserDict(service string) []string { func (sd *ServiceDictionary) SetUserDict(service string, users []string) { sd.mu.Lock() defer sd.mu.Unlock() - + service = strings.ToLower(service) if len(users) > 0 { // 创建副本,避免外部修改影响内部数据 @@ -104,7 +104,7 @@ func (sd *ServiceDictionary) SetUserDict(service string, users []string) { func (sd *ServiceDictionary) AddUsersToService(service string, users []string) { sd.mu.Lock() defer sd.mu.Unlock() - + service = strings.ToLower(service) if existing, exists := sd.userDict[service]; exists { // 合并并去重 @@ -117,7 +117,7 @@ func (sd *ServiceDictionary) AddUsersToService(service string, users []string) { userSet[user] = struct{}{} } } - + // 转换回切片 result := make([]string, 0, len(userSet)) for user := range userSet { @@ -134,7 +134,7 @@ func (sd *ServiceDictionary) AddUsersToService(service string, users []string) { func (sd *ServiceDictionary) GetAllUserDicts() map[string][]string { sd.mu.RLock() defer sd.mu.RUnlock() - + result := make(map[string][]string) for service, users := range sd.userDict { usersCopy := make([]string, len(users)) @@ -148,7 +148,7 @@ func (sd *ServiceDictionary) GetAllUserDicts() map[string][]string { func (sd *ServiceDictionary) GetPasswords() []string { sd.mu.RLock() defer sd.mu.RUnlock() - + // 返回副本,避免外部修改 result := make([]string, len(sd.passwords)) copy(result, sd.passwords) @@ -159,7 +159,7 @@ func (sd *ServiceDictionary) GetPasswords() []string { func (sd *ServiceDictionary) SetPasswords(passwords []string) { sd.mu.Lock() defer sd.mu.Unlock() - + if len(passwords) > 0 { // 创建副本 passwordsCopy := make([]string, len(passwords)) @@ -172,19 +172,19 @@ func (sd *ServiceDictionary) SetPasswords(passwords []string) { func (sd *ServiceDictionary) AddPasswords(passwords []string) { sd.mu.Lock() defer sd.mu.Unlock() - + // 使用map去重 passwordSet := make(map[string]struct{}) for _, pwd := range sd.passwords { passwordSet[pwd] = struct{}{} } - + for _, pwd := range passwords { if pwd != "" { passwordSet[pwd] = struct{}{} } } - + // 转换回切片 result := make([]string, 0, len(passwordSet)) for pwd := range passwordSet { @@ -197,7 +197,7 @@ func (sd *ServiceDictionary) AddPasswords(passwords []string) { func (sd *ServiceDictionary) GetServiceNames() []string { sd.mu.RLock() defer sd.mu.RUnlock() - + services := make([]string, 0, len(sd.userDict)) for service := range sd.userDict { services = append(services, service) @@ -209,7 +209,7 @@ func (sd *ServiceDictionary) GetServiceNames() []string { func (sd *ServiceDictionary) HasService(service string) bool { sd.mu.RLock() defer sd.mu.RUnlock() - + _, exists := sd.userDict[strings.ToLower(service)] return exists } @@ -218,7 +218,7 @@ func (sd *ServiceDictionary) HasService(service string) bool { func (sd *ServiceDictionary) GetUserCount(service string) int { sd.mu.RLock() defer sd.mu.RUnlock() - + if users, exists := sd.userDict[strings.ToLower(service)]; exists { return len(users) } @@ -229,7 +229,7 @@ func (sd *ServiceDictionary) GetUserCount(service string) int { func (sd *ServiceDictionary) GetPasswordCount() int { sd.mu.RLock() defer sd.mu.RUnlock() - + return len(sd.passwords) } @@ -237,7 +237,7 @@ func (sd *ServiceDictionary) GetPasswordCount() int { func (sd *ServiceDictionary) ResetToDefaults() { sd.mu.Lock() defer sd.mu.Unlock() - + sd.userDict = getDefaultUserDict() sd.passwords = getDefaultPasswords() } @@ -255,30 +255,3 @@ func GetGlobalServiceDict() *ServiceDictionary { }) return globalServiceDict } - -// SetGlobalServiceDict 设置全局服务字典实例 -func SetGlobalServiceDict(dict *ServiceDictionary) { - globalServiceDict = dict -} - -// 便利函数,直接使用全局实例 - -// GetUserDict 获取指定服务的用户字典(全局函数) -func GetUserDict(service string) []string { - return GetGlobalServiceDict().GetUserDict(service) -} - -// GetPasswords 获取默认密码字典(全局函数) -func GetPasswords() []string { - return GetGlobalServiceDict().GetPasswords() -} - -// SetUserDict 设置指定服务的用户字典(全局函数) -func SetUserDict(service string, users []string) { - GetGlobalServiceDict().SetUserDict(service, users) -} - -// SetPasswords 设置密码字典(全局函数) -func SetPasswords(passwords []string) { - GetGlobalServiceDict().SetPasswords(passwords) -} \ No newline at end of file diff --git a/Common/i18n.go b/Common/i18n.go index dd0670e..ea5adeb 100644 --- a/Common/i18n.go +++ b/Common/i18n.go @@ -38,7 +38,7 @@ func GetText(key string, args ...interface{}) string { if lang == "" { lang = LangZH } - + if textMap, exists := coreMessages[key]; exists { if text, langExists := textMap[lang]; langExists { if len(args) > 0 { @@ -50,14 +50,9 @@ func GetText(key string, args ...interface{}) string { return key // 找不到时返回key } -// T 简化别名 -func T(key string, args ...interface{}) string { - return GetText(key, args...) -} - // SetLanguage 设置语言(保持兼容性) func SetLanguage(lang string) { if lang == LangZH || lang == LangEN { Language = lang } -} \ No newline at end of file +} diff --git a/Common/logging/Formatter.go b/Common/logging/Formatter.go index 0214902..1f026a6 100644 --- a/Common/logging/Formatter.go +++ b/Common/logging/Formatter.go @@ -27,7 +27,7 @@ func (f *StandardFormatter) Format(entry *LogEntry) string { elapsed := time.Since(f.startTime) timeStr := f.formatElapsedTime(elapsed) prefix := f.getLevelPrefix(entry.Level) - + return fmt.Sprintf("[%s] %s %s", timeStr, prefix, entry.Content) } @@ -75,27 +75,18 @@ type DetailedFormatter struct { includeMetadata bool } -// NewDetailedFormatter 创建详细格式化器 -func NewDetailedFormatter(includeSource, includeMetadata bool) *DetailedFormatter { - return &DetailedFormatter{ - StandardFormatter: StandardFormatter{startTime: time.Now()}, - includeSource: includeSource, - includeMetadata: includeMetadata, - } -} - // Format 格式化日志条目(包含详细信息) func (f *DetailedFormatter) Format(entry *LogEntry) string { baseFormat := f.StandardFormatter.Format(entry) - + if f.includeSource && entry.Source != "" { baseFormat += fmt.Sprintf(" [%s]", entry.Source) } - + if f.includeMetadata && len(entry.Metadata) > 0 { baseFormat += fmt.Sprintf(" %v", entry.Metadata) } - + return baseFormat } @@ -104,13 +95,6 @@ type JSONFormatter struct { startTime time.Time } -// NewJSONFormatter 创建JSON格式化器 -func NewJSONFormatter() *JSONFormatter { - return &JSONFormatter{ - startTime: time.Now(), - } -} - // SetStartTime 设置开始时间 func (f *JSONFormatter) SetStartTime(startTime time.Time) { f.startTime = startTime @@ -119,23 +103,23 @@ func (f *JSONFormatter) SetStartTime(startTime time.Time) { // Format 格式化为JSON格式 func (f *JSONFormatter) Format(entry *LogEntry) string { elapsed := time.Since(f.startTime) - + jsonStr := fmt.Sprintf(`{"level":"%s","time":"%s","elapsed_ms":%d,"content":"%s"`, entry.Level, entry.Time.Format("2006-01-02T15:04:05.000Z07:00"), elapsed.Milliseconds(), entry.Content) - + if entry.Source != "" { jsonStr += fmt.Sprintf(`,"source":"%s"`, entry.Source) } - + if len(entry.Metadata) > 0 { jsonStr += `,"metadata":` // 这里为简化处理,使用简单的格式 jsonStr += fmt.Sprintf(`%v`, entry.Metadata) } - + jsonStr += "}" return jsonStr -} \ No newline at end of file +} diff --git a/Common/logging/Logger.go b/Common/logging/Logger.go index 6dff52f..f5a0f7f 100644 --- a/Common/logging/Logger.go +++ b/Common/logging/Logger.go @@ -15,14 +15,14 @@ import ( // Logger 日志管理器 type Logger struct { - mu sync.RWMutex - config *LoggerConfig - formatter LogFormatter - handlers []LogHandler - scanStatus *ScanStatus - progressBar ProgressDisplay - outputMutex *sync.Mutex - initialized bool + mu sync.RWMutex + config *LoggerConfig + formatter LogFormatter + handlers []LogHandler + scanStatus *ScanStatus + progressBar ProgressDisplay + outputMutex *sync.Mutex + initialized bool } // NewLogger 创建新的日志管理器 @@ -223,7 +223,7 @@ type ConsoleHandler struct { func NewConsoleHandler(config *LoggerConfig) *ConsoleHandler { formatter := NewStandardFormatter() formatter.SetStartTime(config.StartTime) - + return &ConsoleHandler{ config: config, formatter: formatter, @@ -274,25 +274,6 @@ func (h *ConsoleHandler) IsEnabled() bool { return h.enabled } -// 全局日志管理器实例 -var ( - globalLogger *Logger - initOnce sync.Once -) - -// GetGlobalLogger 获取全局日志管理器 -func GetGlobalLogger() *Logger { - initOnce.Do(func() { - globalLogger = NewLogger(DefaultLoggerConfig()) - }) - return globalLogger -} - -// SetGlobalLogger 设置全局日志管理器 -func SetGlobalLogger(logger *Logger) { - globalLogger = logger -} - // 错误检查函数(保持原有逻辑) func CheckErrs(err error) error { if err == nil { @@ -321,4 +302,4 @@ func CheckErrs(err error) error { } return nil -} \ No newline at end of file +} diff --git a/Common/output/Manager.go b/Common/output/Manager.go index b7a9b53..dbc87d9 100644 --- a/Common/output/Manager.go +++ b/Common/output/Manager.go @@ -10,17 +10,17 @@ import ( // Manager 输出管理器 type Manager struct { - mu sync.RWMutex - config *ManagerConfig - writer OutputWriter - reader OutputReader - statistics *Statistics - buffer []*ScanResult - bufferMutex sync.Mutex - flushTicker *time.Ticker - stopChan chan struct{} - initialized bool - closed bool + mu sync.RWMutex + config *ManagerConfig + writer OutputWriter + reader OutputReader + statistics *Statistics + buffer []*ScanResult + bufferMutex sync.Mutex + flushTicker *time.Ticker + stopChan chan struct{} + initialized bool + closed bool } // NewManager 创建新的输出管理器 @@ -56,7 +56,7 @@ func NewManager(config *ManagerConfig) (*Manager, error) { // 如果启用缓冲,初始化缓冲区 if config.EnableBuffer { manager.buffer = make([]*ScanResult, 0, config.BufferSize) - + // 如果启用自动刷新,启动定时器 if config.AutoFlush { manager.startAutoFlush() @@ -299,7 +299,7 @@ func (m *Manager) IsClosed() bool { func (m *Manager) GetConfig() *ManagerConfig { m.mu.RLock() defer m.mu.RUnlock() - + // 返回配置副本 config := *m.config return &config @@ -354,26 +354,9 @@ func (m *Manager) UpdateConfig(updates map[string]interface{}) error { // 全局输出管理器实例 var ( globalManager *Manager - managerOnce sync.Once ) -// GetGlobalManager 获取全局输出管理器 -func GetGlobalManager() *Manager { - return globalManager -} - // SetGlobalManager 设置全局输出管理器 func SetGlobalManager(manager *Manager) { globalManager = manager } - -// InitGlobalManager 初始化全局输出管理器 -func InitGlobalManager(config *ManagerConfig) error { - manager, err := NewManager(config) - if err != nil { - return err - } - - SetGlobalManager(manager) - return nil -} \ No newline at end of file diff --git a/Common/output/Types.go b/Common/output/Types.go index 5eedbb6..f289d68 100644 --- a/Common/output/Types.go +++ b/Common/output/Types.go @@ -22,8 +22,6 @@ const ( TypePort ResultType = "PORT" // 端口开放 TypeService ResultType = "SERVICE" // 服务识别 TypeVuln ResultType = "VULN" // 漏洞发现 - TypeInfo ResultType = "INFO" // 信息收集 - TypeBrute ResultType = "BRUTE" // 爆破结果 ) // ScanResult 扫描结果结构 @@ -53,11 +51,11 @@ type OutputReader interface { // ResultFilter 结果过滤器 type ResultFilter struct { - Types []ResultType `json:"types"` // 过滤的结果类型 - Targets []string `json:"targets"` // 过滤的目标 - TimeRange *TimeRange `json:"time_range"` // 时间范围 - Limit int `json:"limit"` // 限制数量 - Offset int `json:"offset"` // 偏移量 + Types []ResultType `json:"types"` // 过滤的结果类型 + Targets []string `json:"targets"` // 过滤的目标 + TimeRange *TimeRange `json:"time_range"` // 时间范围 + Limit int `json:"limit"` // 限制数量 + Offset int `json:"offset"` // 偏移量 } // TimeRange 时间范围 @@ -68,11 +66,11 @@ type TimeRange struct { // ManagerConfig 输出管理器配置 type ManagerConfig struct { - OutputPath string `json:"output_path"` // 输出路径 - Format OutputFormat `json:"format"` // 输出格式 - EnableBuffer bool `json:"enable_buffer"` // 是否启用缓冲 - BufferSize int `json:"buffer_size"` // 缓冲区大小 - AutoFlush bool `json:"auto_flush"` // 是否自动刷新 + OutputPath string `json:"output_path"` // 输出路径 + Format OutputFormat `json:"format"` // 输出格式 + EnableBuffer bool `json:"enable_buffer"` // 是否启用缓冲 + BufferSize int `json:"buffer_size"` // 缓冲区大小 + AutoFlush bool `json:"auto_flush"` // 是否自动刷新 FlushInterval time.Duration `json:"flush_interval"` // 刷新间隔 } @@ -91,10 +89,10 @@ func DefaultManagerConfig(outputPath string, format OutputFormat) *ManagerConfig // Statistics 输出统计信息 type Statistics struct { mu sync.RWMutex - TotalResults int64 `json:"total_results"` // 总结果数 + TotalResults int64 `json:"total_results"` // 总结果数 TypeCounts map[ResultType]int64 `json:"type_counts"` // 各类型计数 - StartTime time.Time `json:"start_time"` // 开始时间 - LastUpdate time.Time `json:"last_update"` // 最后更新时间 + StartTime time.Time `json:"start_time"` // 开始时间 + LastUpdate time.Time `json:"last_update"` // 最后更新时间 } // NewStatistics 创建新的统计信息 @@ -126,7 +124,7 @@ func (s *Statistics) GetTotalResults() int64 { func (s *Statistics) GetTypeCounts() map[ResultType]int64 { s.mu.RLock() defer s.mu.RUnlock() - + // 返回副本以避免并发问题 counts := make(map[ResultType]int64) for k, v := range s.TypeCounts { @@ -150,4 +148,4 @@ func (s *Statistics) Reset() { s.TypeCounts = make(map[ResultType]int64) s.StartTime = time.Now() s.LastUpdate = time.Now() -} \ No newline at end of file +} diff --git a/Common/parsers/Types.go b/Common/parsers/Types.go index d7fc10f..0d452e7 100644 --- a/Common/parsers/Types.go +++ b/Common/parsers/Types.go @@ -16,13 +16,13 @@ type ParsedConfig struct { // TargetConfig 目标配置 type TargetConfig struct { - Hosts []string `json:"hosts"` - URLs []string `json:"urls"` - Ports []int `json:"ports"` - ExcludePorts []int `json:"exclude_ports"` - HostPorts []string `json:"host_ports"` - LocalMode bool `json:"local_mode"` - Statistics *TargetStatistics `json:"statistics,omitempty"` + Hosts []string `json:"hosts"` + URLs []string `json:"urls"` + Ports []int `json:"ports"` + ExcludePorts []int `json:"exclude_ports"` + HostPorts []string `json:"host_ports"` + LocalMode bool `json:"local_mode"` + Statistics *TargetStatistics `json:"statistics,omitempty"` } // TargetStatistics 目标解析统计 @@ -36,36 +36,36 @@ type TargetStatistics struct { // CredentialConfig 认证配置 type CredentialConfig struct { - Usernames []string `json:"usernames"` - Passwords []string `json:"passwords"` - HashValues []string `json:"hash_values"` - HashBytes [][]byte `json:"hash_bytes,omitempty"` - SshKeyPath string `json:"ssh_key_path"` - Domain string `json:"domain"` - Statistics *CredentialStats `json:"statistics,omitempty"` + Usernames []string `json:"usernames"` + Passwords []string `json:"passwords"` + HashValues []string `json:"hash_values"` + HashBytes [][]byte `json:"hash_bytes,omitempty"` + SshKeyPath string `json:"ssh_key_path"` + Domain string `json:"domain"` + Statistics *CredentialStats `json:"statistics,omitempty"` } // CredentialStats 认证配置统计 type CredentialStats struct { - TotalUsernames int `json:"total_usernames"` - TotalPasswords int `json:"total_passwords"` - TotalHashes int `json:"total_hashes"` - UniqueUsernames int `json:"unique_usernames"` - UniquePasswords int `json:"unique_passwords"` - ValidHashes int `json:"valid_hashes"` - InvalidHashes int `json:"invalid_hashes"` + TotalUsernames int `json:"total_usernames"` + TotalPasswords int `json:"total_passwords"` + TotalHashes int `json:"total_hashes"` + UniqueUsernames int `json:"unique_usernames"` + UniquePasswords int `json:"unique_passwords"` + ValidHashes int `json:"valid_hashes"` + InvalidHashes int `json:"invalid_hashes"` } // NetworkConfig 网络配置 type NetworkConfig struct { - HttpProxy string `json:"http_proxy"` - Socks5Proxy string `json:"socks5_proxy"` - Timeout time.Duration `json:"timeout"` - WebTimeout time.Duration `json:"web_timeout"` - DisablePing bool `json:"disable_ping"` - EnableDNSLog bool `json:"enable_dns_log"` - UserAgent string `json:"user_agent"` - Cookie string `json:"cookie"` + HttpProxy string `json:"http_proxy"` + Socks5Proxy string `json:"socks5_proxy"` + Timeout time.Duration `json:"timeout"` + WebTimeout time.Duration `json:"web_timeout"` + DisablePing bool `json:"disable_ping"` + EnableDNSLog bool `json:"enable_dns_log"` + UserAgent string `json:"user_agent"` + Cookie string `json:"cookie"` } // ValidationConfig 验证配置 @@ -87,27 +87,19 @@ type ParseResult struct { // 预定义错误类型 var ( - ErrEmptyInput = errors.New("输入参数为空") - ErrInvalidFormat = errors.New("格式无效") - ErrFileNotFound = errors.New("文件未找到") - ErrConflictingParams = errors.New("参数冲突") - ErrInvalidProxy = errors.New("代理配置无效") - ErrInvalidHash = errors.New("哈希值无效") - ErrInvalidPort = errors.New("端口号无效") - ErrInvalidIP = errors.New("IP地址无效") - ErrInvalidURL = errors.New("URL格式无效") + ErrEmptyInput = errors.New("输入参数为空") ) // ParserOptions 解析器选项 type ParserOptions struct { - EnableConcurrency bool // 启用并发解析 - MaxWorkers int // 最大工作协程数 - Timeout time.Duration // 解析超时时间 - EnableValidation bool // 启用详细验证 - EnableStatistics bool // 启用统计信息 - IgnoreErrors bool // 忽略非致命错误 - FileMaxSize int64 // 文件最大大小限制 - MaxTargets int // 最大目标数量限制 + EnableConcurrency bool // 启用并发解析 + MaxWorkers int // 最大工作协程数 + Timeout time.Duration // 解析超时时间 + EnableValidation bool // 启用详细验证 + EnableStatistics bool // 启用统计信息 + IgnoreErrors bool // 忽略非致命错误 + FileMaxSize int64 // 文件最大大小限制 + MaxTargets int // 最大目标数量限制 } // DefaultParserOptions 返回默认解析器选项 @@ -120,7 +112,7 @@ func DefaultParserOptions() *ParserOptions { EnableStatistics: true, IgnoreErrors: false, FileMaxSize: 100 * 1024 * 1024, // 100MB - MaxTargets: 10000, // 10K targets + MaxTargets: 10000, // 10K targets } } @@ -166,4 +158,4 @@ func NewParseError(errType, message, source string, line int, original error) *P Line: line, Original: original, } -} \ No newline at end of file +}