Added shodan passive source
parent
53ceab2aa8
commit
e8d0b8e6c4
|
@ -1 +1,2 @@
|
|||
.DS_Store
|
||||
.DS_Store
|
||||
cmd/subfinder/subfinder
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/subfinder/subfinder/pkg/subscraping/sources/ipv4info"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping/sources/passivetotal"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping/sources/securitytrails"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping/sources/shodan"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping/sources/sitedossier"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping/sources/threatcrowd"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping/sources/threatminer"
|
||||
|
@ -42,6 +43,7 @@ var DefaultSources = []string{
|
|||
"ipv4info",
|
||||
"passivetotal",
|
||||
"securitytrails",
|
||||
"shodan",
|
||||
"sitedossier",
|
||||
"threatcrowd",
|
||||
"threatminer",
|
||||
|
@ -102,6 +104,8 @@ func (a *Agent) addSources(sources []string) {
|
|||
a.sources[source] = &passivetotal.Source{}
|
||||
case "securitytrails":
|
||||
a.sources[source] = &securitytrails.Source{}
|
||||
case "shodan":
|
||||
a.sources[source] = &shodan.Source{}
|
||||
case "sitedossier":
|
||||
a.sources[source] = &sitedossier.Source{}
|
||||
case "threatcrowd":
|
||||
|
|
|
@ -24,6 +24,7 @@ type ConfigFile struct {
|
|||
Facebook []string `yaml:"facebook"`
|
||||
PassiveTotal []string `yaml:"passivetotal"`
|
||||
SecurityTrails []string `yaml:"securitytrails"`
|
||||
Shodan []string `yaml:"shodan"`
|
||||
URLScan []string `yaml:"urlscan"`
|
||||
Virustotal []string `yaml:"virustotal"`
|
||||
}
|
||||
|
@ -117,6 +118,9 @@ func (c ConfigFile) GetKeys() subscraping.Keys {
|
|||
if len(c.SecurityTrails) > 0 {
|
||||
keys.Securitytrails = c.SecurityTrails[rand.Intn(len(c.SecurityTrails))]
|
||||
}
|
||||
if len(c.Shodan) > 0 {
|
||||
keys.Shodan = c.Shodan[rand.Intn(len(c.Shodan))]
|
||||
}
|
||||
if len(c.URLScan) > 0 {
|
||||
keys.URLScan = c.URLScan[rand.Intn(len(c.URLScan))]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package shodan
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/subfinder/subfinder/pkg/subscraping"
|
||||
)
|
||||
|
||||
type shodanResult struct {
|
||||
Matches []shodanObject `json:"matches"`
|
||||
Result int `json:"result"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type shodanObject struct {
|
||||
Hostnames []string `json:"hostnames"`
|
||||
}
|
||||
|
||||
// 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() {
|
||||
if session.Keys.Shodan == "" {
|
||||
close(results)
|
||||
return
|
||||
}
|
||||
|
||||
for currentPage := 0; currentPage <= 10; currentPage++ {
|
||||
resp, err := session.NormalGet("https://api.shodan.io/shodan/host/search?query=hostname:" + domain + "&page=" + strconv.Itoa(currentPage) + "&key=" + session.Keys.Shodan)
|
||||
if err != nil {
|
||||
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
|
||||
close(results)
|
||||
return
|
||||
}
|
||||
|
||||
var response shodanResult
|
||||
err = jsoniter.NewDecoder(resp.Body).Decode(&response)
|
||||
if err != nil {
|
||||
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
|
||||
close(results)
|
||||
return
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if response.Error != "" {
|
||||
close(results)
|
||||
return
|
||||
}
|
||||
|
||||
for _, block := range response.Matches {
|
||||
for _, hostname := range block.Hostnames {
|
||||
|
||||
if strings.Contains(hostname, "*.") {
|
||||
hostname = strings.Split(hostname, "*.")[1]
|
||||
}
|
||||
|
||||
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Subdomain, Value: hostname}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(results)
|
||||
}()
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
// Name returns the name of the source
|
||||
func (s *Source) Name() string {
|
||||
return "shodan"
|
||||
}
|
|
@ -36,6 +36,7 @@ type Keys struct {
|
|||
PassiveTotalUsername string `json:"passivetotal_username"`
|
||||
PassiveTotalPassword string `json:"passivetotal_password"`
|
||||
Securitytrails string `json:"securitytrails"`
|
||||
Shodan string `json:"shodan"`
|
||||
URLScan string `json:"urlscan"`
|
||||
Virustotal string `json:"virustotal"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue