mirror of https://github.com/daffainfo/nuclei.git
Added vhost templating support
parent
b7475e84f0
commit
4f5fb2baed
|
@ -186,5 +186,7 @@ func (p *Progress) Stop() {
|
||||||
gologger.Warningf("Couldn't stop statistics: %s\n", err)
|
gologger.Warningf("Couldn't stop statistics: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = p.server.Shutdown(context.Background())
|
if p.server != nil {
|
||||||
|
_ = p.server.Shutdown(context.Background())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
// Options contains the configuration options for tuning
|
// Options contains the configuration options for tuning
|
||||||
// the template requesting process.
|
// the template requesting process.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
Vhost bool // Mark the input specified as VHOST input
|
||||||
RandomAgent bool // Generate random User-Agent
|
RandomAgent bool // Generate random User-Agent
|
||||||
Metrics bool // Metrics enables display of metrics via an http endpoint
|
Metrics bool // Metrics enables display of metrics via an http endpoint
|
||||||
Sandbox bool // Sandbox mode allows users to run isolated workflows with system commands disabled
|
Sandbox bool // Sandbox mode allows users to run isolated workflows with system commands disabled
|
||||||
|
@ -69,6 +70,7 @@ func (m *multiStringFlag) Set(value string) error {
|
||||||
func ParseOptions() *Options {
|
func ParseOptions() *Options {
|
||||||
options := &Options{}
|
options := &Options{}
|
||||||
|
|
||||||
|
flag.BoolVar(&options.Vhost, "vhost", false, "Input supplied is a comma-separated vhost list")
|
||||||
flag.BoolVar(&options.Sandbox, "sandbox", false, "Run workflows in isolated sandbox mode")
|
flag.BoolVar(&options.Sandbox, "sandbox", false, "Run workflows in isolated sandbox mode")
|
||||||
flag.BoolVar(&options.Metrics, "metrics", false, "Expose nuclei metrics on a port")
|
flag.BoolVar(&options.Metrics, "metrics", false, "Expose nuclei metrics on a port")
|
||||||
flag.IntVar(&options.MetricsPort, "metrics-port", 9092, "Port to expose nuclei metrics on")
|
flag.IntVar(&options.MetricsPort, "metrics-port", 9092, "Port to expose nuclei metrics on")
|
||||||
|
|
|
@ -46,6 +46,7 @@ func (r *Runner) processTemplateWithList(p *progress.Progress, template *templat
|
||||||
Template: template,
|
Template: template,
|
||||||
DNSRequest: value,
|
DNSRequest: value,
|
||||||
Writer: r.output,
|
Writer: r.output,
|
||||||
|
VHost: r.options.Vhost,
|
||||||
JSON: r.options.JSON,
|
JSON: r.options.JSON,
|
||||||
JSONRequests: r.options.JSONRequests,
|
JSONRequests: r.options.JSONRequests,
|
||||||
NoMeta: r.options.NoMeta,
|
NoMeta: r.options.NoMeta,
|
||||||
|
@ -68,6 +69,7 @@ func (r *Runner) processTemplateWithList(p *progress.Progress, template *templat
|
||||||
RandomAgent: r.options.RandomAgent,
|
RandomAgent: r.options.RandomAgent,
|
||||||
CustomHeaders: r.options.CustomHeaders,
|
CustomHeaders: r.options.CustomHeaders,
|
||||||
JSON: r.options.JSON,
|
JSON: r.options.JSON,
|
||||||
|
Vhost: r.options.Vhost,
|
||||||
JSONRequests: r.options.JSONRequests,
|
JSONRequests: r.options.JSONRequests,
|
||||||
NoMeta: r.options.NoMeta,
|
NoMeta: r.options.NoMeta,
|
||||||
CookieReuse: value.CookieReuse,
|
CookieReuse: value.CookieReuse,
|
||||||
|
@ -114,7 +116,6 @@ func (r *Runner) processTemplateWithList(p *progress.Progress, template *templat
|
||||||
gologger.Warningf("[%s] Could not execute step: %s\n", r.colorizer.Colorizer.BrightBlue(template.ID), result.Error)
|
gologger.Warningf("[%s] Could not execute step: %s\n", r.colorizer.Colorizer.BrightBlue(template.ID), result.Error)
|
||||||
}
|
}
|
||||||
}(URL)
|
}(URL)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -235,6 +236,7 @@ func (r *Runner) preloadWorkflowTemplates(p *progress.Progress, workflow *workfl
|
||||||
ProxySocksURL: r.options.ProxySocksURL,
|
ProxySocksURL: r.options.ProxySocksURL,
|
||||||
RandomAgent: r.options.RandomAgent,
|
RandomAgent: r.options.RandomAgent,
|
||||||
CustomHeaders: r.options.CustomHeaders,
|
CustomHeaders: r.options.CustomHeaders,
|
||||||
|
Vhost: r.options.Vhost,
|
||||||
JSON: r.options.JSON,
|
JSON: r.options.JSON,
|
||||||
JSONRequests: r.options.JSONRequests,
|
JSONRequests: r.options.JSONRequests,
|
||||||
CookieJar: jar,
|
CookieJar: jar,
|
||||||
|
@ -253,6 +255,7 @@ func (r *Runner) preloadWorkflowTemplates(p *progress.Progress, workflow *workfl
|
||||||
Debug: r.options.Debug,
|
Debug: r.options.Debug,
|
||||||
Template: t,
|
Template: t,
|
||||||
Writer: r.output,
|
Writer: r.output,
|
||||||
|
VHost: r.options.Vhost,
|
||||||
JSON: r.options.JSON,
|
JSON: r.options.JSON,
|
||||||
JSONRequests: r.options.JSONRequests,
|
JSONRequests: r.options.JSONRequests,
|
||||||
ColoredOutput: !r.options.NoColor,
|
ColoredOutput: !r.options.NoColor,
|
||||||
|
@ -309,6 +312,7 @@ func (r *Runner) preloadWorkflowTemplates(p *progress.Progress, workflow *workfl
|
||||||
ProxySocksURL: r.options.ProxySocksURL,
|
ProxySocksURL: r.options.ProxySocksURL,
|
||||||
RandomAgent: r.options.RandomAgent,
|
RandomAgent: r.options.RandomAgent,
|
||||||
CustomHeaders: r.options.CustomHeaders,
|
CustomHeaders: r.options.CustomHeaders,
|
||||||
|
Vhost: r.options.Vhost,
|
||||||
CookieJar: jar,
|
CookieJar: jar,
|
||||||
TraceLog: r.traceLog,
|
TraceLog: r.traceLog,
|
||||||
}
|
}
|
||||||
|
@ -317,6 +321,7 @@ func (r *Runner) preloadWorkflowTemplates(p *progress.Progress, workflow *workfl
|
||||||
Debug: r.options.Debug,
|
Debug: r.options.Debug,
|
||||||
Template: t,
|
Template: t,
|
||||||
Writer: r.output,
|
Writer: r.output,
|
||||||
|
VHost: r.options.Vhost,
|
||||||
TraceLog: r.traceLog,
|
TraceLog: r.traceLog,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/projectdiscovery/gologger"
|
"github.com/projectdiscovery/gologger"
|
||||||
|
@ -28,6 +29,7 @@ type DNSExecuter struct {
|
||||||
jsonRequest bool
|
jsonRequest bool
|
||||||
noMeta bool
|
noMeta bool
|
||||||
Results bool
|
Results bool
|
||||||
|
vhost bool
|
||||||
traceLog tracelog.Log
|
traceLog tracelog.Log
|
||||||
dnsClient *retryabledns.Client
|
dnsClient *retryabledns.Client
|
||||||
template *templates.Template
|
template *templates.Template
|
||||||
|
@ -54,6 +56,7 @@ type DNSOptions struct {
|
||||||
JSON bool
|
JSON bool
|
||||||
JSONRequests bool
|
JSONRequests bool
|
||||||
NoMeta bool
|
NoMeta bool
|
||||||
|
VHost bool
|
||||||
TraceLog tracelog.Log
|
TraceLog tracelog.Log
|
||||||
Template *templates.Template
|
Template *templates.Template
|
||||||
DNSRequest *requests.DNSRequest
|
DNSRequest *requests.DNSRequest
|
||||||
|
@ -76,6 +79,7 @@ func NewDNSExecuter(options *DNSOptions) *DNSExecuter {
|
||||||
traceLog: options.TraceLog,
|
traceLog: options.TraceLog,
|
||||||
jsonRequest: options.JSONRequests,
|
jsonRequest: options.JSONRequests,
|
||||||
dnsClient: dnsClient,
|
dnsClient: dnsClient,
|
||||||
|
vhost: options.VHost,
|
||||||
template: options.Template,
|
template: options.Template,
|
||||||
dnsRequest: options.DNSRequest,
|
dnsRequest: options.DNSRequest,
|
||||||
writer: options.Writer,
|
writer: options.Writer,
|
||||||
|
@ -84,13 +88,16 @@ func NewDNSExecuter(options *DNSOptions) *DNSExecuter {
|
||||||
decolorizer: options.Decolorizer,
|
decolorizer: options.Decolorizer,
|
||||||
ratelimiter: options.RateLimiter,
|
ratelimiter: options.RateLimiter,
|
||||||
}
|
}
|
||||||
|
|
||||||
return executer
|
return executer
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteDNS executes the DNS request on a URL
|
// ExecuteDNS executes the DNS request on a URL
|
||||||
func (e *DNSExecuter) ExecuteDNS(p *progress.Progress, reqURL string) *Result {
|
func (e *DNSExecuter) ExecuteDNS(p *progress.Progress, reqURL string) *Result {
|
||||||
result := &Result{}
|
result := &Result{}
|
||||||
|
if e.vhost {
|
||||||
|
parts := strings.Split(reqURL, ",")
|
||||||
|
reqURL = parts[0]
|
||||||
|
}
|
||||||
|
|
||||||
// Parse the URL and return domain if URL.
|
// Parse the URL and return domain if URL.
|
||||||
var domain string
|
var domain string
|
||||||
|
|
|
@ -61,6 +61,7 @@ type HTTPExecuter struct {
|
||||||
traceLog tracelog.Log
|
traceLog tracelog.Log
|
||||||
decolorizer *regexp.Regexp
|
decolorizer *regexp.Regexp
|
||||||
randomAgent bool
|
randomAgent bool
|
||||||
|
vhost bool
|
||||||
coloredOutput bool
|
coloredOutput bool
|
||||||
debug bool
|
debug bool
|
||||||
Results bool
|
Results bool
|
||||||
|
@ -81,6 +82,7 @@ type HTTPOptions struct {
|
||||||
CookieReuse bool
|
CookieReuse bool
|
||||||
ColoredOutput bool
|
ColoredOutput bool
|
||||||
StopAtFirstMatch bool
|
StopAtFirstMatch bool
|
||||||
|
Vhost bool
|
||||||
Timeout int
|
Timeout int
|
||||||
Retries int
|
Retries int
|
||||||
ProxyURL string
|
ProxyURL string
|
||||||
|
@ -151,9 +153,9 @@ func NewHTTPExecuter(options *HTTPOptions) (*HTTPExecuter, error) {
|
||||||
decolorizer: options.Decolorizer,
|
decolorizer: options.Decolorizer,
|
||||||
stopAtFirstMatch: options.StopAtFirstMatch,
|
stopAtFirstMatch: options.StopAtFirstMatch,
|
||||||
pf: options.PF,
|
pf: options.PF,
|
||||||
|
vhost: options.Vhost,
|
||||||
ratelimiter: options.RateLimiter,
|
ratelimiter: options.RateLimiter,
|
||||||
}
|
}
|
||||||
|
|
||||||
return executer, nil
|
return executer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +339,13 @@ func (e *HTTPExecuter) ExecuteTurboHTTP(reqURL string) *Result {
|
||||||
|
|
||||||
// ExecuteHTTP executes the HTTP request on a URL
|
// ExecuteHTTP executes the HTTP request on a URL
|
||||||
func (e *HTTPExecuter) ExecuteHTTP(p *progress.Progress, reqURL string) *Result {
|
func (e *HTTPExecuter) ExecuteHTTP(p *progress.Progress, reqURL string) *Result {
|
||||||
|
var customHost string
|
||||||
|
if e.vhost {
|
||||||
|
parts := strings.Split(reqURL, ",")
|
||||||
|
reqURL = parts[0]
|
||||||
|
customHost = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
// verify if pipeline was requested
|
// verify if pipeline was requested
|
||||||
if e.bulkHTTPRequest.Pipeline {
|
if e.bulkHTTPRequest.Pipeline {
|
||||||
return e.ExecuteTurboHTTP(reqURL)
|
return e.ExecuteTurboHTTP(reqURL)
|
||||||
|
@ -383,6 +392,15 @@ func (e *HTTPExecuter) ExecuteHTTP(p *progress.Progress, reqURL string) *Result
|
||||||
result.Error = err
|
result.Error = err
|
||||||
p.Drop(remaining)
|
p.Drop(remaining)
|
||||||
} else {
|
} else {
|
||||||
|
if e.vhost {
|
||||||
|
if httpRequest.Request != nil {
|
||||||
|
httpRequest.Request.Host = customHost
|
||||||
|
}
|
||||||
|
if httpRequest.RawRequest != nil && httpRequest.RawRequest.Headers != nil {
|
||||||
|
httpRequest.RawRequest.Headers["Host"] = customHost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.ratelimiter.Take()
|
e.ratelimiter.Take()
|
||||||
// If the request was built correctly then execute it
|
// If the request was built correctly then execute it
|
||||||
format := "%s_" + strconv.Itoa(requestNumber)
|
format := "%s_" + strconv.Itoa(requestNumber)
|
||||||
|
|
|
@ -132,7 +132,6 @@ func (r *BulkHTTPRequest) MakeHTTPRequest(baseURL string, dynamicValues map[stri
|
||||||
if strings.Contains(data, "\n") {
|
if strings.Contains(data, "\n") {
|
||||||
return r.makeHTTPRequestFromRaw(ctx, baseURL, data, values)
|
return r.makeHTTPRequestFromRaw(ctx, baseURL, data, values)
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.makeHTTPRequestFromModel(ctx, data, values)
|
return r.makeHTTPRequestFromModel(ctx, data, values)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +150,6 @@ func (r *BulkHTTPRequest) makeHTTPRequestFromModel(ctx context.Context, data str
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &HTTPRequest{Request: request}, nil
|
return &HTTPRequest{Request: request}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue