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 }