diff --git a/Core/ICMP.go b/Core/ICMP.go index a0227f3..096253f 100644 --- a/Core/ICMP.go +++ b/Core/ICMP.go @@ -14,38 +14,38 @@ import ( ) var ( - AliveHosts []string // 存活主机列表 - ExistHosts = make(map[string]struct{}) // 已发现主机记录 - livewg sync.WaitGroup // 存活检测等待组 + AliveHosts []string // List of alive hosts + ExistHosts = make(map[string]struct{}) // Record of discovered hosts + livewg sync.WaitGroup // Wait group for live detection ) -// CheckLive 检测主机存活状态 +// CheckLive checks the live status of hosts func CheckLive(hostslist []string, Ping bool) []string { - // 创建主机通道 + // Create host channel chanHosts := make(chan string, len(hostslist)) - // 处理存活主机 + // Handle alive hosts go handleAliveHosts(chanHosts, hostslist, Ping) - // 根据Ping参数选择检测方式 + // Choose detection method based on Ping parameter if Ping { - // 使用ping方式探测 + // Use ping method RunPing(hostslist, chanHosts) } else { probeWithICMP(hostslist, chanHosts) } - // 等待所有检测完成 + // Wait for all detections to complete livewg.Wait() close(chanHosts) - // 输出存活统计信息 + // Print alive statistics printAliveStats(hostslist) return AliveHosts } -// IsContain 检查切片中是否包含指定元素 +// IsContain checks if the slice contains the specified element func IsContain(items []string, item string) bool { for _, eachItem := range items { if eachItem == item { @@ -61,7 +61,7 @@ func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool) { ExistHosts[ip] = struct{}{} AliveHosts = append(AliveHosts, ip) - // 使用Output系统保存存活主机信息 + // Use Output system to save alive host information protocol := "ICMP" if isPing { protocol = "PING" @@ -78,7 +78,7 @@ func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool) { } Common.SaveResult(result) - // 保留原有的控制台输出 + // Keep original console output if !Common.Silent { Common.LogSuccess(Common.GetText("target_alive", ip, protocol)) } @@ -87,9 +87,9 @@ func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool) { } } -// probeWithICMP 使用ICMP方式探测 +// probeWithICMP probes using ICMP method func probeWithICMP(hostslist []string, chanHosts chan string) { - // 尝试监听本地ICMP + // Try to listen on local ICMP conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0") if err == nil { RunIcmp1(hostslist, conn, chanHosts) @@ -99,7 +99,7 @@ func probeWithICMP(hostslist []string, chanHosts chan string) { Common.LogError(Common.GetText("icmp_listen_failed", err)) Common.LogInfo(Common.GetText("trying_no_listen_icmp")) - // 尝试无监听ICMP探测 + // Try no-listen ICMP probe conn2, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second) if err == nil { defer conn2.Close() @@ -111,22 +111,22 @@ func probeWithICMP(hostslist []string, chanHosts chan string) { Common.LogInfo(Common.GetText("insufficient_privileges")) Common.LogInfo(Common.GetText("switching_to_ping")) - // 降级使用ping探测 + // Fallback to ping probe RunPing(hostslist, chanHosts) } -// printAliveStats 打印存活统计信息 +// printAliveStats prints alive statistics func printAliveStats(hostslist []string) { - // 大规模扫描时输出 /16 网段统计 - if len(hostslist) > 1000 { + // Output /16 subnet statistics for large-scale scans + if (len(hostslist) > 1000) { arrTop, arrLen := ArrayCountValueTop(AliveHosts, Common.LiveTop, true) for i := 0; i < len(arrTop); i++ { Common.LogSuccess(Common.GetText("subnet_16_alive", arrTop[i], arrLen[i])) } } - // 输出 /24 网段统计 - if len(hostslist) > 256 { + // Output /24 subnet statistics + if (len(hostslist) > 256) { arrTop, arrLen := ArrayCountValueTop(AliveHosts, Common.LiveTop, false) for i := 0; i < len(arrTop); i++ { Common.LogSuccess(Common.GetText("subnet_24_alive", arrTop[i], arrLen[i])) @@ -134,17 +134,17 @@ func printAliveStats(hostslist []string) { } } -// RunIcmp1 使用ICMP批量探测主机存活(监听模式) +// RunIcmp1 uses ICMP to probe host liveliness (listen mode) func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string) { endflag := false - // 启动监听协程 + // Start listening goroutine go func() { for { if endflag { return } - // 接收ICMP响应 + // Receive ICMP response msg := make([]byte, 100) _, sourceIP, _ := conn.ReadFrom(msg) if sourceIP != nil { @@ -154,22 +154,22 @@ func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string) } }() - // 发送ICMP请求 + // Send ICMP requests for _, host := range hostslist { dst, _ := net.ResolveIPAddr("ip", host) IcmpByte := makemsg(host) conn.WriteTo(IcmpByte, dst) } - // 等待响应 + // Wait for responses start := time.Now() for { - // 所有主机都已响应则退出 + // Exit if all hosts have responded if len(AliveHosts) == len(hostslist) { break } - // 根据主机数量设置超时时间 + // Set timeout based on number of hosts since := time.Since(start) wait := time.Second * 6 if len(hostslist) <= 256 { @@ -185,9 +185,9 @@ func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string) conn.Close() } -// RunIcmp2 使用ICMP并发探测主机存活(无监听模式) +// RunIcmp2 uses ICMP to probe host liveliness (no-listen mode) func RunIcmp2(hostslist []string, chanHosts chan string) { - // 控制并发数 + // Control concurrency num := 1000 if len(hostslist) < num { num = len(hostslist) @@ -196,7 +196,7 @@ func RunIcmp2(hostslist []string, chanHosts chan string) { var wg sync.WaitGroup limiter := make(chan struct{}, num) - // 并发探测 + // Concurrent probing for _, host := range hostslist { wg.Add(1) limiter <- struct{}{} @@ -218,29 +218,29 @@ func RunIcmp2(hostslist []string, chanHosts chan string) { close(limiter) } -// icmpalive 检测主机ICMP是否存活 +// icmpalive checks if the host is alive using ICMP func icmpalive(host string) bool { startTime := time.Now() - // 建立ICMP连接 + // Establish ICMP connection conn, err := net.DialTimeout("ip4:icmp", host, 6*time.Second) if err != nil { return false } defer conn.Close() - // 设置超时时间 + // Set timeout if err := conn.SetDeadline(startTime.Add(6 * time.Second)); err != nil { return false } - // 构造并发送ICMP请求 + // Construct and send ICMP request msg := makemsg(host) if _, err := conn.Write(msg); err != nil { return false } - // 接收ICMP响应 + // Receive ICMP response receive := make([]byte, 60) if _, err := conn.Read(receive); err != nil { return false @@ -249,13 +249,13 @@ func icmpalive(host string) bool { return true } -// RunPing 使用系统Ping命令并发探测主机存活 +// RunPing uses system ping command to probe host liveliness concurrently func RunPing(hostslist []string, chanHosts chan string) { var wg sync.WaitGroup - // 限制并发数为50 + // Limit concurrency to 50 limiter := make(chan struct{}, 50) - // 并发探测 + // Concurrent probing for _, host := range hostslist { wg.Add(1) limiter <- struct{}{} @@ -276,9 +276,9 @@ func RunPing(hostslist []string, chanHosts chan string) { wg.Wait() } -// ExecCommandPing 执行系统Ping命令检测主机存活 +// ExecCommandPing executes system ping command to check host liveliness func ExecCommandPing(ip string) bool { - // 过滤黑名单字符 + // Filter blacklist characters forbiddenChars := []string{";", "&", "|", "`", "$", "\\", "'", "%", "\"", "\n"} for _, char := range forbiddenChars { if strings.Contains(ip, char) { @@ -287,7 +287,7 @@ func ExecCommandPing(ip string) bool { } var command *exec.Cmd - // 根据操作系统选择不同的ping命令 + // Choose different ping commands based on OS switch runtime.GOOS { case "windows": command = exec.Command("cmd", "/c", "ping -n 1 -w 1 "+ip+" && echo true || echo false") @@ -297,11 +297,11 @@ func ExecCommandPing(ip string) bool { command = exec.Command("/bin/bash", "-c", "ping -c 1 -w 1 "+ip+" && echo true || echo false") } - // 捕获命令输出 + // Capture command output var outinfo bytes.Buffer command.Stdout = &outinfo - // 执行命令 + // Execute command if err := command.Start(); err != nil { return false } @@ -310,76 +310,76 @@ func ExecCommandPing(ip string) bool { return false } - // 分析输出结果 + // Analyze output result output := outinfo.String() return strings.Contains(output, "true") && strings.Count(output, ip) > 2 } -// makemsg 构造ICMP echo请求消息 +// makemsg constructs ICMP echo request message func makemsg(host string) []byte { msg := make([]byte, 40) - // 获取标识符 + // Get identifier id0, id1 := genIdentifier(host) - // 设置ICMP头部 + // Set ICMP header msg[0] = 8 // Type: Echo Request msg[1] = 0 // Code: 0 - msg[2] = 0 // Checksum高位(待计算) - msg[3] = 0 // Checksum低位(待计算) + msg[2] = 0 // Checksum high byte (to be calculated) + msg[3] = 0 // Checksum low byte (to be calculated) msg[4], msg[5] = id0, id1 // Identifier msg[6], msg[7] = genSequence(1) // Sequence Number - // 计算校验和 + // Calculate checksum check := checkSum(msg[0:40]) - msg[2] = byte(check >> 8) // 设置校验和高位 - msg[3] = byte(check & 255) // 设置校验和低位 + msg[2] = byte(check >> 8) // Set checksum high byte + msg[3] = byte(check & 255) // Set checksum low byte return msg } -// checkSum 计算ICMP校验和 +// checkSum calculates ICMP checksum func checkSum(msg []byte) uint16 { sum := 0 length := len(msg) - // 按16位累加 + // Accumulate in 16-bit units for i := 0; i < length-1; i += 2 { sum += int(msg[i])*256 + int(msg[i+1]) } - // 处理奇数长度情况 + // Handle odd length case if length%2 == 1 { sum += int(msg[length-1]) * 256 } - // 将高16位加到低16位 + // Add high 16 bits to low 16 bits sum = (sum >> 16) + (sum & 0xffff) sum = sum + (sum >> 16) - // 取反得到校验和 + // Take one's complement to get checksum return uint16(^sum) } -// genSequence 生成ICMP序列号 +// genSequence generates ICMP sequence number func genSequence(v int16) (byte, byte) { - ret1 := byte(v >> 8) // 高8位 - ret2 := byte(v & 255) // 低8位 + ret1 := byte(v >> 8) // High 8 bits + ret2 := byte(v & 255) // Low 8 bits return ret1, ret2 } -// genIdentifier 根据主机地址生成标识符 +// genIdentifier generates identifier based on host address func genIdentifier(host string) (byte, byte) { - return host[0], host[1] // 使用主机地址前两个字节 + return host[0], host[1] // Use first two bytes of host address } -// ArrayCountValueTop 统计IP地址段存活数量并返回TOP N结果 +// ArrayCountValueTop counts the number of alive IP segments and returns the top N results func ArrayCountValueTop(arrInit []string, length int, flag bool) (arrTop []string, arrLen []int) { if len(arrInit) == 0 { return } - // 统计各网段出现次数 + // Count occurrences of each segment segmentCounts := make(map[string]int) for _, ip := range arrInit { segments := strings.Split(ip, ".") @@ -387,29 +387,29 @@ func ArrayCountValueTop(arrInit []string, length int, flag bool) (arrTop []strin continue } - // 根据flag确定统计B段还是C段 + // Determine whether to count B segment or C segment based on flag var segment string if flag { - segment = fmt.Sprintf("%s.%s", segments[0], segments[1]) // B段 + segment = fmt.Sprintf("%s.%s", segments[0], segments[1]) // B segment } else { - segment = fmt.Sprintf("%s.%s.%s", segments[0], segments[1], segments[2]) // C段 + segment = fmt.Sprintf("%s.%s.%s", segments[0], segments[1], segments[2]) // C segment } segmentCounts[segment]++ } - // 创建副本用于排序 + // Create a copy for sorting sortMap := make(map[string]int) for k, v := range segmentCounts { sortMap[k] = v } - // 获取TOP N结果 + // Get top N results for i := 0; i < length && len(sortMap) > 0; i++ { maxSegment := "" maxCount := 0 - // 查找当前最大值 + // Find current maximum value for segment, count := range sortMap { if count > maxCount { maxCount = count @@ -417,11 +417,11 @@ func ArrayCountValueTop(arrInit []string, length int, flag bool) (arrTop []strin } } - // 添加到结果集 + // Add to result set arrTop = append(arrTop, maxSegment) arrLen = append(arrLen, maxCount) - // 从待处理map中删除已处理项 + // Remove processed item from map delete(sortMap, maxSegment) } diff --git a/Core/PortFinger.go b/Core/PortFinger.go index a735620..9c32e1f 100644 --- a/Core/PortFinger.go +++ b/Core/PortFinger.go @@ -13,7 +13,7 @@ import ( //go:embed nmap-service-probes.txt var ProbeString string -var v VScan // 改为VScan类型而不是指针 +var v VScan // Changed to VScan type instead of pointer type VScan struct { Exclude string @@ -24,27 +24,27 @@ type VScan struct { } type Probe struct { - Name string // 探测器名称 - Data string // 探测数据 - Protocol string // 协议 - Ports string // 端口范围 - SSLPorts string // SSL端口范围 + Name string // Probe name + Data string // Probe data + Protocol string // Protocol + Ports string // Port range + SSLPorts string // SSL port range - TotalWaitMS int // 总等待时间 - TCPWrappedMS int // TCP包装等待时间 - Rarity int // 稀有度 - Fallback string // 回退探测器名称 + TotalWaitMS int // Total wait time + TCPWrappedMS int // TCP wrapped wait time + Rarity int // Rarity + Fallback string // Fallback probe name - Matchs *[]Match // 匹配规则列表 + Matchs *[]Match // Match rules list } type Match struct { - IsSoft bool // 是否为软匹配 - Service string // 服务名称 - Pattern string // 匹配模式 - VersionInfo string // 版本信息格式 - FoundItems []string // 找到的项目 - PatternCompiled *regexp.Regexp // 编译后的正则表达式 + IsSoft bool // Whether it's a soft match + Service string // Service name + Pattern string // Match pattern + VersionInfo string // Version info format + FoundItems []string // Found items + PatternCompiled *regexp.Regexp // Compiled regular expression } type Directive struct { @@ -65,43 +65,43 @@ type Extras struct { } func init() { - Common.LogDebug("开始初始化全局变量") + Common.LogDebug("Starting to initialize global variables") - v = VScan{} // 直接初始化VScan结构体 + v = VScan{} // Directly initialize VScan struct v.Init() - // 获取并检查 NULL 探测器 + // Get and check NULL probe if nullProbe, ok := v.ProbesMapKName["NULL"]; ok { - Common.LogDebug(fmt.Sprintf("成功获取NULL探测器,Data长度: %d", len(nullProbe.Data))) + Common.LogDebug(fmt.Sprintf("Successfully obtained NULL probe, Data length: %d", len(nullProbe.Data))) null = &nullProbe } else { - Common.LogDebug("警告: 未找到NULL探测器") + Common.LogDebug("Warning: NULL probe not found") } - // 获取并检查 GenericLines 探测器 + // Get and check GenericLines probe if commonProbe, ok := v.ProbesMapKName["GenericLines"]; ok { - Common.LogDebug(fmt.Sprintf("成功获取GenericLines探测器,Data长度: %d", len(commonProbe.Data))) + Common.LogDebug(fmt.Sprintf("Successfully obtained GenericLines probe, Data length: %d", len(commonProbe.Data))) common = &commonProbe } else { - Common.LogDebug("警告: 未找到GenericLines探测器") + Common.LogDebug("Warning: GenericLines probe not found") } - Common.LogDebug("全局变量初始化完成") + Common.LogDebug("Global variables initialization complete") } -// 解析指令语法,返回指令结构 +// Parse directive syntax, return directive structure func (p *Probe) getDirectiveSyntax(data string) (directive Directive) { - Common.LogDebug("开始解析指令语法,输入数据: " + data) + Common.LogDebug("Starting to parse directive syntax, input data: " + data) directive = Directive{} - // 查找第一个空格的位置 + // Find the position of the first space blankIndex := strings.Index(data, " ") if blankIndex == -1 { - Common.LogDebug("未找到空格分隔符") + Common.LogDebug("Space separator not found") return directive } - // 解析各个字段 + // Parse each field directiveName := data[:blankIndex] Flag := data[blankIndex+1 : blankIndex+2] delimiter := data[blankIndex+2 : blankIndex+3] @@ -112,70 +112,70 @@ func (p *Probe) getDirectiveSyntax(data string) (directive Directive) { directive.Delimiter = delimiter directive.DirectiveStr = directiveStr - Common.LogDebug(fmt.Sprintf("指令解析结果: 名称=%s, 标志=%s, 分隔符=%s, 内容=%s", + Common.LogDebug(fmt.Sprintf("Directive parsing result: Name=%s, Flag=%s, Delimiter=%s, Content=%s", directiveName, Flag, delimiter, directiveStr)) return directive } -// 解析探测器信息 +// Parse probe information func (p *Probe) parseProbeInfo(probeStr string) { - Common.LogDebug("开始解析探测器信息,输入字符串: " + probeStr) + Common.LogDebug("Starting to parse probe information, input string: " + probeStr) - // 提取协议和其他信息 + // Extract protocol and other information proto := probeStr[:4] other := probeStr[4:] - // 验证协议类型 + // Validate protocol type if !(proto == "TCP " || proto == "UDP ") { - errMsg := "探测器协议必须是 TCP 或 UDP" - Common.LogDebug("错误: " + errMsg) + errMsg := "Probe protocol must be TCP or UDP" + Common.LogDebug("Error: " + errMsg) panic(errMsg) } - // 验证其他信息不为空 + // Validate other information is not empty if len(other) == 0 { - errMsg := "nmap-service-probes - 探测器名称无效" - Common.LogDebug("错误: " + errMsg) + errMsg := "nmap-service-probes - Invalid probe name" + Common.LogDebug("Error: " + errMsg) panic(errMsg) } - // 解析指令 + // Parse directive directive := p.getDirectiveSyntax(other) - // 设置探测器属性 + // Set probe attributes p.Name = directive.DirectiveName p.Data = strings.Split(directive.DirectiveStr, directive.Delimiter)[0] p.Protocol = strings.ToLower(strings.TrimSpace(proto)) - Common.LogDebug(fmt.Sprintf("探测器解析完成: 名称=%s, 数据=%s, 协议=%s", + Common.LogDebug(fmt.Sprintf("Probe parsing completed: Name=%s, Data=%s, Protocol=%s", p.Name, p.Data, p.Protocol)) } -// 从字符串解析探测器信息 +// Parse probe information from string func (p *Probe) fromString(data string) error { - Common.LogDebug("开始解析探测器字符串数据") + Common.LogDebug("Starting to parse probe string data") var err error - // 预处理数据 + // Preprocess data data = strings.TrimSpace(data) lines := strings.Split(data, "\n") if len(lines) == 0 { - return fmt.Errorf("输入数据为空") + return fmt.Errorf("Input data is empty") } probeStr := lines[0] p.parseProbeInfo(probeStr) - // 解析匹配规则和其他配置 + // Parse match rules and other configurations var matchs []Match for _, line := range lines { - Common.LogDebug("处理行: " + line) + Common.LogDebug("Processing line: " + line) switch { case strings.HasPrefix(line, "match "): match, err := p.getMatch(line) if err != nil { - Common.LogDebug("解析match失败: " + err.Error()) + Common.LogDebug("Failed to parse match: " + err.Error()) continue } matchs = append(matchs, match) @@ -183,7 +183,7 @@ func (p *Probe) fromString(data string) error { case strings.HasPrefix(line, "softmatch "): softMatch, err := p.getSoftMatch(line) if err != nil { - Common.LogDebug("解析softmatch失败: " + err.Error()) + Common.LogDebug("Failed to parse softmatch: " + err.Error()) continue } matchs = append(matchs, softMatch) @@ -208,80 +208,80 @@ func (p *Probe) fromString(data string) error { } } p.Matchs = &matchs - Common.LogDebug(fmt.Sprintf("解析完成,共有 %d 个匹配规则", len(matchs))) + Common.LogDebug(fmt.Sprintf("Parsing completed, total of %d match rules", len(matchs))) return err } -// 解析端口配置 +// Parse port configuration func (p *Probe) parsePorts(data string) { p.Ports = data[len("ports")+1:] - Common.LogDebug("解析端口: " + p.Ports) + Common.LogDebug("Parsing ports: " + p.Ports) } -// 解析SSL端口配置 +// Parse SSL port configuration func (p *Probe) parseSSLPorts(data string) { p.SSLPorts = data[len("sslports")+1:] - Common.LogDebug("解析SSL端口: " + p.SSLPorts) + Common.LogDebug("Parsing SSL ports: " + p.SSLPorts) } -// 解析总等待时间 +// Parse total wait time func (p *Probe) parseTotalWaitMS(data string) { waitMS, err := strconv.Atoi(strings.TrimSpace(data[len("totalwaitms")+1:])) if err != nil { - Common.LogDebug("解析总等待时间失败: " + err.Error()) + Common.LogDebug("Failed to parse total wait time: " + err.Error()) return } p.TotalWaitMS = waitMS - Common.LogDebug(fmt.Sprintf("总等待时间: %d ms", waitMS)) + Common.LogDebug(fmt.Sprintf("Total wait time: %d ms", waitMS)) } -// 解析TCP包装等待时间 +// Parse TCP wrapped wait time func (p *Probe) parseTCPWrappedMS(data string) { wrappedMS, err := strconv.Atoi(strings.TrimSpace(data[len("tcpwrappedms")+1:])) if err != nil { - Common.LogDebug("解析TCP包装等待时间失败: " + err.Error()) + Common.LogDebug("Failed to parse TCP wrapped wait time: " + err.Error()) return } p.TCPWrappedMS = wrappedMS - Common.LogDebug(fmt.Sprintf("TCP包装等待时间: %d ms", wrappedMS)) + Common.LogDebug(fmt.Sprintf("TCP wrapped wait time: %d ms", wrappedMS)) } -// 解析稀有度 +// Parse rarity func (p *Probe) parseRarity(data string) { rarity, err := strconv.Atoi(strings.TrimSpace(data[len("rarity")+1:])) if err != nil { - Common.LogDebug("解析稀有度失败: " + err.Error()) + Common.LogDebug("Failed to parse rarity: " + err.Error()) return } p.Rarity = rarity - Common.LogDebug(fmt.Sprintf("稀有度: %d", rarity)) + Common.LogDebug(fmt.Sprintf("Rarity: %d", rarity)) } -// 解析回退配置 +// Parse fallback configuration func (p *Probe) parseFallback(data string) { p.Fallback = data[len("fallback")+1:] - Common.LogDebug("回退配置: " + p.Fallback) + Common.LogDebug("Fallback configuration: " + p.Fallback) } -// 判断是否为十六进制编码 +// Check if it's a hexadecimal code func isHexCode(b []byte) bool { matchRe := regexp.MustCompile(`\\x[0-9a-fA-F]{2}`) return matchRe.Match(b) } -// 判断是否为八进制编码 +// Check if it's an octal code func isOctalCode(b []byte) bool { matchRe := regexp.MustCompile(`\\[0-7]{1,3}`) return matchRe.Match(b) } -// 判断是否为结构化转义字符 +// Check if it's a structured escape character func isStructCode(b []byte) bool { matchRe := regexp.MustCompile(`\\[aftnrv]`) return matchRe.Match(b) } -// 判断是否为正则表达式特殊字符 +// Check if it's a regular expression special character func isReChar(n int64) bool { reChars := `.*?+{}()^$|\` for _, char := range reChars { @@ -292,19 +292,19 @@ func isReChar(n int64) bool { return false } -// 判断是否为其他转义序列 +// Check if it's another escape sequence func isOtherEscapeCode(b []byte) bool { matchRe := regexp.MustCompile(`\\[^\\]`) return matchRe.Match(b) } -// 从内容解析探测器规则 +// Parse probe rules from content func (v *VScan) parseProbesFromContent(content string) { - Common.LogDebug("开始解析探测器规则文件内容") + Common.LogDebug("Starting to parse probe rules from file content") var probes []Probe var lines []string - // 过滤注释和空行 + // Filter comments and empty lines linesTemp := strings.Split(content, "\n") for _, lineTemp := range linesTemp { lineTemp = strings.TrimSpace(lineTemp) @@ -314,196 +314,196 @@ func (v *VScan) parseProbesFromContent(content string) { lines = append(lines, lineTemp) } - // 验证文件内容 + // Validate file content if len(lines) == 0 { - errMsg := "读取nmap-service-probes文件失败: 内容为空" - Common.LogDebug("错误: " + errMsg) + errMsg := "Failed to read nmap-service-probes file: Content is empty" + Common.LogDebug("Error: " + errMsg) panic(errMsg) } - // 检查Exclude指令 + // Check Exclude directive excludeCount := 0 for _, line := range lines { if strings.HasPrefix(line, "Exclude ") { excludeCount++ } if excludeCount > 1 { - errMsg := "nmap-service-probes文件中只允许有一个Exclude指令" - Common.LogDebug("错误: " + errMsg) + errMsg := "Only one Exclude directive is allowed in nmap-service-probes file" + Common.LogDebug("Error: " + errMsg) panic(errMsg) } } - // 验证第一行格式 + // Validate first line format firstLine := lines[0] if !(strings.HasPrefix(firstLine, "Exclude ") || strings.HasPrefix(firstLine, "Probe ")) { - errMsg := "解析错误: 首行必须以\"Probe \"或\"Exclude \"开头" - Common.LogDebug("错误: " + errMsg) + errMsg := "Parsing error: First line must start with \"Probe \" or \"Exclude \"" + Common.LogDebug("Error: " + errMsg) panic(errMsg) } - // 处理Exclude指令 + // Process Exclude directive if excludeCount == 1 { v.Exclude = firstLine[len("Exclude")+1:] lines = lines[1:] - Common.LogDebug("解析到Exclude规则: " + v.Exclude) + Common.LogDebug("Parsed Exclude rule: " + v.Exclude) } - // 合并内容并分割探测器 + // Merge content and split probes content = "\n" + strings.Join(lines, "\n") probeParts := strings.Split(content, "\nProbe")[1:] - // 解析每个探测器 + // Parse each probe for _, probePart := range probeParts { probe := Probe{} if err := probe.fromString(probePart); err != nil { - Common.LogDebug(fmt.Sprintf("解析探测器失败: %v", err)) + Common.LogDebug(fmt.Sprintf("Failed to parse probe: %v", err)) continue } probes = append(probes, probe) } v.AllProbes = probes - Common.LogDebug(fmt.Sprintf("成功解析 %d 个探测器规则", len(probes))) + Common.LogDebug(fmt.Sprintf("Successfully parsed %d probe rules", len(probes))) } -// 将探测器转换为名称映射 +// Convert probes to name mapping func (v *VScan) parseProbesToMapKName() { - Common.LogDebug("开始构建探测器名称映射") + Common.LogDebug("Starting to build probe name mapping") v.ProbesMapKName = map[string]Probe{} for _, probe := range v.AllProbes { v.ProbesMapKName[probe.Name] = probe - Common.LogDebug("添加探测器映射: " + probe.Name) + Common.LogDebug("Added probe mapping: " + probe.Name) } } -// 设置使用的探测器 +// Set probes to be used func (v *VScan) SetusedProbes() { - Common.LogDebug("开始设置要使用的探测器") + Common.LogDebug("Starting to set probes to be used") for _, probe := range v.AllProbes { if strings.ToLower(probe.Protocol) == "tcp" { if probe.Name == "SSLSessionReq" { - Common.LogDebug("跳过 SSLSessionReq 探测器") + Common.LogDebug("Skipping SSLSessionReq probe") continue } v.Probes = append(v.Probes, probe) - Common.LogDebug("添加TCP探测器: " + probe.Name) + Common.LogDebug("Added TCP probe: " + probe.Name) - // 特殊处理TLS会话请求 + // Special handling for TLS session request if probe.Name == "TLSSessionReq" { sslProbe := v.ProbesMapKName["SSLSessionReq"] v.Probes = append(v.Probes, sslProbe) - Common.LogDebug("为TLSSessionReq添加SSL探测器") + Common.LogDebug("Added SSL probe for TLSSessionReq") } } else { v.UdpProbes = append(v.UdpProbes, probe) - Common.LogDebug("添加UDP探测器: " + probe.Name) + Common.LogDebug("Added UDP probe: " + probe.Name) } } - Common.LogDebug(fmt.Sprintf("探测器设置完成,TCP: %d个, UDP: %d个", + Common.LogDebug(fmt.Sprintf("Probe setting completed, TCP: %d, UDP: %d", len(v.Probes), len(v.UdpProbes))) } -// 解析match指令获取匹配规则 +// Parse match directive to get match rule func (p *Probe) getMatch(data string) (match Match, err error) { - Common.LogDebug("开始解析match指令:" + data) + Common.LogDebug("Starting to parse match directive: " + data) match = Match{} - // 提取match文本并解析指令语法 + // Extract match text and parse directive syntax matchText := data[len("match")+1:] directive := p.getDirectiveSyntax(matchText) - // 分割文本获取pattern和版本信息 + // Split text to get pattern and version info textSplited := strings.Split(directive.DirectiveStr, directive.Delimiter) if len(textSplited) == 0 { - return match, fmt.Errorf("无效的match指令格式") + return match, fmt.Errorf("Invalid match directive format") } pattern := textSplited[0] versionInfo := strings.Join(textSplited[1:], "") - // 解码并编译正则表达式 + // Decode and compile regular expression patternUnescaped, decodeErr := DecodePattern(pattern) if decodeErr != nil { - Common.LogDebug("解码pattern失败: " + decodeErr.Error()) + Common.LogDebug("Failed to decode pattern: " + decodeErr.Error()) return match, decodeErr } patternUnescapedStr := string([]rune(string(patternUnescaped))) patternCompiled, compileErr := regexp.Compile(patternUnescapedStr) if compileErr != nil { - Common.LogDebug("编译正则表达式失败: " + compileErr.Error()) + Common.LogDebug("Failed to compile regular expression: " + compileErr.Error()) return match, compileErr } - // 设置match对象属性 + // Set match object attributes match.Service = directive.DirectiveName match.Pattern = pattern match.PatternCompiled = patternCompiled match.VersionInfo = versionInfo - Common.LogDebug(fmt.Sprintf("解析match成功: 服务=%s, Pattern=%s", + Common.LogDebug(fmt.Sprintf("Match parsing successful: Service=%s, Pattern=%s", match.Service, match.Pattern)) return match, nil } -// 解析softmatch指令获取软匹配规则 +// Parse softmatch directive to get soft match rule func (p *Probe) getSoftMatch(data string) (softMatch Match, err error) { - Common.LogDebug("开始解析softmatch指令:" + data) + Common.LogDebug("Starting to parse softmatch directive: " + data) softMatch = Match{IsSoft: true} - // 提取softmatch文本并解析指令语法 + // Extract softmatch text and parse directive syntax matchText := data[len("softmatch")+1:] directive := p.getDirectiveSyntax(matchText) - // 分割文本获取pattern和版本信息 + // Split text to get pattern and version info textSplited := strings.Split(directive.DirectiveStr, directive.Delimiter) if len(textSplited) == 0 { - return softMatch, fmt.Errorf("无效的softmatch指令格式") + return softMatch, fmt.Errorf("Invalid softmatch directive format") } pattern := textSplited[0] versionInfo := strings.Join(textSplited[1:], "") - // 解码并编译正则表达式 + // Decode and compile regular expression patternUnescaped, decodeErr := DecodePattern(pattern) if decodeErr != nil { - Common.LogDebug("解码pattern失败: " + decodeErr.Error()) + Common.LogDebug("Failed to decode pattern: " + decodeErr.Error()) return softMatch, decodeErr } patternUnescapedStr := string([]rune(string(patternUnescaped))) patternCompiled, compileErr := regexp.Compile(patternUnescapedStr) if compileErr != nil { - Common.LogDebug("编译正则表达式失败: " + compileErr.Error()) + Common.LogDebug("Failed to compile regular expression: " + compileErr.Error()) return softMatch, compileErr } - // 设置softMatch对象属性 + // Set softMatch object attributes softMatch.Service = directive.DirectiveName softMatch.Pattern = pattern softMatch.PatternCompiled = patternCompiled softMatch.VersionInfo = versionInfo - Common.LogDebug(fmt.Sprintf("解析softmatch成功: 服务=%s, Pattern=%s", + Common.LogDebug(fmt.Sprintf("Softmatch parsing successful: Service=%s, Pattern=%s", softMatch.Service, softMatch.Pattern)) return softMatch, nil } -// 解码模式字符串,处理转义序列 +// Decode pattern string, handle escape sequences func DecodePattern(s string) ([]byte, error) { - Common.LogDebug("开始解码pattern: " + s) + Common.LogDebug("Starting to decode pattern: " + s) sByteOrigin := []byte(s) - // 处理十六进制、八进制和结构化转义序列 + // Handle hexadecimal, octal, and structured escape sequences matchRe := regexp.MustCompile(`\\(x[0-9a-fA-F]{2}|[0-7]{1,3}|[aftnrv])`) sByteDec := matchRe.ReplaceAllFunc(sByteOrigin, func(match []byte) (v []byte) { var replace []byte - // 处理十六进制转义 + // Handle hexadecimal escape if isHexCode(match) { hexNum := match[2:] byteNum, _ := strconv.ParseInt(string(hexNum), 16, 32) @@ -514,20 +514,20 @@ func DecodePattern(s string) ([]byte, error) { } } - // 处理结构化转义字符 + // Handle structured escape characters if isStructCode(match) { structCodeMap := map[int][]byte{ - 97: []byte{0x07}, // \a 响铃 - 102: []byte{0x0c}, // \f 换页 - 116: []byte{0x09}, // \t 制表符 - 110: []byte{0x0a}, // \n 换行 - 114: []byte{0x0d}, // \r 回车 - 118: []byte{0x0b}, // \v 垂直制表符 + 97: []byte{0x07}, // \a bell + 102: []byte{0x0c}, // \f form feed + 116: []byte{0x09}, // \t tab + 110: []byte{0x0a}, // \n newline + 114: []byte{0x0d}, // \r carriage return + 118: []byte{0x0b}, // \v vertical tab } replace = structCodeMap[int(match[1])] } - // 处理八进制转义 + // Handle octal escape if isOctalCode(match) { octalNum := match[2:] byteNum, _ := strconv.ParseInt(string(octalNum), 8, 32) @@ -536,7 +536,7 @@ func DecodePattern(s string) ([]byte, error) { return replace }) - // 处理其他转义序列 + // Handle other escape sequences matchRe2 := regexp.MustCompile(`\\([^\\])`) sByteDec2 := matchRe2.ReplaceAllFunc(sByteDec, func(match []byte) (v []byte) { if isOtherEscapeCode(match) { @@ -545,57 +545,57 @@ func DecodePattern(s string) ([]byte, error) { return match }) - Common.LogDebug("pattern解码完成") + Common.LogDebug("Pattern decoding completed") return sByteDec2, nil } -// ProbesRarity 用于按稀有度排序的探测器切片 +// ProbesRarity is a slice of probes for sorting by rarity type ProbesRarity []Probe -// Len 返回切片长度,实现 sort.Interface 接口 +// Len returns slice length, implements sort.Interface func (ps ProbesRarity) Len() int { return len(ps) } -// Swap 交换切片中的两个元素,实现 sort.Interface 接口 +// Swap exchanges two elements in the slice, implements sort.Interface func (ps ProbesRarity) Swap(i, j int) { ps[i], ps[j] = ps[j], ps[i] } -// Less 比较函数,按稀有度升序排序,实现 sort.Interface 接口 +// Less comparison function, sorts by rarity in ascending order, implements sort.Interface func (ps ProbesRarity) Less(i, j int) bool { return ps[i].Rarity < ps[j].Rarity } -// Target 定义目标结构体 +// Target defines target structure type Target struct { - IP string // 目标IP地址 - Port int // 目标端口 - Protocol string // 协议类型 + IP string // Target IP address + Port int // Target port + Protocol string // Protocol type } -// ContainsPort 检查指定端口是否在探测器的端口范围内 +// ContainsPort checks if the specified port is within the probe's port range func (p *Probe) ContainsPort(testPort int) bool { - Common.LogDebug(fmt.Sprintf("检查端口 %d 是否在探测器端口范围内: %s", testPort, p.Ports)) + Common.LogDebug(fmt.Sprintf("Checking if port %d is within probe port range: %s", testPort, p.Ports)) - // 检查单个端口 + // Check individual ports ports := strings.Split(p.Ports, ",") for _, port := range ports { port = strings.TrimSpace(port) cmpPort, err := strconv.Atoi(port) if err == nil && testPort == cmpPort { - Common.LogDebug(fmt.Sprintf("端口 %d 匹配单个端口", testPort)) + Common.LogDebug(fmt.Sprintf("Port %d matches individual port", testPort)) return true } } - // 检查端口范围 + // Check port ranges for _, port := range ports { port = strings.TrimSpace(port) if strings.Contains(port, "-") { portRange := strings.Split(port, "-") if len(portRange) != 2 { - Common.LogDebug("无效的端口范围格式: " + port) + Common.LogDebug("Invalid port range format: " + port) continue } @@ -603,62 +603,62 @@ func (p *Probe) ContainsPort(testPort int) bool { end, err2 := strconv.Atoi(strings.TrimSpace(portRange[1])) if err1 != nil || err2 != nil { - Common.LogDebug(fmt.Sprintf("解析端口范围失败: %s", port)) + Common.LogDebug(fmt.Sprintf("Failed to parse port range: %s", port)) continue } if testPort >= start && testPort <= end { - Common.LogDebug(fmt.Sprintf("端口 %d 在范围 %d-%d 内", testPort, start, end)) + Common.LogDebug(fmt.Sprintf("Port %d is within range %d-%d", testPort, start, end)) return true } } } - Common.LogDebug(fmt.Sprintf("端口 %d 不在探测器端口范围内", testPort)) + Common.LogDebug(fmt.Sprintf("Port %d is not within probe port range", testPort)) return false } -// MatchPattern 使用正则表达式匹配响应内容 +// MatchPattern uses regular expression to match response content func (m *Match) MatchPattern(response []byte) bool { - // 将响应转换为字符串并进行匹配 + // Convert response to string and match responseStr := string([]rune(string(response))) foundItems := m.PatternCompiled.FindStringSubmatch(responseStr) if len(foundItems) > 0 { m.FoundItems = foundItems - Common.LogDebug(fmt.Sprintf("匹配成功,找到 %d 个匹配项", len(foundItems))) + Common.LogDebug(fmt.Sprintf("Match successful, found %d matching items", len(foundItems))) return true } return false } -// ParseVersionInfo 解析版本信息并返回额外信息结构 +// ParseVersionInfo parses version information and returns extra information structure func (m *Match) ParseVersionInfo(response []byte) Extras { - Common.LogDebug("开始解析版本信息") + Common.LogDebug("Starting to parse version information") var extras = Extras{} - // 替换版本信息中的占位符 - foundItems := m.FoundItems[1:] // 跳过第一个完整匹配项 + // Replace placeholders in version info + foundItems := m.FoundItems[1:] // Skip the first complete match item versionInfo := m.VersionInfo for index, value := range foundItems { dollarName := "$" + strconv.Itoa(index+1) versionInfo = strings.Replace(versionInfo, dollarName, value, -1) } - Common.LogDebug("替换后的版本信息: " + versionInfo) + Common.LogDebug("Version info after replacement: " + versionInfo) - // 定义解析函数 + // Define parsing function parseField := func(field, pattern string) string { patterns := []string{ - pattern + `/([^/]*)/`, // 斜线分隔 - pattern + `\|([^|]*)\|`, // 竖线分隔 + pattern + `/([^/]*)/`, // Slash delimiter + pattern + `\|([^|]*)\|`, // Pipe delimiter } for _, p := range patterns { if strings.Contains(versionInfo, pattern) { regex := regexp.MustCompile(p) if matches := regex.FindStringSubmatch(versionInfo); len(matches) > 1 { - Common.LogDebug(fmt.Sprintf("解析到%s: %s", field, matches[1])) + Common.LogDebug(fmt.Sprintf("Parsed %s: %s", field, matches[1])) return matches[1] } } @@ -666,15 +666,15 @@ func (m *Match) ParseVersionInfo(response []byte) Extras { return "" } - // 解析各个字段 - extras.VendorProduct = parseField("厂商产品", " p") - extras.Version = parseField("版本", " v") - extras.Info = parseField("信息", " i") - extras.Hostname = parseField("主机名", " h") - extras.OperatingSystem = parseField("操作系统", " o") - extras.DeviceType = parseField("设备类型", " d") + // Parse each field + extras.VendorProduct = parseField("vendor product", " p") + extras.Version = parseField("version", " v") + extras.Info = parseField("info", " i") + extras.Hostname = parseField("hostname", " h") + extras.OperatingSystem = parseField("operating system", " o") + extras.DeviceType = parseField("device type", " d") - // 特殊处理CPE + // Special handling for CPE if strings.Contains(versionInfo, " cpe:/") || strings.Contains(versionInfo, " cpe:|") { cpePatterns := []string{`cpe:/([^/]*)`, `cpe:\|([^|]*)`} for _, pattern := range cpePatterns { @@ -685,7 +685,7 @@ func (m *Match) ParseVersionInfo(response []byte) Extras { } else { extras.CPE = cpeName[0] } - Common.LogDebug("解析到CPE: " + extras.CPE) + Common.LogDebug("Parsed CPE: " + extras.CPE) break } } @@ -694,12 +694,12 @@ func (m *Match) ParseVersionInfo(response []byte) Extras { return extras } -// ToMap 将 Extras 转换为 map[string]string +// ToMap converts Extras to map[string]string func (e *Extras) ToMap() map[string]string { - Common.LogDebug("开始转换Extras为Map") + Common.LogDebug("Starting to convert Extras to Map") result := make(map[string]string) - // 定义字段映射 + // Define field mapping fields := map[string]string{ "vendor_product": e.VendorProduct, "version": e.Version, @@ -710,31 +710,31 @@ func (e *Extras) ToMap() map[string]string { "cpe": e.CPE, } - // 添加非空字段到结果map + // Add non-empty fields to result map for key, value := range fields { if value != "" { result[key] = value - Common.LogDebug(fmt.Sprintf("添加字段 %s: %s", key, value)) + Common.LogDebug(fmt.Sprintf("Added field %s: %s", key, value)) } } - Common.LogDebug(fmt.Sprintf("转换完成,共有 %d 个字段", len(result))) + Common.LogDebug(fmt.Sprintf("Conversion completed, total %d fields", len(result))) return result } func DecodeData(s string) ([]byte, error) { if len(s) == 0 { - Common.LogDebug("输入数据为空") + Common.LogDebug("Input data is empty") return nil, fmt.Errorf("empty input") } - Common.LogDebug(fmt.Sprintf("开始解码数据,长度: %d, 内容: %q", len(s), s)) + Common.LogDebug(fmt.Sprintf("Starting to decode data, length: %d, content: %q", len(s), s)) sByteOrigin := []byte(s) - // 处理十六进制、八进制和结构化转义序列 + // Handle hexadecimal, octal, and structured escape sequences matchRe := regexp.MustCompile(`\\(x[0-9a-fA-F]{2}|[0-7]{1,3}|[aftnrv])`) sByteDec := matchRe.ReplaceAllFunc(sByteOrigin, func(match []byte) []byte { - // 处理十六进制转义 + // Handle hexadecimal escape if isHexCode(match) { hexNum := match[2:] byteNum, err := strconv.ParseInt(string(hexNum), 16, 32) @@ -744,15 +744,15 @@ func DecodeData(s string) ([]byte, error) { return []byte{uint8(byteNum)} } - // 处理结构化转义字符 + // Handle structured escape characters if isStructCode(match) { structCodeMap := map[int][]byte{ - 97: []byte{0x07}, // \a 响铃 - 102: []byte{0x0c}, // \f 换页 - 116: []byte{0x09}, // \t 制表符 - 110: []byte{0x0a}, // \n 换行 - 114: []byte{0x0d}, // \r 回车 - 118: []byte{0x0b}, // \v 垂直制表符 + 97: []byte{0x07}, // \a bell + 102: []byte{0x0c}, // \f form feed + 116: []byte{0x09}, // \t tab + 110: []byte{0x0a}, // \n newline + 114: []byte{0x0d}, // \r carriage return + 118: []byte{0x0b}, // \v vertical tab } if replace, ok := structCodeMap[int(match[1])]; ok { return replace @@ -760,7 +760,7 @@ func DecodeData(s string) ([]byte, error) { return match } - // 处理八进制转义 + // Handle octal escape if isOctalCode(match) { octalNum := match[2:] byteNum, err := strconv.ParseInt(string(octalNum), 8, 32) @@ -770,11 +770,11 @@ func DecodeData(s string) ([]byte, error) { return []byte{uint8(byteNum)} } - Common.LogDebug(fmt.Sprintf("无法识别的转义序列: %s", string(match))) + Common.LogDebug(fmt.Sprintf("Unrecognized escape sequence: %s", string(match))) return match }) - // 处理其他转义序列 + // Handle other escape sequences matchRe2 := regexp.MustCompile(`\\([^\\])`) sByteDec2 := matchRe2.ReplaceAllFunc(sByteDec, func(match []byte) []byte { if len(match) < 2 { @@ -787,39 +787,39 @@ func DecodeData(s string) ([]byte, error) { }) if len(sByteDec2) == 0 { - Common.LogDebug("解码后数据为空") + Common.LogDebug("Decoded data is empty") return nil, fmt.Errorf("decoded data is empty") } - Common.LogDebug(fmt.Sprintf("解码完成,结果长度: %d, 内容: %x", len(sByteDec2), sByteDec2)) + Common.LogDebug(fmt.Sprintf("Decoding completed, result length: %d, content: %x", len(sByteDec2), sByteDec2)) return sByteDec2, nil } -// GetAddress 获取目标的完整地址(IP:端口) +// GetAddress gets the target's full address (IP:port) func (t *Target) GetAddress() string { addr := t.IP + ":" + strconv.Itoa(t.Port) - Common.LogDebug("获取目标地址: " + addr) + Common.LogDebug("Getting target address: " + addr) return addr } -// trimBanner 处理和清理横幅数据 +// trimBanner processes and cleans banner data func trimBanner(buf []byte) string { - Common.LogDebug("开始处理横幅数据") + Common.LogDebug("Starting to process banner data") bufStr := string(buf) - // 特殊处理SMB协议 + // Special handling for SMB protocol if strings.Contains(bufStr, "SMB") { banner := hex.EncodeToString(buf) if len(banner) > 0xa+6 && banner[0xa:0xa+6] == "534d42" { // "SMB" in hex - Common.LogDebug("检测到SMB协议数据") + Common.LogDebug("Detected SMB protocol data") plain := banner[0xa2:] data, err := hex.DecodeString(plain) if err != nil { - Common.LogDebug("SMB数据解码失败: " + err.Error()) + Common.LogDebug("Failed to decode SMB data: " + err.Error()) return bufStr } - // 解析domain + // Parse domain var domain string var index int for i, s := range data { @@ -831,7 +831,7 @@ func trimBanner(buf []byte) string { } } - // 解析hostname + // Parse hostname var hostname string remainData := data[index:] for i, h := range remainData { @@ -844,12 +844,12 @@ func trimBanner(buf []byte) string { } smbBanner := fmt.Sprintf("hostname: %s domain: %s", hostname, domain) - Common.LogDebug("SMB横幅: " + smbBanner) + Common.LogDebug("SMB banner: " + smbBanner) return smbBanner } } - // 处理常规数据 + // Process regular data var src string for _, ch := range bufStr { if ch > 32 && ch < 125 { @@ -859,19 +859,19 @@ func trimBanner(buf []byte) string { } } - // 清理多余空白 + // Clean up extra whitespace re := regexp.MustCompile(`\s{2,}`) src = re.ReplaceAllString(src, ".") result := strings.TrimSpace(src) - Common.LogDebug("处理后的横幅: " + result) + Common.LogDebug("Processed banner: " + result) return result } -// Init 初始化VScan对象 +// Init initializes the VScan object func (v *VScan) Init() { - Common.LogDebug("开始初始化VScan") + Common.LogDebug("Starting to initialize VScan") v.parseProbesFromContent(ProbeString) v.parseProbesToMapKName() v.SetusedProbes() - Common.LogDebug("VScan初始化完成") + Common.LogDebug("VScan initialization completed") } diff --git a/Core/PortInfo.go b/Core/PortInfo.go index bec4e86..6942be4 100644 --- a/Core/PortInfo.go +++ b/Core/PortInfo.go @@ -9,54 +9,54 @@ import ( "time" ) -// ServiceInfo 定义服务识别的结果信息 +// ServiceInfo defines the service identification result information type ServiceInfo struct { - Name string // 服务名称,如 http、ssh 等 - Banner string // 服务返回的横幅信息 - Version string // 服务版本号 - Extras map[string]string // 其他额外信息,如操作系统、产品名等 + Name string // Service name, such as http, ssh, etc. + Banner string // Banner information returned by the service + Version string // Service version number + Extras map[string]string // Other additional information, such as operating system, product name, etc. } -// Result 定义单次探测的结果 +// Result defines the result of a single detection type Result struct { - Service Service // 识别出的服务信息 - Banner string // 服务横幅 - Extras map[string]string // 额外信息 - Send []byte // 发送的探测数据 - Recv []byte // 接收到的响应数据 + Service Service // Identified service information + Banner string // Service banner + Extras map[string]string // Additional information + Send []byte // Probe data sent + Recv []byte // Response data received } -// Service 定义服务的基本信息 +// Service defines the basic information of a service type Service struct { - Name string // 服务名称 - Extras map[string]string // 服务的额外属性 + Name string // Service name + Extras map[string]string // Additional service attributes } -// Info 定义单个端口探测的上下文信息 +// Info defines the context information for a single port probe type Info struct { - Address string // 目标IP地址 - Port int // 目标端口 - Conn net.Conn // 网络连接 - Result Result // 探测结果 - Found bool // 是否成功识别服务 + Address string // Target IP address + Port int // Target port + Conn net.Conn // Network connection + Result Result // Detection result + Found bool // Whether the service was successfully identified } -// PortInfoScanner 定义端口服务识别器 +// PortInfoScanner defines a port service identifier type PortInfoScanner struct { - Address string // 目标IP地址 - Port int // 目标端口 - Conn net.Conn // 网络连接 - Timeout time.Duration // 超时时间 - info *Info // 探测上下文 + Address string // Target IP address + Port int // Target port + Conn net.Conn // Network connection + Timeout time.Duration // Timeout duration + info *Info // Detection context } -// 预定义的基础探测器 +// Predefined basic probes var ( - null = new(Probe) // 空探测器,用于基本协议识别 - common = new(Probe) // 通用探测器,用于常见服务识别 + null = new(Probe) // Empty probe, used for basic protocol identification + common = new(Probe) // Common probe, used for common service identification ) -// NewPortInfoScanner 创建新的端口服务识别器实例 +// NewPortInfoScanner creates a new port service identifier instance func NewPortInfoScanner(addr string, port int, conn net.Conn, timeout time.Duration) *PortInfoScanner { return &PortInfoScanner{ Address: addr, @@ -74,12 +74,12 @@ func NewPortInfoScanner(addr string, port int, conn net.Conn, timeout time.Durat } } -// Identify 执行服务识别,返回识别结果 +// Identify performs service identification and returns the result func (s *PortInfoScanner) Identify() (*ServiceInfo, error) { - Common.LogDebug(fmt.Sprintf("开始识别服务 %s:%d", s.Address, s.Port)) + Common.LogDebug(fmt.Sprintf("Starting to identify service %s:%d", s.Address, s.Port)) s.info.PortInfo() - // 构造返回结果 + // Construct the return result serviceInfo := &ServiceInfo{ Name: s.info.Result.Service.Name, Banner: s.info.Result.Banner, @@ -87,104 +87,104 @@ func (s *PortInfoScanner) Identify() (*ServiceInfo, error) { Extras: make(map[string]string), } - // 复制额外信息 + // Copy additional information for k, v := range s.info.Result.Service.Extras { serviceInfo.Extras[k] = v } - Common.LogDebug(fmt.Sprintf("服务识别完成 %s:%d => %s", s.Address, s.Port, serviceInfo.Name)) + Common.LogDebug(fmt.Sprintf("Service identification completed %s:%d => %s", s.Address, s.Port, serviceInfo.Name)) return serviceInfo, nil } -// PortInfo 执行端口服务识别的主要逻辑 +// PortInfo executes the main logic of port service identification func (i *Info) PortInfo() { - // 1. 首先尝试读取服务的初始响应 + // 1. First try to read the initial response from the service if response, err := i.Read(); err == nil && len(response) > 0 { - Common.LogDebug(fmt.Sprintf("收到初始响应: %d 字节", len(response))) + Common.LogDebug(fmt.Sprintf("Received initial response: %d bytes", len(response))) - // 使用基础探测器检查响应 - Common.LogDebug("尝试使用基础探测器(null/common)检查响应") + // Check the response using basic probes + Common.LogDebug("Attempting to check response using basic probes (null/common)") if i.tryProbes(response, []*Probe{null, common}) { - Common.LogDebug("基础探测器匹配成功") + Common.LogDebug("Basic probe matching successful") return } - Common.LogDebug("基础探测器未匹配") + Common.LogDebug("Basic probes did not match") } else if err != nil { - Common.LogDebug(fmt.Sprintf("读取初始响应失败: %v", err)) + Common.LogDebug(fmt.Sprintf("Failed to read initial response: %v", err)) } - // 记录已使用的探测器,避免重复使用 + // Record used probes to avoid duplication usedProbes := make(map[string]struct{}) - // 2. 尝试使用端口专用探测器 - Common.LogDebug(fmt.Sprintf("尝试使用端口 %d 的专用探测器", i.Port)) + // 2. Try to use port-specific probes + Common.LogDebug(fmt.Sprintf("Attempting to use dedicated probes for port %d", i.Port)) if i.processPortMapProbes(usedProbes) { - Common.LogDebug("端口专用探测器匹配成功") + Common.LogDebug("Port-specific probe matching successful") return } - Common.LogDebug("端口专用探测器未匹配") + Common.LogDebug("Port-specific probes did not match") - // 3. 使用默认探测器列表 - Common.LogDebug("尝试使用默认探测器列表") + // 3. Use the default probe list + Common.LogDebug("Attempting to use default probe list") if i.processDefaultProbes(usedProbes) { - Common.LogDebug("默认探测器匹配成功") + Common.LogDebug("Default probe matching successful") return } - Common.LogDebug("默认探测器未匹配") + Common.LogDebug("Default probes did not match") - // 4. 如果所有探测都失败,标记为未知服务 + // 4. If all probes fail, mark as unknown service if strings.TrimSpace(i.Result.Service.Name) == "" { - Common.LogDebug("未识别出服务,标记为 unknown") + Common.LogDebug("Service not recognized, marking as unknown") i.Result.Service.Name = "unknown" } } -// tryProbes 尝试使用指定的探测器列表检查响应 +// tryProbes attempts to use the specified probe list to check the response func (i *Info) tryProbes(response []byte, probes []*Probe) bool { for _, probe := range probes { - Common.LogDebug(fmt.Sprintf("尝试探测器: %s", probe.Name)) + Common.LogDebug(fmt.Sprintf("Attempting probe: %s", probe.Name)) i.GetInfo(response, probe) if i.Found { - Common.LogDebug(fmt.Sprintf("探测器 %s 匹配成功", probe.Name)) + Common.LogDebug(fmt.Sprintf("Probe %s matched successfully", probe.Name)) return true } } return false } -// processPortMapProbes 处理端口映射中的专用探测器 +// processPortMapProbes processes dedicated probes in the port mapping func (i *Info) processPortMapProbes(usedProbes map[string]struct{}) bool { - // 检查是否存在端口专用探测器 + // Check if port-specific probes exist if len(Common.PortMap[i.Port]) == 0 { - Common.LogDebug(fmt.Sprintf("端口 %d 没有专用探测器", i.Port)) + Common.LogDebug(fmt.Sprintf("Port %d has no dedicated probes", i.Port)) return false } - // 遍历端口专用探测器 + // Iterate through port-specific probes for _, name := range Common.PortMap[i.Port] { - Common.LogDebug(fmt.Sprintf("尝试端口专用探测器: %s", name)) + Common.LogDebug(fmt.Sprintf("Attempting port-specific probe: %s", name)) usedProbes[name] = struct{}{} probe := v.ProbesMapKName[name] - // 解码探测数据 + // Decode probe data probeData, err := DecodeData(probe.Data) if err != nil || len(probeData) == 0 { - Common.LogDebug(fmt.Sprintf("探测器 %s 数据解码失败", name)) + Common.LogDebug(fmt.Sprintf("Failed to decode probe data for %s", name)) continue } - // 发送探测数据并获取响应 - Common.LogDebug(fmt.Sprintf("发送探测数据: %d 字节", len(probeData))) + // Send probe data and get response + Common.LogDebug(fmt.Sprintf("Sending probe data: %d bytes", len(probeData))) if response := i.Connect(probeData); len(response) > 0 { - Common.LogDebug(fmt.Sprintf("收到响应: %d 字节", len(response))) + Common.LogDebug(fmt.Sprintf("Received response: %d bytes", len(response))) - // 使用当前探测器检查响应 + // Check response with current probe i.GetInfo(response, &probe) if i.Found { return true } - // 根据探测器类型进行额外检查 + // Perform additional checks based on probe type switch name { case "GenericLines": if i.tryProbes(response, []*Probe{null}) { @@ -202,14 +202,14 @@ func (i *Info) processPortMapProbes(usedProbes map[string]struct{}) bool { return false } -// processDefaultProbes 处理默认探测器列表 +// processDefaultProbes processes the default probe list func (i *Info) processDefaultProbes(usedProbes map[string]struct{}) bool { failCount := 0 - const maxFailures = 10 // 最大失败次数 + const maxFailures = 10 // Maximum failure count - // 遍历默认探测器列表 + // Iterate through the default probe list for _, name := range Common.DefaultMap { - // 跳过已使用的探测器 + // Skip already used probes if _, used := usedProbes[name]; used { continue } @@ -220,7 +220,7 @@ func (i *Info) processDefaultProbes(usedProbes map[string]struct{}) bool { continue } - // 发送探测数据并获取响应 + // Send probe data and get response response := i.Connect(probeData) if len(response) == 0 { failCount++ @@ -230,13 +230,13 @@ func (i *Info) processDefaultProbes(usedProbes map[string]struct{}) bool { continue } - // 使用当前探测器检查响应 + // Check response with current probe i.GetInfo(response, &probe) if i.Found { return true } - // 根据探测器类型进行额外检查 + // Perform additional checks based on probe type switch name { case "GenericLines": if i.tryProbes(response, []*Probe{null}) { @@ -250,7 +250,7 @@ func (i *Info) processDefaultProbes(usedProbes map[string]struct{}) bool { } } - // 尝试使用端口映射中的其他探测器 + // Try to use other probes in the port mapping if len(Common.PortMap[i.Port]) > 0 { for _, mappedName := range Common.PortMap[i.Port] { usedProbes[mappedName] = struct{}{} @@ -265,13 +265,13 @@ func (i *Info) processDefaultProbes(usedProbes map[string]struct{}) bool { return false } -// GetInfo 分析响应数据并提取服务信息 +// GetInfo analyzes response data and extracts service information func (i *Info) GetInfo(response []byte, probe *Probe) { - Common.LogDebug(fmt.Sprintf("开始分析响应数据,长度: %d", len(response))) + Common.LogDebug(fmt.Sprintf("Starting to analyze response data, length: %d", len(response))) - // 响应数据有效性检查 + // Check response data validity if len(response) <= 0 { - Common.LogDebug("响应数据为空") + Common.LogDebug("Response data is empty") return } @@ -281,42 +281,42 @@ func (i *Info) GetInfo(response []byte, probe *Probe) { softFound bool ) - // 处理主要匹配规则 - Common.LogDebug(fmt.Sprintf("处理探测器 %s 的主要匹配规则", probe.Name)) + // Process main matching rules + Common.LogDebug(fmt.Sprintf("Processing main matching rules for probe %s", probe.Name)) if matched, match := i.processMatches(response, probe.Matchs); matched { - Common.LogDebug("找到硬匹配") + Common.LogDebug("Hard match found") return } else if match != nil { - Common.LogDebug("找到软匹配") + Common.LogDebug("Soft match found") softFound = true softMatch = *match } - // 处理回退匹配规则 + // Process fallback matching rules if probe.Fallback != "" { - Common.LogDebug(fmt.Sprintf("尝试回退匹配: %s", probe.Fallback)) + Common.LogDebug(fmt.Sprintf("Attempting fallback match: %s", probe.Fallback)) if fbProbe, ok := v.ProbesMapKName[probe.Fallback]; ok { if matched, match := i.processMatches(response, fbProbe.Matchs); matched { - Common.LogDebug("回退匹配成功") + Common.LogDebug("Fallback match successful") return } else if match != nil { - Common.LogDebug("找到回退软匹配") + Common.LogDebug("Fallback soft match found") softFound = true softMatch = *match } } } - // 处理未找到匹配的情况 + // Handle case when no match is found if !i.Found { - Common.LogDebug("未找到硬匹配,处理未匹配情况") + Common.LogDebug("No hard match found, handling no match case") i.handleNoMatch(response, result, softFound, softMatch) } } -// processMatches 处理匹配规则集 +// processMatches processes the set of matching rules func (i *Info) processMatches(response []byte, matches *[]Match) (bool, *Match) { - Common.LogDebug(fmt.Sprintf("开始处理匹配规则,共 %d 条", len(*matches))) + Common.LogDebug(fmt.Sprintf("Starting to process matching rules, total %d rules", len(*matches))) var softMatch *Match for _, match := range *matches { @@ -325,11 +325,11 @@ func (i *Info) processMatches(response []byte, matches *[]Match) (bool, *Match) } if !match.IsSoft { - Common.LogDebug(fmt.Sprintf("找到硬匹配: %s", match.Service)) + Common.LogDebug(fmt.Sprintf("Hard match found: %s", match.Service)) i.handleHardMatch(response, &match) return true, nil } else if softMatch == nil { - Common.LogDebug(fmt.Sprintf("找到软匹配: %s", match.Service)) + Common.LogDebug(fmt.Sprintf("Soft match found: %s", match.Service)) tmpMatch := match softMatch = &tmpMatch } @@ -338,9 +338,9 @@ func (i *Info) processMatches(response []byte, matches *[]Match) (bool, *Match) return false, softMatch } -// handleHardMatch 处理硬匹配结果 +// handleHardMatch handles hard match results func (i *Info) handleHardMatch(response []byte, match *Match) { - Common.LogDebug(fmt.Sprintf("处理硬匹配结果: %s", match.Service)) + Common.LogDebug(fmt.Sprintf("Processing hard match result: %s", match.Service)) result := &i.Result extras := match.ParseVersionInfo(response) extrasMap := extras.ToMap() @@ -350,64 +350,64 @@ func (i *Info) handleHardMatch(response []byte, match *Match) { result.Banner = trimBanner(response) result.Service.Extras = extrasMap - // 特殊处理 microsoft-ds 服务 + // Special handling for microsoft-ds service if result.Service.Name == "microsoft-ds" { - Common.LogDebug("特殊处理 microsoft-ds 服务") + Common.LogDebug("Special handling for microsoft-ds service") result.Service.Extras["hostname"] = result.Banner } i.Found = true - Common.LogDebug(fmt.Sprintf("服务识别结果: %s, Banner: %s", result.Service.Name, result.Banner)) + Common.LogDebug(fmt.Sprintf("Service identification result: %s, Banner: %s", result.Service.Name, result.Banner)) } -// handleNoMatch 处理未找到匹配的情况 +// handleNoMatch handles the case when no match is found func (i *Info) handleNoMatch(response []byte, result *Result, softFound bool, softMatch Match) { - Common.LogDebug("处理未匹配情况") + Common.LogDebug("Handling no match case") result.Banner = trimBanner(response) if !softFound { - // 尝试识别 HTTP 服务 + // Try to identify HTTP service if strings.Contains(result.Banner, "HTTP/") || strings.Contains(result.Banner, "html") { - Common.LogDebug("识别为HTTP服务") + Common.LogDebug("Identified as HTTP service") result.Service.Name = "http" } else { - Common.LogDebug("未知服务") + Common.LogDebug("Unknown service") result.Service.Name = "unknown" } } else { - Common.LogDebug("使用软匹配结果") + Common.LogDebug("Using soft match result") extras := softMatch.ParseVersionInfo(response) result.Service.Extras = extras.ToMap() result.Service.Name = softMatch.Service i.Found = true - Common.LogDebug(fmt.Sprintf("软匹配服务: %s", result.Service.Name)) + Common.LogDebug(fmt.Sprintf("Soft match service: %s", result.Service.Name)) } } -// Connect 发送数据并获取响应 +// Connect sends data and gets response func (i *Info) Connect(msg []byte) []byte { i.Write(msg) reply, _ := i.Read() return reply } -const WrTimeout = 5 // 默认读写超时时间(秒) +const WrTimeout = 5 // Default read/write timeout (seconds) -// Write 写入数据到连接 +// Write writes data to the connection func (i *Info) Write(msg []byte) error { if i.Conn == nil { return nil } - // 设置写入超时 + // Set write timeout i.Conn.SetWriteDeadline(time.Now().Add(time.Second * time.Duration(WrTimeout))) - // 写入数据 + // Write data _, err := i.Conn.Write(msg) if err != nil && strings.Contains(err.Error(), "close") { i.Conn.Close() - // 连接关闭时重试 + // Retry when connection is closed i.Conn, err = net.DialTimeout("tcp4", fmt.Sprintf("%s:%d", i.Address, i.Port), time.Duration(6)*time.Second) if err == nil { i.Conn.SetWriteDeadline(time.Now().Add(time.Second * time.Duration(WrTimeout))) @@ -415,7 +415,7 @@ func (i *Info) Write(msg []byte) error { } } - // 记录发送的数据 + // Record sent data if err == nil { i.Result.Send = msg } @@ -423,22 +423,22 @@ func (i *Info) Write(msg []byte) error { return err } -// Read 从连接读取响应 +// Read reads response from the connection func (i *Info) Read() ([]byte, error) { if i.Conn == nil { return nil, nil } - // 设置读取超时 + // Set read timeout i.Conn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(WrTimeout))) - // 读取数据 + // Read data result, err := readFromConn(i.Conn) if err != nil && strings.Contains(err.Error(), "close") { return result, err } - // 记录接收到的数据 + // Record received data if len(result) > 0 { i.Result.Recv = result } @@ -446,9 +446,9 @@ func (i *Info) Read() ([]byte, error) { return result, err } -// readFromConn 从连接读取数据的辅助函数 +// readFromConn helper function to read data from connection func readFromConn(conn net.Conn) ([]byte, error) { - size := 2 * 1024 // 读取缓冲区大小 + size := 2 * 1024 // Read buffer size var result []byte for { @@ -473,4 +473,4 @@ func readFromConn(conn net.Conn) ([]byte, error) { return result, nil } } -} +} \ No newline at end of file diff --git a/Core/PortScan.go b/Core/PortScan.go index eb048f3..747fe6e 100644 --- a/Core/PortScan.go +++ b/Core/PortScan.go @@ -10,47 +10,47 @@ import ( "time" ) -// Addr 表示待扫描的地址 +// Addr represents the address to be scanned type Addr struct { - ip string // IP地址 - port int // 端口号 + ip string // IP address + port int // Port number } -// ScanResult 扫描结果 +// ScanResult scanning result type ScanResult struct { - Address string // IP地址 - Port int // 端口号 - Service *ServiceInfo // 服务信息 + Address string // IP address + Port int // Port number + Service *ServiceInfo // Service information } -// PortScan 执行端口扫描 -// hostslist: 待扫描的主机列表 -// ports: 待扫描的端口范围 -// timeout: 超时时间(秒) -// 返回活跃地址列表 +// PortScan executes port scanning +// hostslist: List of hosts to be scanned +// ports: Port range to be scanned +// timeout: Timeout in seconds +// Returns list of active addresses func PortScan(hostslist []string, ports string, timeout int64) []string { var results []ScanResult var aliveAddrs []string var mu sync.Mutex - // 解析并验证端口列表 + // Parse and validate port list probePorts := Common.ParsePort(ports) if len(probePorts) == 0 { - Common.LogError(fmt.Sprintf("端口格式错误: %s", ports)) + Common.LogError(fmt.Sprintf("Invalid port format: %s", ports)) return aliveAddrs } - // 排除指定端口 + // Exclude specified ports probePorts = excludeNoPorts(probePorts) - // 初始化并发控制 + // Initialize concurrency control workers := Common.ThreadNum - addrs := make(chan Addr, 100) // 待扫描地址通道 - scanResults := make(chan ScanResult, 100) // 扫描结果通道 + addrs := make(chan Addr, 100) // Channel for addresses to be scanned + scanResults := make(chan ScanResult, 100) // Channel for scan results var wg sync.WaitGroup var workerWg sync.WaitGroup - // 启动扫描工作协程 + // Start scanning worker goroutines for i := 0; i < workers; i++ { workerWg.Add(1) go func() { @@ -61,7 +61,7 @@ func PortScan(hostslist []string, ports string, timeout int64) []string { }() } - // 启动结果处理协程 + // Start result processing goroutine var resultWg sync.WaitGroup resultWg.Add(1) go func() { @@ -75,7 +75,7 @@ func PortScan(hostslist []string, ports string, timeout int64) []string { } }() - // 分发扫描任务 + // Distribute scanning tasks for _, port := range probePorts { for _, host := range hostslist { wg.Add(1) @@ -83,7 +83,7 @@ func PortScan(hostslist []string, ports string, timeout int64) []string { } } - // 等待所有任务完成 + // Wait for all tasks to complete close(addrs) workerWg.Wait() wg.Wait() @@ -93,11 +93,11 @@ func PortScan(hostslist []string, ports string, timeout int64) []string { return aliveAddrs } -// PortConnect 执行单个端口连接检测 -// addr: 待检测的地址 -// results: 结果通道 -// timeout: 超时时间 -// wg: 等待组 +// PortConnect performs connection detection for a single port +// addr: Address to be detected +// results: Results channel +// timeout: Timeout duration +// wg: Wait group func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.WaitGroup) { defer wg.Done() @@ -105,7 +105,7 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W var err error var conn net.Conn - // 尝试建立TCP连接 + // Try to establish TCP connection conn, err = Common.WrapperTcpWithTimeout("tcp4", fmt.Sprintf("%s:%v", addr.ip, addr.port), time.Duration(timeout)*time.Second) @@ -118,11 +118,11 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W return } - // 记录开放端口 + // Record open port address := fmt.Sprintf("%s:%d", addr.ip, addr.port) - Common.LogSuccess(fmt.Sprintf("端口开放 %s", address)) + Common.LogSuccess(fmt.Sprintf("Port open %s", address)) - // 保存端口扫描结果 + // Save port scan result portResult := &Common.ScanResult{ Time: time.Now(), Type: Common.PORT, @@ -134,66 +134,66 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W } Common.SaveResult(portResult) - // 构造扫描结果 + // Construct scan result result := ScanResult{ Address: addr.ip, Port: addr.port, } - // 执行服务识别 + // Perform service identification if !Common.SkipFingerprint && conn != nil { scanner := NewPortInfoScanner(addr.ip, addr.port, conn, time.Duration(timeout)*time.Second) if serviceInfo, err := scanner.Identify(); err == nil { result.Service = serviceInfo - // 构造服务识别日志 + // Construct service identification log var logMsg strings.Builder - logMsg.WriteString(fmt.Sprintf("服务识别 %s => ", address)) + logMsg.WriteString(fmt.Sprintf("Service identification %s => ", address)) if serviceInfo.Name != "unknown" { logMsg.WriteString(fmt.Sprintf("[%s]", serviceInfo.Name)) } if serviceInfo.Version != "" { - logMsg.WriteString(fmt.Sprintf(" 版本:%s", serviceInfo.Version)) + logMsg.WriteString(fmt.Sprintf(" Version:%s", serviceInfo.Version)) } - // 收集服务详细信息 + // Collect service details details := map[string]interface{}{ "port": addr.port, "service": serviceInfo.Name, } - // 添加版本信息 + // Add version information if serviceInfo.Version != "" { details["version"] = serviceInfo.Version } - // 添加产品信息 + // Add product information if v, ok := serviceInfo.Extras["vendor_product"]; ok && v != "" { details["product"] = v - logMsg.WriteString(fmt.Sprintf(" 产品:%s", v)) + logMsg.WriteString(fmt.Sprintf(" Product:%s", v)) } - // 添加操作系统信息 + // Add operating system information if v, ok := serviceInfo.Extras["os"]; ok && v != "" { details["os"] = v - logMsg.WriteString(fmt.Sprintf(" 系统:%s", v)) + logMsg.WriteString(fmt.Sprintf(" OS:%s", v)) } - // 添加额外信息 + // Add additional information if v, ok := serviceInfo.Extras["info"]; ok && v != "" { details["info"] = v - logMsg.WriteString(fmt.Sprintf(" 信息:%s", v)) + logMsg.WriteString(fmt.Sprintf(" Info:%s", v)) } - // 添加Banner信息 + // Add Banner information if len(serviceInfo.Banner) > 0 && len(serviceInfo.Banner) < 100 { details["banner"] = strings.TrimSpace(serviceInfo.Banner) logMsg.WriteString(fmt.Sprintf(" Banner:[%s]", strings.TrimSpace(serviceInfo.Banner))) } - // 保存服务识别结果 + // Save service identification result serviceResult := &Common.ScanResult{ Time: time.Now(), Type: Common.SERVICE, @@ -210,17 +210,17 @@ func PortConnect(addr Addr, results chan<- ScanResult, timeout int64, wg *sync.W results <- result } -// NoPortScan 生成端口列表(不进行扫描) -// hostslist: 主机列表 -// ports: 端口范围 -// 返回地址列表 +// NoPortScan generates a port list (without scanning) +// hostslist: Host list +// ports: Port range +// Returns address list func NoPortScan(hostslist []string, ports string) []string { var AliveAddress []string - // 解析并排除端口 + // Parse and exclude ports probePorts := excludeNoPorts(Common.ParsePort(ports)) - // 生成地址列表 + // Generate address list for _, port := range probePorts { for _, host := range hostslist { address := fmt.Sprintf("%s:%d", host, port) @@ -231,27 +231,27 @@ func NoPortScan(hostslist []string, ports string) []string { return AliveAddress } -// excludeNoPorts 排除指定的端口 -// ports: 原始端口列表 -// 返回过滤后的端口列表 +// excludeNoPorts excludes specified ports +// ports: Original port list +// Returns filtered port list func excludeNoPorts(ports []int) []int { noPorts := Common.ParsePort(Common.ExcludePorts) if len(noPorts) == 0 { return ports } - // 使用map过滤端口 + // Use map to filter ports temp := make(map[int]struct{}) for _, port := range ports { temp[port] = struct{}{} } - // 移除需要排除的端口 + // Remove ports to be excluded for _, port := range noPorts { delete(temp, port) } - // 转换为有序切片 + // Convert to ordered slice var newPorts []int for port := range temp { newPorts = append(newPorts, port) @@ -259,4 +259,4 @@ func excludeNoPorts(ports []int) []int { sort.Ints(newPorts) return newPorts -} +} \ No newline at end of file diff --git a/Core/Registry.go b/Core/Registry.go index 44fc693..2c1a912 100644 --- a/Core/Registry.go +++ b/Core/Registry.go @@ -5,11 +5,11 @@ import ( "github.com/shadow1ng/fscan/Plugins" ) -// init 初始化并注册所有扫描插件 -// 包括标准端口服务扫描、特殊扫描类型和本地信息收集等 +// init initializes and registers all scan plugins +// including standard port service scans, special scan types, and local information collection func init() { - // 1. 标准网络服务扫描插件 - // 文件传输和远程访问服务 + // 1. Standard network service scan plugins + // File transfer and remote access services Common.RegisterPlugin("ftp", Common.ScanPlugin{ Name: "FTP", Ports: []int{21}, @@ -28,7 +28,7 @@ func init() { ScanFunc: Plugins.TelnetScan, }) - // Windows网络服务 + // Windows network services Common.RegisterPlugin("findnet", Common.ScanPlugin{ Name: "FindNet", Ports: []int{135}, @@ -47,7 +47,7 @@ func init() { ScanFunc: Plugins.SmbScan, }) - // 数据库服务 + // Database services Common.RegisterPlugin("mssql", Common.ScanPlugin{ Name: "MSSQL", Ports: []int{1433, 1434}, @@ -66,7 +66,7 @@ func init() { ScanFunc: Plugins.MysqlScan, }) - // 中间件和消息队列服务 + // Middleware and message queue services Common.RegisterPlugin("elasticsearch", Common.ScanPlugin{ Name: "Elasticsearch", Ports: []int{9200, 9300}, @@ -91,14 +91,14 @@ func init() { ScanFunc: Plugins.ActiveMQScan, }) - // 目录和认证服务 + // Directory and authentication services Common.RegisterPlugin("ldap", Common.ScanPlugin{ Name: "LDAP", Ports: []int{389, 636}, ScanFunc: Plugins.LDAPScan, }) - // 邮件服务 + // Mail services Common.RegisterPlugin("smtp", Common.ScanPlugin{ Name: "SMTP", Ports: []int{25, 465, 587}, @@ -117,7 +117,7 @@ func init() { ScanFunc: Plugins.POP3Scan, }) - // 网络管理和监控服务 + // Network management and monitoring services Common.RegisterPlugin("snmp", Common.ScanPlugin{ Name: "SNMP", Ports: []int{161, 162}, @@ -130,14 +130,14 @@ func init() { ScanFunc: Plugins.ModbusScan, }) - // 数据同步和备份服务 + // Data synchronization and backup services Common.RegisterPlugin("rsync", Common.ScanPlugin{ Name: "Rsync", Ports: []int{873}, ScanFunc: Plugins.RsyncScan, }) - // NoSQL数据库 + // NoSQL databases Common.RegisterPlugin("cassandra", Common.ScanPlugin{ Name: "Cassandra", Ports: []int{9042}, @@ -150,7 +150,7 @@ func init() { ScanFunc: Plugins.Neo4jScan, }) - // 远程桌面和显示服务 + // Remote desktop and display services Common.RegisterPlugin("rdp", Common.ScanPlugin{ Name: "RDP", Ports: []int{3389, 13389, 33389}, @@ -169,7 +169,7 @@ func init() { ScanFunc: Plugins.VncScan, }) - // 缓存和键值存储服务 + // Cache and key-value storage services Common.RegisterPlugin("redis", Common.ScanPlugin{ Name: "Redis", Ports: []int{6379, 6380, 16379}, @@ -194,7 +194,7 @@ func init() { ScanFunc: Plugins.MongodbScan, }) - // 2. 特殊漏洞扫描插件 + // 2. Special vulnerability scan plugins Common.RegisterPlugin("ms17010", Common.ScanPlugin{ Name: "MS17010", Ports: []int{445}, @@ -207,7 +207,7 @@ func init() { ScanFunc: Plugins.SmbGhost, }) - // 3. Web应用扫描插件 + // 3. Web application scan plugins Common.RegisterPlugin("webtitle", Common.ScanPlugin{ Name: "WebTitle", Ports: Common.ParsePortsFromString(Common.WebPorts), @@ -220,7 +220,7 @@ func init() { ScanFunc: Plugins.WebPoc, }) - // 4. Windows系统专用插件 + // 4. Windows system specific plugins Common.RegisterPlugin("smb2", Common.ScanPlugin{ Name: "SMBScan2", Ports: []int{445}, @@ -233,7 +233,7 @@ func init() { ScanFunc: Plugins.WmiExec, }) - // 5. 本地信息收集插件 + // 5. Local information collection plugins Common.RegisterPlugin("localinfo", Common.ScanPlugin{ Name: "LocalInfo", Ports: []int{}, diff --git a/Core/Scanner.go b/Core/Scanner.go index a3ab49d..23b35db 100644 --- a/Core/Scanner.go +++ b/Core/Scanner.go @@ -13,92 +13,92 @@ import ( "time" ) -// 全局变量定义 +// Global variable definitions var ( - LocalScan bool // 本地扫描模式标识 - WebScan bool // Web扫描模式标识 + LocalScan bool // Local scan mode identifier + WebScan bool // Web scan mode identifier ) -// Scan 执行扫描主流程 -// info: 主机信息结构体,包含扫描目标的基本信息 +// Scan executes the main scanning process +// info: Host information structure, contains basic information about the scan target func Scan(info Common.HostInfo) { - Common.LogInfo("开始信息扫描") + Common.LogInfo("Starting information scan") - // 初始化HTTP客户端配置 + // Initialize HTTP client configuration lib.Inithttp() - // 初始化并发控制 + // Initialize concurrency control ch := make(chan struct{}, Common.ThreadNum) wg := sync.WaitGroup{} - // 根据扫描模式执行不同的扫描策略 + // Execute different scanning strategies based on scan mode switch { case Common.LocalMode: - // 本地信息收集模式 + // Local information collection mode LocalScan = true executeLocalScan(info, &ch, &wg) case len(Common.URLs) > 0: - // Web扫描模式 + // Web scanning mode WebScan = true executeWebScan(info, &ch, &wg) default: - // 主机扫描模式 + // Host scanning mode executeHostScan(info, &ch, &wg) } - // 等待所有扫描任务完成 + // Wait for all scanning tasks to complete finishScan(&wg) } -// executeLocalScan 执行本地扫描 -// info: 主机信息 -// ch: 并发控制通道 -// wg: 等待组 +// executeLocalScan executes local scanning +// info: Host information +// ch: Concurrency control channel +// wg: Wait group func executeLocalScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) { - Common.LogInfo("执行本地信息收集") + Common.LogInfo("Executing local information collection") - // 获取本地模式支持的插件列表 + // Get list of plugins supported by local mode validLocalPlugins := getValidPlugins(Common.ModeLocal) - // 验证扫描模式的合法性 + // Validate scan mode legality if err := validateScanMode(validLocalPlugins, Common.ModeLocal); err != nil { Common.LogError(err.Error()) return } - // 输出使用的插件信息 + // Output plugin information being used if Common.ScanMode == Common.ModeLocal { - Common.LogInfo("使用全部本地插件") + Common.LogInfo("Using all local plugins") Common.ParseScanMode(Common.ScanMode) } else { - Common.LogInfo(fmt.Sprintf("使用插件: %s", Common.ScanMode)) + Common.LogInfo(fmt.Sprintf("Using plugin: %s", Common.ScanMode)) } - // 执行扫描任务 + // Execute scanning tasks executeScans([]Common.HostInfo{info}, ch, wg) } -// executeWebScan 执行Web扫描 -// info: 主机信息 -// ch: 并发控制通道 -// wg: 等待组 +// executeWebScan executes Web scanning +// info: Host information +// ch: Concurrency control channel +// wg: Wait group func executeWebScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) { - Common.LogInfo("开始Web扫描") + Common.LogInfo("Starting Web scanning") - // 获取Web模式支持的插件列表 + // Get list of plugins supported by Web mode validWebPlugins := getValidPlugins(Common.ModeWeb) - // 验证扫描模式的合法性 + // Validate scan mode legality if err := validateScanMode(validWebPlugins, Common.ModeWeb); err != nil { Common.LogError(err.Error()) return } - // 处理目标URL列表 + // Process target URL list var targetInfos []Common.HostInfo for _, url := range Common.URLs { urlInfo := info - // 确保URL包含协议头 + // Ensure URL contains protocol header if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { url = "http://" + url } @@ -106,43 +106,43 @@ func executeWebScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) targetInfos = append(targetInfos, urlInfo) } - // 输出使用的插件信息 + // Output plugin information being used if Common.ScanMode == Common.ModeWeb { - Common.LogInfo("使用全部Web插件") + Common.LogInfo("Using all Web plugins") Common.ParseScanMode(Common.ScanMode) } else { - Common.LogInfo(fmt.Sprintf("使用插件: %s", Common.ScanMode)) + Common.LogInfo(fmt.Sprintf("Using plugin: %s", Common.ScanMode)) } - // 执行扫描任务 + // Execute scanning tasks executeScans(targetInfos, ch, wg) } -// executeHostScan 执行主机扫描 -// info: 主机信息 -// ch: 并发控制通道 -// wg: 等待组 +// executeHostScan executes host scanning +// info: Host information +// ch: Concurrency control channel +// wg: Wait group func executeHostScan(info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) { - // 验证扫描目标 + // Validate scan target if info.Host == "" { - Common.LogError("未指定扫描目标") + Common.LogError("Scan target not specified") return } - // 解析目标主机 + // Parse target host hosts, err := Common.ParseIP(info.Host, Common.HostsFile, Common.ExcludeHosts) if err != nil { - Common.LogError(fmt.Sprintf("解析主机错误: %v", err)) + Common.LogError(fmt.Sprintf("Host parsing error: %v", err)) return } - Common.LogInfo("开始主机扫描") + Common.LogInfo("Starting host scanning") executeScan(hosts, info, ch, wg) } -// getValidPlugins 获取指定模式下的有效插件列表 -// mode: 扫描模式 -// 返回: 有效插件映射表 +// getValidPlugins gets list of valid plugins for the specified mode +// mode: Scan mode +// returns: Valid plugins mapping table func getValidPlugins(mode string) map[string]bool { validPlugins := make(map[string]bool) for _, plugin := range Common.PluginGroups[mode] { @@ -151,94 +151,94 @@ func getValidPlugins(mode string) map[string]bool { return validPlugins } -// validateScanMode 验证扫描模式的合法性 -// validPlugins: 有效插件列表 -// mode: 扫描模式 -// 返回: 错误信息 +// validateScanMode validates the legality of scan mode +// validPlugins: Valid plugin list +// mode: Scan mode +// returns: Error information func validateScanMode(validPlugins map[string]bool, mode string) error { if Common.ScanMode == "" || Common.ScanMode == "All" { Common.ScanMode = mode } else if _, exists := validPlugins[Common.ScanMode]; !exists { - return fmt.Errorf("无效的%s插件: %s", mode, Common.ScanMode) + return fmt.Errorf("Invalid %s plugin: %s", mode, Common.ScanMode) } return nil } -// executeScan 执行主扫描流程 -// hosts: 目标主机列表 -// info: 主机信息 -// ch: 并发控制通道 -// wg: 等待组 +// executeScan executes main scanning process +// hosts: Target host list +// info: Host information +// ch: Concurrency control channel +// wg: Wait group func executeScan(hosts []string, info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) { var targetInfos []Common.HostInfo - // 处理主机和端口扫描 + // Process host and port scanning if len(hosts) > 0 || len(Common.HostPort) > 0 { - // 检查主机存活性 + // Check host liveness if shouldPingScan(hosts) { hosts = CheckLive(hosts, Common.UsePing) - Common.LogInfo(fmt.Sprintf("存活主机数量: %d", len(hosts))) + Common.LogInfo(fmt.Sprintf("Number of live hosts: %d", len(hosts))) if Common.IsICMPScan() { return } } - // 获取存活端口 + // Get alive ports alivePorts := getAlivePorts(hosts) if len(alivePorts) > 0 { targetInfos = prepareTargetInfos(alivePorts, info) } } - // 添加URL扫描目标 + // Add URL scanning targets targetInfos = appendURLTargets(targetInfos, info) - // 执行漏洞扫描 + // Execute vulnerability scanning if len(targetInfos) > 0 { - Common.LogInfo("开始漏洞扫描") + Common.LogInfo("Starting vulnerability scanning") executeScans(targetInfos, ch, wg) } } -// shouldPingScan 判断是否需要执行ping扫描 -// hosts: 目标主机列表 -// 返回: 是否需要ping扫描 +// shouldPingScan determines if ping scanning should be executed +// hosts: Target host list +// returns: Whether ping scanning is needed func shouldPingScan(hosts []string) bool { return (Common.DisablePing == false && len(hosts) > 1) || Common.IsICMPScan() } -// getAlivePorts 获取存活端口列表 -// hosts: 目标主机列表 -// 返回: 存活端口列表 +// getAlivePorts gets list of alive ports +// hosts: Target host list +// returns: List of alive ports func getAlivePorts(hosts []string) []string { var alivePorts []string - // 根据扫描模式选择端口扫描方式 + // Choose port scanning method based on scan mode if Common.IsWebScan() { alivePorts = NoPortScan(hosts, Common.Ports) } else if len(hosts) > 0 { alivePorts = PortScan(hosts, Common.Ports, Common.Timeout) - Common.LogInfo(fmt.Sprintf("存活端口数量: %d", len(alivePorts))) + Common.LogInfo(fmt.Sprintf("Number of alive ports: %d", len(alivePorts))) if Common.IsPortScan() { return nil } } - // 合并额外指定的端口 + // Merge additional specified ports if len(Common.HostPort) > 0 { alivePorts = append(alivePorts, Common.HostPort...) alivePorts = Common.RemoveDuplicate(alivePorts) Common.HostPort = nil - Common.LogInfo(fmt.Sprintf("存活端口数量: %d", len(alivePorts))) + Common.LogInfo(fmt.Sprintf("Number of alive ports: %d", len(alivePorts))) } return alivePorts } -// appendURLTargets 添加URL扫描目标 -// targetInfos: 现有目标列表 -// baseInfo: 基础主机信息 -// 返回: 更新后的目标列表 +// appendURLTargets adds URL scanning targets +// targetInfos: Existing target list +// baseInfo: Base host information +// returns: Updated target list func appendURLTargets(targetInfos []Common.HostInfo, baseInfo Common.HostInfo) []Common.HostInfo { for _, url := range Common.URLs { urlInfo := baseInfo @@ -248,16 +248,16 @@ func appendURLTargets(targetInfos []Common.HostInfo, baseInfo Common.HostInfo) [ return targetInfos } -// prepareTargetInfos 准备扫描目标信息 -// alivePorts: 存活端口列表 -// baseInfo: 基础主机信息 -// 返回: 目标信息列表 +// prepareTargetInfos prepares scanning target information +// alivePorts: Alive port list +// baseInfo: Base host information +// returns: Target information list func prepareTargetInfos(alivePorts []string, baseInfo Common.HostInfo) []Common.HostInfo { var infos []Common.HostInfo for _, targetIP := range alivePorts { hostParts := strings.Split(targetIP, ":") if len(hostParts) != 2 { - Common.LogError(fmt.Sprintf("无效的目标地址格式: %s", targetIP)) + Common.LogError(fmt.Sprintf("Invalid target address format: %s", targetIP)) continue } info := baseInfo @@ -268,27 +268,27 @@ func prepareTargetInfos(alivePorts []string, baseInfo Common.HostInfo) []Common. return infos } -// ScanTask 扫描任务结构体 +// ScanTask scan task structure type ScanTask struct { - pluginName string // 插件名称 - target Common.HostInfo // 目标信息 + pluginName string // Plugin name + target Common.HostInfo // Target information } -// executeScans 执行扫描任务 -// targets: 目标列表 -// ch: 并发控制通道 -// wg: 等待组 +// executeScans executes scanning tasks +// targets: Target list +// ch: Concurrency control channel +// wg: Wait group func executeScans(targets []Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) { mode := Common.GetScanMode() - // 获取要执行的插件列表 + // Get list of plugins to execute pluginsToRun, isSinglePlugin := getPluginsToRun(mode) var tasks []ScanTask actualTasks := 0 loadedPlugins := make([]string, 0) - // 收集扫描任务 + // Collect scanning tasks for _, target := range targets { targetPort, _ := strconv.Atoi(target.Ports) for _, pluginName := range pluginsToRun { @@ -305,22 +305,22 @@ func executeScans(targets []Common.HostInfo, ch *chan struct{}, wg *sync.WaitGro } } - // 处理插件列表 + // Process plugin list finalPlugins := getUniquePlugins(loadedPlugins) - Common.LogInfo(fmt.Sprintf("加载的插件: %s", strings.Join(finalPlugins, ", "))) + Common.LogInfo(fmt.Sprintf("Loaded plugins: %s", strings.Join(finalPlugins, ", "))) - // 初始化进度条 + // Initialize progress bar initializeProgressBar(actualTasks) - // 执行扫描任务 + // Execute scanning tasks for _, task := range tasks { AddScan(task.pluginName, task.target, ch, wg) } } -// getPluginsToRun 获取要执行的插件列表 -// mode: 扫描模式 -// 返回: 插件列表和是否为单插件模式 +// getPluginsToRun gets list of plugins to execute +// mode: Scan mode +// returns: Plugin list and whether it's single plugin mode func getPluginsToRun(mode string) ([]string, bool) { var pluginsToRun []string isSinglePlugin := false @@ -335,13 +335,13 @@ func getPluginsToRun(mode string) ([]string, bool) { return pluginsToRun, isSinglePlugin } -// collectScanTasks 收集扫描任务 -// plugin: 插件信息 -// target: 目标信息 -// targetPort: 目标端口 -// pluginName: 插件名称 -// isSinglePlugin: 是否为单插件模式 -// 返回: 是否添加任务和任务列表 +// collectScanTasks collects scanning tasks +// plugin: Plugin information +// target: Target information +// targetPort: Target port +// pluginName: Plugin name +// isSinglePlugin: Whether it's single plugin mode +// returns: Whether task was added and task list func collectScanTasks(plugin Common.ScanPlugin, target Common.HostInfo, targetPort int, pluginName string, isSinglePlugin bool) (bool, []ScanTask) { var tasks []ScanTask taskAdded := false @@ -357,9 +357,9 @@ func collectScanTasks(plugin Common.ScanPlugin, target Common.HostInfo, targetPo return taskAdded, tasks } -// getUniquePlugins 获取去重后的插件列表 -// loadedPlugins: 已加载的插件列表 -// 返回: 去重并排序后的插件列表 +// getUniquePlugins gets deduplicated plugin list +// loadedPlugins: Already loaded plugin list +// returns: Deduplicated and sorted plugin list func getUniquePlugins(loadedPlugins []string) []string { uniquePlugins := make(map[string]struct{}) for _, p := range loadedPlugins { @@ -375,15 +375,15 @@ func getUniquePlugins(loadedPlugins []string) []string { return finalPlugins } -// initializeProgressBar 初始化进度条 -// actualTasks: 实际任务数量 +// initializeProgressBar initializes progress bar +// actualTasks: Actual number of tasks func initializeProgressBar(actualTasks int) { if Common.ShowProgress { Common.ProgressBar = progressbar.NewOptions(actualTasks, progressbar.OptionEnableColorCodes(true), progressbar.OptionShowCount(), progressbar.OptionSetWidth(15), - progressbar.OptionSetDescription("[cyan]扫描进度:[reset]"), + progressbar.OptionSetDescription("[cyan]Scanning progress:[reset]"), progressbar.OptionSetTheme(progressbar.Theme{ Saucer: "[green]=[reset]", SaucerHead: "[green]>[reset]", @@ -398,25 +398,25 @@ func initializeProgressBar(actualTasks int) { } } -// finishScan 完成扫描任务 -// wg: 等待组 +// finishScan completes scanning tasks +// wg: Wait group func finishScan(wg *sync.WaitGroup) { wg.Wait() if Common.ProgressBar != nil { Common.ProgressBar.Finish() fmt.Println() } - Common.LogSuccess(fmt.Sprintf("扫描已完成: %v/%v", Common.End, Common.Num)) + Common.LogSuccess(fmt.Sprintf("Scanning completed: %v/%v", Common.End, Common.Num)) } -// Mutex 用于保护共享资源的并发访问 +// Mutex for protecting concurrent access to shared resources var Mutex = &sync.Mutex{} -// AddScan 添加扫描任务并启动扫描 -// plugin: 插件名称 -// info: 目标信息 -// ch: 并发控制通道 -// wg: 等待组 +// AddScan adds scanning task and starts scanning +// plugin: Plugin name +// info: Target information +// ch: Concurrency control channel +// wg: Wait group func AddScan(plugin string, info Common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) { *ch <- struct{}{} wg.Add(1) @@ -433,29 +433,29 @@ func AddScan(plugin string, info Common.HostInfo, ch *chan struct{}, wg *sync.Wa }() } -// ScanFunc 执行扫描插件 -// name: 插件名称 -// info: 目标信息 +// ScanFunc executes scanning plugin +// name: Plugin name +// info: Target information func ScanFunc(name *string, info *Common.HostInfo) { defer func() { if err := recover(); err != nil { - Common.LogError(fmt.Sprintf("扫描错误 %v:%v - %v", info.Host, info.Ports, err)) + Common.LogError(fmt.Sprintf("Scanning error %v:%v - %v", info.Host, info.Ports, err)) } }() plugin, exists := Common.PluginManager[*name] if !exists { - Common.LogInfo(fmt.Sprintf("扫描类型 %v 无对应插件,已跳过", *name)) + Common.LogInfo(fmt.Sprintf("Scan type %v has no corresponding plugin, skipped", *name)) return } if err := plugin.ScanFunc(info); err != nil { - Common.LogError(fmt.Sprintf("扫描错误 %v:%v - %v", info.Host, info.Ports, err)) + Common.LogError(fmt.Sprintf("Scanning error %v:%v - %v", info.Host, info.Ports, err)) } } -// updateScanProgress 更新扫描进度 -// info: 目标信息 +// updateScanProgress updates scanning progress +// info: Target information func updateScanProgress(info *Common.HostInfo) { Common.OutputMutex.Lock() atomic.AddInt64(&Common.End, 1) @@ -464,4 +464,4 @@ func updateScanProgress(info *Common.HostInfo) { Common.ProgressBar.Add(1) } Common.OutputMutex.Unlock() -} +} \ No newline at end of file