From 78a74d3f2b77b716242b2aed669c0414bc0b4241 Mon Sep 17 00:00:00 2001 From: RicYaben Date: Wed, 31 Jul 2024 13:25:49 +0100 Subject: [PATCH] add token as param to url --- modules/webproxy/request/builder.go | 55 +++++++++++++++++++++++------ modules/webproxy/scanner.go | 10 ++++-- modules/webproxy/webproxy_test.go | 7 ++-- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/modules/webproxy/request/builder.go b/modules/webproxy/request/builder.go index 98ac3ab3..03bb048b 100644 --- a/modules/webproxy/request/builder.go +++ b/modules/webproxy/request/builder.go @@ -2,6 +2,8 @@ package request import ( "fmt" + "net" + "net/url" "strings" "github.com/zmap/zgrab2/lib/http" @@ -14,7 +16,7 @@ type HttpRequestBuilder interface { Build(body string) (*http.Request, error) } -func NewHttpRequestBuilder(method, url string, headers http.Header) (HttpRequestBuilder, error) { +func NewHttpRequestBuilder(method, url string, headers http.Header, slug bool) (HttpRequestBuilder, error) { builder := new(httpProxyRequestBuilder) err := builder.setMethod(method) @@ -24,22 +26,45 @@ func NewHttpRequestBuilder(method, url string, headers http.Header) (HttpRequest builder.setUrl(url) builder.setHeaders(headers) + builder.setSlugToken(slug) return builder, nil } type httpProxyRequestBuilder struct { method string - url string + url *url.URL headers http.Header + slug bool } -func (builder *httpProxyRequestBuilder) setUrl(url string) { - if len(url) > 0 { - builder.url = fmt.Sprintf("http://%s", url) - return +func (builder *httpProxyRequestBuilder) setUrl(uri string) { + u, err := url.Parse(uri) + if err != nil { + host, port, err := net.SplitHostPort(uri) + if err != nil { + // If SplitHostPort fails, it might be because there is no port + host = uri + port = "80" + } + + // Attempt to handle input as a plain host (domain or IP without scheme) + if ip := net.ParseIP(host); ip == nil { + panic("uri %s not a valid address") + } + u = &url.URL{Host: net.JoinHostPort(host, port)} + } + + if u.Scheme == "" { + u.Scheme = "http" // Default scheme if none is provided } - builder.url = "/" + + builder.url = u +} + +func (builder *httpProxyRequestBuilder) setSlugToken(slug bool) *httpProxyRequestBuilder { + builder.slug = slug + return builder } func (builder *httpProxyRequestBuilder) setMethod(method string) error { @@ -69,16 +94,24 @@ func (builder *httpProxyRequestBuilder) setHeaders(headers http.Header) { } } -func (builder *httpProxyRequestBuilder) Build(body string) (*http.Request, error) { +func (builder *httpProxyRequestBuilder) Build(token string) (*http.Request, error) { // Add the body var b *strings.Reader - if len(body) > 0 { - b = strings.NewReader(body) + if len(token) > 0 { + b = strings.NewReader(token) + } + + // Slug token if needed + uri := builder.url + if builder.slug { + q := uri.Query() + q.Add("token", token) + uri.RawQuery = q.Encode() } // Create the request - req, err := http.NewRequest(builder.method, builder.url, b) + req, err := http.NewRequest(builder.method, uri.String(), b) if err != nil { return nil, err } diff --git a/modules/webproxy/scanner.go b/modules/webproxy/scanner.go index f19b2940..93212d87 100644 --- a/modules/webproxy/scanner.go +++ b/modules/webproxy/scanner.go @@ -42,6 +42,7 @@ type Flags struct { MaxSize int `long:"max-size" default:"256" description:"Max kilobytes to read in response to an HTTP request"` MaxRedirects int `long:"max-redirects" default:"0" description:"Max number of redirects to follow"` HmacKey string `long:"hmac-key" description:"HMAC secret to create and verify JWT identifiers"` + SlugToken bool `long:"slug-token" default:"true" description:"Use the JWT as a parameter in the request. E.g.: /scan?token="` CustomHeadersNames string `long:"custom-headers-names" description:"CSV of custom HTTP headers to send to server"` CustomHeadersValues string `long:"custom-headers-values" description:"CSV of custom HTTP header values to send to server. Should match order of custom-headers-names."` @@ -122,7 +123,12 @@ func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error { if fl.Method == "" { fl.Method = "POST" } - reqBuilder, err := request.NewHttpRequestBuilder(fl.Method, fl.Endpoint, headers) + + if len(fl.Endpoint) == 0 { + return fmt.Errorf("must include flag endpoint") + } + + reqBuilder, err := request.NewHttpRequestBuilder(fl.Method, fl.Endpoint, headers, fl.SlugToken) if err != nil { return err } @@ -158,7 +164,7 @@ func (scanner *Scanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{ } // Build the token (body) - addr := fmt.Sprintf("%s:%d", t.IP.String(), t.Port) + addr := fmt.Sprintf("%s:%d", t.IP.String(), *t.Port) tkn, err := scanner.tokenBuilder.GenerateToken(addr) if err != nil { return zgrab2.SCAN_UNKNOWN_ERROR, nil, err diff --git a/modules/webproxy/webproxy_test.go b/modules/webproxy/webproxy_test.go index 441860bb..9a46c6e6 100644 --- a/modules/webproxy/webproxy_test.go +++ b/modules/webproxy/webproxy_test.go @@ -19,6 +19,7 @@ type webproxyTester struct { laddress string hmackey string bChan chan string + slug bool } func (cfg *webproxyTester) runHTTPServer(t *testing.T) { @@ -49,6 +50,7 @@ func (cfg *webproxyTester) getScanner() (*Scanner, error) { flags.Timeout = 5 * time.Second flags.Endpoint = fmt.Sprintf("%s:%d", cfg.laddress, cfg.lport) flags.HmacKey = cfg.hmackey + //flags.SlugToken = cfg.slug scanner := module.NewScanner() if err := scanner.Init(flags); err != nil { @@ -99,12 +101,13 @@ func (cfg *webproxyTester) runTest(t *testing.T, testName string) { var tests = map[string]*webproxyTester{ "success": { - paddress: "192.168.0.1", - laddress: "127.0.0.1", + paddress: "10.176.21.85", + laddress: "10.176.21.141", pport: 8080, lport: 8081, bChan: make(chan string, 1), hmackey: "gz13WcqhVBy09Mnw7ZZYNCqqlWvyRfJx", + slug: true, }, }