mirror of
https://github.com/OJ/gobuster.git
synced 2024-05-13 00:46:05 +02:00
Add support for network interface selection #45
This commit is contained in:
parent
660e20f526
commit
d46567c609
|
@ -43,6 +43,7 @@ All funds that are donated to this project will be donated to charity. A full lo
|
|||
- automatically disable progress output when output is redirected
|
||||
- fix extra special characters when run with `--no-progress`
|
||||
- warn when using vhost mode with a proxy and http based urls as this might not work as expected
|
||||
- add `interface` and `local-ip` parameters to specify the interface for http requests
|
||||
|
||||
## 3.6
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
@ -31,6 +32,8 @@ func BasicHTTPOptions() []cli.Flag {
|
|||
&cli.StringFlag{Name: "client-cert-pem-key", Aliases: []string{"ccpk"}, Usage: "private key in PEM format for optional TLS client certificates (this key needs to have no password)"},
|
||||
&cli.StringFlag{Name: "client-cert-p12", Aliases: []string{"ccp12"}, Usage: "a p12 file to use for options TLS client certificates"},
|
||||
&cli.StringFlag{Name: "client-cert-p12-password", Aliases: []string{"ccp12p"}, Usage: "the password to the p12 file"},
|
||||
&cli.StringFlag{Name: "interface", Aliases: []string{"iface"}, Usage: "specify network interface to use. Can't be used with local-ip"},
|
||||
&cli.StringFlag{Name: "local-ip", Usage: "specify local ip of network interface to use. Can't be used with interface"},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,6 +84,27 @@ func ParseBasicHTTPOptions(c *cli.Context) (libgobuster.BasicHTTPOptions, error)
|
|||
}
|
||||
}
|
||||
|
||||
iface := c.String("interface")
|
||||
localIP := c.String("local-ip")
|
||||
if iface != "" && localIP != "" {
|
||||
return opts, fmt.Errorf("can not set both interface and local-ip")
|
||||
}
|
||||
|
||||
switch {
|
||||
case iface != "":
|
||||
a, err := getLocalAddrFromInterface(iface)
|
||||
if err != nil {
|
||||
return opts, err
|
||||
}
|
||||
opts.LocalAddr = a
|
||||
case localIP != "":
|
||||
a, err := net.ResolveIPAddr("ip", localIP)
|
||||
if err != nil {
|
||||
return opts, err
|
||||
}
|
||||
opts.LocalAddr = a
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
|
@ -238,3 +262,28 @@ func ParseGlobalOptions(c *cli.Context) (libgobuster.Options, error) {
|
|||
opts.Debug = c.Bool("debug")
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func getLocalAddrFromInterface(iface string) (net.Addr, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get interfaces: %w", err)
|
||||
}
|
||||
|
||||
for _, i := range ifaces {
|
||||
if i.Name == iface {
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get local addrs for iface %s: %w", i.Name, err)
|
||||
}
|
||||
for _, a := range addrs {
|
||||
switch v := a.(type) {
|
||||
case *net.IPAddr:
|
||||
return v, nil
|
||||
case *net.IPNet:
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("could not find ip for interface %s", iface)
|
||||
}
|
||||
|
|
|
@ -368,6 +368,12 @@ func (d *GobusterDir) GetConfigString() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if o.BasicHTTPOptions.LocalAddr != nil {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Local IP:\t%s\n", o.BasicHTTPOptions.LocalAddr); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if o.HideLength {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Show length:\tfalse\n"); err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -266,6 +266,12 @@ func (d *GobusterFuzz) GetConfigString() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if o.BasicHTTPOptions.LocalAddr != nil {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Local IP:\t%s\n", o.BasicHTTPOptions.LocalAddr); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if o.Username != "" {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Auth User:\t%s\n", o.Username); err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -245,6 +245,12 @@ func (s *GobusterGCS) GetConfigString() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if o.BasicHTTPOptions.LocalAddr != nil {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Local IP:\t%s\n", o.BasicHTTPOptions.LocalAddr); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(tw, "[+] Timeout:\t%s\n", o.Timeout.String()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -236,6 +236,12 @@ func (s *GobusterS3) GetConfigString() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if o.BasicHTTPOptions.LocalAddr != nil {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Local IP:\t%s\n", o.BasicHTTPOptions.LocalAddr); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(tw, "[+] Timeout:\t%s\n", o.Timeout.String()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -266,6 +266,12 @@ func (v *GobusterVhost) GetConfigString() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if o.BasicHTTPOptions.LocalAddr != nil {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Local IP:\t%s\n", o.BasicHTTPOptions.LocalAddr); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if o.Username != "" {
|
||||
if _, err := fmt.Fprintf(tw, "[+] Auth User:\t%s\n", o.Username); err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
|
@ -79,15 +80,28 @@ func NewHTTPClient(opt *HTTPOptions, logger *Logger) (*HTTPClient, error) {
|
|||
tlsConfig.Certificates = []tls.Certificate{*opt.TLSCertificate}
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
Proxy: proxyURLFunc,
|
||||
MaxIdleConns: 100,
|
||||
MaxIdleConnsPerHost: 100,
|
||||
TLSClientConfig: &tlsConfig,
|
||||
}
|
||||
|
||||
// set specific network interface
|
||||
if opt.LocalAddr != nil {
|
||||
dialer := &net.Dialer{
|
||||
Timeout: opt.Timeout,
|
||||
LocalAddr: opt.LocalAddr,
|
||||
}
|
||||
transport.DialContext = dialer.DialContext
|
||||
}
|
||||
|
||||
client.client = &http.Client{
|
||||
Timeout: opt.Timeout,
|
||||
CheckRedirect: redirectFunc,
|
||||
Transport: &http.Transport{
|
||||
Proxy: proxyURLFunc,
|
||||
MaxIdleConns: 100,
|
||||
MaxIdleConnsPerHost: 100,
|
||||
TLSClientConfig: &tlsConfig,
|
||||
}}
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
client.username = opt.Username
|
||||
client.password = opt.Password
|
||||
client.userAgent = opt.UserAgent
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package libgobuster
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Options holds all options that can be passed to libgobuster
|
||||
type Options struct {
|
||||
|
|
|
@ -2,6 +2,7 @@ package libgobuster
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -14,6 +15,7 @@ type BasicHTTPOptions struct {
|
|||
RetryOnTimeout bool
|
||||
RetryAttempts int
|
||||
TLSCertificate *tls.Certificate
|
||||
LocalAddr net.Addr
|
||||
}
|
||||
|
||||
// HTTPOptions is the struct to pass in all http options to Gobuster
|
||||
|
|
Loading…
Reference in New Issue