github.com/projectdiscovery/nuclei/v2@v2.9.15/pkg/protocols/network/operators_test.go (about) 1 package network 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 8 "github.com/projectdiscovery/nuclei/v2/pkg/model" 9 "github.com/projectdiscovery/nuclei/v2/pkg/model/types/severity" 10 "github.com/projectdiscovery/nuclei/v2/pkg/operators" 11 "github.com/projectdiscovery/nuclei/v2/pkg/operators/extractors" 12 "github.com/projectdiscovery/nuclei/v2/pkg/operators/matchers" 13 "github.com/projectdiscovery/nuclei/v2/pkg/output" 14 "github.com/projectdiscovery/nuclei/v2/pkg/testutils" 15 ) 16 17 func TestResponseToDSLMap(t *testing.T) { 18 options := testutils.DefaultOptions 19 20 testutils.Init(options) 21 templateID := "testing-network" 22 request := &Request{ 23 ID: templateID, 24 Address: []string{"{{Hostname}}"}, 25 ReadSize: 1024, 26 Inputs: []*Input{{Data: "test-data\r\n"}}, 27 } 28 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 29 ID: templateID, 30 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 31 }) 32 err := request.Compile(executerOpts) 33 require.Nil(t, err, "could not compile network request") 34 35 req := "test-data\r\n" 36 resp := "resp-data\r\n" 37 event := request.responseToDSLMap(req, resp, "test", "one.one.one.one", "one.one.one.one") 38 require.Len(t, event, 9, "could not get correct number of items in dsl map") 39 require.Equal(t, resp, event["data"], "could not get correct resp") 40 } 41 42 func TestNetworkOperatorMatch(t *testing.T) { 43 options := testutils.DefaultOptions 44 45 testutils.Init(options) 46 templateID := "testing-network" 47 request := &Request{ 48 ID: templateID, 49 Address: []string{"{{Hostname}}"}, 50 ReadSize: 1024, 51 Inputs: []*Input{{Data: "test-data\r\n"}}, 52 } 53 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 54 ID: templateID, 55 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 56 }) 57 err := request.Compile(executerOpts) 58 require.Nil(t, err, "could not compile network request") 59 60 req := "test-data\r\n" 61 resp := "resp-data\r\nSTAT \r\n" 62 event := request.responseToDSLMap(req, resp, "one.one.one.one", "one.one.one.one", "test") 63 64 t.Run("valid", func(t *testing.T) { 65 matcher := &matchers.Matcher{ 66 Part: "body", 67 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 68 Words: []string{"STAT "}, 69 } 70 err = matcher.CompileMatchers() 71 require.Nil(t, err, "could not compile matcher") 72 73 isMatched, matched := request.Match(event, matcher) 74 require.True(t, isMatched, "could not match valid response") 75 require.Equal(t, matcher.Words, matched) 76 }) 77 78 t.Run("negative", func(t *testing.T) { 79 matcher := &matchers.Matcher{ 80 Part: "data", 81 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 82 Negative: true, 83 Words: []string{"random"}, 84 } 85 err := matcher.CompileMatchers() 86 require.Nil(t, err, "could not compile negative matcher") 87 88 isMatched, matched := request.Match(event, matcher) 89 require.True(t, isMatched, "could not match valid negative response matcher") 90 require.Equal(t, []string{}, matched) 91 }) 92 93 t.Run("invalid", func(t *testing.T) { 94 matcher := &matchers.Matcher{ 95 Part: "data", 96 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 97 Words: []string{"random"}, 98 } 99 err := matcher.CompileMatchers() 100 require.Nil(t, err, "could not compile matcher") 101 102 isMatched, matched := request.Match(event, matcher) 103 require.False(t, isMatched, "could match invalid response matcher") 104 require.Equal(t, []string{}, matched) 105 }) 106 107 t.Run("caseInsensitive", func(t *testing.T) { 108 matcher := &matchers.Matcher{ 109 Part: "body", 110 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 111 Words: []string{"rESp-DAta"}, 112 CaseInsensitive: true, 113 } 114 err = matcher.CompileMatchers() 115 require.Nil(t, err, "could not compile matcher") 116 117 req := "TEST-DATA\r\n" 118 resp := "RESP-DATA\r\nSTAT \r\n" 119 event := request.responseToDSLMap(req, resp, "one.one.one.one", "one.one.one.one", "TEST") 120 121 isMatched, matched := request.Match(event, matcher) 122 require.True(t, isMatched, "could not match valid response") 123 require.Equal(t, []string{"resp-data"}, matched) 124 }) 125 } 126 127 func TestNetworkOperatorExtract(t *testing.T) { 128 options := testutils.DefaultOptions 129 130 testutils.Init(options) 131 templateID := "testing-network" 132 request := &Request{ 133 ID: templateID, 134 Address: []string{"{{Hostname}}"}, 135 ReadSize: 1024, 136 Inputs: []*Input{{Data: "test-data\r\n"}}, 137 } 138 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 139 ID: templateID, 140 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 141 }) 142 err := request.Compile(executerOpts) 143 require.Nil(t, err, "could not compile network request") 144 145 req := "test-data\r\n" 146 resp := "resp-data\r\nSTAT \r\n1.1.1.1\r\n" 147 event := request.responseToDSLMap(req, resp, "one.one.one.one", "one.one.one.one", "test") 148 149 t.Run("extract", func(t *testing.T) { 150 extractor := &extractors.Extractor{ 151 Part: "data", 152 Type: extractors.ExtractorTypeHolder{ExtractorType: extractors.RegexExtractor}, 153 Regex: []string{"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"}, 154 } 155 err = extractor.CompileExtractors() 156 require.Nil(t, err, "could not compile extractor") 157 158 data := request.Extract(event, extractor) 159 require.Greater(t, len(data), 0, "could not extractor valid response") 160 require.Equal(t, map[string]struct{}{"1.1.1.1": {}}, data, "could not extract correct data") 161 }) 162 163 t.Run("kval", func(t *testing.T) { 164 extractor := &extractors.Extractor{ 165 Type: extractors.ExtractorTypeHolder{ExtractorType: extractors.KValExtractor}, 166 KVal: []string{"request"}, 167 } 168 err = extractor.CompileExtractors() 169 require.Nil(t, err, "could not compile kval extractor") 170 171 data := request.Extract(event, extractor) 172 require.Greater(t, len(data), 0, "could not extractor kval valid response") 173 require.Equal(t, map[string]struct{}{req: {}}, data, "could not extract correct kval data") 174 }) 175 } 176 177 func TestNetworkMakeResult(t *testing.T) { 178 options := testutils.DefaultOptions 179 180 testutils.Init(options) 181 templateID := "testing-network" 182 request := &Request{ 183 ID: templateID, 184 Address: []string{"{{Hostname}}"}, 185 ReadSize: 1024, 186 Inputs: []*Input{{Data: "test-data\r\n"}}, 187 Operators: operators.Operators{ 188 Matchers: []*matchers.Matcher{{ 189 Name: "test", 190 Part: "data", 191 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 192 Words: []string{"STAT "}, 193 }}, 194 Extractors: []*extractors.Extractor{{ 195 Part: "data", 196 Type: extractors.ExtractorTypeHolder{ExtractorType: extractors.RegexExtractor}, 197 Regex: []string{"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"}, 198 }}, 199 }, 200 } 201 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 202 ID: templateID, 203 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 204 }) 205 err := request.Compile(executerOpts) 206 require.Nil(t, err, "could not compile network request") 207 208 req := "test-data\r\n" 209 resp := "resp-data\rSTAT \r\n1.1.1.1\n" 210 event := request.responseToDSLMap(req, resp, "one.one.one.one", "one.one.one.one", "test") 211 finalEvent := &output.InternalWrappedEvent{InternalEvent: event} 212 event["ip"] = "192.168.1.1" 213 if request.CompiledOperators != nil { 214 result, ok := request.CompiledOperators.Execute(event, request.Match, request.Extract, false) 215 if ok && result != nil { 216 finalEvent.OperatorsResult = result 217 finalEvent.Results = request.MakeResultEvent(finalEvent) 218 } 219 } 220 require.Equal(t, 1, len(finalEvent.Results), "could not get correct number of results") 221 require.Equal(t, "test", finalEvent.Results[0].MatcherName, "could not get correct matcher name of results") 222 require.Equal(t, "1.1.1.1", finalEvent.Results[0].ExtractedResults[0], "could not get correct extracted results") 223 }