From 44757fc58828cad367fc985742e18de4fad732d3 Mon Sep 17 00:00:00 2001 From: HENRIQUE RESTANI SCOCCO Date: Fri, 31 Mar 2023 00:58:40 -0300 Subject: [PATCH] fix: Add HTTP/2 support Adding HTTP/2 support. The way that jaeles use to parse the requests was changed because the net/http lib don't support HTTP/2 requests. --- core/parser.go | 109 +++++++++++++++++++++++++++++++++++-------------- libs/http.go | 1 + 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/core/parser.go b/core/parser.go index 0751c82..531b1ae 100644 --- a/core/parser.go +++ b/core/parser.go @@ -11,6 +11,7 @@ import ( "path" "path/filepath" "strings" + "bytes" "github.com/jaeles-project/jaeles/libs" "github.com/thoas/go-funk" @@ -451,45 +452,93 @@ func ParsePayloads(sign libs.Signature) []string { func ParseBurpRequest(raw string) (req libs.Request) { var realReq libs.Request realReq.Raw = raw - reader := bufio.NewReader(strings.NewReader(raw)) - parsedReq, err := http.ReadRequest(reader) - if err != nil { - return realReq - } - realReq.Method = parsedReq.Method - // URL part - if parsedReq.URL.Host == "" { - realReq.Host = parsedReq.Host - parsedReq.URL.Host = parsedReq.Host - } - if parsedReq.URL.Scheme == "" { - if parsedReq.Referer() == "" { - realReq.Scheme = "https" - parsedReq.URL.Scheme = "https" - } else { - u, err := url.Parse(parsedReq.Referer()) - if err == nil { - realReq.Scheme = u.Scheme - parsedReq.URL.Scheme = u.Scheme - } + + // create a scanner to read the request + scanner := bufio.NewScanner(strings.NewReader(raw)) + + // read the first request line that contains HTTP version, method and path + scanner.Scan() + requestLine := scanner.Text() + parts := strings.Split(requestLine, " ") + if len(parts) != 3 { + return + } + httpMethod := parts[0] + httpVersion := parts[2] + path := parts[1] + + // create a new buffer for the request body + bodyBuffer := bytes.NewBuffer([]byte{}) + + // create a new map to hold the headers + headers := make([]map[string]string, 0) + + // read the headers + for scanner.Scan() { + line := scanner.Text() + if line == "" { + break } + + parts := strings.Split(line, ": ") + if len(parts) != 2 { + return + } + headerName := parts[0] + headerValue := parts[1] + + header := map[string]string{ + headerName: headerValue, + } + headers = append(headers, header) + } + + // read the request body + for scanner.Scan() { + bodyBuffer.Write(scanner.Bytes()) + bodyBuffer.Write([]byte("\r\n")) } - realReq.URL = parsedReq.URL.String() - realReq.Path = parsedReq.RequestURI - realReq.Headers = ParseHeaders(parsedReq.Header) - body, _ := ioutil.ReadAll(parsedReq.Body) - realReq.Body = string(body) - // net/http parse something weird here - if !strings.HasSuffix(raw, realReq.Body) { - if strings.Contains(raw, "\n\n") { - realReq.Body = strings.Split(raw, "\n\n")[1] + body := bodyBuffer.String() + + var urlScheme string + referer := headersGet(headers, "Referer") + if referer != "" { + refURL, err := url.Parse(referer) + if err == nil { + urlScheme = refURL.Scheme } } + if urlScheme == "" { + urlScheme = "https" + } + + url := urlScheme + "://" + headers[0]["Host"] + path + + realReq.Body = body + realReq.Headers = headers + realReq.Path = path + realReq.URL = url + realReq.Method = httpMethod + realReq.Scheme = urlScheme + realReq.Proto = httpVersion + return realReq } +// helper function to get header value +func headersGet(headers []map[string]string, headerName string) string { + for _, header := range headers { + for k, v := range header { + if strings.ToLower(k) == strings.ToLower(headerName) { + return v + } + } + } + return "" +} + // ParseHeaders parse header for sending method func ParseHeaders(rawHeaders map[string][]string) []map[string]string { var headers []map[string]string diff --git a/libs/http.go b/libs/http.go index bd44806..ff4f103 100644 --- a/libs/http.go +++ b/libs/http.go @@ -38,6 +38,7 @@ type Request struct { Port string Path string URL string + Proto string Proxy string Method string Payload string