github.com/chainreactors/fingers@v1.2.1/common/vuln.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "github.com/chainreactors/utils/iutils" 6 "strings" 7 ) 8 9 const ( 10 SeverityINFO int = iota + 1 11 SeverityMEDIUM 12 SeverityHIGH 13 SeverityCRITICAL 14 SeverityUnknown 15 ) 16 17 func GetSeverityLevel(s string) int { 18 switch s { 19 case "info": 20 return SeverityINFO 21 case "medium": 22 return SeverityMEDIUM 23 case "high": 24 return SeverityHIGH 25 case "critical": 26 return SeverityCRITICAL 27 default: 28 return SeverityUnknown 29 } 30 } 31 32 var SeverityMap = map[int]string{ 33 SeverityINFO: "info", 34 SeverityMEDIUM: "medium", 35 SeverityHIGH: "high", 36 SeverityCRITICAL: "critical", 37 } 38 39 type Vuln struct { 40 Name string `json:"name"` 41 Tags []string `json:"tags,omitempty"` 42 Payload map[string]interface{} `json:"payload,omitempty"` 43 Detail map[string][]string `json:"detail,omitempty"` 44 SeverityLevel int `json:"severity"` 45 Framework *Framework `json:"-"` 46 } 47 48 func (v *Vuln) HasTag(tag string) bool { 49 for _, t := range v.Tags { 50 if t == tag { 51 return true 52 } 53 } 54 return false 55 } 56 57 func (v *Vuln) GetPayload() string { 58 return iutils.MapToString(v.Payload) 59 } 60 61 func (v *Vuln) GetDetail() string { 62 var s strings.Builder 63 for k, v := range v.Detail { 64 s.WriteString(fmt.Sprintf(" %s:%s ", k, strings.Join(v, ","))) 65 } 66 return s.String() 67 } 68 69 func (v *Vuln) String() string { 70 s := v.Name 71 if payload := v.GetPayload(); payload != "" { 72 s += fmt.Sprintf(" payloads:%s", iutils.AsciiEncode(payload)) 73 } 74 if detail := v.GetDetail(); detail != "" { 75 s += fmt.Sprintf(" payloads:%s", iutils.AsciiEncode(detail)) 76 } 77 return s 78 } 79 80 type Vulns map[string]*Vuln 81 82 func (vs Vulns) One() *Vuln { 83 for _, v := range vs { 84 return v 85 } 86 return nil 87 } 88 89 func (vs Vulns) List() []*Vuln { 90 var vulns []*Vuln 91 for _, v := range vs { 92 vulns = append(vulns, v) 93 } 94 return vulns 95 } 96 97 func (vs Vulns) Add(other *Vuln) bool { 98 if _, ok := vs[other.Name]; !ok { 99 vs[other.Name] = other 100 return true 101 } 102 return false 103 } 104 105 func (vs Vulns) String() string { 106 var s string 107 108 for _, vuln := range vs { 109 s += fmt.Sprintf("[ %s: %s ] ", SeverityMap[vuln.SeverityLevel], vuln.String()) 110 } 111 return s 112 } 113 114 func (vs Vulns) Merge(other Vulns) int { 115 // name, tag 统一小写, 减少指纹库之间的差异 116 var n int 117 for _, v := range other { 118 v.Name = strings.ToLower(v.Name) 119 if frame, ok := vs[v.Name]; ok { 120 if len(v.Tags) > 0 { 121 for i, tag := range v.Tags { 122 v.Tags[i] = strings.ToLower(tag) 123 } 124 frame.Tags = iutils.StringsUnique(append(frame.Tags, v.Tags...)) 125 } 126 } else { 127 vs[v.Name] = v 128 n += n 129 } 130 } 131 return n 132 } 133 134 func (vs Vulns) HasTag(tag string) bool { 135 for _, f := range vs { 136 if f.HasTag(tag) { 137 return true 138 } 139 } 140 return false 141 }