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

Adding support to scan all v4/v6 IPs #2709

Merged
merged 32 commits into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9a39cd2
Adding support to scan all v4/v6 IPs
Mzack9999 Oct 11, 2022
fc5f2ac
adding tests
Mzack9999 Oct 12, 2022
f150ec7
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Oct 19, 2022
8861e06
metainput prototype
Mzack9999 Oct 20, 2022
fafd067
using new signature
Mzack9999 Oct 20, 2022
6d6468c
fixing nil pointer
Mzack9999 Oct 20, 2022
fb754e7
adding request context with metadata
Mzack9999 Oct 21, 2022
188cbd1
removing log instruction
Mzack9999 Oct 21, 2022
b1fb54c
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Oct 21, 2022
5f12254
fixing merge conflicts
Mzack9999 Oct 21, 2022
ef6997a
adding clone helpers
Mzack9999 Oct 21, 2022
0ec52f8
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Oct 21, 2022
0a5706b
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Oct 31, 2022
04cf51f
attempting to fix ipv6 square parenthesis wrap
Mzack9999 Oct 31, 2022
a9dde6c
fixing dialed ip info
Mzack9999 Oct 31, 2022
2b52a00
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Nov 2, 2022
470c661
fixing syntax
Mzack9999 Nov 2, 2022
51b6580
fixing output ip selection
Mzack9999 Nov 2, 2022
b5e034f
adding integration tests
Mzack9999 Nov 2, 2022
91fd8bd
disabling test due to gh ipv6 issue
Mzack9999 Nov 2, 2022
27cf523
using ipv4 only due to GH limited networking
Mzack9999 Nov 2, 2022
5a910cf
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Nov 3, 2022
139186c
extending metainput marshaling
Mzack9999 Nov 3, 2022
2310552
fixing hmap key
Mzack9999 Nov 3, 2022
131be15
adding test for httpx integration
Mzack9999 Nov 3, 2022
15a735d
fixing lint error
Mzack9999 Nov 3, 2022
05b11d9
reworking marshaling/id-calculation
Mzack9999 Nov 3, 2022
aa398a7
adding ip version validation
Mzack9999 Nov 3, 2022
d30a2f1
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Nov 6, 2022
46097b7
improving handling non url targets
Mzack9999 Nov 7, 2022
2a32341
Merge branch 'dev' into issue-2141-scan-all-ips
Mzack9999 Nov 9, 2022
8c4287e
fixing condition check
Mzack9999 Nov 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion v2/cmd/integration-test/code.go
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/parsers"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/hosterrorscache"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolinit"
Expand Down Expand Up @@ -123,7 +124,7 @@ func executeNucleiAsCode(templatePath, templateURL string) ([]string, error) {
}
store.Load()

input := &inputs.SimpleInputProvider{Inputs: []string{templateURL}}
input := &inputs.SimpleInputProvider{Inputs: []*contextargs.MetaInput{{Input: templateURL}}}
_ = engine.Execute(store.Templates(), input)
engine.WorkPool().Wait() // Wait for the scan to finish

Expand Down
2 changes: 2 additions & 0 deletions v2/cmd/nuclei/main.go
Expand Up @@ -125,6 +125,8 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.StringSliceVarP(&options.Targets, "target", "u", []string{}, "target URLs/hosts to scan", goflags.StringSliceOptions),
flagSet.StringVarP(&options.TargetsFilePath, "list", "l", "", "path to file containing a list of target URLs/hosts to scan (one per line)"),
flagSet.StringVar(&options.Resume, "resume", "", "Resume scan using resume.cfg (clustering will be disabled)"),
flagSet.BoolVarP(&options.ScanAllIPs, "scan-all-ips", "sa", false, "Scan all the ip's associated with dns record"),
flagSet.StringVarP(&options.IPVersion, "ip-version", "iv", "any", "IP version to scan of hostname (4,6,any) - (default any)"),
)

flagSet.CreateGroup("templates", "Templates",
Expand Down
5 changes: 3 additions & 2 deletions v2/internal/runner/enumerate.go
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/core"
"github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
"go.uber.org/atomic"
)

