diff --git a/TODO.md b/TODO.md index b535080..220afda 100644 --- a/TODO.md +++ b/TODO.md @@ -2,5 +2,4 @@ - [ ] Clean up CLI - [ ] Fix logger levels -- [ ] Move wildcard to separate function - [ ] Complete all options (ENT, verify etc) diff --git a/v1/cmd/blink/main.go b/v1/cmd/blink/main.go index 5db2f1c..2cf8c51 100644 --- a/v1/cmd/blink/main.go +++ b/v1/cmd/blink/main.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "slices" + "strconv" "strings" "git.supernets.org/perp/blink/v1/internal/bar" @@ -30,6 +31,7 @@ var opts runner.Options var ( wordlist string resolvers string + wildcard bool verbose bool ) @@ -94,22 +96,13 @@ var rootCmd = &cobra.Command{ // Create bar pb := bar.New(tasks) - // Store shown - // var shown bool - // Handle results opts.OnResult = func(result *dns.Result) { + // Render bar defer pb.RenderBlank() pb.Add(1) pb.Clear() - //if !shown { - // if result.Wildcard { - // log.Warn().Str("domain", result.Domain).Msg("Wildcard detected") - // shown = true - // } - //} - // Error found if result.Error != nil { // Verbose enabled @@ -149,10 +142,28 @@ var rootCmd = &cobra.Command{ // Create runner run := runner.New(&opts) - run.Bruteforce() + + // Wildcard enabled + if wildcard { + // Go through domains + for _, domain := range opts.Domains { + // Check wildcard + found := run.Wildcard(domain) + + // Print detection + log.Info(). + Str("domain", domain). + Str("detected", strconv.FormatBool(found)). + Msg("Wildcard detection") + } + } + + // Start runner + run.Start() // Go through domains for domain, count := range domains { + // Print count log.Info().Str("subdomains", fmt.Sprintf("%d", count)).Msg(domain) } }, @@ -164,7 +175,7 @@ func init() { rootCmd.Flags().StringVarP(&resolvers, "resolvers", "r", "", "Path to resolvers") rootCmd.Flags().BoolVarP(&opts.UDP, "udp", "u", false, "Query using UDP") rootCmd.Flags().BoolVarP(&opts.IPv6, "ipv6", "i", false, "Query for IPv6") - rootCmd.Flags().BoolVarP(&opts.Wildcard, "wildcard", "c", false, "Query for wildcard") + rootCmd.Flags().BoolVarP(&wildcard, "wildcard", "c", false, "Query for wildcard") rootCmd.Flags().IntVarP(&opts.Timeout, "timeout", "d", 5, "Query timeout") rootCmd.Flags().IntVarP(&opts.Threads, "threads", "t", 1, "Concurrent threads") rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Verbose logging") @@ -174,7 +185,10 @@ func init() { rootCmd.MarkFlagRequired("wordlist") // Setup logger - log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, PartsExclude: []string{"time"}}) + log.Logger = log.Output(zerolog.ConsoleWriter{ + Out: os.Stderr, + PartsExclude: []string{"time"}, + }) } func main() { diff --git a/v1/pkg/dns/dns.go b/v1/pkg/dns/dns.go index eafcae6..f54fa12 100644 --- a/v1/pkg/dns/dns.go +++ b/v1/pkg/dns/dns.go @@ -21,7 +21,6 @@ type Query struct { type Result struct { Domain string // Target domain Subdomain string // Target subdomain - Wildcard bool // Wildcard detect IPv4 []net.IP // IPv4 hosts IPv6 []net.IP // IPv6 hosts Error error // Error response diff --git a/v1/pkg/runner/options.go b/v1/pkg/runner/options.go index d079f1d..e3582d9 100644 --- a/v1/pkg/runner/options.go +++ b/v1/pkg/runner/options.go @@ -12,9 +12,8 @@ type Options struct { Wordlist []string // Target wordlist Resolvers []string // Target resolvers // ENT bool // Query for ENT - UDP bool // Query using UDP - IPv6 bool // Query for IPv6 - Wildcard bool // Detect wildcard + UDP bool // Query using UDP + IPv6 bool // Query for IPv6 // Verify bool // Verify query Timeout int // Query timeout Threads int // Concurrent threads diff --git a/v1/pkg/runner/runner.go b/v1/pkg/runner/runner.go index ef53d23..8a13902 100644 --- a/v1/pkg/runner/runner.go +++ b/v1/pkg/runner/runner.go @@ -10,11 +10,10 @@ import ( // Bruteforce runner type Runner struct { - options *Options // CLI options - client *mdns.Client // DNS client - pool *ants.Pool // Goroutine pool - results chan *dns.Result // Results channel - wildcards map[string]bool // Domain wildcards + options *Options // CLI options + client *mdns.Client // DNS client + pool *ants.Pool // Goroutine pool + results chan *dns.Result // Results channel } // Return a new Runner @@ -45,25 +44,17 @@ func New(options *Options) *Runner { // Create channel results := make(chan *dns.Result, tasks) - // Create wildcards - wildcards := make(map[string]bool) - return &Runner{ - options: options, - client: client, - pool: pool, - results: results, - wildcards: wildcards, + options: options, + client: client, + pool: pool, + results: results, } } // Detect wildcard -func (r *Runner) Detect() { - // Go through domains - for _, domain := range r.options.Domains { - // Get wildcard status - r.wildcards[domain] = dns.Wildcard(r.client, r.options.Resolvers, domain) - } +func (r *Runner) Wildcard(domain string) bool { + return dns.Wildcard(r.client, r.options.Resolvers, domain) } // Submit tasks into pool @@ -103,27 +94,14 @@ func (r *Runner) Receive() { for range tasks { select { case result := <-r.results: - // Go through domains - for domain, wildcard := range r.wildcards { - // Domain found - if result.Domain == domain { - // Set wildcard - result.Wildcard = wildcard - } - } - // Send result r.options.OnResult(result) } } } -// Start bruteforcing -func (r *Runner) Bruteforce() { - if r.options.Wildcard { - r.Detect() - } - +// Start runner +func (r *Runner) Start() { go r.Submit() r.Receive() }