add strict probe for httpx

This commit is contained in:
Doğan Can Bakır
2025-12-03 11:43:49 +07:00
parent 3dab87bf77
commit 39b58805fc
4 changed files with 18 additions and 9 deletions

View File

@@ -434,6 +434,7 @@ on extensive configurability, massive extensibility and ease of use.`)
}),
flagSet.DurationVarP(&options.InputReadTimeout, "input-read-timeout", "irt", time.Duration(3*time.Minute), "timeout on input read"),
flagSet.BoolVarP(&options.DisableHTTPProbe, "no-httpx", "nh", false, "disable httpx probing for non-url input"),
flagSet.BoolVarP(&options.StrictProbe, "strict-probe", "sp", false, "stop scanning when httpx probe returns 0 URLs (no fallback to raw input)"),
flagSet.BoolVar(&options.DisableStdin, "no-stdin", false, "disable stdin processing"),
)

View File

@@ -19,14 +19,15 @@ import (
// initializeTemplatesHTTPInput initializes the http form of input
// for any loaded http templates if input is in non-standard format.
func (r *Runner) initializeTemplatesHTTPInput() (*hybrid.HybridMap, error) {
// Returns the hybrid map, the count of URLs found, and an error.
func (r *Runner) initializeTemplatesHTTPInput() (*hybrid.HybridMap, int32, error) {
hm, err := hybrid.New(hybrid.DefaultDiskOptions)
if err != nil {
return nil, errors.Wrap(err, "could not create temporary input file")
return nil, 0, errors.Wrap(err, "could not create temporary input file")
}
if r.inputProvider.InputType() == provider.MultiFormatInputProvider {
// currently http probing for input mode types is not supported
return hm, nil
return hm, 0, nil
}
r.Logger.Info().Msgf("Running httpx on input host")
@@ -41,19 +42,19 @@ func (r *Runner) initializeTemplatesHTTPInput() (*hybrid.HybridMap, error) {
dialers := protocolstate.GetDialersWithId(r.options.ExecutionId)
if dialers == nil {
return nil, fmt.Errorf("dialers not initialized for %s", r.options.ExecutionId)
return nil, 0, fmt.Errorf("dialers not initialized for %s", r.options.ExecutionId)
}
httpxOptions.NetworkPolicy = dialers.NetworkPolicy
httpxClient, err := httpx.New(&httpxOptions)
if err != nil {
return nil, errors.Wrap(err, "could not create httpx client")
return nil, 0, errors.Wrap(err, "could not create httpx client")
}
// Probe the non-standard URLs and store them in cache
swg, err := syncutil.New(syncutil.WithSize(r.options.BulkSize))
if err != nil {
return nil, errors.Wrap(err, "could not create adaptive group")
return nil, 0, errors.Wrap(err, "could not create adaptive group")
}
var count atomic.Int32
r.inputProvider.Iterate(func(value *contextargs.MetaInput) bool {
@@ -80,6 +81,7 @@ func (r *Runner) initializeTemplatesHTTPInput() (*hybrid.HybridMap, error) {
})
swg.Wait()
r.Logger.Info().Msgf("Found %d URL from httpx", count.Load())
return hm, nil
urlCount := count.Load()
r.Logger.Info().Msgf("Found %d URL from httpx", urlCount)
return hm, urlCount, nil
}

View File

@@ -701,10 +701,14 @@ func (r *Runner) RunEnumeration() error {
// are used, and if inputs are non-http to pre-perform probing
// of urls and storing them for execution.
if !r.options.DisableHTTPProbe && loader.IsHTTPBasedProtocolUsed(store) && r.isInputNonHTTP() {
inputHelpers, err := r.initializeTemplatesHTTPInput()
inputHelpers, urlCount, err := r.initializeTemplatesHTTPInput()
if err != nil {
return errors.Wrap(err, "could not probe http input")
}
if r.options.StrictProbe && urlCount == 0 {
r.Logger.Info().Msgf("Strict probe mode: No URLs found from httpx probe, skipping scan")
return nil
}
executorOpts.InputHelper.InputsHTTP = inputHelpers
}

View File

@@ -201,6 +201,8 @@ type Options struct {
DebugResponse bool
// DisableHTTPProbe disables http probing feature of input normalization
DisableHTTPProbe bool
// StrictProbe stops scanning when httpx probe returns 0 URLs (no fallback to raw input)
StrictProbe bool
// LeaveDefaultPorts skips normalization of default ports
LeaveDefaultPorts bool
// AutomaticScan enables automatic tech based template execution