add request tracking to -stats flag

Adds request counting to all sources to help users monitor API usage
and debug quota consumption issues like #1562.

Changes:
- Add Requests field to Statistics struct
- Track HTTP requests in all 53 sources
- Display request count in stats output

Closes #1698
This commit is contained in:
Doğan Can Bakır
2026-01-05 14:14:20 +03:00
parent c1977c0315
commit e96320ec38
54 changed files with 221 additions and 2 deletions
+2 -2
View File
@@ -24,12 +24,12 @@ func printStatistics(stats map[string]subscraping.Statistics) {
if sourceStats.Skipped {
skipped = append(skipped, fmt.Sprintf(" %s", source))
} else {
lines = append(lines, fmt.Sprintf(" %-20s %-10s %10d %10d", source, sourceStats.TimeTaken.Round(time.Millisecond).String(), sourceStats.Results, sourceStats.Errors))
lines = append(lines, fmt.Sprintf(" %-20s %-10s %10d %10d %10d", source, sourceStats.TimeTaken.Round(time.Millisecond).String(), sourceStats.Results, sourceStats.Requests, sourceStats.Errors))
}
}
if len(lines) > 0 {
gologger.Print().Msgf("\n Source Duration Results Errors\n%s\n", strings.Repeat("─", 56))
gologger.Print().Msgf("\n Source Duration Results Requests Errors\n%s\n", strings.Repeat("─", 68))
gologger.Print().Msg(strings.Join(lines, "\n"))
gologger.Print().Msgf("\n")
}
@@ -23,6 +23,7 @@ type Source struct {
timeTaken time.Duration
results int
errors int
requests int
apiKeys []string
skipped bool
}
@@ -32,6 +33,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -45,6 +47,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("https://otx.alienvault.com/api/v1/indicators/domain/%s/passive_dns", domain), "",
map[string]string{"Authorization": "Bearer " + randomApiKey})
if err != nil && resp == nil {
@@ -110,6 +113,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -17,6 +17,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -24,6 +25,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -31,6 +33,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://jonlu.ca/anubis/subdomains/%s", domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -94,6 +97,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
}
}
@@ -21,6 +21,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -28,6 +29,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -43,6 +45,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
getUrl := fmt.Sprintf("https://osint.bevigil.com/api/%s/subdomains/", domain)
s.requests++
resp, err := session.Get(ctx, getUrl, "", map[string]string{
"X-Access-Token": randomApiKey, "User-Agent": "subfinder",
})
@@ -106,6 +109,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -27,6 +27,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -35,6 +36,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -55,6 +57,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
func (s *Source) getData(ctx context.Context, sourceURL string, apiKey string, session *subscraping.Session, results chan subscraping.Result) {
s.requests++
resp, err := session.Get(ctx, sourceURL, "", map[string]string{"x-api-key": apiKey})
if err != nil && resp == nil {
@@ -131,6 +134,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -35,6 +35,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -43,6 +44,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -55,6 +57,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://api.builtwith.com/v21/api.json?KEY=%s&HIDETEXT=yes&HIDEDL=yes&NOLIVE=yes&NOMETA=yes&NOPII=yes&NOATTR=yes&LOOKUP=%s", randomApiKey, domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -112,6 +115,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -18,6 +18,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -36,6 +37,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -50,6 +52,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
searchURL := fmt.Sprintf("https://api.c99.nl/subdomainfinder?key=%s&domain=%s&json", randomApiKey, domain)
s.requests++
resp, err := session.SimpleGet(ctx, searchURL)
if err != nil {
session.DiscardHTTPResponse(resp)
@@ -119,6 +122,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -75,6 +75,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -83,6 +84,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -136,6 +138,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
headers[orgIDHeader] = randomApiKey.orgID
}
s.requests++
resp, err := session.HTTPRequest(
ctx,
http.MethodPost,
@@ -220,6 +223,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -22,6 +22,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -30,6 +31,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -46,6 +48,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
headers := map[string]string{"Authorization": "Bearer " + randomApiKey}
cookies := ""
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("https://api.certspotter.com/v1/issuances?domain=%s&include_subdomains=true&expand=dns_names", domain), cookies, headers)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -88,6 +91,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
reqURL := fmt.Sprintf("https://api.certspotter.com/v1/issuances?domain=%s&include_subdomains=true&expand=dns_names&after=%s", domain, id)
s.requests++
resp, err := session.Get(ctx, reqURL, cookies, headers)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -152,6 +156,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -16,6 +16,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -24,6 +25,7 @@ func (s *Source) Run(ctx context.Context, domain string, _ *subscraping.Session)
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -38,6 +40,7 @@ func (s *Source) Run(ctx context.Context, domain string, _ *subscraping.Session)
}
chaosClient := chaos.New(randomApiKey)
s.requests++
for result := range chaosClient.GetSubdomains(&chaos.SubdomainsRequest{
Domain: domain,
}) {
@@ -86,6 +89,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -17,6 +17,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -25,6 +26,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -38,6 +40,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://apidatav2.chinaz.com/single/alexa?key=%s&domain=%s", randomApiKey, domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -103,6 +106,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -32,6 +32,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -39,6 +40,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -46,6 +48,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, indexURL)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -117,6 +120,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
}
}
@@ -128,6 +132,7 @@ func (s *Source) getSubdomains(ctx context.Context, searchURL, domain string, se
return false
default:
var headers = map[string]string{"Host": "index.commoncrawl.org"}
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("%s?url=*.%s", searchURL, domain), "", headers)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
+4
View File
@@ -29,6 +29,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -36,6 +37,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -145,6 +147,7 @@ func (s *Source) getSubdomainsFromSQL(ctx context.Context, domain string, sessio
}
func (s *Source) getSubdomainsFromHTTP(ctx context.Context, domain string, session *subscraping.Session, results chan subscraping.Result) bool {
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://crt.sh/?q=%%25.%s&output=json", domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -212,6 +215,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
}
}
@@ -16,6 +16,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -34,6 +35,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -48,6 +50,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
searchURL := fmt.Sprintf("https://api.digitalyama.com/subdomain_finder?domain=%s", domain)
s.requests++
resp, err := session.Get(ctx, searchURL, "", map[string]string{"x-api-key": randomApiKey})
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -131,6 +134,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -18,6 +18,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -25,6 +26,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -32,6 +34,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://certificatedetails.com/%s", domain))
// the 404 page still contains around 100 subdomains - https://github.com/projectdiscovery/subfinder/issues/774
if err != nil && ptr.Safe(resp).StatusCode != http.StatusNotFound {
@@ -99,6 +102,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
}
}
+5
View File
@@ -43,6 +43,7 @@ type Source struct {
timeTaken time.Duration
errors int
results uint64
requests int
skipped bool
}
@@ -51,6 +52,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -70,6 +72,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
"Accept": "application/x-ndjson",
}
s.requests++
offsetMax, err := getMaxOffset(ctx, session, headers)
if err != nil {
results <- subscraping.Result{Source: sourceName, Type: subscraping.Error, Error: err}
@@ -92,6 +95,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
url := urlTemplate + queryParams.Encode()
s.requests++
resp, err := session.Get(ctx, url, "", headers)
if err != nil {
results <- subscraping.Result{Source: sourceName, Type: subscraping.Error, Error: err}
@@ -195,6 +199,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: int(s.results),
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -25,6 +25,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -33,6 +34,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -46,6 +48,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("https://api.dnsdumpster.com/domain/%s", domain), "", map[string]string{"X-API-Key": randomApiKey})
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -103,6 +106,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -17,6 +17,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -28,6 +29,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -50,6 +52,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
token := randomApiInfo[0]
apiKey := randomApiInfo[1]
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("https://dnsarchive.net/api/?apikey=%s&search=%s", apiKey, domain), "", map[string]string{"X-API-Access": token})
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -112,6 +115,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -18,6 +18,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -36,6 +37,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -50,6 +52,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
searchURL := fmt.Sprintf("https://api.domainsproject.org/api/tld/search?domain=%s", domain)
s.requests++
resp, err := session.HTTPRequest(
ctx,
"GET",
@@ -131,6 +134,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -28,6 +28,7 @@ type Source struct {
timeTaken time.Duration
errors atomic.Int32
results atomic.Int32
requests atomic.Int32
skipped bool
}
@@ -65,6 +66,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors.Store(0)
s.results.Store(0)
s.requests.Store(0)
// Waitgroup for subsources
var wg sync.WaitGroup
@@ -119,6 +121,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: int(s.errors.Load()),
Results: int(s.results.Load()),
Requests: int(s.requests.Load()),
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -139,6 +142,7 @@ func (s *Source) runSubsource(ctx context.Context, domain string, session *subsc
// Request
requestURL := fmt.Sprintf("%s%s?%s%s&summarize=host&summary_context=%s&summary_limit=%d", baseURL, epConfig.endpoint, epConfig.param, url.QueryEscape(domain), epConfig.context, summaryLimit)
s.requests.Add(1)
resp, err := session.Get(ctx, requestURL, "", headers)
if err != nil {
// HTTP 204 is not an error from the Driftnet API
@@ -78,6 +78,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -86,6 +87,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
if len(s.apiKeys) == 0 {
s.skipped = true
@@ -108,6 +110,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
default:
}
s.requests++
resp, err := session.Get(ctx, domainsURL, "", nil)
if err != nil {
s.errors++
@@ -192,6 +195,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -27,6 +27,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -40,6 +41,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -55,6 +57,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
// fofa api doc https://fofa.info/static_pages/api_help
qbase64 := base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "domain=\"%s\"", domain))
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://fofa.info/api/v1/search/all?full=true&fields=host&page=1&size=10000&email=%s&key=%s&qbase64=%s", randomApiKey.username, randomApiKey.secret, qbase64))
if err != nil && resp == nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -131,6 +134,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -23,6 +23,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -30,6 +31,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -43,6 +45,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("https://fullhunt.io/api/v1/domain/%s/subdomains", domain), "", map[string]string{"X-API-KEY": randomApiKey})
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -98,6 +101,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+5
View File
@@ -43,6 +43,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -51,6 +52,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -86,6 +88,7 @@ func (s *Source) enumerate(ctx context.Context, searchURL string, domainRegexp *
}
// Initial request to GitHub search
s.requests++
resp, err := session.Get(ctx, searchURL, "", headers)
isForbidden := resp != nil && resp.StatusCode == http.StatusForbidden
if err != nil && !isForbidden {
@@ -167,6 +170,7 @@ func (s *Source) proccesItems(ctx context.Context, items []item, domainRegexp *r
default:
}
s.requests++
resp, err := session.SimpleGet(ctx, rawURL(responseItem.HTMLURL))
if err != nil {
if resp != nil && resp.StatusCode != http.StatusNotFound {
@@ -277,6 +281,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+5
View File
@@ -22,6 +22,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -37,6 +38,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -66,6 +68,7 @@ func (s *Source) enumerate(ctx context.Context, searchURL string, domainRegexp *
default:
}
s.requests++
resp, err := session.Get(ctx, searchURL, "", headers)
if err != nil && resp == nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -91,6 +94,7 @@ func (s *Source) enumerate(ctx context.Context, searchURL string, domainRegexp *
go func(item item) {
// The original item.Path causes 404 error because the Gitlab API is expecting the url encoded path
fileUrl := fmt.Sprintf("https://gitlab.com/api/v4/projects/%d/repository/files/%s/raw?ref=%s", item.ProjectId, url.QueryEscape(item.Path), item.Ref)
s.requests++
resp, err := session.Get(ctx, fileUrl, "", headers)
if err != nil {
if resp == nil || (resp != nil && resp.StatusCode != http.StatusNotFound) {
@@ -173,6 +177,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -16,6 +16,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -24,6 +25,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -40,6 +42,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
htSearchUrl = fmt.Sprintf("%s&apikey=%s", htSearchUrl, randomApiKey)
s.requests++
resp, err := session.SimpleGet(ctx, htSearchUrl)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -109,5 +112,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -26,6 +26,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -33,6 +34,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -40,6 +42,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://cavalier.hudsonrock.com/api/json/v2/osint-tools/urls-by-domain?domain=%s", domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -99,6 +102,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
}
}
+5
View File
@@ -43,6 +43,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -56,6 +57,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -85,6 +87,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.SimplePost(ctx, searchURL, "application/json", bytes.NewBuffer(body))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -112,6 +115,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
default:
}
s.requests++
resp, err = session.Get(ctx, resultsURL, "", nil)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -179,6 +183,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -16,6 +16,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -24,6 +25,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -40,6 +42,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
headers["api-key"] = randomApiKey
}
// Request
s.requests++
resp, err := session.Get(ctx, "https://leakix.net/api/subdomains/"+domain, "", headers)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -100,6 +103,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -21,6 +21,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -29,6 +30,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -97,6 +99,7 @@ func (s *Source) fetchAllPages(ctx context.Context, domain string, headers map[s
func (s *Source) fetchPage(ctx context.Context, baseURL string, page int, headers map[string]string, session *subscraping.Session) (*response, error) {
url := baseURL + "&page=" + strconv.Itoa(page)
s.requests++
resp, err := session.Get(ctx, url, "", headers)
if err != nil {
return nil, err
@@ -153,6 +156,7 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
+5
View File
@@ -40,6 +40,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -47,6 +48,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -63,6 +65,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
// Pick an API key
randomApiKey := subscraping.PickRandom(s.apiKeys, s.Name())
s.requests++
resp1, err := session.HTTPRequest(ctx, http.MethodGet, countUrl, "", map[string]string{
"accept": "application/json",
"X-API-Key": randomApiKey,
@@ -120,6 +123,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
// Pick an API key
randomApiKey = subscraping.PickRandom(s.apiKeys, s.Name())
s.requests++
resp2, err := session.HTTPRequest(ctx, http.MethodPost, apiUrl, "", map[string]string{
"accept": "application/json",
"X-API-Key": randomApiKey,
@@ -196,6 +200,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
+4
View File
@@ -36,6 +36,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -44,6 +45,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -73,6 +75,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
urlWithQuery := fmt.Sprintf("https://www.onyphe.io/api/v2/search/?q=%s&page=%d&size=%d",
url.QueryEscape("category:resolver domain:"+domain), page, pageSize)
s.requests++
resp, err = session.Get(ctx, urlWithQuery, "", headers)
if err != nil {
@@ -159,6 +162,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -18,6 +18,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -26,6 +27,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -52,6 +54,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
"Accept": "text/event-stream",
}
s.requests++
resp, err := session.Post(ctx, "https://api.profundis.io/api/v2/common/data/subdomains", "",
headers, bytes.NewReader(requestBody))
@@ -123,5 +126,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -32,6 +32,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -40,6 +41,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -71,6 +73,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
apiURL := "https://pugrecon.com/api/v1/domains"
s.requests++
resp, err := session.HTTPRequest(ctx, http.MethodPost, apiURL, "", headers, bodyReader, subscraping.BasicAuth{}) // Use HTTPRequest for full header control
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -150,5 +153,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
+4
View File
@@ -36,6 +36,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -44,6 +45,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -69,6 +71,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
default:
}
var requestBody = fmt.Appendf(nil, `{"query":"domain: %s", "include":["service.http.host"], "latest": true, "size":%d, "start":%d}`, domain, pageSize, start)
s.requests++
resp, err := session.Post(ctx, "https://quake.360.net/api/v3/search/quake_service", "", map[string]string{
"Content-Type": "application/json", "X-QuakeToken": randomApiKey,
}, bytes.NewReader(requestBody))
@@ -153,5 +156,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -19,6 +19,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -26,6 +27,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -41,6 +43,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
default:
}
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://rapiddns.io/subdomain/%s?page=%d&full=1", domain, page))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -115,5 +118,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
@@ -29,6 +29,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -36,6 +37,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -43,6 +45,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://recon.cloud/api/search?domain=%s", domain))
if err != nil && resp == nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -102,5 +105,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
@@ -22,6 +22,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -29,6 +30,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -46,6 +48,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
"X-API-KEY": randomApiKey,
}
apiURL := fmt.Sprintf("https://www.reconeer.com/api/domain/%s", domain)
s.requests++
resp, err := session.Get(ctx, apiURL, "", headers)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -106,5 +109,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -28,6 +28,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -35,6 +36,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
pageSize := 1000
go func() {
defer func(startTime time.Time) {
@@ -56,6 +58,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
baseUrl := randomApiInfo[0] + ":" + randomApiInfo[1]
requestHeaders := map[string]string{"X-BLOBR-KEY": randomApiInfo[2], "User-Agent": "subfinder"}
getUrl := fmt.Sprintf("%s?domain=%s&page=1&page_size=%d", baseUrl, domain, pageSize)
s.requests++
resp, err := session.Get(ctx, getUrl, "", requestHeaders)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("encountered error: %v; note: if you get a 'limit has been reached' error, head over to https://devportal.redhuntlabs.com", err)}
@@ -82,6 +85,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
default:
}
getUrl = fmt.Sprintf("%s?domain=%s&page=%d&page_size=%d", baseUrl, domain, page, pageSize)
s.requests++
resp, err := session.Get(ctx, getUrl, "", requestHeaders)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("encountered error: %v; note: if you get a 'limit has been reached' error, head over to https://devportal.redhuntlabs.com", err)}
@@ -150,5 +154,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -15,6 +15,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -22,6 +23,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -29,6 +31,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://riddler.io/search?q=pld:%s&view_type=data_table", domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -91,5 +94,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
@@ -24,6 +24,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -32,6 +33,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -55,6 +57,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
default:
}
s.requests++
resp, err := session.Get(ctx, fmt.Sprintf("https://api.rsecloud.com/api/v2/subdomains/%s/%s?page=%d", endpoint, domain, page), "", headers)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -122,5 +125,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -31,6 +31,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -39,6 +40,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -66,13 +68,16 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
if scrollId == "" {
var requestBody = fmt.Appendf(nil, `{"query":"apex_domain='%s'"}`, domain)
s.requests++
resp, err = session.Post(ctx, "https://api.securitytrails.com/v1/domains/list?include_ips=false&scroll=true", "",
headers, bytes.NewReader(requestBody))
} else {
s.requests++
resp, err = session.Get(ctx, fmt.Sprintf("https://api.securitytrails.com/v1/scroll/%s", scrollId), "", headers)
}
if err != nil && ptr.Safe(resp).StatusCode == 403 {
s.requests++
resp, err = session.Get(ctx, fmt.Sprintf("https://api.securitytrails.com/v1/domain/%s/subdomains", domain), "", headers)
}
@@ -156,5 +161,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
+4
View File
@@ -17,6 +17,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -33,6 +34,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -55,6 +57,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
}
searchURL := fmt.Sprintf("https://api.shodan.io/dns/domain/%s?key=%s&page=%d", domain, randomApiKey, page)
s.requests++
resp, err := session.SimpleGet(ctx, searchURL)
if err != nil {
session.DiscardHTTPResponse(resp)
@@ -127,6 +130,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -23,6 +23,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -30,6 +31,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -50,6 +52,7 @@ func (s *Source) enumerate(ctx context.Context, session *subscraping.Session, ba
default:
}
s.requests++
resp, err := session.SimpleGet(ctx, baseURL)
isnotfound := resp != nil && resp.StatusCode == http.StatusNotFound
if err != nil && !isnotfound {
@@ -110,5 +113,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
+4
View File
@@ -24,6 +24,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -38,6 +39,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -63,6 +65,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.Post(ctx, apiURL, "", headers, bytes.NewReader(bodyBytes))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -123,5 +126,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -30,6 +30,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -38,6 +39,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -51,6 +53,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://api.threatbook.cn/v3/domain/sub_domains?apikey=%s&resource=%s", randomApiKey, domain))
if err != nil && resp == nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -127,5 +130,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -23,6 +23,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run queries the ThreatCrowd API for the given domain and returns found subdomains.
@@ -30,6 +31,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func(startTime time.Time) {
defer func() {
@@ -45,6 +47,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.Client.Do(req)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -122,5 +125,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
@@ -22,6 +22,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -29,6 +30,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -36,6 +38,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://api.threatminer.org/v2/domain.php?q=%s&rt=5", domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -93,5 +96,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
@@ -30,6 +30,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -38,6 +39,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -60,6 +62,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
if cursor != "" {
url = fmt.Sprintf("%s&cursor=%s", url, cursor)
}
s.requests++
resp, err := session.Get(ctx, url, "", map[string]string{"x-apikey": randomApiKey})
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -125,6 +128,7 @@ func (s *Source) Statistics() subscraping.Statistics {
return subscraping.Statistics{
Errors: s.errors,
Results: s.results,
Requests: s.requests,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
}
@@ -17,6 +17,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
}
// Run function returns all subdomains found with the service
@@ -24,6 +25,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -31,6 +33,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
close(results)
}(time.Now())
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("http://web.archive.org/cdx/search/cdx?url=*.%s/*&output=txt&fl=original&collapse=urlkey", domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -97,5 +100,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Errors: s.errors,
Results: s.results,
TimeTaken: s.timeTaken,
Requests: s.requests,
}
}
@@ -33,6 +33,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -41,6 +42,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -54,6 +56,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
return
}
s.requests++
resp, err := session.SimpleGet(ctx, fmt.Sprintf("https://subdomains.whoisxmlapi.com/api/v1?apiKey=%s&domainName=%s", randomApiKey, domain))
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
@@ -113,5 +116,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -38,6 +38,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -45,6 +46,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -72,6 +74,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
var err error
requestBody, _ := json.Marshal(map[string]interface{}{"domain": domain, "page_request": map[string]int{"page": page, "count": count}})
s.requests++
resp, err = session.Post(ctx, "https://windvane.lichoin.com/trpc.backendhub.public.WindvaneService/ListSubDomain",
"", headers, bytes.NewReader(requestBody))
@@ -150,5 +153,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
@@ -27,6 +27,7 @@ type Source struct {
timeTaken time.Duration
errors int
results int
requests int
skipped bool
}
@@ -35,6 +36,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
results := make(chan subscraping.Result)
s.errors = 0
s.results = 0
s.requests = 0
go func() {
defer func(startTime time.Time) {
@@ -69,6 +71,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se
default:
}
api := fmt.Sprintf("https://api.%s/domain/search?q=%s&type=1&s=1000&page=%d", host, domain, currentPage)
s.requests++
resp, err := session.Get(ctx, api, "", headers)
isForbidden := resp != nil && resp.StatusCode == http.StatusForbidden
if err != nil {
@@ -132,5 +135,6 @@ func (s *Source) Statistics() subscraping.Statistics {
Results: s.results,
TimeTaken: s.timeTaken,
Skipped: s.skipped,
Requests: s.requests,
}
}
+1
View File
@@ -28,6 +28,7 @@ type BasicAuth struct {
// Statistics contains statistics about the scraping process
type Statistics struct {
TimeTaken time.Duration
Requests int
Errors int
Results int
Skipped bool