github.com/chainreactors/fingers@v1.2.1/goby/goby.go (about) 1 package goby 2 3 import ( 4 "bytes" 5 "github.com/chainreactors/fingers/common" 6 "github.com/chainreactors/fingers/resources" 7 "github.com/chainreactors/words/logic" 8 "strings" 9 ) 10 11 func NewGobyEngine(data []byte) (*GobyEngine, error) { 12 var fingers []*GobyFinger 13 err := resources.UnmarshalData(data, &fingers) 14 if err != nil { 15 return nil, err 16 } 17 engine := &GobyEngine{ 18 Fingers: fingers, 19 } 20 err = engine.Compile() 21 if err != nil { 22 return nil, err 23 } 24 return engine, nil 25 } 26 27 type GobyEngine struct { 28 Fingers []*GobyFinger 29 } 30 31 func (engine *GobyEngine) Name() string { 32 return "goby" 33 } 34 35 func (engine *GobyEngine) Len() int { 36 return len(engine.Fingers) 37 } 38 39 func (engine *GobyEngine) Compile() error { 40 for _, finger := range engine.Fingers { 41 err := finger.Compile() 42 if err != nil { 43 return err 44 } 45 } 46 return nil 47 } 48 49 // WebMatch 实现Web指纹匹配 50 func (engine *GobyEngine) WebMatch(content []byte) common.Frameworks { 51 return engine.MatchRaw(string(bytes.ToLower(content))) 52 } 53 54 // ServiceMatch 实现Service指纹匹配 - goby不支持Service指纹 55 func (engine *GobyEngine) ServiceMatch(host string, portStr string, level int, sender common.ServiceSender, callback common.ServiceCallback) *common.ServiceResult { 56 // goby不支持Service指纹识别 57 return nil 58 } 59 60 func (engine *GobyEngine) Capability() common.EngineCapability { 61 return common.EngineCapability{ 62 SupportWeb: true, // goby支持Web指纹 63 SupportService: false, // goby不支持Service指纹 64 } 65 } 66 67 func (engine *GobyEngine) MatchRaw(raw string) common.Frameworks { 68 frames := make(common.Frameworks) 69 for _, finger := range engine.Fingers { 70 frame := finger.Match(raw) 71 if frame != nil { 72 frames.Add(frame) 73 } 74 } 75 return frames 76 } 77 78 type gobyRule struct { 79 Label string `json:"label"` 80 Feature string `json:"feature"` 81 IsEquel bool `json:"is_equal"` //是则判断条件相等,否则判断不等 82 } 83 84 type GobyFinger struct { 85 Logic string `json:"logic"` 86 logicExpr *logic.Program 87 Name string `json:"name"` 88 Rule []gobyRule `json:"rule"` 89 } 90 91 func (finger *GobyFinger) Compile() error { 92 for i, r := range finger.Rule { 93 // Fix bug: golang 不支持直接使用 `r.Feature` 的方式修改循环内的值 94 //r.Feature = strings.ToLower(r.Feature) 95 finger.Rule[i].Feature = strings.ToLower(r.Feature) 96 } 97 98 finger.logicExpr = logic.Compile(finger.Logic) 99 return nil 100 } 101 102 func (finger *GobyFinger) Match(raw string) *common.Framework { 103 env := make(map[string]bool) 104 for _, r := range finger.Rule { 105 match := strings.Contains(raw, r.Feature) 106 env[r.Label] = match == r.IsEquel 107 } 108 109 matched := logic.EvalLogic(finger.logicExpr, env) 110 111 if matched { 112 return common.NewFramework(finger.Name, common.FrameFromGoby) 113 } 114 return nil 115 }