yellow.git


yellow

~ opinionated web scanning pipeline for pentesters in a hurry
git clone https://github.com/djnnvx/yellow.git
log | files | refs | archive | README | LICENSE

catchall.go (1555B)

      1 package scan
      2 
      3 import (
      4 	"fmt"
      5 	"net/http"
      6 	"net/url"
      7 	"strconv"
      8 	"time"
      9 
     10 	helper "evil.djnn.sh/djnn/yellow/helpers"
     11 )
     12 
     13 // answersEveryPath probes a path that cannot exist. A host that still answers
     14 // makes every path-existence template match, so its findings are worthless.
     15 func answersEveryPath(root string) bool {
     16 	probe := root + "/yellow-probe-" + strconv.FormatInt(time.Now().UnixNano(), 36)
     17 
     18 	req, err := http.NewRequest("GET", probe, nil)
     19 	if err != nil {
     20 		return false
     21 	}
     22 	req.Header.Set("User-Agent", helper.GetUserAgent())
     23 
     24 	resp, err := helper.GetHttpClient(true).Do(req)
     25 	if err != nil || resp == nil {
     26 		return false
     27 	}
     28 	defer resp.Body.Close()
     29 
     30 	return resp.StatusCode < http.StatusBadRequest
     31 }
     32 
     33 // collapseCatchAll replaces each catch-all host's URLs with just its root, so
     34 // one bogus finding is reported instead of one per crawled URL.
     35 func collapseCatchAll(urls []string, catchAll func(string) bool) []string {
     36 	probed := map[string]bool{}
     37 	kept := map[string]bool{}
     38 	out := []string{}
     39 
     40 	for _, raw := range urls {
     41 		u, err := url.Parse(raw)
     42 		if err != nil || u.Host == "" {
     43 			out = append(out, raw)
     44 			continue
     45 		}
     46 
     47 		root := u.Scheme + "://" + u.Host
     48 		bad, seen := probed[root]
     49 		if !seen {
     50 			bad = catchAll(root)
     51 			probed[root] = bad
     52 			if bad {
     53 				fmt.Printf("[!] nuclei: %s answers every path, collapsing to 1 target (findings here may be false positives)\n", root)
     54 			}
     55 		}
     56 
     57 		if !bad {
     58 			out = append(out, raw)
     59 			continue
     60 		}
     61 		if !kept[root] {
     62 			kept[root] = true
     63 			out = append(out, root+"/")
     64 		}
     65 	}
     66 
     67 	return out
     68 }