mirror of
https://github.com/projectdiscovery/httpx
synced 2026-06-08 16:50:17 +00:00
Fixing and improving custom ports handling (#714)
* Fixing and improving custom ports * adding test case from https://github.com/projectdiscovery/httpx/pull/713
This commit is contained in:
@@ -14,3 +14,4 @@ scanme.sh {{binary}} -silent -unsafe
|
||||
scanme.sh {{binary}} -silent -x all
|
||||
scanme.sh {{binary}} -silent -body 'a=b'
|
||||
scanme.sh {{binary}} -silent -exclude-cdn
|
||||
scanme.sh {{binary}} -silent -ports https:443
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectdiscovery/sliceutil"
|
||||
|
||||
"github.com/projectdiscovery/httpx/common/httpx"
|
||||
@@ -29,36 +29,6 @@ func (c *CustomPorts) String() string {
|
||||
return "Custom Ports"
|
||||
}
|
||||
|
||||
// ValidateCustomPorts to validate the custom port range
|
||||
func ValidateCustomPorts(value string) error {
|
||||
potentialRange := strings.Split(value, "-")
|
||||
if len(potentialRange) < portRangeParts {
|
||||
if _, err := strconv.Atoi(value); err != nil {
|
||||
return fmt.Errorf("Could not cast port to integer from your value: %s. Resulting error: %s.\n", value, err.Error())
|
||||
}
|
||||
} else {
|
||||
part1 := potentialRange[0]
|
||||
part2 := potentialRange[1]
|
||||
lowP, err := strconv.Atoi(part1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not cast first port of your range(%s) to integer from your value: %s. Resulting error: %s.\n",
|
||||
value, part1, err.Error())
|
||||
}
|
||||
highP, err := strconv.Atoi(part2)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not cast last port of your port range(%s) to integer from "+
|
||||
"your value: %s. Resulting error %s.\n",
|
||||
value, part2, err.Error())
|
||||
}
|
||||
if lowP > highP {
|
||||
return fmt.Errorf("First value of port range should be lower than the last port "+
|
||||
"from your range: [%d, %d].\n",
|
||||
lowP, highP)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set a port range
|
||||
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
|
||||
@@ -83,39 +53,38 @@ func (c *CustomPorts) Set(value string) error {
|
||||
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 from your value: %s. Resulting error: %s. Skipping it.\n",
|
||||
potentialPort, err.Error())
|
||||
p, err := strconv.Atoi(potentialPort)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Could not cast port to integer from your value: %s\n", potentialPort))
|
||||
}
|
||||
if err := checkPortValue(p); err != nil {
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
// expand range
|
||||
var lowP, highP int
|
||||
lowP, err := strconv.Atoi(potentialRange[0])
|
||||
if err != nil {
|
||||
gologger.Warning().Msgf("Could not cast first port of your range(%s) to integer from your value: %s. Resulting error: %s. Skipping it.\n",
|
||||
potentialPort, potentialRange[0], err.Error())
|
||||
continue
|
||||
return errors.Wrap(err, fmt.Sprintf("Could not cast first port of your range(%s) to integer from your value: %s", potentialPort, potentialRange[0]))
|
||||
}
|
||||
highP, err = strconv.Atoi(potentialRange[1])
|
||||
if err := checkPortValue(lowP); err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("first port of your range(%d)", lowP))
|
||||
}
|
||||
highP, err := strconv.Atoi(potentialRange[1])
|
||||
if err != nil {
|
||||
gologger.Warning().Msgf("Could not cast last port of your port range(%s) to integer from "+
|
||||
"your value: %s. Resulting error %s. Skipping it\n",
|
||||
potentialPort, potentialRange[1], err.Error())
|
||||
continue
|
||||
return errors.Wrap(err, fmt.Sprintf("Could not cast last port of your port range(%s) to integer from your value: %s", potentialPort, potentialRange[1]))
|
||||
}
|
||||
if err := checkPortValue(highP); err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("last port of your range(%d)", lowP))
|
||||
}
|
||||
|
||||
if lowP > highP {
|
||||
gologger.Warning().Msgf("First value of port range should be lower than the last port "+
|
||||
"from your range: [%d, %d]. Skipping it.\n",
|
||||
lowP, highP)
|
||||
continue
|
||||
return fmt.Errorf("First value of port range should be lower than the last port from your range: [%d, %d]", lowP, highP)
|
||||
}
|
||||
|
||||
for i := lowP; i <= highP; i++ {
|
||||
@@ -132,3 +101,10 @@ func (c *CustomPorts) Set(value string) error {
|
||||
*c = append(*c, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPortValue(port int) error {
|
||||
if port > 65535 {
|
||||
return errors.New("port value is bigger than 65535")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-13
@@ -22,7 +22,6 @@ import (
|
||||
fileutilz "github.com/projectdiscovery/httpx/common/fileutil"
|
||||
"github.com/projectdiscovery/httpx/common/slice"
|
||||
"github.com/projectdiscovery/httpx/common/stringz"
|
||||
"github.com/projectdiscovery/sliceutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -319,7 +318,7 @@ func ParseOptions() *Options {
|
||||
|
||||
flagSet.CreateGroup("Misc", "Miscellaneous",
|
||||
flagSet.BoolVarP(&options.ProbeAllIPS, "probe-all-ips", "pa", false, "probe all the ips associated with same host"),
|
||||
flagSet.VarP(&options.CustomPorts, "ports", "p", "ports to probe (nmap syntax: eg 1,2-10,11)"),
|
||||
flagSet.VarP(&options.CustomPorts, "ports", "p", "ports to probe (nmap syntax: eg http:1,2-10,11,https:80)"),
|
||||
flagSet.StringVar(&options.RequestURIs, "path", "", "path or list of paths to probe (comma-separated, file)"),
|
||||
flagSet.BoolVar(&options.TLSProbe, "tls-probe", false, "send http probes on the extracted TLS domains (dns_name)"),
|
||||
flagSet.BoolVar(&options.CSPProbe, "csp-probe", false, "send http probes on the extracted CSP domains"),
|
||||
@@ -512,17 +511,7 @@ func (options *Options) ValidateOptions() error {
|
||||
if len(options.OutputMatchCdn) > 0 || len(options.OutputFilterCdn) > 0 {
|
||||
options.OutputCDN = true
|
||||
}
|
||||
// Validate the custom port range
|
||||
if len(options.CustomPorts) > 0 {
|
||||
for _, value := range options.CustomPorts {
|
||||
potentialPorts := sliceutil.Dedupe(strings.Split(value, ","))
|
||||
for _, port := range potentialPorts {
|
||||
if err := customport.ValidateCustomPorts(port); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user