mirror of https://github.com/daffainfo/nuclei.git
Refactor code, add meaningful comments
parent
002daadf46
commit
97901f36b4
13
v2/go.sum
13
v2/go.sum
|
@ -1,5 +1,9 @@
|
|||
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
|
@ -24,6 +28,10 @@ github.com/karrick/godirwalk v1.15.6 h1:Yf2mmR8TJy+8Fa0SuQVto5SYap6IF7lNVX4Jdl8G
|
|||
github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
|
@ -42,6 +50,8 @@ github.com/projectdiscovery/retryablehttp-go v1.0.1/go.mod h1:SrN6iLZilNG1X4neq1
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/vbauerster/mpb/v5 v5.2.2 h1:zIICVOm+XD+uV6crpSORaL6I0Q1WqOdvxZTp+r3L9cw=
|
||||
github.com/vbauerster/mpb/v5 v5.2.2/go.mod h1:W5Fvgw4dm3/0NhqzV8j6EacfuTe5SvnzBRwiXxDR9ww=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -57,8 +67,11 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package progress
|
||||
|
||||
import (
|
||||
"github.com/vbauerster/mpb/v5"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Represents a single progress bar
|
||||
type Bar struct {
|
||||
bar *mpb.Bar
|
||||
total int64
|
||||
initialTotal int64
|
||||
}
|
||||
|
||||
// Drops the specified number of requests from the progress bar total.
|
||||
// This may be the case when uncompleted requests are encountered and shouldn't be part of the total count.
|
||||
func (b *Bar) Drop(count int64) {
|
||||
atomic.AddInt64(&b.total, -count)
|
||||
b.bar.SetTotal(atomic.LoadInt64(&b.total), false)
|
||||
}
|
||||
|
||||
// Ensures that a progress bar's total count is up-to-date if during an enumeration there were uncompleted requests.
|
||||
func (b *Bar) finish() {
|
||||
if b.initialTotal != b.total {
|
||||
b.bar.SetTotal(b.total, true)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
// Tracks enumeration progress information and implements visible tracking with one or more progress bars.
|
||||
package progress
|
|
@ -9,14 +9,14 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Encapsulates progress tracking.
|
||||
type Progress struct {
|
||||
progress *mpb.Progress
|
||||
bar *mpb.Bar
|
||||
total int64
|
||||
initialTotal int64
|
||||
progress *mpb.Progress
|
||||
barTemplate *Bar
|
||||
barGlobal *Bar
|
||||
|
||||
captureData *captureData
|
||||
termWidth int
|
||||
stdCaptureMutex *sync.Mutex
|
||||
|
@ -24,6 +24,7 @@ type Progress struct {
|
|||
stderr *strings.Builder
|
||||
}
|
||||
|
||||
// Creates and returns a new progress tracking object.
|
||||
func NewProgress(group *sync.WaitGroup) *Progress {
|
||||
w := cwriter.New(os.Stderr)
|
||||
tw, err := w.GetWidth()
|
||||
|
@ -45,54 +46,110 @@ func NewProgress(group *sync.WaitGroup) *Progress {
|
|||
return p
|
||||
}
|
||||
|
||||
func (p *Progress) SetupProgressBar(name string, total int64) *mpb.Bar {
|
||||
barname := "[" + aurora.Green(name).String() + "]"
|
||||
bar := p.progress.AddBar(
|
||||
// Creates and returns a progress bar that tracks request progress for a specific template.
|
||||
func (p *Progress) SetupTemplateProgressbar(templateIndex int, templateCount int, name string, requestCount int64) {
|
||||
barName := "[" + aurora.Green(name).String() + "]"
|
||||
|
||||
if templateIndex > -1 && templateCount > -1 {
|
||||
barName = aurora.Sprintf("[%d/%d] ", aurora.Bold(aurora.Cyan(templateIndex)), aurora.Cyan(templateCount)) + barName
|
||||
}
|
||||
|
||||
bar := p.setupProgressbar(barName, requestCount)
|
||||
|
||||
if p.barTemplate != nil {
|
||||
// ensure any previous bar has finished and aborted requests have also been considered
|
||||
p.barTemplate.finish()
|
||||
}
|
||||
|
||||
p.barTemplate = &Bar{
|
||||
bar: bar,
|
||||
total: requestCount,
|
||||
initialTotal: requestCount,
|
||||
}
|
||||
}
|
||||
|
||||
// Creates and returns a progress bar that tracks all the requests progress.
|
||||
// This is only useful when multiple templates are processed within the same run.
|
||||
func (p *Progress) SetupGlobalProgressbar(hostCount int64, templateCount int, requestCount int64) {
|
||||
hostPlural := "host"
|
||||
if hostCount > 1 {
|
||||
hostPlural = "hosts"
|
||||
}
|
||||
|
||||
barName := "[" + aurora.Sprintf(
|
||||
aurora.Cyan("%d templates, %d %s"),
|
||||
aurora.Bold(aurora.Cyan(templateCount)),
|
||||
aurora.Bold(aurora.Cyan(hostCount)),
|
||||
hostPlural) + "]"
|
||||
|
||||
bar := p.setupProgressbar(barName, requestCount)
|
||||
|
||||
p.barGlobal = &Bar{
|
||||
bar: bar,
|
||||
total: requestCount,
|
||||
initialTotal: requestCount,
|
||||
}
|
||||
}
|
||||
|
||||
// Update progress tracking information and increments the request counter by one unit.
|
||||
// If a global progress bar is present it will be updated as well.
|
||||
func (p *Progress) Update() {
|
||||
p.barTemplate.bar.Increment()
|
||||
|
||||
if p.barGlobal != nil {
|
||||
p.barGlobal.bar.Increment()
|
||||
}
|
||||
}
|
||||
|
||||
// Drops the specified number of requests from the progress bar total.
|
||||
// This may be the case when uncompleted requests are encountered and shouldn't be part of the total count.
|
||||
// If a global progress bar is present it will be updated as well.
|
||||
func (p *Progress) Drop(count int64) {
|
||||
p.barTemplate.Drop(count)
|
||||
|
||||
if p.barGlobal != nil {
|
||||
p.barGlobal.Drop(count)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures that a progress bar's total count is up-to-date if during an enumeration there were uncompleted requests and
|
||||
// wait for all the progress bars to finish.
|
||||
// If a global progress bar is present it will be updated as well.
|
||||
func (p *Progress) Wait() {
|
||||
p.barTemplate.finish()
|
||||
|
||||
if p.barGlobal != nil {
|
||||
p.barGlobal.finish()
|
||||
}
|
||||
|
||||
p.progress.Wait()
|
||||
}
|
||||
|
||||
// Creates and returns a progress bar.
|
||||
func (p *Progress) setupProgressbar(name string, total int64) *mpb.Bar {
|
||||
return p.progress.AddBar(
|
||||
total,
|
||||
mpb.BarNoPop(),
|
||||
mpb.BarRemoveOnComplete(),
|
||||
mpb.PrependDecorators(
|
||||
decor.Name(barname),
|
||||
decor.CountersNoUnit(aurora.Blue(" %d/%d").String()),
|
||||
decor.Name(name, decor.WCSyncSpaceR),
|
||||
decor.CountersNoUnit(aurora.Blue(" %d/%d").String(), decor.WCSyncSpace),
|
||||
decor.NewPercentage(aurora.Bold("%d").String(), decor.WCSyncSpace),
|
||||
),
|
||||
mpb.AppendDecorators(
|
||||
decor.AverageSpeed(0, aurora.Yellow("%.2f req/s ").String()),
|
||||
decor.OnComplete(
|
||||
decor.AverageETA(decor.ET_STYLE_GO), aurora.Bold("done!").String(),
|
||||
),
|
||||
decor.AverageSpeed(0, aurora.Yellow("%.2f r/s ").String(), decor.WCSyncSpace),
|
||||
decor.AverageETA(decor.ET_STYLE_GO, decor.WCSyncSpace),
|
||||
),
|
||||
)
|
||||
|
||||
p.bar = bar
|
||||
p.total = total
|
||||
p.initialTotal = total
|
||||
return bar
|
||||
}
|
||||
|
||||
func (p *Progress) Update() {
|
||||
p.bar.Increment()
|
||||
}
|
||||
|
||||
func (p *Progress) Abort(remaining int64) {
|
||||
atomic.AddInt64(&p.total, -remaining)
|
||||
p.bar.SetTotal(atomic.LoadInt64(&p.total), false)
|
||||
}
|
||||
|
||||
func (p *Progress) Wait() {
|
||||
if p.initialTotal != p.total {
|
||||
p.bar.SetTotal(p.total, true)
|
||||
}
|
||||
p.progress.Wait()
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// Starts capturing stdout and stderr instead of producing visual output that may interfere with the progress bars.
|
||||
func (p *Progress) StartStdCapture() {
|
||||
p.stdCaptureMutex.Lock()
|
||||
p.captureData = startStdCapture()
|
||||
}
|
||||
|
||||
// Stops capturing stdout and stderr and store both output to be shown later.
|
||||
func (p *Progress) StopStdCapture() {
|
||||
stopStdCapture(p.captureData)
|
||||
p.stdout.Write(p.captureData.DataStdOut.Bytes())
|
||||
|
@ -100,12 +157,14 @@ func (p *Progress) StopStdCapture() {
|
|||
p.stdCaptureMutex.Unlock()
|
||||
}
|
||||
|
||||
// Writes the captured stdout data to stdout, if any.
|
||||
func (p *Progress) ShowStdOut() {
|
||||
if p.stdout.Len() > 0 {
|
||||
fmt.Fprint(os.Stdout, p.stdout.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the captured stderr data to stderr, if any.
|
||||
func (p *Progress) ShowStdErr() {
|
||||
if p.stderr.Len() > 0 {
|
||||
fmt.Fprint(os.Stderr, p.stderr.String())
|
||||
|
|
|
@ -137,7 +137,7 @@ func (r *Runner) RunEnumeration() {
|
|||
var results bool
|
||||
template := t.(*templates.Template)
|
||||
|
||||
p.SetupProgressBar(template.ID, r.inputCount * template.GetHTTPRequestsCount())
|
||||
p.SetupTemplateProgressbar(-1, -1, template.ID, r.inputCount * template.GetHTTPRequestsCount())
|
||||
|
||||
// process http requests
|
||||
for _, request := range template.RequestsHTTP {
|
||||
|
@ -197,11 +197,9 @@ func (r *Runner) RunEnumeration() {
|
|||
gologger.Fatalf("Error, no templates found in directory: '%s'\n", r.options.Templates)
|
||||
}
|
||||
|
||||
// track progress
|
||||
p := progress.NewProgress(nil)
|
||||
|
||||
// precompute request count
|
||||
var totalRequests int64 = 0
|
||||
var totalTemplates int = len(matches)
|
||||
for _, match := range matches {
|
||||
t, err := r.parse(match)
|
||||
switch t.(type) {
|
||||
|
@ -209,20 +207,23 @@ func (r *Runner) RunEnumeration() {
|
|||
template := t.(*templates.Template)
|
||||
totalRequests += template.GetHTTPRequestsCount()
|
||||
default:
|
||||
p.StartStdCapture()
|
||||
gologger.Errorf("Could not parse file '%s': %s\n", r.options.Templates, err)
|
||||
p.StopStdCapture()
|
||||
}
|
||||
}
|
||||
|
||||
p.SetupProgressBar("Multiple templates", r.inputCount * totalRequests)
|
||||
// track progress
|
||||
p := progress.NewProgress(nil)
|
||||
p.SetupGlobalProgressbar(r.inputCount, len(matches), r.inputCount * totalRequests)
|
||||
|
||||
var results bool
|
||||
for _, match := range matches {
|
||||
for i, match := range matches {
|
||||
t, err := r.parse(match)
|
||||
switch t.(type) {
|
||||
case *templates.Template:
|
||||
template := t.(*templates.Template)
|
||||
|
||||
p.SetupTemplateProgressbar(i, totalTemplates, template.ID, r.inputCount * template.GetHTTPRequestsCount())
|
||||
|
||||
for _, request := range template.RequestsDNS {
|
||||
dnsResults := r.processTemplateWithList(p, template, request)
|
||||
if dnsResults {
|
||||
|
@ -256,9 +257,7 @@ func (r *Runner) RunEnumeration() {
|
|||
r.output.Close()
|
||||
os.Remove(outputFile)
|
||||
}
|
||||
//p.StartStdCapture()
|
||||
gologger.Infof("No results found for the template. Happy hacking!")
|
||||
//p.StopStdCapture()
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
@ -106,7 +106,7 @@ func (e *HTTPExecutor) ExecuteHTTP(p *progress.Progress, URL string) error {
|
|||
mainLoop:
|
||||
for compiledRequest := range compiledRequest {
|
||||
if compiledRequest.Error != nil {
|
||||
p.Abort(remaining)
|
||||
p.Drop(remaining)
|
||||
return errors.Wrap(err, "error in compiled http request")
|
||||
}
|
||||
e.setCustomHeaders(compiledRequest)
|
||||
|
@ -115,7 +115,7 @@ mainLoop:
|
|||
if e.debug {
|
||||
dumpedRequest, err := httputil.DumpRequest(req.Request, true)
|
||||
if err != nil {
|
||||
p.Abort(remaining)
|
||||
p.Drop(remaining)
|
||||
return errors.Wrap(err, "could not dump http request")
|
||||
}
|
||||
p.StartStdCapture()
|
||||
|
@ -129,7 +129,7 @@ mainLoop:
|
|||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
p.Abort(1)
|
||||
p.Drop(1)
|
||||
p.StartStdCapture()
|
||||
gologger.Warningf("Could not do request: %s\n", err)
|
||||
p.StopStdCapture()
|
||||
|
@ -139,7 +139,7 @@ mainLoop:
|
|||
if e.debug {
|
||||
dumpedResponse, err := httputil.DumpResponse(resp, true)
|
||||
if err != nil {
|
||||
p.Abort(remaining)
|
||||
p.Drop(remaining)
|
||||
return errors.Wrap(err, "could not dump http response")
|
||||
}
|
||||
p.StartStdCapture()
|
||||
|
@ -152,7 +152,7 @@ mainLoop:
|
|||
if err != nil {
|
||||
io.Copy(ioutil.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
p.Abort(remaining)
|
||||
p.Drop(remaining)
|
||||
return errors.Wrap(err, "could not read http body")
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
@ -161,7 +161,7 @@ mainLoop:
|
|||
// so in case we have to manually do it
|
||||
data, err = requests.HandleDecompression(compiledRequest.Request, data)
|
||||
if err != nil {
|
||||
p.Abort(remaining)
|
||||
p.Drop(remaining)
|
||||
return errors.Wrap(err, "could not decompress http body")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue