github.com/chainreactors/fingers@v1.2.1/fingers/common.go (about)

     1  package fingers
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/chainreactors/fingers/common"
     6  	"github.com/chainreactors/fingers/resources"
     7  	"github.com/chainreactors/utils/iutils"
     8  )
     9  
    10  func NewContent(c []byte, cert string, ishttp bool) *Content {
    11  	content := &Content{
    12  		Cert: cert,
    13  	}
    14  	c = iutils.UTF8ConvertBytes(c)
    15  	if ishttp {
    16  		content.UpdateContent(c)
    17  	} else {
    18  		content.Content = c
    19  	}
    20  	return content
    21  }
    22  
    23  type Content struct {
    24  	Content []byte `json:"content"`
    25  	Header  []byte `json:"header"`
    26  	Body    []byte `json:"body"`
    27  	Cert    string `json:"cert"`
    28  }
    29  
    30  func (c *Content) UpdateContent(content []byte) {
    31  	c.Content = bytes.ToLower(content)
    32  	cs := bytes.Index(c.Content, []byte("\r\n\r\n"))
    33  	if cs != -1 {
    34  		c.Body = c.Content[cs+4:]
    35  		c.Header = c.Content[:cs]
    36  	}
    37  }
    38  
    39  // LoadFingers 加载指纹 迁移到fingers包, 允许其他服务调用
    40  func LoadFingers(content []byte) (fingers Fingers, err error) {
    41  	err = resources.UnmarshalData(content, &fingers)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	return fingers, nil
    47  }
    48  
    49  type FingerMapper map[string]Fingers
    50  
    51  type Fingers []*Finger
    52  
    53  func (fs Fingers) GroupByPort() FingerMapper {
    54  	fingermap := make(FingerMapper)
    55  	for _, f := range fs {
    56  		if f.DefaultPort != nil {
    57  			for _, port := range resources.PrePort.ParsePortSlice(f.DefaultPort) {
    58  				fingermap[port] = append(fingermap[port], f)
    59  			}
    60  		} else {
    61  			fingermap["0"] = append(fingermap["0"], f)
    62  		}
    63  	}
    64  	return fingermap
    65  }
    66  
    67  func (fs Fingers) GroupByMod() (Fingers, Fingers) {
    68  	var active, passive Fingers
    69  	for _, f := range fs {
    70  		if f.IsActive {
    71  			active = append(active, f)
    72  		} else {
    73  			passive = append(passive, f)
    74  		}
    75  	}
    76  	return active, passive
    77  }
    78  
    79  func (fs Fingers) ACPassiveMatch(input *Content, idx *KeywordIndex, stopAtFirst bool) (common.Frameworks, common.Vulns) {
    80  	frames := make(common.Frameworks)
    81  	vulns := make(common.Vulns)
    82  	candidates := idx.MatchCandidates(input.Header, input.Body)
    83  	for fi := range candidates {
    84  		finger := fs[fi]
    85  
    86  		if idx.IsFastPath(fi) && !finger.EnableMatchDetail {
    87  			frame, vuln := finger.ToResult(true, finger.Rules[0].Vuln != "", "", 0)
    88  			if frame != nil {
    89  				if finger.Focus {
    90  					frame.IsFocus = true
    91  				}
    92  				for _, tag := range finger.Tags {
    93  					frame.AddTag(tag)
    94  				}
    95  				frames.Add(frame)
    96  				if vuln != nil {
    97  					vulns[vuln.Name] = vuln
    98  				}
    99  				if stopAtFirst {
   100  					break
   101  				}
   102  			}
   103  			continue
   104  		}
   105  
   106  		frame, vuln, ok := finger.PassiveMatch(input)
   107  		if ok {
   108  			frames.Add(frame)
   109  			if vuln != nil {
   110  				vulns[vuln.Name] = vuln
   111  			}
   112  			if stopAtFirst {
   113  				break
   114  			}
   115  		}
   116  	}
   117  	return frames, vulns
   118  }
   119  
   120  func (fs Fingers) PassiveMatch(input *Content, stopAtFirst bool) (common.Frameworks, common.Vulns) {
   121  	frames := make(common.Frameworks)
   122  	vulns := make(common.Vulns)
   123  	for _, finger := range fs {
   124  		// sender置空, 所有的发包交给spray的pool
   125  		frame, vuln, ok := finger.PassiveMatch(input)
   126  		if ok {
   127  			frames.Add(frame)
   128  			if vuln != nil {
   129  				vulns[vuln.Name] = vuln
   130  			}
   131  			if stopAtFirst {
   132  				break
   133  			}
   134  		}
   135  	}
   136  	return frames, vulns
   137  }
   138  
   139  func (fs Fingers) ActiveMatch(level int, sender Sender, callback Callback, stopAtFirst bool) (common.Frameworks, common.Vulns) {
   140  	frames := make(common.Frameworks)
   141  	vulns := make(common.Vulns)
   142  	for _, finger := range fs {
   143  		frame, vuln, ok := finger.ActiveMatch(level, sender)
   144  		if callback != nil {
   145  			callback(frame, vuln)
   146  		}
   147  		if ok {
   148  			frames.Add(frame)
   149  			if vuln != nil {
   150  				vulns[vuln.Name] = vuln
   151  			}
   152  			if stopAtFirst {
   153  				break
   154  			}
   155  		}
   156  	}
   157  	return frames, vulns
   158  }
   159  
   160  func (fs Fingers) Match(input *Content, level int, sender Sender, callback Callback, stopAtFirst bool) (common.Frameworks, common.Vulns) {
   161  	frames := make(common.Frameworks)
   162  	vulns := make(common.Vulns)
   163  	for _, finger := range fs {
   164  		frame, vuln, ok := finger.Match(input, level, sender)
   165  		if callback != nil {
   166  			callback(frame, vuln)
   167  		}
   168  		if ok {
   169  			ok = true
   170  			frames.Add(frame)
   171  			if vuln != nil {
   172  				vulns.Add(vuln)
   173  			}
   174  			if stopAtFirst {
   175  				break
   176  			}
   177  		}
   178  	}
   179  	return frames, vulns
   180  }