Expand Down Expand Up @@ -84,8 +85,8 @@ func (r *Runner) runCloudEnumeration(store *loader.Store, nostore bool) (*atomic
// TODO: Add payload file and workflow support for private templates
catalogChecksums := nucleicloud.ReadCatalogChecksum()

targets := make([]string, 0, r.hmapInputProvider.Count())
r.hmapInputProvider.Scan(func(value string) bool {
targets := make([]*contextargs.MetaInput, 0, r.hmapInputProvider.Count())
r.hmapInputProvider.Scan(func(value *contextargs.MetaInput) bool {
targets = append(targets, value)
return true
})
Expand Down
11 changes: 6 additions & 5 deletions v2/internal/runner/inputs.go
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/pkg/errors"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/hmap/store/hybrid"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
"github.com/projectdiscovery/retryablehttp-go"
"github.com/remeh/sizedwaitgroup"
Expand Down Expand Up @@ -37,18 +38,18 @@ func (r *Runner) initializeTemplatesHTTPInput() (*hybrid.HybridMap, error) {
// Probe the non-standard URLs and store them in cache
swg := sizedwaitgroup.New(bulkSize)
count := int32(0)
r.hmapInputProvider.Scan(func(value string) bool {
if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") {
r.hmapInputProvider.Scan(func(value *contextargs.MetaInput) bool {
if strings.HasPrefix(value.Input, "http://") || strings.HasPrefix(value.Input, "https://") {
return true
}

swg.Add()
go func(input string) {
go func(input *contextargs.MetaInput) {
defer swg.Done()

if result := probeURL(input, httpclient); result != "" {
if result := probeURL(input.Input, httpclient); result != "" {
atomic.AddInt32(&count, 1)
_ = hm.Set(input, []byte(result))
_ = hm.Set(input.String(), []byte(result))
}
}(value)
return true
Expand Down
8 changes: 6 additions & 2 deletions v2/internal/runner/nucleicloud/types.go
@@ -1,11 +1,15 @@
package nucleicloud

import "time"
import (
"time"

"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
)

// AddScanRequest is a nuclei scan input item.
type AddScanRequest struct {
// RawTargets is a list of raw target URLs for the scan.
RawTargets []string `json:"raw_targets,omitempty"`
RawTargets []*contextargs.MetaInput `json:"raw_targets,omitempty"`
// PublicTemplates is a list of public templates for the scan
PublicTemplates []string `json:"public_templates,omitempty"`
// PrivateTemplates is a map of template-name->contents that
Expand Down
5 changes: 3 additions & 2 deletions v2/internal/runner/runner.go
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/projectfile"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/automaticscan"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/hosterrorscache"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolinit"
Expand Down Expand Up @@ -474,8 +475,8 @@ func (r *Runner) RunEnumeration() error {

func (r *Runner) isInputNonHTTP() bool {
var nonURLInput bool
r.hmapInputProvider.Scan(func(value string) bool {
if !strings.Contains(value, "://") {
r.hmapInputProvider.Scan(func(value *contextargs.MetaInput) bool {
if !strings.Contains(value.Input, "://") {
nonURLInput = true
return false
}
Expand Down
3 changes: 2 additions & 1 deletion v2/pkg/core/engine.go
Expand Up @@ -2,6 +2,7 @@ package core

import (
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
"github.com/projectdiscovery/nuclei/v2/pkg/types"
)

Expand Down Expand Up @@ -29,7 +30,7 @@ type InputProvider interface {
Count() int64
// Scan iterates the input and each found item is passed to the
// callback consumer.
Scan(callback func(value string) bool)
Scan(callback func(value *contextargs.MetaInput) bool)
}

// New returns a new Engine instance
Expand Down
26 changes: 14 additions & 12 deletions v2/pkg/core/execute.go
Expand Up @@ -43,6 +43,8 @@ func (e *Engine) ExecuteWithOpts(templatesList []*templates.Template, target Inp

wg.Add()
go func(tpl *templates.Template) {
defer wg.Done()

switch {
case tpl.SelfContained:
// Self Contained requests are executed here separately
Expand All @@ -51,7 +53,6 @@ func (e *Engine) ExecuteWithOpts(templatesList []*templates.Template, target Inp
// All other request types are executed here
e.executeModelWithInput(templateType, tpl, target, results)
}
wg.Done()
}(template)
}
e.workPool.Wait()
Expand Down Expand Up @@ -98,7 +99,7 @@ func (e *Engine) executeModelWithInput(templateType types.ProtocolType, template
currentInfo.Unlock()
}

target.Scan(func(scannedValue string) bool {
target.Scan(func(scannedValue *contextargs.MetaInput) bool {
// Best effort to track the host progression
// skips indexes lower than the minimum in-flight at interruption time
var skip bool
Expand All @@ -122,12 +123,12 @@ func (e *Engine) executeModelWithInput(templateType types.ProtocolType, template
currentInfo.Unlock()

// Skip if the host has had errors
if e.executerOpts.HostErrorsCache != nil && e.executerOpts.HostErrorsCache.Check(scannedValue) {
if e.executerOpts.HostErrorsCache != nil && e.executerOpts.HostErrorsCache.Check(scannedValue.String()) {
return true
}

wg.WaitGroup.Add()
go func(index uint32, skip bool, value string) {
go func(index uint32, skip bool, value *contextargs.MetaInput) {
defer wg.WaitGroup.Done()
defer cleanupInFlight(index)
if skip {
Expand All @@ -141,7 +142,7 @@ func (e *Engine) executeModelWithInput(templateType types.ProtocolType, template
match = e.executeWorkflow(value, template.CompiledWorkflow)
default:
ctxArgs := contextargs.New()
ctxArgs.Input = value
ctxArgs.MetaInput = value
match, err = template.Executer.Execute(ctxArgs)
}
if err != nil {
Expand Down Expand Up @@ -188,14 +189,14 @@ func (e *Engine) ExecuteWithResults(templatesList []*templates.Template, target
func (e *Engine) executeModelWithInputAndResult(templateType types.ProtocolType, template *templates.Template, target InputProvider, results *atomic.Bool, callback func(*output.ResultEvent)) {
wg := e.workPool.InputPool(templateType)

target.Scan(func(scannedValue string) bool {
target.Scan(func(scannedValue *contextargs.MetaInput) bool {
// Skip if the host has had errors
if e.executerOpts.HostErrorsCache != nil && e.executerOpts.HostErrorsCache.Check(scannedValue) {
if e.executerOpts.HostErrorsCache != nil && e.executerOpts.HostErrorsCache.Check(scannedValue.String()) {
return true
}

wg.WaitGroup.Add()
go func(value string) {
go func(value *contextargs.MetaInput) {
defer wg.WaitGroup.Done()

var match bool
Expand All @@ -205,7 +206,7 @@ func (e *Engine) executeModelWithInputAndResult(templateType types.ProtocolType,
match = e.executeWorkflow(value, template.CompiledWorkflow)
default:
ctxArgs := contextargs.New()
ctxArgs.Input = value
ctxArgs.MetaInput = value
err = template.Executer.ExecuteWithResults(ctxArgs, func(event *output.InternalWrappedEvent) {
for _, result := range event.Results {
callback(result)
Expand Down Expand Up @@ -235,7 +236,7 @@ func (e *ChildExecuter) Close() *atomic.Bool {
}

// Execute executes a template and URLs
func (e *ChildExecuter) Execute(template *templates.Template, URL string) {
func (e *ChildExecuter) Execute(template *templates.Template, value *contextargs.MetaInput) {
templateType := template.Type()

var wg *sizedwaitgroup.SizedWaitGroup
Expand All @@ -247,14 +248,15 @@ func (e *ChildExecuter) Execute(template *templates.Template, URL string) {

wg.Add()
go func(tpl *templates.Template) {
defer wg.Done()

ctxArgs := contextargs.New()
ctxArgs.Input = URL
ctxArgs.MetaInput = value
match, err := template.Executer.Execute(ctxArgs)
if err != nil {
gologger.Warning().Msgf("[%s] Could not execute step: %s\n", e.e.executerOpts.Colorizer.BrightBlue(template.ID), err)
}
e.results.CompareAndSwap(false, match)
wg.Done()
}(template)
}

Expand Down