Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add probe-all-ips feature #427

Merged
merged 7 commits into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions runner/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type scanOptions struct {
extractRegex *regexp.Regexp
ExcludeCDN bool
HostMaxErrors int
ProbeAllIPS bool
}

func (s *scanOptions) Clone() *scanOptions {
Expand Down Expand Up @@ -192,6 +193,7 @@ type Options struct {
HostMaxErrors int
Stream bool
SkipDedupe bool
ProbeAllIPS bool
}

// ParseOptions parses the command line options for application
Expand Down Expand Up @@ -288,6 +290,7 @@ func ParseOptions() *Options {
flagSet.StringVar(&options.RequestBody, "body", "", "Post body to include in HTTP request"),
flagSet.BoolVarP(&options.Stream, "stream","s", false, "Stream mode - start elaborating input targets without sorting"),
flagSet.BoolVarP(&options.SkipDedupe, "skip-dedupe","sd", false, "Disable dedupe input items (only used with stream mode)"),
flagSet.BoolVar(&options.ProbeAllIPS, "probe-all-ips", false, "Probe all the ips"),
)

createGroup(flagSet, "debug", "Debug",
Expand Down
56 changes: 40 additions & 16 deletions runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ func New(options *Options) (*Runner, error) {

scanopts.ExcludeCDN = options.ExcludeCDN
scanopts.HostMaxErrors = options.HostMaxErrors
scanopts.ProbeAllIPS = options.ProbeAllIPS
runner.scanopts = scanopts

if options.ShowStatistics {
Expand Down Expand Up @@ -637,7 +638,7 @@ func (r *Runner) process(t string, wg *sizedwaitgroup.SizedWaitGroup, hp *httpx.
protocols = []string{httpx.HTTPS, httpx.HTTP}
}

for target := range targets(stringz.TrimProtocol(t, scanopts.NoFallback || scanopts.NoFallbackScheme)) {
for target := range r.targets(hp, stringz.TrimProtocol(t, scanopts.NoFallback || scanopts.NoFallbackScheme)) {
// if no custom ports specified then test the default ones
if len(customport.Ports) == 0 {
for _, method := range scanopts.Methods {
Expand Down Expand Up @@ -700,7 +701,7 @@ func (r *Runner) process(t string, wg *sizedwaitgroup.SizedWaitGroup, hp *httpx.
}

// returns all the targets within a cidr range or the single target
func targets(target string) chan string {
func (r *Runner) targets(hp *httpx.HTTPX, target string) chan string {
results := make(chan string)
go func() {
defer close(results)
Expand All @@ -721,6 +722,14 @@ func targets(target string) chan string {
for _, ip := range cidrIps {
results <- ip
}
} else if r.options.ProbeAllIPS {
ips, _, err := getDNSData(hp, target)
if err != nil || len(ips) == 0 {
results <- target
}
for _, ip := range ips {
results <- strings.Join([]string{ip, target}, ",")
}
} else {
results <- target
}
Expand All @@ -735,7 +744,15 @@ func (r *Runner) analyze(hp *httpx.HTTPX, protocol, domain, method, origInput st
}
retried := false
retry:
var customHost string
var customHost, customIP string
if scanopts.ProbeAllIPS {
parts := strings.SplitN(domain, ",", 2) // support `ProbeAllIPS` with `VHostInput`
if len(parts) == 2 {
customIP = parts[0]
domain = parts[1]
customHost = parts[1]
}
}
if scanopts.VHostInput {
parts := strings.Split(domain, ",")
//nolint:gomnd // not a magic number
Expand Down Expand Up @@ -789,6 +806,9 @@ retry:
if customHost != "" {
req.Host = customHost
}
if customIP != "" {
req.URL.Host = customIP
}

hp.SetCustomHeaders(req, hp.CustomHeaders)
// We set content-length even if zero to allow net/http to follow 307/308 redirects (it fails on unknown size)
Expand Down Expand Up @@ -836,7 +856,7 @@ retry:
}
}
// fix the final output url
fullURL := req.URL.String()
fullURL := URL.String()
parsedURL, _ := urlutil.Parse(fullURL)
if r.options.Unsafe {
parsedURL.RequestURI = reqURI
Expand Down Expand Up @@ -1038,21 +1058,13 @@ retry:
r.stats.IncrementCounter("requests", 1)
}
}
ip := hp.Dialer.GetDialedIP(URL.Host)
if scanopts.OutputIP {
ip := hp.Dialer.GetDialedIP(req.URL.Host)
if scanopts.OutputIP || scanopts.ProbeAllIPS {
builder.WriteString(fmt.Sprintf(" [%s]", ip))
}

var (
ips []string
cnames []string
)
dnsData, err := hp.Dialer.GetDNSData(URL.Host)
if dnsData != nil && err == nil {
ips = append(ips, dnsData.A...)
ips = append(ips, dnsData.AAAA...)
cnames = dnsData.CNAME
} else {
ips, cnames, err := getDNSData(hp, URL.Host)
if err != nil {
ips = append(ips, ip)
}

Expand Down Expand Up @@ -1370,3 +1382,15 @@ func (r *Runner) skipCDNPort(host string, port string) bool {

return false
}

func getDNSData(hp *httpx.HTTPX, hostname string) (ips, cnames []string, err error) {
dnsData, err := hp.Dialer.GetDNSData(hostname)
if err != nil {
return nil, nil, err
}
ips = make([]string, 0, len(dnsData.A)+len(dnsData.AAAA))
ips = append(ips, dnsData.A...)
ips = append(ips, dnsData.AAAA...)
cnames = dnsData.CNAME
return
}