diff --git a/common/customports/customport.go b/common/customports/customport.go index 8a67186..7728b78 100644 --- a/common/customports/customport.go +++ b/common/customports/customport.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/projectdiscovery/gologger" + "github.com/projectdiscovery/sliceutil" "github.com/projectdiscovery/httpx/common/httpx" ) @@ -31,7 +32,7 @@ func (c *CustomPorts) String() string { func (c *CustomPorts) Set(value string) error { // ports can be like nmap -p [https|http:]start-end,[https|http:]port1,[https|http:]port2,[https|http:]port3 // splits on comma - potentialPorts := strings.Split(value, ",") + potentialPorts := sliceutil.Dedupe(strings.Split(value, ",")) // check if port is a single integer value or needs to be expanded further for _, potentialPort := range potentialPorts { @@ -43,12 +44,20 @@ func (c *CustomPorts) Set(value string) error { } else if strings.HasPrefix(potentialPort, httpx.HTTPS+":") { potentialPort = strings.TrimPrefix(potentialPort, httpx.HTTPS+":") protocol = httpx.HTTPS + } else if strings.HasPrefix(potentialPort, httpx.HTTPandHTTPS+":") { + potentialPort = strings.TrimPrefix(potentialPort, httpx.HTTPandHTTPS+":") + protocol = httpx.HTTPandHTTPS } potentialRange := strings.Split(potentialPort, "-") // it's a single port? if len(potentialRange) < portRangeParts { if p, err := strconv.Atoi(potentialPort); err == nil { + if existingProtocol, ok := Ports[p]; ok { + if existingProtocol == httpx.HTTP && protocol == httpx.HTTPS || existingProtocol == httpx.HTTPS && protocol == httpx.HTTP { + protocol = httpx.HTTPandHTTPS + } + } Ports[p] = protocol } else { gologger.Warning().Msgf("Could not cast port to integer, your value: %s, resulting error %s. Skipping it\n", @@ -79,6 +88,11 @@ func (c *CustomPorts) Set(value string) error { } for i := lowP; i <= highP; i++ { + if existingProtocol, ok := Ports[i]; ok { + if existingProtocol == httpx.HTTP && protocol == httpx.HTTPS || existingProtocol == httpx.HTTPS && protocol == httpx.HTTP { + protocol = httpx.HTTPandHTTPS + } + } Ports[i] = protocol } } diff --git a/common/httpx/http2.go b/common/httpx/http2.go index 83f827c..a1f0bb3 100644 --- a/common/httpx/http2.go +++ b/common/httpx/http2.go @@ -16,8 +16,10 @@ const ( HTTP = "http" // HTTPS defines the secure http scheme HTTPS = "https" - // HTTPorHTTPS defines the both http and https scheme + // HTTPorHTTPS defines both http and https scheme in mutual exclusion HTTPorHTTPS = "http|https" + // HTTPandHTTPS defines both http and https scheme + HTTPandHTTPS = "http&https" ) // SupportHTTP2 checks if the target host supports HTTP2 diff --git a/go.mod b/go.mod index cfb893c..62a745b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.14 require ( github.com/akrylysov/pogreb v0.10.1 // indirect - github.com/bluele/gcache v0.0.2 // indirect + github.com/bluele/gcache v0.0.2 github.com/corpix/uarand v0.1.1 github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/golang/glog v0.0.0-20210429001901-424d2337a529 // indirect @@ -28,6 +28,7 @@ require ( github.com/projectdiscovery/rawhttp v0.0.8-0.20210814181734-56cca67b6e7e github.com/projectdiscovery/retryabledns v1.0.12 // indirect github.com/projectdiscovery/retryablehttp-go v1.0.2-0.20210526144436-e15804ddc7dc + github.com/projectdiscovery/sliceutil v0.0.0-20210804143453-61f3e7fd43ea github.com/projectdiscovery/stringsutil v0.0.0-20210617141317-00728870f68d github.com/projectdiscovery/urlutil v0.0.0-20210805190935-3d83726391c1 github.com/projectdiscovery/wappalyzergo v0.0.10 diff --git a/go.sum b/go.sum index 21554c9..82f509b 100644 --- a/go.sum +++ b/go.sum @@ -153,8 +153,6 @@ github.com/projectdiscovery/hmap v0.0.1/go.mod h1:VDEfgzkKQdq7iGTKz8Ooul0NuYHQ8q github.com/projectdiscovery/hmap v0.0.2-0.20210616215655-7b78e7f33d1f/go.mod h1:FH+MS/WNKTXJQtdRn+/Zg5WlKCiMN0Z1QUedUIuM5n8= github.com/projectdiscovery/hmap v0.0.2-0.20210630092648-6c0a1b362caa h1:KeN6/bZOVxtS4XkgzRvYxpXWZSZt+AoGP5Myyr3/Duk= github.com/projectdiscovery/hmap v0.0.2-0.20210630092648-6c0a1b362caa/go.mod h1:FH+MS/WNKTXJQtdRn+/Zg5WlKCiMN0Z1QUedUIuM5n8= -github.com/projectdiscovery/httputil v0.0.0-20210508183653-2e37c34b438d h1:IdBTOSGaPrZ8+FK0uYMQIva9dYIR5F55PLFWYtBBKc0= -github.com/projectdiscovery/httputil v0.0.0-20210508183653-2e37c34b438d/go.mod h1:Vm2DY4NwUV5yA6TNzJOOjTYGjTcVfuEN8m9Y5dAksLQ= github.com/projectdiscovery/httputil v0.0.0-20210816170244-86fd46bc09f5 h1:GzruqQhb+sj1rEuHRFLhWX8gH/tJ+sj1udRjOy9VCJo= github.com/projectdiscovery/httputil v0.0.0-20210816170244-86fd46bc09f5/go.mod h1:BueJPSPWAX11IFS6bdAqTkekiIz5Fgco5LVc1kqO9L4= github.com/projectdiscovery/ipranger v0.0.2/go.mod h1:kcAIk/lo5rW+IzUrFkeYyXnFJ+dKwYooEOHGVPP/RWE= @@ -178,6 +176,8 @@ github.com/projectdiscovery/retryabledns v1.0.12/go.mod h1:4sMC8HZyF01HXukRleSQY github.com/projectdiscovery/retryablehttp-go v1.0.1/go.mod h1:SrN6iLZilNG1X4neq1D+SBxoqfAF4nyzvmevkTkWsek= github.com/projectdiscovery/retryablehttp-go v1.0.2-0.20210526144436-e15804ddc7dc h1:769c7sQOl9BP8dhE8uv0mQX9WmcXo6Jzv//Nm+qAf50= github.com/projectdiscovery/retryablehttp-go v1.0.2-0.20210526144436-e15804ddc7dc/go.mod h1:dx//aY9V247qHdsRf0vdWHTBZuBQ2vm6Dq5dagxrDYI= +github.com/projectdiscovery/sliceutil v0.0.0-20210804143453-61f3e7fd43ea h1:S+DC2tmKG93Om42cnTqrBfIv699pwSIhafqZvip+RIA= +github.com/projectdiscovery/sliceutil v0.0.0-20210804143453-61f3e7fd43ea/go.mod h1:QHXvznfPfA5f0AZUIBkbLapoUJJlsIDgUlkKva6dOr4= github.com/projectdiscovery/stringsutil v0.0.0-20210524051937-51dabe3b72c0/go.mod h1:TVSdZC0rRQeMIbsNSiGPhbmhyRtxqqtAGA9JiiNp2r4= github.com/projectdiscovery/stringsutil v0.0.0-20210617141317-00728870f68d h1:nlOAex7twmrEqD5i6WLnugF9uO3DQ6jDEKN9gevrTAk= github.com/projectdiscovery/stringsutil v0.0.0-20210617141317-00728870f68d/go.mod h1:TVSdZC0rRQeMIbsNSiGPhbmhyRtxqqtAGA9JiiNp2r4= diff --git a/runner/runner.go b/runner/runner.go index 06bfd61..e6eb804 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -520,7 +520,7 @@ func (r *Runner) RunEnumeration() { func (r *Runner) process(t string, wg *sizedwaitgroup.SizedWaitGroup, hp *httpx.HTTPX, protocol string, scanopts *scanOptions, output chan Result) { protocols := []string{protocol} - if scanopts.NoFallback { + if scanopts.NoFallback || protocol == httpx.HTTPandHTTPS { protocols = []string{httpx.HTTPS, httpx.HTTP} } @@ -554,24 +554,30 @@ func (r *Runner) process(t string, wg *sizedwaitgroup.SizedWaitGroup, hp *httpx. } } - for port, wantedProtocol := range customport.Ports { - for _, method := range scanopts.Methods { - wg.Add() - go func(port int, method, protocol string) { - defer wg.Done() - h, _ := urlutil.ChangePort(target, fmt.Sprint(port)) - result := r.analyze(hp, protocol, h, method, t, scanopts) - output <- result - if scanopts.TLSProbe && result.TLSData != nil { - scanopts.TLSProbe = false - for _, tt := range result.TLSData.DNSNames { - r.process(tt, wg, hp, protocol, scanopts, output) + for port, wantedProtocolForPort := range customport.Ports { + wantedProtocols := []string{wantedProtocolForPort} + if wantedProtocolForPort == httpx.HTTPandHTTPS { + wantedProtocols = []string{httpx.HTTPS, httpx.HTTP} + } + for _, wantedProtocol := range wantedProtocols { + for _, method := range scanopts.Methods { + wg.Add() + go func(port int, method, protocol string) { + defer wg.Done() + h, _ := urlutil.ChangePort(target, fmt.Sprint(port)) + result := r.analyze(hp, protocol, h, method, t, scanopts) + output <- result + if scanopts.TLSProbe && result.TLSData != nil { + scanopts.TLSProbe = false + for _, tt := range result.TLSData.DNSNames { + r.process(tt, wg, hp, protocol, scanopts, output) + } + for _, tt := range result.TLSData.CommonName { + r.process(tt, wg, hp, protocol, scanopts, output) + } } - for _, tt := range result.TLSData.CommonName { - r.process(tt, wg, hp, protocol, scanopts, output) - } - } - }(port, method, wantedProtocol) + }(port, method, wantedProtocol) + } } } if r.options.ShowStatistics { @@ -611,7 +617,7 @@ func targets(target string) chan string { func (r *Runner) analyze(hp *httpx.HTTPX, protocol, domain, method, origInput string, scanopts *scanOptions) Result { origProtocol := protocol - if protocol == httpx.HTTPorHTTPS { + if protocol == httpx.HTTPorHTTPS || protocol == httpx.HTTPandHTTPS { protocol = httpx.HTTPS } retried := false