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  }