2020-04-04 03:45:39 +05:30
package runner
import (
2020-08-29 15:26:11 +02:00
"errors"
2020-04-04 03:45:39 +05:30
"flag"
2020-08-29 15:26:11 +02:00
"net/url"
2020-04-04 03:45:39 +05:30
"os"
"github.com/projectdiscovery/gologger"
2020-07-01 16:17:24 +05:30
"github.com/projectdiscovery/nuclei/v2/pkg/requests"
2020-04-04 03:45:39 +05:30
)
// Options contains the configuration options for tuning
// the template requesting process.
type Options struct {
2020-08-25 23:24:31 +02:00
Debug bool // Debug mode allows debugging request/responses for the engine
Silent bool // Silent suppresses any extra text and only writes found URLs on screen.
Version bool // Version specifies if we should just show version and exit
Verbose bool // Verbose flag indicates whether to show verbose output or not
NoColor bool // No-Color disables the colored output.
UpdateTemplates bool // UpdateTemplates updates the templates installed at startup
JSON bool // JSON writes json output to files
JSONRequests bool // write requests/responses for matches in JSON output
EnableProgressBar bool // Enable progrss bar
2020-08-29 15:26:11 +02:00
TemplateList bool // List available templates
2020-08-25 23:24:31 +02:00
Stdin bool // Stdin specifies whether stdin input was given to the process
2020-07-14 00:01:46 +02:00
Templates multiStringFlag // Signature specifies the template/templates to use
2020-08-02 15:48:10 +02:00
ExcludedTemplates multiStringFlag // Signature specifies the template/templates to exclude
2020-08-25 23:24:31 +02:00
Severity string // Filter templates based on their severity and only run the matching ones.
2020-06-25 21:40:20 +05:30
Target string // Target is a single URL/Domain to scan usng a template
2020-06-25 03:53:37 +05:30
Targets string // Targets specifies the targets to scan using templates.
Threads int // Thread controls the number of concurrent requests to make.
Timeout int // Timeout is the seconds to wait for a response from the server.
Retries int // Retries is the number of times to retry the request
Output string // Output is the file to write found subdomains to.
ProxyURL string // ProxyURL is the URL for the proxy server
ProxySocksURL string // ProxySocksURL is the URL for the proxy socks server
CustomHeaders requests . CustomHeaders // Custom global headers
TemplatesDirectory string // TemplatesDirectory is the directory to use for storing templates
2020-09-12 15:41:24 +02:00
RateLimit int // Rate-Limit of requests per specified target
2020-04-04 03:45:39 +05:30
}
2020-07-14 00:01:46 +02:00
type multiStringFlag [ ] string
func ( m * multiStringFlag ) String ( ) string {
return ""
}
func ( m * multiStringFlag ) Set ( value string ) error {
* m = append ( * m , value )
return nil
}
2020-04-04 03:45:39 +05:30
// ParseOptions parses the command line flags provided by a user
func ParseOptions ( ) * Options {
options := & Options { }
2020-06-25 21:40:20 +05:30
flag . StringVar ( & options . Target , "target" , "" , "Target is a single target to scan using template" )
2020-08-02 15:48:10 +02:00
flag . Var ( & options . Templates , "t" , "Template input dir/file/files to run on host. Can be used multiple times. Supports globbing." )
flag . Var ( & options . ExcludedTemplates , "exclude" , "Template input dir/file/files to exclude. Can be used multiple times. Supports globbing." )
2020-08-02 18:33:55 +02:00
flag . StringVar ( & options . Severity , "severity" , "" , "Filter templates based on their severity and only run the matching ones. Comma-separated values can be used to specify multiple severities." )
2020-04-04 17:24:31 +05:30
flag . StringVar ( & options . Targets , "l" , "" , "List of URLs to run templates on" )
2020-04-04 03:45:39 +05:30
flag . StringVar ( & options . Output , "o" , "" , "File to write output to (optional)" )
2020-04-27 23:49:53 +05:30
flag . StringVar ( & options . ProxyURL , "proxy-url" , "" , "URL of the proxy server" )
2020-04-28 04:01:25 +02:00
flag . StringVar ( & options . ProxySocksURL , "proxy-socks-url" , "" , "URL of the proxy socks server" )
2020-04-04 17:24:31 +05:30
flag . BoolVar ( & options . Silent , "silent" , false , "Show only results in output" )
flag . BoolVar ( & options . Version , "version" , false , "Show version of nuclei" )
2020-04-04 03:45:39 +05:30
flag . BoolVar ( & options . Verbose , "v" , false , "Show Verbose output" )
flag . BoolVar ( & options . NoColor , "nC" , false , "Don't Use colors in output" )
2020-07-24 18:12:16 +02:00
flag . IntVar ( & options . Threads , "c" , 50 , "Number of concurrent requests to make" )
2020-04-04 18:10:26 +05:30
flag . IntVar ( & options . Timeout , "timeout" , 5 , "Time to wait in seconds before timeout" )
flag . IntVar ( & options . Retries , "retries" , 1 , "Number of times to retry a failed request" )
2020-05-22 00:23:38 +02:00
flag . Var ( & options . CustomHeaders , "H" , "Custom Header." )
2020-06-22 19:30:01 +05:30
flag . BoolVar ( & options . Debug , "debug" , false , "Allow debugging of request/responses" )
2020-06-25 03:53:37 +05:30
flag . BoolVar ( & options . UpdateTemplates , "update-templates" , false , "Update Templates updates the installed templates (optional)" )
2020-06-27 20:52:54 +05:30
flag . StringVar ( & options . TemplatesDirectory , "update-directory" , "" , "Directory to use for storing nuclei-templates" )
2020-06-27 20:19:43 +05:30
flag . BoolVar ( & options . JSON , "json" , false , "Write json output to files" )
2020-07-15 13:38:45 +02:00
flag . BoolVar ( & options . JSONRequests , "json-requests" , false , "Write requests/responses for matches in JSON output" )
2020-07-31 18:46:23 +02:00
flag . BoolVar ( & options . EnableProgressBar , "pbar" , false , "Enable the progress bar" )
2020-08-29 15:26:11 +02:00
flag . BoolVar ( & options . TemplateList , "tl" , false , "List available templates" )
2020-09-12 17:28:25 +02:00
flag . IntVar ( & options . RateLimit , "rl" , 9999999 , "Rate-Limit of requests per specified target" ) // 9999999 to avoid limiting
2020-04-04 03:45:39 +05:30
flag . Parse ( )
// Check if stdin pipe was given
options . Stdin = hasStdin ( )
// Read the inputs and configure the logging
options . configureOutput ( )
// Show the user the banner
showBanner ( )
if options . Version {
gologger . Infof ( "Current Version: %s\n" , Version )
os . Exit ( 0 )
}
2020-04-26 06:48:10 +05:30
2020-04-04 03:45:39 +05:30
// Validate the options passed by the user and if any
// invalid options have been used, exit.
err := options . validateOptions ( )
if err != nil {
gologger . Fatalf ( "Program exiting: %s\n" , err )
}
2020-08-25 23:24:31 +02:00
2020-04-04 03:45:39 +05:30
return options
}
func hasStdin ( ) bool {
fi , err := os . Stdin . Stat ( )
if err != nil {
return false
}
2020-08-25 23:24:31 +02:00
2020-04-04 03:45:39 +05:30
if fi . Mode ( ) & os . ModeNamedPipe == 0 {
return false
}
2020-08-25 23:24:31 +02:00
2020-04-04 03:45:39 +05:30
return true
}
2020-08-29 15:26:11 +02:00
// validateOptions validates the configuration options passed
func ( options * Options ) validateOptions ( ) error {
// Both verbose and silent flags were used
if options . Verbose && options . Silent {
return errors . New ( "both verbose and silent mode specified" )
}
2020-08-29 23:02:45 +02:00
if ! options . TemplateList {
2020-08-29 15:26:11 +02:00
// Check if a list of templates was provided and it exists
if len ( options . Templates ) == 0 && ! options . UpdateTemplates {
return errors . New ( "no template/templates provided" )
}
if options . Targets == "" && ! options . Stdin && options . Target == "" && ! options . UpdateTemplates {
return errors . New ( "no target input provided" )
}
}
// Validate proxy options if provided
2020-08-29 16:25:30 +02:00
err := validateProxyURL (
options . ProxyURL ,
"invalid http proxy format (It should be http://username:password@host:port)" ,
)
if err != nil {
return err
}
err = validateProxyURL (
options . ProxySocksURL ,
"invalid socks proxy format (It should be socks5://username:password@host:port)" ,
)
if err != nil {
return err
2020-08-29 15:26:11 +02:00
}
2020-08-29 16:25:30 +02:00
return nil
}
func validateProxyURL ( proxyURL , message string ) error {
if proxyURL != "" && ! isValidURL ( proxyURL ) {
return errors . New ( message )
2020-08-29 15:26:11 +02:00
}
return nil
}
2020-08-29 16:25:30 +02:00
func isValidURL ( urlString string ) bool {
_ , err := url . Parse ( urlString )
2020-08-29 15:26:11 +02:00
return err == nil
}
// configureOutput configures the output on the screen
func ( options * Options ) configureOutput ( ) {
// If the user desires verbose output, show verbose output
if options . Verbose {
gologger . MaxLevel = gologger . Verbose
}
if options . NoColor {
gologger . UseColors = false
}
if options . Silent {
gologger . MaxLevel = gologger . Silent
}
}