mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00
121 lines
3.5 KiB
Go
121 lines
3.5 KiB
Go
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
|
||
}
|
||
|
||
|