From ead10fe6075d94846932af3659554d74ac7abacc Mon Sep 17 00:00:00 2001 From: mzack Date: Tue, 21 Jun 2022 11:41:16 +0200 Subject: [PATCH 1/2] Improving RFC request/response passive parsing --- v2/pkg/protocols/offlinehttp/read_response.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/v2/pkg/protocols/offlinehttp/read_response.go b/v2/pkg/protocols/offlinehttp/read_response.go index c6e1d22d19..ac2d9da8f5 100644 --- a/v2/pkg/protocols/offlinehttp/read_response.go +++ b/v2/pkg/protocols/offlinehttp/read_response.go @@ -12,8 +12,16 @@ var noMinor = regexp.MustCompile(`HTTP/([0-9]) `) // readResponseFromString reads a raw http response from a string. func readResponseFromString(data string) (*http.Response, error) { - var final string + // Check if "data" contains RFC compatible Request followed by a response + br := bufio.NewReader(strings.NewReader(data)) + if req, err := http.ReadRequest(br); err == nil { + if resp, err := http.ReadResponse(br, req); err == nil { + return resp, nil + } + } + // otherwise tries to patch known cases such as http minor version + var final string if strings.HasPrefix(data, "HTTP/") { final = addMinorVersionToHTTP(data) } else { From ee500d0499e37f56ae9c55a5c5c23594f1fe259c Mon Sep 17 00:00:00 2001 From: mzack Date: Wed, 22 Jun 2022 09:43:22 +0200 Subject: [PATCH 2/2] adding test --- .../data/req-resp-with-http-keywords.txt | 26 +++++++++++++++++++ .../offlinehttp/rfc-req-resp.yaml | 15 +++++++++++ v2/cmd/integration-test/integration-test.go | 1 + v2/cmd/integration-test/offline-http.go | 21 +++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 integration_tests/offlinehttp/data/req-resp-with-http-keywords.txt create mode 100644 integration_tests/offlinehttp/rfc-req-resp.yaml create mode 100644 v2/cmd/integration-test/offline-http.go diff --git a/integration_tests/offlinehttp/data/req-resp-with-http-keywords.txt b/integration_tests/offlinehttp/data/req-resp-with-http-keywords.txt new file mode 100644 index 0000000000..b40793ec6d --- /dev/null +++ b/integration_tests/offlinehttp/data/req-resp-with-http-keywords.txt @@ -0,0 +1,26 @@ +GET / HTTP/1.1 +Host: pastebin.com +User-Agent: curl/7.79.1 +Accept: */* +Connection: close + +HTTP/1.1 200 OK +Date: Tue, 21 Jun 2022 09:32:01 GMT +Content-Type: text/plain; charset=utf-8 +Connection: close +x-frame-options: DENY +x-content-type-options: nosniff +x-xss-protection: 1;mode=block +cache-control: public, max-age=1801 +CF-Cache-Status: HIT +Age: 1585 +Last-Modified: Tue, 21 Jun 2022 09:05:36 GMT +Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" +Server: cloudflare +CF-RAY: 71ebbc0a7ea83b8b-CDG + +54 +line1 +this is a line containing HTTP/1.1 FOO BAR +line3 +0 \ No newline at end of file diff --git a/integration_tests/offlinehttp/rfc-req-resp.yaml b/integration_tests/offlinehttp/rfc-req-resp.yaml new file mode 100644 index 0000000000..582af906a1 --- /dev/null +++ b/integration_tests/offlinehttp/rfc-req-resp.yaml @@ -0,0 +1,15 @@ +id: rfc-req-resp + +info: + name: Basic GET Request + author: pdteam + severity: info + +requests: + - method: GET + path: + - "{{BaseURL}}" + matchers: + - type: word + words: + - "this is a line containing HTTP/1.1 FOO BAR" \ No newline at end of file diff --git a/v2/cmd/integration-test/integration-test.go b/v2/cmd/integration-test/integration-test.go index 1a2f04ed36..28f5394262 100644 --- a/v2/cmd/integration-test/integration-test.go +++ b/v2/cmd/integration-test/integration-test.go @@ -32,6 +32,7 @@ var ( "templatesPath": templatesPathTestCases, "templatesDir": templatesDirTestCases, "file": fileTestcases, + "offlineHttp": offlineHttpTestcases, } ) diff --git a/v2/cmd/integration-test/offline-http.go b/v2/cmd/integration-test/offline-http.go new file mode 100644 index 0000000000..3ec9e5f1ca --- /dev/null +++ b/v2/cmd/integration-test/offline-http.go @@ -0,0 +1,21 @@ +package main + +import ( + "github.com/projectdiscovery/nuclei/v2/pkg/testutils" +) + +var offlineHttpTestcases = map[string]testutils.TestCase{ + "offlinehttp/rfc-req-resp.yaml": &RfcRequestResponse{}, +} + +type RfcRequestResponse struct{} + +// Execute executes a test case and returns an error if occurred +func (h *RfcRequestResponse) Execute(filePath string) error { + results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "offlinehttp/data/", debug, "-passive") + if err != nil { + return err + } + + return expectResultsCount(results, 1) +}