Merge branch 'lc/add-chaos-upload' of github.com:lc/subfinder into lc-lc/add-chaos-upload
commit
66df39eee6
|
@ -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: []
|
||||||
|
|
|
@ -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))]
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 != "" {
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"`
|
||||||
|
|
Loading…
Reference in New Issue