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

run.go (3100B)

      1 package osint
      2 
      3 import (
      4 	"fmt"
      5 	"net"
      6 	"net/url"
      7 	"os"
      8 	"strings"
      9 
     10 	"evil.djnn.sh/djnn/yellow/core"
     11 	"evil.djnn.sh/djnn/yellow/helpers"
     12 )
     13 
     14 type OsintOpts struct {
     15 	Domain     string
     16 	ScanPath   string
     17 	Proxy      string
     18 	DryRun     bool
     19 	RateLimit  int32
     20 	EmailsFile string
     21 }
     22 
     23 func (opts *OsintOpts) context() *core.Context {
     24 	return &core.Context{
     25 		Domain:     opts.Domain,
     26 		ScanPath:   opts.ScanPath,
     27 		Proxy:      opts.Proxy,
     28 		DryRun:     opts.DryRun,
     29 		RateLimit:  opts.RateLimit,
     30 		EmailsFile: opts.EmailsFile,
     31 	}
     32 }
     33 
     34 func (opts OsintOpts) RunCleanup() {
     35 	fmt.Println("[+] cleaning up...")
     36 
     37 	/* remove superfluous files */
     38 	asfFilepath := fmt.Sprintf("%s/assetfinder.txt", opts.ScanPath)
     39 	sbfOutfile := fmt.Sprintf("%s/subfinder.txt", opts.ScanPath)
     40 
     41 	for _, f := range []string{asfFilepath, sbfOutfile} {
     42 		if err := os.Remove(f); err != nil && !os.IsNotExist(err) {
     43 			fmt.Printf("[!] cleanup: could not remove %s: %v\n", f, err)
     44 		}
     45 	}
     46 }
     47 
     48 func (opts *OsintOpts) Run() {
     49 	fmt.Printf("\n[OSINT] domain: %s\n\n", opts.Domain)
     50 
     51 	ctx := opts.context()
     52 
     53 	core.RunModules(ctx, []core.Module{
     54 		&Dorks{},
     55 		&Subfinder{},
     56 		&Assetfinder{},
     57 		&Dnsx{},
     58 		&Gau{},
     59 		&Leaker{},
     60 	})
     61 
     62 	ctx.Domains = opts.aggregateDomains()
     63 
     64 	core.RunModules(ctx, []core.Module{&Alterx{}, &Shodan{}, &ASN{}})
     65 
     66 	uniqueOutfile := fmt.Sprintf("%s/domains.txt", opts.ScanPath)
     67 	if err := core.WriteLines(uniqueOutfile, ctx.Domains); err != nil {
     68 		fmt.Printf("[!] osint: could not write %s: %v\n", uniqueOutfile, err)
     69 		return
     70 	}
     71 
     72 	fmt.Printf("[OSINT %s] Registered %v IP addresses and assets.\n", opts.Domain, len(ctx.Domains))
     73 	fmt.Printf("[OSINT %s] Location of unique domain names: %s\n", opts.Domain, uniqueOutfile)
     74 	fmt.Printf("[OSINT %s] done.\n", opts.Domain)
     75 
     76 	opts.RunCleanup()
     77 }
     78 
     79 func (opts *OsintOpts) aggregateDomains() []string {
     80 	var domains []string
     81 	seen := map[string]struct{}{}
     82 
     83 	add := func(candidate string) {
     84 		candidate = strings.Trim(candidate, "\t \",")
     85 		if candidate == "" {
     86 			return
     87 		}
     88 		if _, ok := seen[candidate]; ok {
     89 			return
     90 		}
     91 		ip := net.ParseIP(candidate)
     92 		if (ip != nil && ip.To4() != nil) || (ip == nil && !helper.StringHasUnwantedCharactersForDomainName(candidate)) {
     93 			seen[candidate] = struct{}{}
     94 			domains = append(domains, candidate)
     95 		}
     96 	}
     97 
     98 	asfFilepath := fmt.Sprintf("%s/assetfinder.txt", opts.ScanPath)
     99 	dnsxFilepath := fmt.Sprintf("%s/dnsx.json", opts.ScanPath)
    100 	sbfOutfile := fmt.Sprintf("%s/subfinder.txt", opts.ScanPath)
    101 
    102 	for _, file := range []string{asfFilepath, dnsxFilepath, sbfOutfile} {
    103 		data, err := os.ReadFile(file)
    104 		if err != nil {
    105 			fmt.Printf("[!] osint: could not read %s, skipping: %v\n", file, err)
    106 			continue
    107 		}
    108 		for _, line := range strings.Split(strings.ReplaceAll(string(data), "\r\n", "\n"), "\n") {
    109 			add(line)
    110 		}
    111 	}
    112 
    113 	urlsFile := fmt.Sprintf("%s/urls.txt", opts.ScanPath)
    114 	if data, err := os.ReadFile(urlsFile); err == nil {
    115 		for _, line := range strings.Split(strings.ReplaceAll(string(data), "\r\n", "\n"), "\n") {
    116 			if u, err := url.Parse(strings.TrimSpace(line)); err == nil {
    117 				add(u.Hostname())
    118 			}
    119 		}
    120 	}
    121 
    122 	return domains
    123 }