// Package stats implements a statistics recording module for // nuclei fuzzing. package stats import ( "fmt" "log" "net/url" "github.com/pkg/errors" ) // Tracker is a stats tracker module for fuzzing server type Tracker struct { database *simpleStats } // NewTracker creates a new tracker instance func NewTracker() (*Tracker, error) { db, err := NewSimpleStats() if err != nil { return nil, errors.Wrap(err, "could not create new tracker") } tracker := &Tracker{ database: db, } return tracker, nil } func (t *Tracker) GetStats() SimpleStatsResponse { return t.database.GetStatistics() } // Close closes the tracker func (t *Tracker) Close() { t.database.Close() } // FuzzingEvent is a fuzzing event type FuzzingEvent struct { URL string ComponentType string ComponentName string TemplateID string PayloadSent string StatusCode int Matched bool RawRequest string RawResponse string Severity string siteName string } func (t *Tracker) RecordResultEvent(event FuzzingEvent) { event.siteName = getCorrectSiteName(event.URL) if err := t.database.InsertMatchedRecord(event); err != nil { log.Printf("could not insert matched record: %s", err) } } type ComponentEvent struct { URL string ComponentType string ComponentName string siteName string } func (t *Tracker) RecordComponentEvent(event ComponentEvent) { event.siteName = getCorrectSiteName(event.URL) if err := t.database.InsertComponent(event); err != nil { log.Printf("could not insert component record: %s", err) } } type ErrorEvent struct { TemplateID string URL string Error string } func (t *Tracker) RecordErrorEvent(event ErrorEvent) { if err := t.database.InsertError(event); err != nil { log.Printf("could not insert error record: %s", err) } } func getCorrectSiteName(originalURL string) string { parsed, err := url.Parse(originalURL) if err != nil { return "" } // Site is the host:port combo siteName := parsed.Host if parsed.Port() == "" { switch parsed.Scheme { case "https": siteName = fmt.Sprintf("%s:443", siteName) case "http": siteName = fmt.Sprintf("%s:80", siteName) } } return siteName }