Added shodan passive source

master
Ice3man543 2019-12-05 00:12:55 +05:30
parent 53ceab2aa8
commit e8d0b8e6c4
5 changed files with 88 additions and 1 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
.DS_Store
.DS_Store
cmd/subfinder/subfinder

View File

@ -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":

View File

@ -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))]
}

View File

@ -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"
}

View File

@ -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"`
}