-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
105 lines (99 loc) · 2.15 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"flag"
"fmt"
"os"
"strings"
"sync"
)
// Fetcher definition
type fchr func(string) ([]string, error)
func main() {
var o = flag.String("o", "", "Set the output file if you want to save subdomains.")
flag.Parse()
if len(flag.Args()) != 1 {
fmt.Println("syntax: subsearch [-o output.txt] [domain].")
os.Exit(1)
}
var url string = flag.Arg(0)
var subdomains = make([]string, 0)
var wg sync.WaitGroup
var e = make([]string, 0)
var s = make(chan []string) // subdomains channel
var fetchers = []fchr{
crtshFetcher,
certspotterFetcher,
bufferoverrunFetcher,
threadcrowdFetcher,
urlscanIOFetcher,
}
var q = make(chan int, len(fetchers)) // when full, quit.
for _, f := range fetchers {
wg.Add(1)
go func(url string, f fchr, wg *sync.WaitGroup) {
defer wg.Done()
subs, err := f(url)
if err != nil {
e = append(e, err.Error())
}
s <- subs
}(url, f, &wg)
}
wg.Add(1)
go func(url string, q chan int, s chan []string, wg *sync.WaitGroup) {
var qcount = 0
for {
select {
case subs := <-s:
for i := 0; i < len(subs); i++ {
sub := subs[i]
sub = strings.ReplaceAll(strings.ReplaceAll(sub, "*.", ""), " ", "")
if !strings.Contains(sub, url) {
continue
}
if strings.Contains(sub, "\n") {
subs = append(subs, strings.Split(sub, "\n")...)
continue
}
exists := false
for _, sd := range subdomains {
if sub == sd {
exists = true
}
}
if !exists && sub != "" {
subdomains = append(subdomains, sub)
fmt.Println(sub)
}
}
q <- 1
case c := <-q:
qcount += c
if qcount == len(fetchers) {
wg.Done()
return
}
}
}
}(url, q, s, &wg)
wg.Wait()
close(q)
close(s)
if !(*o == "") {
f, err := os.OpenFile(*o, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
e = append(e, err.Error())
}
if _, err = f.WriteString(strings.Join(subdomains, "\n") + "\n"); err != nil {
e = append(e, err.Error())
}
f.Close()
}
/* print errors, etc... */
if len(e) > 0 {
fmt.Println("The following errors have been generated:")
for _, cErr := range e {
fmt.Println(cErr)
}
}
}