github.com/projectdiscovery/nuclei/v2@v2.9.15/pkg/protocols/network/request_test.go (about) 1 package network 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 "net/url" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 13 "github.com/projectdiscovery/nuclei/v2/pkg/model" 14 "github.com/projectdiscovery/nuclei/v2/pkg/model/types/severity" 15 "github.com/projectdiscovery/nuclei/v2/pkg/operators" 16 "github.com/projectdiscovery/nuclei/v2/pkg/operators/extractors" 17 "github.com/projectdiscovery/nuclei/v2/pkg/operators/matchers" 18 "github.com/projectdiscovery/nuclei/v2/pkg/output" 19 "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs" 20 "github.com/projectdiscovery/nuclei/v2/pkg/testutils" 21 ) 22 23 func TestNetworkExecuteWithResults(t *testing.T) { 24 options := testutils.DefaultOptions 25 26 testutils.Init(options) 27 templateID := "testing-network" 28 request := &Request{ 29 ID: templateID, 30 Address: []string{"{{Hostname}}:"}, 31 ReadSize: 2048, 32 Inputs: []*Input{}, 33 Operators: operators.Operators{ 34 Matchers: []*matchers.Matcher{{ 35 Name: "test", 36 Part: "data", 37 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 38 Words: []string{"200 OK"}, 39 }}, 40 Extractors: []*extractors.Extractor{{ 41 Part: "data", 42 Type: extractors.ExtractorTypeHolder{ExtractorType: extractors.RegexExtractor}, 43 Regex: []string{"<h1>.*</h1>"}, 44 }}, 45 }, 46 } 47 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 48 _, _ = w.Write([]byte(exampleBody)) 49 })) 50 defer ts.Close() 51 52 parsed, err := url.Parse(ts.URL) 53 require.Nil(t, err, "could not parse url") 54 request.Address[0] = "{{Hostname}}" 55 56 request.Inputs = append(request.Inputs, &Input{Data: fmt.Sprintf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", parsed.Host)}) 57 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 58 ID: templateID, 59 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 60 }) 61 err = request.Compile(executerOpts) 62 require.Nil(t, err, "could not compile network request") 63 64 var finalEvent *output.InternalWrappedEvent 65 t.Run("domain-valid", func(t *testing.T) { 66 metadata := make(output.InternalEvent) 67 previous := make(output.InternalEvent) 68 ctxArgs := contextargs.NewWithInput(parsed.Host) 69 err := request.ExecuteWithResults(ctxArgs, metadata, previous, func(event *output.InternalWrappedEvent) { 70 finalEvent = event 71 }) 72 require.Nil(t, err, "could not execute network request") 73 }) 74 require.NotNil(t, finalEvent, "could not get event output from request") 75 require.Equal(t, 1, len(finalEvent.Results), "could not get correct number of results") 76 require.Equal(t, "test", finalEvent.Results[0].MatcherName, "could not get correct matcher name of results") 77 require.Equal(t, 1, len(finalEvent.Results[0].ExtractedResults), "could not get correct number of extracted results") 78 require.Equal(t, "<h1>Example Domain</h1>", finalEvent.Results[0].ExtractedResults[0], "could not get correct extracted results") 79 finalEvent = nil 80 81 t.Run("invalid-port-override", func(t *testing.T) { 82 metadata := make(output.InternalEvent) 83 previous := make(output.InternalEvent) 84 ctxArgs := contextargs.NewWithInput("127.0.0.1:11211") 85 err := request.ExecuteWithResults(ctxArgs, metadata, previous, func(event *output.InternalWrappedEvent) { 86 finalEvent = event 87 }) 88 require.Nil(t, err, "could not execute network request") 89 }) 90 require.Nil(t, finalEvent.Results, "could not get event output from request") 91 92 request.Inputs[0].Type = NetworkInputTypeHolder{NetworkInputType: hexType} 93 request.Inputs[0].Data = hex.EncodeToString([]byte(fmt.Sprintf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", parsed.Host))) 94 95 t.Run("hex-to-string", func(t *testing.T) { 96 metadata := make(output.InternalEvent) 97 previous := make(output.InternalEvent) 98 ctxArgs := contextargs.NewWithInput(parsed.Host) 99 err := request.ExecuteWithResults(ctxArgs, metadata, previous, func(event *output.InternalWrappedEvent) { 100 finalEvent = event 101 }) 102 require.Nil(t, err, "could not execute network request") 103 }) 104 require.NotNil(t, finalEvent, "could not get event output from request") 105 require.Equal(t, 1, len(finalEvent.Results), "could not get correct number of results") 106 require.Equal(t, "test", finalEvent.Results[0].MatcherName, "could not get correct matcher name of results") 107 require.Equal(t, 1, len(finalEvent.Results[0].ExtractedResults), "could not get correct number of extracted results") 108 require.Equal(t, "<h1>Example Domain</h1>", finalEvent.Results[0].ExtractedResults[0], "could not get correct extracted results") 109 } 110 111 var exampleBody = `<!doctype html> 112 <html> 113 <head> 114 <title>Example Domain</title> 115 116 <meta charset="utf-8" /> 117 <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 118 <meta name="viewport" content="width=device-width, initial-scale=1" /> 119 <style type="text/css"> 120 body { 121 background-color: #f0f0f2; 122 margin: 0; 123 padding: 0; 124 font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 125 126 } 127 div { 128 width: 600px; 129 margin: 5em auto; 130 padding: 2em; 131 background-color: #fdfdff; 132 border-radius: 0.5em; 133 box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); 134 } 135 a:link, a:visited { 136 color: #38488f; 137 text-decoration: none; 138 } 139 @media (max-width: 700px) { 140 div { 141 margin: 0 auto; 142 width: auto; 143 } 144 } 145 </style> 146 </head> 147 148 <body> 149 <div> 150 <h1>Example Domain</h1> 151 <p>This domain is for use in illustrative examples in documents. You may use this 152 domain in literature without prior coordination or asking for permission.</p> 153 <p><a href="https://www.iana.org/domains/example">More information...</a></p> 154 </div> 155 </body> 156 </html> 157 `