File: dns.go

package info (click to toggle)
gobuster 3.8.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,200 kB
  • sloc: makefile: 8
file content (83 lines) | stat: -rw-r--r-- 2,946 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package dns

import (
	"errors"
	"fmt"
	"runtime"
	"time"

	internalcli "github.com/OJ/gobuster/v3/cli"
	"github.com/OJ/gobuster/v3/gobusterdns"
	"github.com/OJ/gobuster/v3/libgobuster"
	"github.com/urfave/cli/v2"
)

func Command() *cli.Command {
	cmd := cli.Command{
		Name:   "dns",
		Usage:  "Uses DNS subdomain enumeration mode",
		Action: run,
		Flags:  getFlags(),
	}
	return &cmd
}

func getFlags() []cli.Flag {
	var flags []cli.Flag
	flags = append(flags, []cli.Flag{
		&cli.StringFlag{Name: "domain", Aliases: []string{"do"}, Usage: "The target domain", Required: true},
		&cli.BoolFlag{Name: "check-cname", Aliases: []string{"c"}, Value: false, Usage: "Also check CNAME records"},
		&cli.DurationFlag{Name: "timeout", Aliases: []string{"to"}, Value: 1 * time.Second, Usage: "DNS resolver timeout"},
		&cli.BoolFlag{Name: "wildcard", Aliases: []string{"wc"}, Value: false, Usage: "Force continued operation when wildcard found"},
		&cli.BoolFlag{Name: "no-fqdn", Aliases: []string{"nf"}, Value: false, Usage: "Do not automatically add a trailing dot to the domain, so the resolver uses the DNS search domain"},
		&cli.StringFlag{Name: "resolver", Usage: "Use custom DNS server (format server.com or server.com:port)"},
		&cli.StringFlag{Name: "protocol", Value: "udp", Usage: "Use either 'udp' or 'tcp' as protocol on the custom resolver"},
	}...)
	flags = append(flags, internalcli.GlobalOptions()...)
	return flags
}

func run(c *cli.Context) error {
	pluginOpts := gobusterdns.NewOptions()

	pluginOpts.Domain = c.String("domain")
	pluginOpts.CheckCNAME = c.Bool("check-cname")
	pluginOpts.Timeout = c.Duration("timeout")
	pluginOpts.WildcardForced = c.Bool("wildcard")
	pluginOpts.NoFQDN = c.Bool("no-fqdn")
	pluginOpts.Resolver = c.String("resolver")
	pluginOpts.Protocol = c.String("protocol")

	if pluginOpts.Resolver != "" && runtime.GOOS == "windows" {
		return errors.New("currently can not set custom dns resolver on windows. See https://golang.org/pkg/net/#hdr-Name_Resolution")
	}

	if pluginOpts.Protocol != "udp" && pluginOpts.Protocol != "tcp" {
		return errors.New("protocol must be either 'udp' or 'tcp'")
	}

	if pluginOpts.Protocol != "udp" && pluginOpts.Resolver == "" {
		return errors.New("custom protocol can only be set if a custom resolver is set")
	}

	globalOpts, err := internalcli.ParseGlobalOptions(c)
	if err != nil {
		return err
	}

	plugin, err := gobusterdns.New(&globalOpts, pluginOpts)
	if err != nil {
		return fmt.Errorf("error on creating gobusterdns: %w", err)
	}

	log := libgobuster.NewLogger(globalOpts.Debug)
	if err := internalcli.Gobuster(c.Context, &globalOpts, plugin, log); err != nil {
		var wErr *gobusterdns.WildcardError
		if errors.As(err, &wErr) {
			return fmt.Errorf("%w. To force processing of Wildcard DNS, specify the '--wildcard' switch", wErr)
		}
		log.Debugf("%#v", err)
		return fmt.Errorf("error on running gobuster on %s: %w", pluginOpts.Domain, err)
	}
	return nil
}