-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathspyse.go
More file actions
108 lines (88 loc) · 2.9 KB
/
Copy pathspyse.go
File metadata and controls
108 lines (88 loc) · 2.9 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
// Package spyse logic
package spyse
import (
"context"
"github.com/projectdiscovery/subfinder/v2/pkg/subscraping"
spyse "github.com/spyse-com/go-spyse/pkg"
)
const searchMethodResultsLimit = 10000
// Source is the passive scraping agent
type Source struct{}
// Run function returns all subdomains found with the service
func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Session) <-chan subscraping.Result {
results := make(chan subscraping.Result)
go func() {
defer close(results)
if session.Keys.Spyse == "" {
return
}
client, err := spyse.NewClient(session.Keys.Spyse, nil)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
return
}
domainSvc := spyse.NewDomainService(client)
var searchDomain = "." + domain
var subdomainsSearchParams spyse.QueryBuilder
subdomainsSearchParams.AppendParam(spyse.QueryParam{
Name: domainSvc.Params().Name.Name,
Operator: domainSvc.Params().Name.Operator.EndsWith,
Value: searchDomain,
})
totalResults, err := domainSvc.SearchCount(ctx, subdomainsSearchParams.Query)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
return
}
if totalResults == 0 {
return
}
// The default "Search" method returns only first 10 000 subdomains
// To obtain more than 10 000 subdomains the "Scroll" method should be using
// Note: The "Scroll" method is only available for "PRO" customers, so we need to check
// quota.IsScrollSearchEnabled param
if totalResults > searchMethodResultsLimit && client.Account().IsScrollSearchEnabled {
var scrollID string
var scrollResults *spyse.DomainScrollResponse
for {
scrollResults, err = domainSvc.ScrollSearch(ctx, subdomainsSearchParams.Query, scrollID)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
return
}
if len(scrollResults.Items) > 0 {
scrollID = scrollResults.SearchID
for i := range scrollResults.Items {
results <- subscraping.Result{
Source: s.Name(),
Type: subscraping.Subdomain,
Value: scrollResults.Items[i].Name,
}
}
}
}
} else {
var limit = 100
var searchResults []spyse.Domain
for offset := 0; int64(offset) < totalResults && int64(offset) < searchMethodResultsLimit; offset += limit {
searchResults, err = domainSvc.Search(ctx, subdomainsSearchParams.Query, limit, offset)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
return
}
for i := range searchResults {
results <- subscraping.Result{
Source: s.Name(),
Type: subscraping.Subdomain,
Value: searchResults[i].Name,
}
}
}
}
}()
return results
}
// Name returns the name of the source
func (s *Source) Name() string {
return "spyse"
}