mirror of https://github.com/daffainfo/nuclei.git
add option to specify network interface (#2384)
* add option to specify network interface * add source-ip flag * fix typo * fix err return * readme update Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io>dev
parent
30054d1fb6
commit
011da1388d
|
@ -142,6 +142,7 @@ OUTPUT:
|
|||
|
||||
CONFIGURATIONS:
|
||||
-config string path to the nuclei configuration file
|
||||
-config-directory string override the default config path ($home/.config)
|
||||
-fr, -follow-redirects enable following redirects for http templates
|
||||
-mr, -max-redirects int max number of redirects to follow for http templates (default 10)
|
||||
-dr, -disable-redirects disable redirects for http templates
|
||||
|
@ -158,6 +159,8 @@ CONFIGURATIONS:
|
|||
-sml, -show-match-line show match lines for file templates, works with extractors only
|
||||
-ztls use ztls library with autofallback to standard one for tls13
|
||||
-sni string tls sni hostname to use (default: input domain name)
|
||||
-i, -interface string network interface to use for network scan
|
||||
-sip, -source-ip string source ip address to use for network scan
|
||||
|
||||
INTERACTSH:
|
||||
-iserver, -interactsh-server string interactsh server url for self-hosted instance (default: oast.pro,oast.live,oast.site,oast.online,oast.fun,oast.me)
|
||||
|
|
|
@ -183,6 +183,8 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||
flagSet.BoolVarP(&options.ShowMatchLine, "show-match-line", "sml", false, "show match lines for file templates, works with extractors only"),
|
||||
flagSet.BoolVar(&options.ZTLS, "ztls", false, "use ztls library with autofallback to standard one for tls13"),
|
||||
flagSet.StringVar(&options.SNI, "sni", "", "tls sni hostname to use (default: input domain name)"),
|
||||
flagSet.StringVarP(&options.Interface, "interface", "i", "", "network interface to use for network scan"),
|
||||
flagSet.StringVarP(&options.SourceIP, "source-ip", "sip", "", "source ip address to use for network scan"),
|
||||
flagSet.StringVar(&options.CustomConfigDir, "config-directory", "", "Override the default config path ($home/.config)"),
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package protocolstate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/projectdiscovery/fastdialer/fastdialer"
|
||||
|
@ -16,6 +19,48 @@ func Init(options *types.Options) error {
|
|||
return nil
|
||||
}
|
||||
opts := fastdialer.DefaultOptions
|
||||
|
||||
switch {
|
||||
case options.SourceIP != "" && options.Interface != "":
|
||||
isAssociated, err := isIpAssociatedWithInterface(options.SourceIP, options.Interface)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isAssociated {
|
||||
opts.Dialer = &net.Dialer{
|
||||
LocalAddr: &net.TCPAddr{
|
||||
IP: net.ParseIP(options.SourceIP),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("source ip (%s) is not associated with the interface (%s)", options.SourceIP, options.Interface)
|
||||
}
|
||||
case options.SourceIP != "":
|
||||
isAssociated, err := isIpAssociatedWithInterface(options.SourceIP, "any")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isAssociated {
|
||||
opts.Dialer = &net.Dialer{
|
||||
LocalAddr: &net.TCPAddr{
|
||||
IP: net.ParseIP(options.SourceIP),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("source ip (%s) is not associated with any network interface", options.SourceIP)
|
||||
}
|
||||
case options.Interface != "":
|
||||
ifadrr, err := interfaceAddress(options.Interface)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.Dialer = &net.Dialer{
|
||||
LocalAddr: &net.TCPAddr{
|
||||
IP: ifadrr,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if options.SystemResolvers {
|
||||
opts.EnableFallback = true
|
||||
}
|
||||
|
@ -33,6 +78,58 @@ func Init(options *types.Options) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// isIpAssociatedWithInterface checks if the given IP is associated with the given interface.
|
||||
func isIpAssociatedWithInterface(souceIP, interfaceName string) (bool, error) {
|
||||
addrs, err := interfaceAddresses(interfaceName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok {
|
||||
if ipnet.IP.String() == souceIP {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// interfaceAddress returns the first IPv4 address of the given interface.
|
||||
func interfaceAddress(interfaceName string) (net.IP, error) {
|
||||
addrs, err := interfaceAddresses(interfaceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var address net.IP
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
address = ipnet.IP
|
||||
}
|
||||
}
|
||||
}
|
||||
if address == nil {
|
||||
return nil, fmt.Errorf("no suitable address found for interface: `%s`", interfaceName)
|
||||
}
|
||||
return address, nil
|
||||
}
|
||||
|
||||
// interfaceAddresses returns all interface addresses.
|
||||
func interfaceAddresses(interfaceName string) ([]net.Addr, error) {
|
||||
if interfaceName == "any" {
|
||||
return net.InterfaceAddrs()
|
||||
}
|
||||
ief, err := net.InterfaceByName(interfaceName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get interface: `%s`", interfaceName)
|
||||
}
|
||||
addrs, err := ief.Addrs()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get interface addresses for: `%s`", interfaceName)
|
||||
}
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
// Close closes the global shared fastdialer
|
||||
func Close() {
|
||||
if Dialer != nil {
|
||||
|
|
|
@ -230,6 +230,10 @@ type Options struct {
|
|||
DisableRedirects bool
|
||||
// SNI custom hostname
|
||||
SNI string
|
||||
// Interface to use for network scan
|
||||
Interface string
|
||||
// SourceIP sets custom source IP address for network requests
|
||||
SourceIP string
|
||||
// Health Check
|
||||
HealthCheck bool
|
||||
// Time to wait between each input read operation before closing the stream
|
||||
|
|
Loading…
Reference in New Issue