package output import ( "html" "html/template" "os" "time" "github.com/ffuf/ffuf/pkg/ffuf" ) type htmlResult struct { Input map[string]string Position int StatusCode int64 ContentLength int64 ContentWords int64 ContentLines int64 ContentType string RedirectLocation string ScraperData string Duration time.Duration ResultFile string Url string Host string } type htmlFileOutput struct { CommandLine string Time string Keys []string Results []htmlResult } const ( htmlTemplate = ` FFUF Report -


FFUF Report

{{ .CommandLine }}
{{ .Time }}
|result_raw|StatusCode|Input|Position|ContentLength|ContentWords|ContentLines|ContentType|Duration|Resultfile|ScraperData|
{{ range .Keys }} {{ end }} {{range $result := .Results}}
|result_raw|{{ $result.StatusCode }}{{ range $keyword, $value := $result.Input }}|{{ $value | printf "%s" }}{{ end }}|{{ $result.Url }}|{{ $result.RedirectLocation }}|{{ $result.Position }}|{{ $result.ContentLength }}|{{ $result.ContentWords }}|{{ $result.ContentLines }}|{{ $result.ContentType }}|
{{ range $keyword, $value := $result.Input }} {{ end }} {{ end }}
Status{{ . }}URL Redirect location Position Length Words Lines Type Duration Resultfile Scraper data
{{ $result.StatusCode }}{{ $value | printf "%s" }}{{ $result.Url }} {{ $result.RedirectLocation }} {{ $result.Position }} {{ $result.ContentLength }} {{ $result.ContentWords }} {{ $result.ContentLines }} {{ $result.ContentType }} {{ $result.Duration }} {{ $result.ResultFile }} {{ $result.ScraperData }}


` ) // colorizeResults returns a new slice with HTMLColor attribute func colorizeResults(results []ffuf.Result) []ffuf.Result { newResults := make([]ffuf.Result, 0) for _, r := range results { result := r result.HTMLColor = "black" s := result.StatusCode if s >= 200 && s <= 299 { result.HTMLColor = "#adea9e" } if s >= 300 && s <= 399 { result.HTMLColor = "#bbbbe6" } if s >= 400 && s <= 499 { result.HTMLColor = "#d2cb7e" } if s >= 500 && s <= 599 { result.HTMLColor = "#de8dc1" } newResults = append(newResults, result) } return newResults } func writeHTML(filename string, config *ffuf.Config, results []ffuf.Result) error { results = colorizeResults(results) ti := time.Now() keywords := make([]string, 0) for _, inputprovider := range config.InputProviders { keywords = append(keywords, inputprovider.Keyword) } htmlResults := make([]htmlResult, 0) for _, r := range results { strinput := make(map[string]string) for k, v := range r.Input { strinput[k] = string(v) } strscraper := "" for k, v := range r.ScraperData { if len(v) > 0 { strscraper = strscraper + "

" + html.EscapeString(k) + ":
" firstval := true for _, val := range v { if !firstval { strscraper += "
" } strscraper += html.EscapeString(val) firstval = false } strscraper += "

" } } hres := htmlResult{ Input: strinput, Position: r.Position, StatusCode: r.StatusCode, ContentLength: r.ContentLength, ContentWords: r.ContentWords, ContentLines: r.ContentLines, ContentType: r.ContentType, RedirectLocation: r.RedirectLocation, ScraperData: strscraper, Duration: r.Duration, ResultFile: r.ResultFile, Url: r.Url, Host: r.Host, } htmlResults = append(htmlResults, hres) } outHTML := htmlFileOutput{ CommandLine: config.CommandLine, Time: ti.Format(time.RFC3339), Results: htmlResults, Keys: keywords, } f, err := os.Create(filename) if err != nil { return err } defer f.Close() templateName := "output.html" t := template.New(templateName).Delims("{{", "}}") _, err = t.Parse(htmlTemplate) if err != nil { return err } err = t.Execute(f, outHTML) return err }