Merge branch 'lc/add-chaos-upload' of github.com:lc/subfinder into lc-lc/add-chaos-upload

master
Mzack9999 2020-05-18 20:08:16 +02:00
commit 66df39eee6
6 changed files with 68 additions and 3 deletions

View File

@ -41,10 +41,11 @@ sources:
binaryedge: [] binaryedge: []
censys: [] censys: []
certspotter: [] certspotter: []
chaos: []
dnsdb: [] dnsdb: []
passivetotal: [] passivetotal: []
securitytrails: [] securitytrails: []
shodan: [] shodan: []
urlscan: [] urlscan: []
virustotal: [] virustotal: []
zoomeye: [] zoomeye: []

View File

@ -22,6 +22,7 @@ type ConfigFile struct {
Binaryedge []string `yaml:"binaryedge"` Binaryedge []string `yaml:"binaryedge"`
Censys []string `yaml:"censys"` Censys []string `yaml:"censys"`
Certspotter []string `yaml:"certspotter"` Certspotter []string `yaml:"certspotter"`
Chaos []string `yaml:"chaos"`
DNSDB []string `yaml:"dnsdb"` DNSDB []string `yaml:"dnsdb"`
PassiveTotal []string `yaml:"passivetotal"` PassiveTotal []string `yaml:"passivetotal"`
SecurityTrails []string `yaml:"securitytrails"` SecurityTrails []string `yaml:"securitytrails"`
@ -109,7 +110,9 @@ func (c ConfigFile) GetKeys() subscraping.Keys {
if len(c.Certspotter) > 0 { if len(c.Certspotter) > 0 {
keys.Certspotter = c.Certspotter[rand.Intn(len(c.Certspotter))] keys.Certspotter = c.Certspotter[rand.Intn(len(c.Certspotter))]
} }
if len(c.Chaos) > 0 {
keys.Chaos = c.Chaos[rand.Intn(len(c.Chaos))]
}
if (len(c.DNSDB)) > 0 { if (len(c.DNSDB)) > 0 {
keys.DNSDB = c.DNSDB[rand.Intn(len(c.DNSDB))] keys.DNSDB = c.DNSDB[rand.Intn(len(c.DNSDB))]
} }

View File

@ -1,6 +1,7 @@
package runner package runner
import ( import (
"bytes"
"os" "os"
"strings" "strings"
"sync" "sync"
@ -113,7 +114,25 @@ func (r *Runner) EnumerateSingleDomain(domain, output string, append bool) error
} }
} }
} }
// In case the user has specified to upload to chaos, write everything to a temporary buffer and upload
if r.options.ChaosUpload {
var buf = &bytes.Buffer{}
err := WriteHostOutput(uniqueMap, buf)
// If an error occurs, do not interrupt, continue to check if user specifed an output file
if err != nil {
gologger.Errorf("Could not prepare results for chaos %s\n", err)
} else {
// no error in writing host output, upload to chaos
err = r.UploadToChaos(buf)
if err != nil {
gologger.Errorf("Could not upload results to chaos %s\n", err)
} else {
gologger.Infof("Input processed successfully and subdomains with valid records will be updated to chaos dataset.\n")
}
// clear buffer
buf = nil
}
}
// In case the user has given an output file, write all the found // In case the user has given an output file, write all the found
// subdomains to the output file. // subdomains to the output file.
if output != "" { if output != "" {

View File

@ -18,6 +18,7 @@ type Options struct {
MaxEnumerationTime int // MaxEnumerationTime is the maximum amount of time in mins to wait for enumeration MaxEnumerationTime int // MaxEnumerationTime is the maximum amount of time in mins to wait for enumeration
Domain string // Domain is the domain to find subdomains for Domain string // Domain is the domain to find subdomains for
DomainsFile string // DomainsFile is the file containing list of domains to find subdomains for DomainsFile string // DomainsFile is the file containing list of domains to find subdomains for
ChaosUpload bool // ChaosUpload indicates whether to upload results to the Chaos API
Output string // Output is the file to write found subdomains to. Output string // Output is the file to write found subdomains to.
OutputDirectory string // OutputDirectory is the directory to write results to in case list of domains is given OutputDirectory string // OutputDirectory is the directory to write results to in case list of domains is given
JSON bool // JSON specifies whether to use json for output format or text file JSON bool // JSON specifies whether to use json for output format or text file
@ -52,6 +53,7 @@ func ParseOptions() *Options {
flag.IntVar(&options.MaxEnumerationTime, "max-time", 10, "Minutes to wait for enumeration results") flag.IntVar(&options.MaxEnumerationTime, "max-time", 10, "Minutes to wait for enumeration results")
flag.StringVar(&options.Domain, "d", "", "Domain to find subdomains for") flag.StringVar(&options.Domain, "d", "", "Domain to find subdomains for")
flag.StringVar(&options.DomainsFile, "dL", "", "File containing list of domains to enumerate") flag.StringVar(&options.DomainsFile, "dL", "", "File containing list of domains to enumerate")
flag.BoolVar(&options.ChaosUpload, "cd", false, "Upload results to the Chaos API (api-key required)")
flag.StringVar(&options.Output, "o", "", "File to write output to (optional)") flag.StringVar(&options.Output, "o", "", "File to write output to (optional)")
flag.StringVar(&options.OutputDirectory, "oD", "", "Directory to write enumeration results to (optional)") flag.StringVar(&options.OutputDirectory, "oD", "", "Directory to write enumeration results to (optional)")
flag.BoolVar(&options.JSON, "oJ", false, "Write output in JSON lines Format") flag.BoolVar(&options.JSON, "oJ", false, "Write output in JSON lines Format")

View File

@ -2,10 +2,16 @@ package runner
import ( import (
"bufio" "bufio"
"crypto/tls"
"fmt"
"io" "io"
"io/ioutil"
"net/http"
"strings" "strings"
"time"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
) )
// JSONResult contains the result for a host in JSON format // JSONResult contains the result for a host in JSON format
@ -14,6 +20,39 @@ type JSONResult struct {
IP string `json:"ip"` IP string `json:"ip"`
} }
func (r *Runner) UploadToChaos(reader io.Reader) error {
httpClient := &http.Client{
Transport: &http.Transport{
MaxIdleConnsPerHost: 100,
MaxIdleConns: 100,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
Timeout: time.Duration(600) * time.Second, // 10 minutes - uploads may take long
}
request, err := http.NewRequest("POST", "https://dns.projectdiscovery.io/dns/add", reader)
if err != nil {
return errors.Wrap(err, "could not create request")
}
request.Header.Set("Authorization", r.options.YAMLConfig.GetKeys().Chaos)
resp, err := httpClient.Do(request)
if err != nil {
return errors.Wrap(err, "could not make request")
}
defer func() {
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
}()
if resp.StatusCode != 200 {
return fmt.Errorf("invalid status code received: %d", resp.StatusCode)
}
return nil
}
// WriteHostOutput writes the output list of subdomain to an io.Writer // WriteHostOutput writes the output list of subdomain to an io.Writer
func WriteHostOutput(results map[string]struct{}, writer io.Writer) error { func WriteHostOutput(results map[string]struct{}, writer io.Writer) error {
bufwriter := bufio.NewWriter(writer) bufwriter := bufio.NewWriter(writer)

View File

@ -33,6 +33,7 @@ type Keys struct {
CensysToken string `json:"censysUsername"` CensysToken string `json:"censysUsername"`
CensysSecret string `json:"censysPassword"` CensysSecret string `json:"censysPassword"`
Certspotter string `json:"certspotter"` Certspotter string `json:"certspotter"`
Chaos string `json:"chaos"`
DNSDB string `json:"dnsdb"` DNSDB string `json:"dnsdb"`
PassiveTotalUsername string `json:"passivetotal_username"` PassiveTotalUsername string `json:"passivetotal_username"`
PassiveTotalPassword string `json:"passivetotal_password"` PassiveTotalPassword string `json:"passivetotal_password"`