subfinder/v2/pkg/runner/config.go

180 lines
4.6 KiB
Go

package runner
import (
"os"
"gopkg.in/yaml.v3"
"github.com/projectdiscovery/sliceutil"
"github.com/projectdiscovery/subfinder/v2/pkg/subscraping"
)
// MultipleKeyPartsLength is the max length for multiple keys
const MultipleKeyPartsLength = 2
// Providers contains the providers stored in the configuration file
type Providers struct {
// API keys for different sources
Bufferover []string `yaml:"bufferover"`
Binaryedge []string `yaml:"binaryedge"`
C99 []string `yaml:"c99"`
Censys []string `yaml:"censys"`
Certspotter []string `yaml:"certspotter"`
Chaos []string `yaml:"chaos"`
Chinaz []string `yaml:"chinaz"`
DNSDB []string `yaml:"dnsdb"`
Fofa []string `yaml:"fofa"`
FullHunt []string `json:"fullhunt"`
GitHub []string `yaml:"github"`
IntelX []string `yaml:"intelx"`
PassiveTotal []string `yaml:"passivetotal"`
Robtex []string `yaml:"robtex"`
SecurityTrails []string `yaml:"securitytrails"`
Shodan []string `yaml:"shodan"`
ThreatBook []string `yaml:"threatbook"`
URLScan []string `yaml:"urlscan"`
Virustotal []string `yaml:"virustotal"`
ZoomEye []string `yaml:"zoomeye"`
ZoomEyeApi []string `yaml:"zoomeyeapi"`
}
// GetConfigDirectory gets the subfinder config directory for a user
func GetConfigDirectory() (string, error) {
var config string
directory, err := os.UserHomeDir()
if err != nil {
return config, err
}
config = directory + "/.config/subfinder"
// Create All directory for subfinder even if they exist
err = os.MkdirAll(config, os.ModePerm)
if err != nil {
return config, err
}
return config, nil
}
// MarshalTo writes the marshaled yaml config to disk
func (c *Providers) MarshalTo(file string) error {
f, err := os.Create(file)
if err != nil {
return err
}
defer f.Close()
return yaml.NewEncoder(f).Encode(c)
}
// MarshalTo writes the marshaled yaml config to disk
func (c *Providers) UnmarshalFrom(file string) error {
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
return yaml.NewDecoder(f).Decode(c)
}
// GetKeys gets the API keys from config file and creates a Keys struct
// We use random selection of api keys from the list of keys supplied.
// Keys that require 2 options are separated by colon (:).
func (c *Providers) GetKeys() subscraping.Keys {
keys := subscraping.Keys{}
if len(c.Binaryedge) > 0 {
keys.Binaryedge = sliceutil.PickRandom(c.Binaryedge)
}
if len(c.C99) > 0 {
keys.C99 = sliceutil.PickRandom(c.C99)
}
if len(c.Bufferover) > 0 {
keys.Bufferover = sliceutil.PickRandom(c.Bufferover)
}
if len(c.Censys) > 0 {
censysKeys := sliceutil.PickRandom(c.Censys)
if keyPartA, keyPartB, ok := multipartKey(censysKeys); ok {
keys.CensysToken = keyPartA
keys.CensysSecret = keyPartB
}
}
if len(c.Certspotter) > 0 {
keys.Certspotter = sliceutil.PickRandom(c.Certspotter)
}
if len(c.Chaos) > 0 {
keys.Chaos = sliceutil.PickRandom(c.Chaos)
}
if len(c.Chinaz) > 0 {
keys.Chinaz = sliceutil.PickRandom(c.Chinaz)
}
if (len(c.DNSDB)) > 0 {
keys.DNSDB = sliceutil.PickRandom(c.DNSDB)
}
if (len(c.GitHub)) > 0 {
keys.GitHub = c.GitHub
}
if len(c.IntelX) > 0 {
intelxKeys := sliceutil.PickRandom(c.IntelX)
if keyPartA, keyPartB, ok := multipartKey(intelxKeys); ok {
keys.IntelXHost = keyPartA
keys.IntelXKey = keyPartB
}
}
if len(c.PassiveTotal) > 0 {
passiveTotalKeys := sliceutil.PickRandom(c.PassiveTotal)
if keyPartA, keyPartB, ok := multipartKey(passiveTotalKeys); ok {
keys.PassiveTotalUsername = keyPartA
keys.PassiveTotalPassword = keyPartB
}
}
if len(c.Robtex) > 0 {
keys.Robtex = sliceutil.PickRandom(c.Robtex)
}
if len(c.SecurityTrails) > 0 {
keys.Securitytrails = sliceutil.PickRandom(c.SecurityTrails)
}
if len(c.Shodan) > 0 {
keys.Shodan = sliceutil.PickRandom(c.Shodan)
}
if len(c.ThreatBook) > 0 {
keys.ThreatBook = sliceutil.PickRandom(c.ThreatBook)
}
if len(c.URLScan) > 0 {
keys.URLScan = sliceutil.PickRandom(c.URLScan)
}
if len(c.Virustotal) > 0 {
keys.Virustotal = sliceutil.PickRandom(c.Virustotal)
}
if len(c.ZoomEye) > 0 {
zoomEyeKeys := sliceutil.PickRandom(c.ZoomEye)
if keyPartA, keyPartB, ok := multipartKey(zoomEyeKeys); ok {
keys.ZoomEyeUsername = keyPartA
keys.ZoomEyePassword = keyPartB
}
}
if len(c.ZoomEyeApi) > 0 {
keys.ZoomEyeKey = sliceutil.PickRandom(c.ZoomEyeApi)
}
if len(c.Fofa) > 0 {
fofaKeys := sliceutil.PickRandom(c.Fofa)
if keyPartA, keyPartB, ok := multipartKey(fofaKeys); ok {
keys.FofaUsername = keyPartA
keys.FofaSecret = keyPartB
}
}
if len(c.FullHunt) > 0 {
keys.FullHunt = sliceutil.PickRandom(c.FullHunt)
}
return keys
}