diff --git a/cmd/subfinder/main.go b/cmd/subfinder/main.go index fb3e9401a..301096cc5 100644 --- a/cmd/subfinder/main.go +++ b/cmd/subfinder/main.go @@ -1,15 +1,16 @@ package main import ( - "github.com/projectdiscovery/subfinder/v2/pkg/runner" + "github.com/ducksify/subfinder/v2/pkg/runner" // Attempts to increase the OS file descriptors - Fail silently _ "github.com/projectdiscovery/fdmax/autofdmax" "github.com/projectdiscovery/gologger" ) func main() { + opt := &runner.Options{} // Parse the command line flags and read config files - options := runner.ParseOptions() + options := runner.ParseOptions(opt) newRunner, err := runner.NewRunner(options) if err != nil { diff --git a/examples/main.go b/examples/main.go index 8edf7ea72..b6e96ce40 100644 --- a/examples/main.go +++ b/examples/main.go @@ -6,7 +6,7 @@ import ( "io" "log" - "github.com/projectdiscovery/subfinder/v2/pkg/runner" + "github.com/ducksify/subfinder/v2/pkg/runner" ) func main() { diff --git a/go.mod b/go.mod index 436e17e84..be9386d48 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ -module github.com/projectdiscovery/subfinder/v2 +module github.com/ducksify/subfinder/v2 -go 1.24.0 - -toolchain go1.24.1 +go 1.24.3 require ( github.com/corpix/uarand v0.2.0 @@ -73,7 +71,7 @@ require ( github.com/minio/selfupdate v0.6.1-0.20230907112617-f11e74f84ca7 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect - github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 // indirect + github.com/nwaples/rardecode/v2 v2.2.0 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/projectdiscovery/blackrock v0.0.1 // indirect diff --git a/go.sum b/go.sum index 2aeebb583..65a222683 100644 --- a/go.sum +++ b/go.sum @@ -231,8 +231,8 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg= github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= -github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 h1:MYzLheyVx1tJVDqfu3YnN4jtnyALNzLvwl+f58TcvQY= -github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY= +github.com/nwaples/rardecode/v2 v2.2.0 h1:4ufPGHiNe1rYJxYfehALLjup4Ls3ck42CWwjKiOqu0A= +github.com/nwaples/rardecode/v2 v2.2.0/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/pkg/passive/passive.go b/pkg/passive/passive.go index 199686bd4..20bd62ece 100644 --- a/pkg/passive/passive.go +++ b/pkg/passive/passive.go @@ -10,7 +10,7 @@ import ( "time" "github.com/projectdiscovery/ratelimit" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type EnumerationOptions struct { diff --git a/pkg/passive/sources.go b/pkg/passive/sources.go index e74d874be..2a28897e3 100644 --- a/pkg/passive/sources.go +++ b/pkg/passive/sources.go @@ -8,50 +8,50 @@ import ( "golang.org/x/exp/maps" "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/alienvault" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/anubis" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/bevigil" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/bufferover" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/builtwith" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/c99" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/censys" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/certspotter" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/chaos" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/chinaz" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/commoncrawl" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/crtsh" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/digitalyama" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/digitorus" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/dnsdb" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/dnsdumpster" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/dnsrepo" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/driftnet" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/facebook" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/fofa" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/fullhunt" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/github" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/hackertarget" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/hudsonrock" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/hunter" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/intelx" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/leakix" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/netlas" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/pugrecon" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/quake" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/rapiddns" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/redhuntlabs" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/robtex" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/rsecloud" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/securitytrails" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/shodan" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/sitedossier" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/threatbook" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/threatcrowd" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/virustotal" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/waybackarchive" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/whoisxmlapi" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping/sources/zoomeyeapi" + "github.com/ducksify/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/alienvault" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/anubis" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/bevigil" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/bufferover" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/builtwith" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/c99" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/censys" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/certspotter" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/chaos" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/chinaz" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/commoncrawl" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/crtsh" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/digitalyama" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/digitorus" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/dnsdb" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/dnsdumpster" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/dnsrepo" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/driftnet" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/facebook" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/fofa" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/fullhunt" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/github" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/hackertarget" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/hudsonrock" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/hunter" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/intelx" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/leakix" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/netlas" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/pugrecon" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/quake" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/rapiddns" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/redhuntlabs" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/robtex" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/rsecloud" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/securitytrails" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/shodan" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/sitedossier" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/threatbook" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/threatcrowd" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/virustotal" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/waybackarchive" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/whoisxmlapi" + "github.com/ducksify/subfinder/v2/pkg/subscraping/sources/zoomeyeapi" mapsutil "github.com/projectdiscovery/utils/maps" ) diff --git a/pkg/passive/sources_w_auth_test.go b/pkg/passive/sources_w_auth_test.go index 0a1085275..8339d7bf6 100644 --- a/pkg/passive/sources_w_auth_test.go +++ b/pkg/passive/sources_w_auth_test.go @@ -15,7 +15,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/gologger/levels" "github.com/projectdiscovery/ratelimit" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) func TestSourcesWithKeys(t *testing.T) { diff --git a/pkg/passive/sources_wo_auth_test.go b/pkg/passive/sources_wo_auth_test.go index 036588cc3..a355a6706 100644 --- a/pkg/passive/sources_wo_auth_test.go +++ b/pkg/passive/sources_wo_auth_test.go @@ -15,7 +15,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/gologger/levels" "github.com/projectdiscovery/ratelimit" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) func TestSourcesWithoutKeys(t *testing.T) { diff --git a/pkg/runner/config.go b/pkg/runner/config.go index 1751c9054..893b4a751 100644 --- a/pkg/runner/config.go +++ b/pkg/runner/config.go @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/passive" + "github.com/ducksify/subfinder/v2/pkg/passive" fileutil "github.com/projectdiscovery/utils/file" ) diff --git a/pkg/runner/enumerate.go b/pkg/runner/enumerate.go index f71a347dd..59d669f46 100644 --- a/pkg/runner/enumerate.go +++ b/pkg/runner/enumerate.go @@ -11,9 +11,9 @@ import ( "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/passive" - "github.com/projectdiscovery/subfinder/v2/pkg/resolve" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/passive" + "github.com/ducksify/subfinder/v2/pkg/resolve" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) const maxNumCount = 2 diff --git a/pkg/runner/initialize.go b/pkg/runner/initialize.go index afc65b1cf..e385a1a2b 100644 --- a/pkg/runner/initialize.go +++ b/pkg/runner/initialize.go @@ -5,8 +5,8 @@ import ( "strings" "github.com/projectdiscovery/dnsx/libs/dnsx" - "github.com/projectdiscovery/subfinder/v2/pkg/passive" - "github.com/projectdiscovery/subfinder/v2/pkg/resolve" + "github.com/ducksify/subfinder/v2/pkg/passive" + "github.com/ducksify/subfinder/v2/pkg/resolve" ) // initializePassiveEngine creates the passive engine and loads sources etc diff --git a/pkg/runner/options.go b/pkg/runner/options.go index 7f39e0315..646c1abb6 100644 --- a/pkg/runner/options.go +++ b/pkg/runner/options.go @@ -13,8 +13,8 @@ import ( "github.com/projectdiscovery/chaos-client/pkg/chaos" "github.com/projectdiscovery/goflags" "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/passive" - "github.com/projectdiscovery/subfinder/v2/pkg/resolve" + "github.com/ducksify/subfinder/v2/pkg/passive" + "github.com/ducksify/subfinder/v2/pkg/resolve" fileutil "github.com/projectdiscovery/utils/file" folderutil "github.com/projectdiscovery/utils/folder" logutil "github.com/projectdiscovery/utils/log" @@ -73,79 +73,9 @@ type Options struct { type OnResultCallback func(result *resolve.HostEntry) // ParseOptions parses the command line flags provided by a user -func ParseOptions() *Options { +func ParseOptions(options *Options) *Options { logutil.DisableDefaultLogger() - options := &Options{} - - var err error - flagSet := goflags.NewFlagSet() - flagSet.SetDescription(`Subfinder is a subdomain discovery tool that discovers subdomains for websites by using passive online sources.`) - - flagSet.CreateGroup("input", "Input", - flagSet.StringSliceVarP(&options.Domain, "domain", "d", nil, "domains to find subdomains for", goflags.NormalizedStringSliceOptions), - flagSet.StringVarP(&options.DomainsFile, "list", "dL", "", "file containing list of domains for subdomain discovery"), - ) - - flagSet.CreateGroup("source", "Source", - flagSet.StringSliceVarP(&options.Sources, "sources", "s", nil, "specific sources to use for discovery (-s crtsh,github). Use -ls to display all available sources.", goflags.NormalizedStringSliceOptions), - flagSet.BoolVar(&options.OnlyRecursive, "recursive", false, "use only sources that can handle subdomains recursively rather than both recursive and non-recursive sources"), - flagSet.BoolVar(&options.All, "all", false, "use all sources for enumeration (slow)"), - flagSet.StringSliceVarP(&options.ExcludeSources, "exclude-sources", "es", nil, "sources to exclude from enumeration (-es alienvault,zoomeyeapi)", goflags.NormalizedStringSliceOptions), - ) - - flagSet.CreateGroup("filter", "Filter", - flagSet.StringSliceVarP(&options.Match, "match", "m", nil, "subdomain or list of subdomain to match (file or comma separated)", goflags.FileNormalizedStringSliceOptions), - flagSet.StringSliceVarP(&options.Filter, "filter", "f", nil, " subdomain or list of subdomain to filter (file or comma separated)", goflags.FileNormalizedStringSliceOptions), - ) - - flagSet.CreateGroup("rate-limit", "Rate-limit", - flagSet.IntVarP(&options.RateLimit, "rate-limit", "rl", 0, "maximum number of http requests to send per second (global)"), - flagSet.RateLimitMapVarP(&options.RateLimits, "rate-limits", "rls", defaultRateLimits, "maximum number of http requests to send per second for providers in key=value format (-rls hackertarget=10/m)", goflags.NormalizedStringSliceOptions), - flagSet.IntVar(&options.Threads, "t", 10, "number of concurrent goroutines for resolving (-active only)"), - ) - - flagSet.CreateGroup("update", "Update", - flagSet.CallbackVarP(GetUpdateCallback(), "update", "up", "update subfinder to latest version"), - flagSet.BoolVarP(&options.DisableUpdateCheck, "disable-update-check", "duc", false, "disable automatic subfinder update check"), - ) - - flagSet.CreateGroup("output", "Output", - flagSet.StringVarP(&options.OutputFile, "output", "o", "", "file to write output to"), - flagSet.BoolVarP(&options.JSON, "json", "oJ", false, "write output in JSONL(ines) format"), - flagSet.StringVarP(&options.OutputDirectory, "output-dir", "oD", "", "directory to write output (-dL only)"), - flagSet.BoolVarP(&options.CaptureSources, "collect-sources", "cs", false, "include all sources in the output (-json only)"), - flagSet.BoolVarP(&options.HostIP, "ip", "oI", false, "include host IP in output (-active only)"), - ) - - flagSet.CreateGroup("configuration", "Configuration", - flagSet.StringVar(&options.Config, "config", defaultConfigLocation, "flag config file"), - flagSet.StringVarP(&options.ProviderConfig, "provider-config", "pc", defaultProviderConfigLocation, "provider config file"), - flagSet.StringSliceVar(&options.Resolvers, "r", nil, "comma separated list of resolvers to use", goflags.NormalizedStringSliceOptions), - flagSet.StringVarP(&options.ResolverList, "rlist", "rL", "", "file containing list of resolvers to use"), - flagSet.BoolVarP(&options.RemoveWildcard, "active", "nW", false, "display active subdomains only"), - flagSet.StringVar(&options.Proxy, "proxy", "", "http proxy to use with subfinder"), - flagSet.BoolVarP(&options.ExcludeIps, "exclude-ip", "ei", false, "exclude IPs from the list of domains"), - ) - - flagSet.CreateGroup("debug", "Debug", - flagSet.BoolVar(&options.Silent, "silent", false, "show only subdomains in output"), - flagSet.BoolVar(&options.Version, "version", false, "show version of subfinder"), - flagSet.BoolVar(&options.Verbose, "v", false, "show verbose output"), - flagSet.BoolVarP(&options.NoColor, "no-color", "nc", false, "disable color in output"), - flagSet.BoolVarP(&options.ListSources, "list-sources", "ls", false, "list all available sources"), - flagSet.BoolVar(&options.Statistics, "stats", false, "report source statistics"), - ) - - flagSet.CreateGroup("optimization", "Optimization", - flagSet.IntVar(&options.Timeout, "timeout", 30, "seconds to wait before timing out"), - flagSet.IntVar(&options.MaxEnumerationTime, "max-time", 10, "minutes to wait for enumeration results"), - ) - - if err := flagSet.Parse(); err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } // set chaos mode chaos.IsSDK = false @@ -156,13 +86,7 @@ func ParseOptions() *Options { } } - if options.Config != defaultConfigLocation { - // An empty source file is not a fatal error - if err := flagSet.MergeConfigFile(options.Config); err != nil && !errors.Is(err, io.EOF) { - gologger.Fatal().Msgf("Could not read config: %s\n", err) - } - } - + var err error // Default output is stdout options.Output = os.Stdout @@ -178,7 +102,6 @@ func ParseOptions() *Options { options.preProcessDomains() options.ConfigureOutput() - showBanner() if !options.DisableUpdateCheck { latestVersion, err := updateutils.GetToolVersionCallback("subfinder", version)() diff --git a/pkg/runner/outputter.go b/pkg/runner/outputter.go index cfa4fc1a5..824bfdc44 100644 --- a/pkg/runner/outputter.go +++ b/pkg/runner/outputter.go @@ -10,7 +10,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/resolve" + "github.com/ducksify/subfinder/v2/pkg/resolve" ) // OutputWriter outputs content to writers. diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index f00ce6418..04c3f56bb 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -10,15 +10,18 @@ import ( "regexp" "strconv" "strings" + "sync" + "time" + "github.com/hako/durafmt" "github.com/projectdiscovery/gologger" contextutil "github.com/projectdiscovery/utils/context" fileutil "github.com/projectdiscovery/utils/file" mapsutil "github.com/projectdiscovery/utils/maps" - "github.com/projectdiscovery/subfinder/v2/pkg/passive" - "github.com/projectdiscovery/subfinder/v2/pkg/resolve" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/passive" + "github.com/ducksify/subfinder/v2/pkg/resolve" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Runner is an instance of the subdomain enumeration @@ -173,3 +176,263 @@ func (r *Runner) EnumerateMultipleDomainsWithCtx(ctx context.Context, reader io. } return nil } + +// EnumerationResult represents the result of subdomain enumeration for a single domain +type EnumerationResult struct { + Domain string `json:"domain"` + Subdomains []string `json:"subdomains"` + HostEntries []resolve.HostEntry `json:"host_entries"` + SourceMap map[string]map[string]struct{} `json:"source_map"` + Statistics map[string]subscraping.Statistics `json:"statistics,omitempty"` + Duration string `json:"duration"` + Error error `json:"error,omitempty"` +} + +// MultipleEnumerationResult represents the result of subdomain enumeration for multiple domains +type MultipleEnumerationResult struct { + Results []EnumerationResult `json:"results"` + Errors []error `json:"errors,omitempty"` +} + +// RunEnumerationWithReturn runs the subdomain enumeration and returns structured results +// This method is designed for library usage, returning data objects instead of writing to files +func (r *Runner) RunEnumerationWithReturn() (*MultipleEnumerationResult, error) { + ctx, _ := contextutil.WithValues(context.Background(), contextutil.ContextArg("All"), contextutil.ContextArg(strconv.FormatBool(r.options.All))) + return r.RunEnumerationWithReturnWithCtx(ctx) +} + +// RunEnumerationWithReturnWithCtx runs the subdomain enumeration with context and returns structured results +func (r *Runner) RunEnumerationWithReturnWithCtx(ctx context.Context) (*MultipleEnumerationResult, error) { + result := &MultipleEnumerationResult{ + Results: []EnumerationResult{}, + Errors: []error{}, + } + + if len(r.options.Domain) > 0 { + domainsReader := strings.NewReader(strings.Join(r.options.Domain, "\n")) + return r.EnumerateMultipleDomainsReturnWithCtx(ctx, domainsReader) + } + + // If we have multiple domains as input, + if r.options.DomainsFile != "" { + f, err := os.Open(r.options.DomainsFile) + if err != nil { + return nil, err + } + defer func() { + if closeErr := f.Close(); closeErr != nil { + gologger.Error().Msgf("Error closing file %s: %s", r.options.DomainsFile, closeErr) + } + }() + return r.EnumerateMultipleDomainsReturnWithCtx(ctx, f) + } + + // If we have STDIN input, treat it as multiple domains + if r.options.Stdin { + return r.EnumerateMultipleDomainsReturnWithCtx(ctx, os.Stdin) + } + + return result, nil +} + +// EnumerateMultipleDomainsAsLibrary wraps EnumerateMultipleDomainsAsLibraryWithCtx with an empty context +func (r *Runner) EnumerateMultipleDomainsReturn(reader io.Reader) (*MultipleEnumerationResult, error) { + ctx, _ := contextutil.WithValues(context.Background(), contextutil.ContextArg("All"), contextutil.ContextArg(strconv.FormatBool(r.options.All))) + return r.EnumerateMultipleDomainsReturnWithCtx(ctx, reader) +} + +// EnumerateMultipleDomainsAsLibraryWithCtx enumerates subdomains for multiple domains and returns structured results +func (r *Runner) EnumerateMultipleDomainsReturnWithCtx(ctx context.Context, reader io.Reader) (*MultipleEnumerationResult, error) { + result := &MultipleEnumerationResult{ + Results: []EnumerationResult{}, + Errors: []error{}, + } + + scanner := bufio.NewScanner(reader) + ip, _ := regexp.Compile(`^([0-9\.]+$)`) + + for scanner.Scan() { + domain := preprocessDomain(scanner.Text()) + domain = replacer.Replace(domain) + + if domain == "" || (r.options.ExcludeIps && ip.MatchString(domain)) { + continue + } + + enumResult, err := r.EnumerateSingleDomainReturnWithCtx(ctx, domain) + if err != nil { + result.Errors = append(result.Errors, err) + continue + } + + result.Results = append(result.Results, *enumResult) + } + + return result, nil +} + +// EnumerateSingleDomainAsLibrary wraps EnumerateSingleDomainAsLibraryWithCtx with an empty context +func (r *Runner) EnumerateSingleDomainAsLibrary(domain string) (*EnumerationResult, error) { + return r.EnumerateSingleDomainReturnWithCtx(context.Background(), domain) +} + +// EnumerateSingleDomainAsLibraryWithCtx performs subdomain enumeration against a single domain and returns structured results +func (r *Runner) EnumerateSingleDomainReturnWithCtx(ctx context.Context, domain string) (*EnumerationResult, error) { + gologger.Info().Msgf("Enumerating subdomains for %s\n", domain) + + // Check if the user has asked to remove wildcards explicitly. + // If yes, create the resolution pool and get the wildcards for the current domain + var resolutionPool *resolve.ResolutionPool + if r.options.RemoveWildcard { + resolutionPool = r.resolverClient.NewResolutionPool(r.options.Threads, r.options.RemoveWildcard) + err := resolutionPool.InitWildcards(domain) + if err != nil { + // Log the error but don't quit. + gologger.Warning().Msgf("Could not get wildcards for domain %s: %s\n", domain, err) + } + } + + // Run the passive subdomain enumeration + now := time.Now() + passiveResults := r.passiveAgent.EnumerateSubdomainsWithCtx(ctx, domain, r.options.Proxy, r.options.RateLimit, r.options.Timeout, time.Duration(r.options.MaxEnumerationTime)*time.Minute, passive.WithCustomRateLimit(r.rateLimit)) + + wg := &sync.WaitGroup{} + wg.Add(1) + // Create a unique map for filtering duplicate subdomains out + uniqueMap := make(map[string]resolve.HostEntry) + // Create a map to track sources for each host + sourceMap := make(map[string]map[string]struct{}) + skippedCounts := make(map[string]int) + // Process the results in a separate goroutine + go func() { + for result := range passiveResults { + switch result.Type { + case subscraping.Error: + gologger.Warning().Msgf("Encountered an error with source %s: %s\n", result.Source, result.Error) + case subscraping.Subdomain: + subdomain := replacer.Replace(result.Value) + + // Validate the subdomain found and remove wildcards from + if !strings.HasSuffix(subdomain, "."+domain) { + skippedCounts[result.Source]++ + continue + } + + if matchSubdomain := r.filterAndMatchSubdomain(subdomain); matchSubdomain { + if _, ok := uniqueMap[subdomain]; !ok { + sourceMap[subdomain] = make(map[string]struct{}) + } + + // Log the verbose message about the found subdomain per source + if _, ok := sourceMap[subdomain][result.Source]; !ok { + gologger.Verbose().Label(result.Source).Msg(subdomain) + } + + sourceMap[subdomain][result.Source] = struct{}{} + + // Check if the subdomain is a duplicate. If not, + // send the subdomain for resolution. + if _, ok := uniqueMap[subdomain]; ok { + skippedCounts[result.Source]++ + continue + } + + hostEntry := resolve.HostEntry{Domain: domain, Host: subdomain, Source: result.Source} + + uniqueMap[subdomain] = hostEntry + // If the user asked to remove wildcard then send on the resolve + // queue. Otherwise, if mode is not verbose print the results on + // the screen as they are discovered. + if r.options.RemoveWildcard { + resolutionPool.Tasks <- hostEntry + } + } + } + } + // Close the task channel only if wildcards are asked to be removed + if r.options.RemoveWildcard { + close(resolutionPool.Tasks) + } + wg.Done() + }() + + // If the user asked to remove wildcards, listen from the results + // queue and write to the map. At the end, print the found results to the screen + foundResults := make(map[string]resolve.Result) + if r.options.RemoveWildcard { + // Process the results coming from the resolutions pool + for result := range resolutionPool.Results { + switch result.Type { + case resolve.Error: + gologger.Warning().Msgf("Could not resolve host: %s\n", result.Error) + case resolve.Subdomain: + // Add the found subdomain to a map. + if _, ok := foundResults[result.Host]; !ok { + foundResults[result.Host] = result + } + } + } + } + wg.Wait() + + // Show found subdomain count in any case. + duration := durafmt.Parse(time.Since(now)).LimitFirstN(maxNumCount).String() + var numberOfSubDomains int + var hostEntries []resolve.HostEntry + var subdomains []string + + if r.options.RemoveWildcard { + numberOfSubDomains = len(foundResults) + for _, result := range foundResults { + hostEntries = append(hostEntries, resolve.HostEntry{Domain: domain, Host: result.Host, Source: result.Source}) + subdomains = append(subdomains, result.Host) + } + } else { + numberOfSubDomains = len(uniqueMap) + for _, v := range uniqueMap { + hostEntries = append(hostEntries, v) + subdomains = append(subdomains, v.Host) + } + } + + // Call result callback if provided + if r.options.ResultCallback != nil { + if r.options.RemoveWildcard { + for _, result := range foundResults { + r.options.ResultCallback(&resolve.HostEntry{Domain: domain, Host: result.Host, Source: result.Source}) + } + } else { + for _, v := range uniqueMap { + r.options.ResultCallback(&v) + } + } + } + + gologger.Info().Msgf("Found %d subdomains for %s in %s\n", numberOfSubDomains, domain, duration) + + // Prepare statistics if requested + var statistics map[string]subscraping.Statistics + if r.options.Statistics { + gologger.Info().Msgf("Printing source statistics for %s", domain) + statistics = r.passiveAgent.GetStatistics() + // This is a hack to remove the skipped count from the statistics + // as we don't want to show it in the statistics. + // TODO: Design a better way to do this. + for source, count := range skippedCounts { + if stat, ok := statistics[source]; ok { + stat.Results -= count + statistics[source] = stat + } + } + printStatistics(statistics) + } + + return &EnumerationResult{ + Domain: domain, + Subdomains: subdomains, + HostEntries: hostEntries, + SourceMap: sourceMap, + Statistics: statistics, + Duration: duration, + }, nil +} diff --git a/pkg/runner/stats.go b/pkg/runner/stats.go index d34b20f82..665badff2 100644 --- a/pkg/runner/stats.go +++ b/pkg/runner/stats.go @@ -7,7 +7,7 @@ import ( "time" "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" "golang.org/x/exp/maps" ) diff --git a/pkg/runner/validate.go b/pkg/runner/validate.go index 79b59b612..50d86eac0 100644 --- a/pkg/runner/validate.go +++ b/pkg/runner/validate.go @@ -9,7 +9,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/gologger/formatter" "github.com/projectdiscovery/gologger/levels" - "github.com/projectdiscovery/subfinder/v2/pkg/passive" + "github.com/ducksify/subfinder/v2/pkg/passive" mapsutil "github.com/projectdiscovery/utils/maps" sliceutil "github.com/projectdiscovery/utils/slice" ) diff --git a/pkg/subscraping/sources/alienvault/alienvault.go b/pkg/subscraping/sources/alienvault/alienvault.go index 27e1f57b4..f85e18e54 100644 --- a/pkg/subscraping/sources/alienvault/alienvault.go +++ b/pkg/subscraping/sources/alienvault/alienvault.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type alienvaultResponse struct { diff --git a/pkg/subscraping/sources/anubis/anubis.go b/pkg/subscraping/sources/anubis/anubis.go index 6efbd5343..bf590f426 100644 --- a/pkg/subscraping/sources/anubis/anubis.go +++ b/pkg/subscraping/sources/anubis/anubis.go @@ -9,7 +9,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/bevigil/bevigil.go b/pkg/subscraping/sources/bevigil/bevigil.go index 2021e4c64..872b9dc46 100644 --- a/pkg/subscraping/sources/bevigil/bevigil.go +++ b/pkg/subscraping/sources/bevigil/bevigil.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type Response struct { diff --git a/pkg/subscraping/sources/bufferover/bufferover.go b/pkg/subscraping/sources/bufferover/bufferover.go index 207cb8190..d398a8d48 100644 --- a/pkg/subscraping/sources/bufferover/bufferover.go +++ b/pkg/subscraping/sources/bufferover/bufferover.go @@ -9,7 +9,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/builtwith/builtwith.go b/pkg/subscraping/sources/builtwith/builtwith.go index 4c6b516f6..360c4806d 100644 --- a/pkg/subscraping/sources/builtwith/builtwith.go +++ b/pkg/subscraping/sources/builtwith/builtwith.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/c99/c99.go b/pkg/subscraping/sources/c99/c99.go index c2e45e818..45a7812a7 100644 --- a/pkg/subscraping/sources/c99/c99.go +++ b/pkg/subscraping/sources/c99/c99.go @@ -9,7 +9,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/censys/censys.go b/pkg/subscraping/sources/censys/censys.go index 4427821ae..76faa556b 100644 --- a/pkg/subscraping/sources/censys/censys.go +++ b/pkg/subscraping/sources/censys/censys.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" urlutil "github.com/projectdiscovery/utils/url" ) diff --git a/pkg/subscraping/sources/certspotter/certspotter.go b/pkg/subscraping/sources/certspotter/certspotter.go index e501e1730..d8379b447 100644 --- a/pkg/subscraping/sources/certspotter/certspotter.go +++ b/pkg/subscraping/sources/certspotter/certspotter.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type certspotterObject struct { diff --git a/pkg/subscraping/sources/chaos/chaos.go b/pkg/subscraping/sources/chaos/chaos.go index 2cc873679..c19e99ad5 100644 --- a/pkg/subscraping/sources/chaos/chaos.go +++ b/pkg/subscraping/sources/chaos/chaos.go @@ -7,7 +7,7 @@ import ( "time" "github.com/projectdiscovery/chaos-client/pkg/chaos" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/chinaz/chinaz.go b/pkg/subscraping/sources/chinaz/chinaz.go index c6e43c05d..c75998e1e 100644 --- a/pkg/subscraping/sources/chinaz/chinaz.go +++ b/pkg/subscraping/sources/chinaz/chinaz.go @@ -8,7 +8,7 @@ import ( "time" jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/commoncrawl/commoncrawl.go b/pkg/subscraping/sources/commoncrawl/commoncrawl.go index 09ad4967d..9b0ba7067 100644 --- a/pkg/subscraping/sources/commoncrawl/commoncrawl.go +++ b/pkg/subscraping/sources/commoncrawl/commoncrawl.go @@ -12,7 +12,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) const ( diff --git a/pkg/subscraping/sources/crtsh/crtsh.go b/pkg/subscraping/sources/crtsh/crtsh.go index 76ac02b45..5c7351079 100644 --- a/pkg/subscraping/sources/crtsh/crtsh.go +++ b/pkg/subscraping/sources/crtsh/crtsh.go @@ -15,7 +15,7 @@ import ( _ "github.com/lib/pq" "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" contextutil "github.com/projectdiscovery/utils/context" ) diff --git a/pkg/subscraping/sources/digitalyama/digitalyama.go b/pkg/subscraping/sources/digitalyama/digitalyama.go index 7ab719576..7daa40733 100644 --- a/pkg/subscraping/sources/digitalyama/digitalyama.go +++ b/pkg/subscraping/sources/digitalyama/digitalyama.go @@ -7,7 +7,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/digitorus/digitorus.go b/pkg/subscraping/sources/digitorus/digitorus.go index 8c680a2b6..54838ac16 100644 --- a/pkg/subscraping/sources/digitorus/digitorus.go +++ b/pkg/subscraping/sources/digitorus/digitorus.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" "github.com/projectdiscovery/utils/ptr" ) @@ -33,7 +33,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se }(time.Now()) resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://certificatedetails.com/%s", domain)) - // the 404 page still contains around 100 subdomains - https://github.com/projectdiscovery/subfinder/issues/774 + // the 404 page still contains around 100 subdomains - https://github.com/ducksify/subfinder/issues/774 if err != nil && ptr.Safe(resp).StatusCode != http.StatusNotFound { results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err} s.errors++ diff --git a/pkg/subscraping/sources/dnsdb/dnsdb.go b/pkg/subscraping/sources/dnsdb/dnsdb.go index e5dc0e246..27ef17726 100644 --- a/pkg/subscraping/sources/dnsdb/dnsdb.go +++ b/pkg/subscraping/sources/dnsdb/dnsdb.go @@ -14,7 +14,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) const urlBase string = "https://api.dnsdb.info/dnsdb/v2" diff --git a/pkg/subscraping/sources/dnsdumpster/dnsdumpster.go b/pkg/subscraping/sources/dnsdumpster/dnsdumpster.go index 72be41c3b..7bda0940a 100644 --- a/pkg/subscraping/sources/dnsdumpster/dnsdumpster.go +++ b/pkg/subscraping/sources/dnsdumpster/dnsdumpster.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/dnsrepo/dnsrepo.go b/pkg/subscraping/sources/dnsrepo/dnsrepo.go index e98c82399..6b8fb96b0 100644 --- a/pkg/subscraping/sources/dnsrepo/dnsrepo.go +++ b/pkg/subscraping/sources/dnsrepo/dnsrepo.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/driftnet/driftnet.go b/pkg/subscraping/sources/driftnet/driftnet.go index 758bbfa44..bd2e4412c 100644 --- a/pkg/subscraping/sources/driftnet/driftnet.go +++ b/pkg/subscraping/sources/driftnet/driftnet.go @@ -11,7 +11,7 @@ import ( "sync/atomic" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) const ( diff --git a/pkg/subscraping/sources/facebook/ctlogs.go b/pkg/subscraping/sources/facebook/ctlogs.go index f96436008..bf2faf407 100644 --- a/pkg/subscraping/sources/facebook/ctlogs.go +++ b/pkg/subscraping/sources/facebook/ctlogs.go @@ -9,7 +9,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/retryablehttp-go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" errorutil "github.com/projectdiscovery/utils/errors" "github.com/projectdiscovery/utils/generic" urlutil "github.com/projectdiscovery/utils/url" diff --git a/pkg/subscraping/sources/fofa/fofa.go b/pkg/subscraping/sources/fofa/fofa.go index 78be69d1f..fa95b10ec 100644 --- a/pkg/subscraping/sources/fofa/fofa.go +++ b/pkg/subscraping/sources/fofa/fofa.go @@ -11,7 +11,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type fofaResponse struct { diff --git a/pkg/subscraping/sources/fullhunt/fullhunt.go b/pkg/subscraping/sources/fullhunt/fullhunt.go index 60c64e52d..a33b6d3d6 100644 --- a/pkg/subscraping/sources/fullhunt/fullhunt.go +++ b/pkg/subscraping/sources/fullhunt/fullhunt.go @@ -7,7 +7,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // fullhunt response diff --git a/pkg/subscraping/sources/github/github.go b/pkg/subscraping/sources/github/github.go index 2e8b3224b..ebce26cd6 100644 --- a/pkg/subscraping/sources/github/github.go +++ b/pkg/subscraping/sources/github/github.go @@ -19,7 +19,7 @@ import ( "github.com/tomnomnom/linkheader" "github.com/projectdiscovery/gologger" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type textMatch struct { diff --git a/pkg/subscraping/sources/gitlab/gitlab.go b/pkg/subscraping/sources/gitlab/gitlab.go index 902ef4691..fa9386d55 100644 --- a/pkg/subscraping/sources/gitlab/gitlab.go +++ b/pkg/subscraping/sources/gitlab/gitlab.go @@ -12,7 +12,7 @@ import ( "time" jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" "github.com/tomnomnom/linkheader" ) diff --git a/pkg/subscraping/sources/hackertarget/hackertarget.go b/pkg/subscraping/sources/hackertarget/hackertarget.go index c84957722..72b3acaf9 100644 --- a/pkg/subscraping/sources/hackertarget/hackertarget.go +++ b/pkg/subscraping/sources/hackertarget/hackertarget.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/hudsonrock/hudsonrock.go b/pkg/subscraping/sources/hudsonrock/hudsonrock.go index 51d6bc2fa..fb32789f3 100644 --- a/pkg/subscraping/sources/hudsonrock/hudsonrock.go +++ b/pkg/subscraping/sources/hudsonrock/hudsonrock.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type hudsonrockResponse struct { diff --git a/pkg/subscraping/sources/hunter/hunter.go b/pkg/subscraping/sources/hunter/hunter.go index 960563279..b089696e3 100644 --- a/pkg/subscraping/sources/hunter/hunter.go +++ b/pkg/subscraping/sources/hunter/hunter.go @@ -7,7 +7,7 @@ import ( "time" jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type hunterResp struct { diff --git a/pkg/subscraping/sources/intelx/intelx.go b/pkg/subscraping/sources/intelx/intelx.go index b3a3a45a1..76b5ae755 100644 --- a/pkg/subscraping/sources/intelx/intelx.go +++ b/pkg/subscraping/sources/intelx/intelx.go @@ -11,7 +11,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type searchResponseType struct { diff --git a/pkg/subscraping/sources/leakix/leakix.go b/pkg/subscraping/sources/leakix/leakix.go index 4159e6aba..218dcbf1f 100644 --- a/pkg/subscraping/sources/leakix/leakix.go +++ b/pkg/subscraping/sources/leakix/leakix.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/netlas/netlas.go b/pkg/subscraping/sources/netlas/netlas.go index c29bc2c8b..090f785de 100644 --- a/pkg/subscraping/sources/netlas/netlas.go +++ b/pkg/subscraping/sources/netlas/netlas.go @@ -12,7 +12,7 @@ import ( "net/url" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type Item struct { diff --git a/pkg/subscraping/sources/pugrecon/pugrecon.go b/pkg/subscraping/sources/pugrecon/pugrecon.go index e7f2255f8..0849e3e1f 100644 --- a/pkg/subscraping/sources/pugrecon/pugrecon.go +++ b/pkg/subscraping/sources/pugrecon/pugrecon.go @@ -9,7 +9,7 @@ import ( "net/http" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // pugreconResult stores a single result from the pugrecon API diff --git a/pkg/subscraping/sources/quake/quake.go b/pkg/subscraping/sources/quake/quake.go index 5cac4ed2e..afd6313e8 100644 --- a/pkg/subscraping/sources/quake/quake.go +++ b/pkg/subscraping/sources/quake/quake.go @@ -10,7 +10,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type quakeResults struct { diff --git a/pkg/subscraping/sources/rapiddns/rapiddns.go b/pkg/subscraping/sources/rapiddns/rapiddns.go index 89ec70632..25d5c0f7b 100644 --- a/pkg/subscraping/sources/rapiddns/rapiddns.go +++ b/pkg/subscraping/sources/rapiddns/rapiddns.go @@ -9,7 +9,7 @@ import ( "strconv" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) var pagePattern = regexp.MustCompile(`class="page-link" href="/subdomain/[^"]+\?page=(\d+)">`) diff --git a/pkg/subscraping/sources/reconcloud/reconcloud.go b/pkg/subscraping/sources/reconcloud/reconcloud.go index 8aacc7d4e..ed6fb809f 100644 --- a/pkg/subscraping/sources/reconcloud/reconcloud.go +++ b/pkg/subscraping/sources/reconcloud/reconcloud.go @@ -7,7 +7,7 @@ import ( "time" jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type reconCloudResponse struct { diff --git a/pkg/subscraping/sources/redhuntlabs/redhuntlabs.go b/pkg/subscraping/sources/redhuntlabs/redhuntlabs.go index a07e9a5b4..1c5de76c3 100644 --- a/pkg/subscraping/sources/redhuntlabs/redhuntlabs.go +++ b/pkg/subscraping/sources/redhuntlabs/redhuntlabs.go @@ -9,7 +9,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type Response struct { diff --git a/pkg/subscraping/sources/riddler/riddler.go b/pkg/subscraping/sources/riddler/riddler.go index 9a3401c27..c15a1f7c0 100644 --- a/pkg/subscraping/sources/riddler/riddler.go +++ b/pkg/subscraping/sources/riddler/riddler.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/robtex/robtext.go b/pkg/subscraping/sources/robtex/robtext.go index 9214363ed..691e0b8f2 100644 --- a/pkg/subscraping/sources/robtex/robtext.go +++ b/pkg/subscraping/sources/robtex/robtext.go @@ -10,7 +10,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) const ( diff --git a/pkg/subscraping/sources/rsecloud/rsecloud.go b/pkg/subscraping/sources/rsecloud/rsecloud.go index 8601b7732..dccfecbee 100644 --- a/pkg/subscraping/sources/rsecloud/rsecloud.go +++ b/pkg/subscraping/sources/rsecloud/rsecloud.go @@ -7,7 +7,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/securitytrails/securitytrails.go b/pkg/subscraping/sources/securitytrails/securitytrails.go index e6d38fe44..16f8c237a 100644 --- a/pkg/subscraping/sources/securitytrails/securitytrails.go +++ b/pkg/subscraping/sources/securitytrails/securitytrails.go @@ -11,7 +11,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" "github.com/projectdiscovery/utils/ptr" ) diff --git a/pkg/subscraping/sources/shodan/shodan.go b/pkg/subscraping/sources/shodan/shodan.go index d2224a810..5c4a6cc7d 100644 --- a/pkg/subscraping/sources/shodan/shodan.go +++ b/pkg/subscraping/sources/shodan/shodan.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/sitedossier/sitedossier.go b/pkg/subscraping/sources/sitedossier/sitedossier.go index 38d31dd5c..fd4b1bc34 100644 --- a/pkg/subscraping/sources/sitedossier/sitedossier.go +++ b/pkg/subscraping/sources/sitedossier/sitedossier.go @@ -9,7 +9,7 @@ import ( "regexp" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // SleepRandIntn is the integer value to get the pseudo-random number diff --git a/pkg/subscraping/sources/threatbook/threatbook.go b/pkg/subscraping/sources/threatbook/threatbook.go index 0033a4d32..3c7483d50 100644 --- a/pkg/subscraping/sources/threatbook/threatbook.go +++ b/pkg/subscraping/sources/threatbook/threatbook.go @@ -9,7 +9,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type threatBookResponse struct { diff --git a/pkg/subscraping/sources/threatcrowd/threatcrowd.go b/pkg/subscraping/sources/threatcrowd/threatcrowd.go index e09ab91ef..cbce1fc47 100644 --- a/pkg/subscraping/sources/threatcrowd/threatcrowd.go +++ b/pkg/subscraping/sources/threatcrowd/threatcrowd.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // threatCrowdResponse represents the JSON response from the ThreatCrowd API. diff --git a/pkg/subscraping/sources/threatminer/threatminer.go b/pkg/subscraping/sources/threatminer/threatminer.go index 6776f9ef9..c8016a940 100644 --- a/pkg/subscraping/sources/threatminer/threatminer.go +++ b/pkg/subscraping/sources/threatminer/threatminer.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/virustotal/virustotal.go b/pkg/subscraping/sources/virustotal/virustotal.go index 7ac4c6c50..3ea97037f 100644 --- a/pkg/subscraping/sources/virustotal/virustotal.go +++ b/pkg/subscraping/sources/virustotal/virustotal.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/waybackarchive/waybackarchive.go b/pkg/subscraping/sources/waybackarchive/waybackarchive.go index f3cba9809..e847ad51d 100644 --- a/pkg/subscraping/sources/waybackarchive/waybackarchive.go +++ b/pkg/subscraping/sources/waybackarchive/waybackarchive.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // Source is the passive scraping agent diff --git a/pkg/subscraping/sources/whoisxmlapi/whoisxmlapi.go b/pkg/subscraping/sources/whoisxmlapi/whoisxmlapi.go index 18375e3ff..43c2235c8 100644 --- a/pkg/subscraping/sources/whoisxmlapi/whoisxmlapi.go +++ b/pkg/subscraping/sources/whoisxmlapi/whoisxmlapi.go @@ -8,7 +8,7 @@ import ( jsoniter "github.com/json-iterator/go" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) type response struct { diff --git a/pkg/subscraping/sources/zoomeyeapi/zoomeyeapi.go b/pkg/subscraping/sources/zoomeyeapi/zoomeyeapi.go index 62c2d1f91..73dc7e66e 100644 --- a/pkg/subscraping/sources/zoomeyeapi/zoomeyeapi.go +++ b/pkg/subscraping/sources/zoomeyeapi/zoomeyeapi.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/projectdiscovery/subfinder/v2/pkg/subscraping" + "github.com/ducksify/subfinder/v2/pkg/subscraping" ) // search results