-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.go
More file actions
136 lines (115 loc) · 3.78 KB
/
main.go
File metadata and controls
136 lines (115 loc) · 3.78 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"flag"
"fmt"
"os"
"sync"
"time"
"github.com/topscoder/subgomain/domainchecker"
"github.com/topscoder/subgomain/fingerprints"
"github.com/topscoder/subgomain/logger"
"github.com/topscoder/subgomain/utils"
)
func main() {
// Define command-line flags
domain := flag.String("domain", "", "A single domain to be checked")
domainsFile := flag.String("domains", "", "The file containing the domains to be checked")
fingerprintsArg := flag.String("fingerprints", "", "URL or local file path to the fingerprints.json file to be used")
resolversArg := flag.String("resolvers", "", "URL to the resolvers.txt file to be used")
threads := flag.Int("threads", 5, "The amount of threads to be used")
timeout := flag.Int("timeout", 2, "Timeout in seconds for HTTP requests")
silent := flag.Bool("silent", false, "Only print vulnerable domains")
debug := flag.Bool("debug", false, "enable debug logging")
flag.Parse()
logger.SetVerbose(debug)
// Check if the domains file is provided
if *domain == "" && *domainsFile == "" {
fmt.Println("Usage: subgomain -domain <domain> | -domains <filename> [-fingerprints <url_or_local_path>] [-threads <int>] [-timeout <seconds>] [-silent]")
os.Exit(1)
}
// Load fingerprints
var fps []fingerprints.Fingerprint
var err error
fingerprintFile := ""
if *fingerprintsArg != "" {
fingerprintFile = *fingerprintsArg
} else {
fingerprintFile = "https://raw.githubusercontent.com/topscoder/subgomain/main/tests/testfingerprints.json"
}
fps, err = loadFingerprints(fingerprintFile)
if err != nil {
fmt.Printf("Error loading fingerprints: %v\n", err)
os.Exit(1)
}
// Load resolvers
resolversFile := ""
if *resolversArg != "" {
resolversFile = *resolversArg
} else {
resolversFile = "https://raw.githubusercontent.com/trickest/resolvers/main/resolvers.txt"
}
logger.LogDebug("Downloading resolvers list from ", resolversFile)
resolvers, err := utils.LoadResolvers(resolversFile)
if err != nil {
fmt.Printf("Error loading resolvers: %v\n", err)
os.Exit(1)
}
var domains []string
// If a single domain is provided, use it
if *domain != "" {
domains = []string{*domain}
} else {
// Read domains from file
domains, err = utils.ReadDomainsFromFile(*domainsFile)
if err != nil {
fmt.Printf("Error reading domains: %v\n", err)
os.Exit(1)
}
}
// Create a channel to manage domain processing
domainChan := make(chan string, len(domains))
for _, domain := range domains {
domainChan <- domain
}
close(domainChan)
httpTimeout := time.Duration(*timeout) * time.Second
// Create a wait group to manage goroutines
var wg sync.WaitGroup
// Create worker goroutines
for i := 0; i < *threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for domain := range domainChan {
vulnerable, fingerprint, err := domainchecker.CheckDomain(domain, fps, resolvers, httpTimeout)
if err != nil {
if !*silent {
fmt.Printf("[ERROR] %s: %v\n", domain, err)
}
continue
}
if vulnerable != "" && (fingerprint.Vulnerable || fingerprint.Status == "Vulnerable") {
if fingerprint.PaymentRequired {
fmt.Printf("[%s] [%s] [paid] %s -> %s \n", fingerprint.Status, fingerprint.Service, domain, vulnerable)
} else {
fmt.Printf("[%s] [%s] %s -> %s \n", fingerprint.Status, fingerprint.Service, domain, vulnerable)
}
} else {
if !*silent {
fmt.Printf("[NOT VULNERABLE] %s\n", domain)
}
}
}
}()
}
// Wait for all goroutines to finish
wg.Wait()
}
func loadFingerprints(fingerprintsArg string) ([]fingerprints.Fingerprint, error) {
if utils.IsValidURL(fingerprintsArg) {
// Load fingerprints from URL
return fingerprints.LoadFingerprints(fingerprintsArg)
}
// Load fingerprints from local file
return fingerprints.LoadFingerprintsFromFile(fingerprintsArg)
}