fscan/core/portfinger/match_engine.go
2025-08-12 13:04:14 +08:00

121 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

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

package portfinger
import (
"fmt"
"regexp"
"strings"
"github.com/shadow1ng/fscan/common"
)
// 解析match指令获取匹配规则
func (p *Probe) getMatch(data string) (match Match, err error) {
common.LogDebug("开始解析match指令" + data)
match = Match{}
// 提取match文本并解析指令语法
matchText := data[len("match")+1:]
directive := p.getDirectiveSyntax(matchText)
// 分割文本获取pattern和版本信息
textSplited := strings.Split(directive.DirectiveStr, directive.Delimiter)
if len(textSplited) == 0 {
return match, fmt.Errorf("无效的match指令格式")
}
pattern := textSplited[0]
versionInfo := strings.Join(textSplited[1:], "")
// 解码并编译正则表达式
patternUnescaped, decodeErr := DecodePattern(pattern)
if decodeErr != nil {
common.LogDebug("解码pattern失败: " + decodeErr.Error())
return match, decodeErr
}
patternUnescapedStr := string([]rune(string(patternUnescaped)))
patternCompiled, compileErr := regexp.Compile(patternUnescapedStr)
if compileErr != nil {
common.LogDebug("编译正则表达式失败: " + compileErr.Error())
return match, compileErr
}
// 设置match对象属性
match.Service = directive.DirectiveName
match.Pattern = pattern
match.PatternCompiled = patternCompiled
match.VersionInfo = versionInfo
common.LogDebug(fmt.Sprintf("解析match成功: 服务=%s, Pattern=%s",
match.Service, match.Pattern))
return match, nil
}
// 解析softmatch指令获取软匹配规则
func (p *Probe) getSoftMatch(data string) (softMatch Match, err error) {
common.LogDebug("开始解析softmatch指令" + data)
softMatch = Match{IsSoft: true}
// 提取softmatch文本并解析指令语法
matchText := data[len("softmatch")+1:]
directive := p.getDirectiveSyntax(matchText)
// 分割文本获取pattern和版本信息
textSplited := strings.Split(directive.DirectiveStr, directive.Delimiter)
if len(textSplited) == 0 {
return softMatch, fmt.Errorf("无效的softmatch指令格式")
}
pattern := textSplited[0]
versionInfo := strings.Join(textSplited[1:], "")
// 解码并编译正则表达式
patternUnescaped, decodeErr := DecodePattern(pattern)
if decodeErr != nil {
common.LogDebug("解码pattern失败: " + decodeErr.Error())
return softMatch, decodeErr
}
patternUnescapedStr := string([]rune(string(patternUnescaped)))
patternCompiled, compileErr := regexp.Compile(patternUnescapedStr)
if compileErr != nil {
common.LogDebug("编译正则表达式失败: " + compileErr.Error())
return softMatch, compileErr
}
// 设置softMatch对象属性
softMatch.Service = directive.DirectiveName
softMatch.Pattern = pattern
softMatch.PatternCompiled = patternCompiled
softMatch.VersionInfo = versionInfo
common.LogDebug(fmt.Sprintf("解析softmatch成功: 服务=%s, Pattern=%s",
softMatch.Service, softMatch.Pattern))
return softMatch, nil
}
// MatchPattern 检查响应是否与匹配规则匹配
func (m *Match) MatchPattern(response []byte) bool {
if m.PatternCompiled == nil {
common.LogDebug("警告: 匹配规则的正则表达式未编译")
return false
}
matched := m.PatternCompiled.Match(response)
if matched {
// 提取匹配到的子组
submatches := m.PatternCompiled.FindStringSubmatch(string(response))
if len(submatches) > 1 {
m.FoundItems = submatches[1:] // 排除完整匹配,只保留分组
common.LogDebug(fmt.Sprintf("模式匹配成功,提取到 %d 个分组", len(m.FoundItems)))
} else {
common.LogDebug("模式匹配成功,但没有分组匹配")
}
}
return matched
}