Updated Formatting and Added Silent Switch
parent
158472f53a
commit
477e349b6f
|
@ -16,23 +16,23 @@ import (
|
|||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
func CheckDNSEntry(state *helper.State, domain string, channel chan string) {
|
||||
func CheckDNSEntry(state *helper.State, domain string, channel chan string) {
|
||||
// Create a prepared subdomain
|
||||
preparedSubdomain := <-channel + "." + domain
|
||||
ipAddress, err := net.LookupHost(preparedSubdomain)
|
||||
|
||||
|
||||
if err == nil {
|
||||
// No eror, let's see if it's a Wildcard subdomain
|
||||
if !state.WildcardIPs.ContainsAny(ipAddress) {
|
||||
channel <- preparedSubdomain
|
||||
return
|
||||
channel <- preparedSubdomain
|
||||
return
|
||||
} else {
|
||||
// This is likely a wildcard entry, skip it
|
||||
channel <- ""
|
||||
return
|
||||
// This is likely a wildcard entry, skip it
|
||||
channel <- ""
|
||||
return
|
||||
}
|
||||
} else {
|
||||
channel <- ""
|
||||
return
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//
|
||||
// brutefoce.go : Helper method for bruteforce functionality implemented
|
||||
//
|
||||
// brutefoce.go : Helper method for bruteforce functionality implemented
|
||||
// in subfinder.
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -11,13 +11,13 @@
|
|||
package bruteforce
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"bufio"
|
||||
"sync"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/bruteforcer"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
func Bruteforce(state *helper.State) (subdomains []string) {
|
||||
|
@ -54,7 +54,7 @@ func Process(wordlist string, domain string, state *helper.State) (subdomains []
|
|||
|
||||
var wg sync.WaitGroup
|
||||
var channel = make(chan string)
|
||||
|
||||
|
||||
for i := 0; i < state.Threads; i++ {
|
||||
wg.Add(1)
|
||||
|
||||
|
@ -62,7 +62,7 @@ func Process(wordlist string, domain string, state *helper.State) (subdomains []
|
|||
defer wg.Done()
|
||||
bruteforcer.CheckDNSEntry(state, domain, channel)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
for _, word := range words {
|
||||
channel <- word
|
||||
|
@ -78,4 +78,4 @@ func Process(wordlist string, domain string, state *helper.State) (subdomains []
|
|||
wg.Wait()
|
||||
|
||||
return subdomains, err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
// All Rights Reserved
|
||||
|
||||
// Passive Subdomain Discovery Helper method
|
||||
// Calls all the functions and also manages error handling
|
||||
package passive
|
||||
package passive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -17,37 +17,37 @@ import (
|
|||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
|
||||
// Load different Passive data sources
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/certspotter"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/certdb"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/certspotter"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/crtsh"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/hackertarget"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/findsubdomains"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/dnsdumpster"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/findsubdomains"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/hackertarget"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/netcraft"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/passivetotal"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/ptrarchive"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/securitytrails"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/threatcrowd"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/virustotal"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/netcraft"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/sources/securitytrails"
|
||||
)
|
||||
|
||||
// Sources configuration structure specifying what should we use
|
||||
// to do passive subdomain discovery.
|
||||
type Source struct {
|
||||
Certdb bool
|
||||
Crtsh bool
|
||||
Certspotter bool
|
||||
Threatcrowd bool
|
||||
Findsubdomains bool
|
||||
Dnsdumpster bool
|
||||
Passivetotal bool
|
||||
Ptrarchive bool
|
||||
Hackertarget bool
|
||||
Virustotal bool
|
||||
Securitytrails bool
|
||||
Netcraft bool
|
||||
Certdb bool
|
||||
Crtsh bool
|
||||
Certspotter bool
|
||||
Threatcrowd bool
|
||||
Findsubdomains bool
|
||||
Dnsdumpster bool
|
||||
Passivetotal bool
|
||||
Ptrarchive bool
|
||||
Hackertarget bool
|
||||
Virustotal bool
|
||||
Securitytrails bool
|
||||
Netcraft bool
|
||||
|
||||
NoOfSources int
|
||||
NoOfSources int
|
||||
}
|
||||
|
||||
func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
||||
|
@ -57,17 +57,19 @@ func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
|||
if state.Sources == "all" {
|
||||
// Search all data sources
|
||||
|
||||
fmt.Printf("\n[-] Searching For Subdomains in CertDB")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Certspotter")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Threatcrowd")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Findsubdomains")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in DNSDumpster")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PassiveTotal")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PTRArchive")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Hackertarget")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Virustotal")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Securitytrails")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Netcraft\n")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in CertDB")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Certspotter")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Threatcrowd")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Findsubdomains")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in DNSDumpster")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PassiveTotal")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PTRArchive")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Hackertarget")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Virustotal")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Securitytrails")
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Netcraft\n")
|
||||
}
|
||||
|
||||
sourceConfig = Source{true, true, true, true, true, true, true, true, true, true, true, true, 12}
|
||||
} else {
|
||||
|
@ -76,51 +78,75 @@ func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
|||
dataSources := strings.Split(state.Sources, ",")
|
||||
for _, source := range dataSources {
|
||||
if source == "crtsh" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Crt.sh")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Crt.sh")
|
||||
}
|
||||
sourceConfig.Crtsh = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "certdb" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in CertDB")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in CertDB")
|
||||
}
|
||||
sourceConfig.Certdb = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "certspotter" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Certspotter")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Certspotter")
|
||||
}
|
||||
sourceConfig.Certspotter = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "threatcrowd" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Threatcrowd")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Threatcrowd")
|
||||
}
|
||||
sourceConfig.Threatcrowd = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "findsubdomains" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Findsubdomains")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Findsubdomains")
|
||||
}
|
||||
sourceConfig.Findsubdomains = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "dnsdumpster" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in DNSDumpster")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in DNSDumpster")
|
||||
}
|
||||
sourceConfig.Dnsdumpster = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "passivetotal" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PassiveTotal")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PassiveTotal")
|
||||
}
|
||||
sourceConfig.Passivetotal = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "ptrarchive" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PTRArchive")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in PTRArchive")
|
||||
}
|
||||
sourceConfig.Ptrarchive = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "hackertarget" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Hackertarget")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Hackertarget")
|
||||
}
|
||||
sourceConfig.Hackertarget = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "virustotal" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Virustotal")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Virustotal")
|
||||
}
|
||||
sourceConfig.Virustotal = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "securitytrails" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Securitytrails")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Securitytrails")
|
||||
}
|
||||
sourceConfig.Securitytrails = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
} else if source == "netcraft" {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Netcraft")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[-] Searching For Subdomains in Netcraft")
|
||||
}
|
||||
sourceConfig.Netcraft = true
|
||||
sourceConfig.NoOfSources = sourceConfig.NoOfSources + 1
|
||||
}
|
||||
|
@ -132,18 +158,42 @@ func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
|||
// Create goroutines for added speed and recieve data via channels
|
||||
// Check if we the user has specified custom sources and if yes, run them
|
||||
// via if statements.
|
||||
if sourceConfig.Crtsh == true { go crtsh.Query(state, ch) }
|
||||
if sourceConfig.Certdb == true { go certdb.Query(state, ch) }
|
||||
if sourceConfig.Certspotter == true { go certspotter.Query(state, ch) }
|
||||
if sourceConfig.Threatcrowd == true { go threatcrowd.Query(state, ch) }
|
||||
if sourceConfig.Findsubdomains == true { go findsubdomains.Query(state, ch) }
|
||||
if sourceConfig.Dnsdumpster == true { go dnsdumpster.Query(state, ch) }
|
||||
if sourceConfig.Passivetotal == true { go passivetotal.Query(state, ch) }
|
||||
if sourceConfig.Ptrarchive == true { go ptrarchive.Query(state, ch) }
|
||||
if sourceConfig.Hackertarget == true { go hackertarget.Query(state, ch) }
|
||||
if sourceConfig.Virustotal == true { go virustotal.Query(state, ch) }
|
||||
if sourceConfig.Securitytrails == true { go securitytrails.Query(state, ch) }
|
||||
if sourceConfig.Netcraft == true { go netcraft.Query(state, ch) }
|
||||
if sourceConfig.Crtsh == true {
|
||||
go crtsh.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Certdb == true {
|
||||
go certdb.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Certspotter == true {
|
||||
go certspotter.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Threatcrowd == true {
|
||||
go threatcrowd.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Findsubdomains == true {
|
||||
go findsubdomains.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Dnsdumpster == true {
|
||||
go dnsdumpster.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Passivetotal == true {
|
||||
go passivetotal.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Ptrarchive == true {
|
||||
go ptrarchive.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Hackertarget == true {
|
||||
go hackertarget.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Virustotal == true {
|
||||
go virustotal.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Securitytrails == true {
|
||||
go securitytrails.Query(state, ch)
|
||||
}
|
||||
if sourceConfig.Netcraft == true {
|
||||
go netcraft.Query(state, ch)
|
||||
}
|
||||
|
||||
// Recieve data from all goroutines running
|
||||
for i := 0; i < sourceConfig.NoOfSources; i++ {
|
||||
|
@ -151,7 +201,9 @@ func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
|||
|
||||
if result.Error != nil {
|
||||
// some error occured
|
||||
fmt.Printf("\nerror: %v\n", result.Error)
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\nerror: %v\n", result.Error)
|
||||
}
|
||||
}
|
||||
for _, subdomain := range result.Subdomains {
|
||||
finalPassiveSubdomains = append(finalPassiveSubdomains, subdomain)
|
||||
|
@ -162,9 +214,9 @@ func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
|||
uniquePassiveSubdomains := helper.Unique(finalPassiveSubdomains)
|
||||
// Now, validate all subdomains found
|
||||
validPassiveSubdomains := helper.Validate(state, uniquePassiveSubdomains)
|
||||
|
||||
|
||||
var PassiveSubdomains []string
|
||||
|
||||
|
||||
if state.Alive == true {
|
||||
// Nove remove all wildcard subdomains
|
||||
PassiveSubdomains = helper.RemoveWildcardSubdomains(state, validPassiveSubdomains)
|
||||
|
@ -175,7 +227,9 @@ func PassiveDiscovery(state *helper.State) (finalPassiveSubdomains []string) {
|
|||
// Sort the subdomains found alphabetically
|
||||
sort.Strings(PassiveSubdomains)
|
||||
|
||||
fmt.Printf("\n\n[#] Total %d Unique subdomains found passively\n\n", len(PassiveSubdomains))
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n\n[#] Total %d Unique subdomains found passively\n\n", len(PassiveSubdomains))
|
||||
}
|
||||
for _, subdomain := range PassiveSubdomains {
|
||||
fmt.Println(subdomain)
|
||||
}
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
//
|
||||
// Contains color constants for printing
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
||||
|
||||
package helper
|
||||
|
||||
// Use like this
|
||||
// Use like this
|
||||
// fmt.Printf("[%sCRTSH%s] %s", r, rs, subdomain)
|
||||
var (
|
||||
Red = "\033[31;1;4m" // red color
|
||||
Cyan = "\033[36;6;2m" // cyan color
|
||||
Green = "\033[32;6;3m" // Green color
|
||||
Reset = "\033[0m" // reset for default color
|
||||
Red = "\033[31;1;4m" // red color
|
||||
Cyan = "\033[36;6;2m" // cyan color
|
||||
Green = "\033[32;6;3m" // Green color
|
||||
Reset = "\033[0m" // reset for default color
|
||||
|
||||
Info = "\033[33;1;1m"
|
||||
Que = "\033[34;1;1m"
|
||||
Bad = "\033[31;1;1m"
|
||||
Good = "\033[32;1;1m"
|
||||
Run = "\033[97;1;1m"
|
||||
)
|
||||
Que = "\033[34;1;1m"
|
||||
Bad = "\033[31;1;1m"
|
||||
Good = "\033[32;1;1m"
|
||||
Run = "\033[97;1;1m"
|
||||
)
|
||||
|
|
|
@ -9,29 +9,29 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"strings"
|
||||
"encoding/json"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Current result structure
|
||||
type Result struct {
|
||||
Subdomains []string // Subdomains found
|
||||
Error error // Any error that has occured
|
||||
Subdomains []string // Subdomains found
|
||||
Error error // Any error that has occured
|
||||
}
|
||||
|
||||
// Current Bruteforce structure
|
||||
type BruteforceResult struct {
|
||||
Entity string // Current Subdomain we found
|
||||
Error error // Error
|
||||
Entity string // Current Subdomain we found
|
||||
Error error // Error
|
||||
}
|
||||
|
||||
// NewUUID generates a random UUID according to RFC 4122
|
||||
// Taken from : https://play.golang.org/p/4FkNSiUDMg
|
||||
//
|
||||
//
|
||||
// Used for bruteforcing and detection of Wildcard Subdomains :-)
|
||||
func NewUUID() (string, error) {
|
||||
uuid := make([]byte, 16)
|
||||
|
@ -49,29 +49,28 @@ func NewUUID() (string, error) {
|
|||
// Reads a config file from disk and returns Configuration structure
|
||||
func ReadConfigFile() (configuration *Config, err error) {
|
||||
|
||||
var config Config
|
||||
var config Config
|
||||
|
||||
// Read the file
|
||||
raw, err := ioutil.ReadFile("./config.json")
|
||||
// Read the file
|
||||
raw, err := ioutil.ReadFile("./config.json")
|
||||
if err != nil {
|
||||
return &config, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(raw, &config)
|
||||
if (err != nil) {
|
||||
return &config, err
|
||||
if err != nil {
|
||||
return &config, err
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
|
||||
// Returns unique items in a slice
|
||||
// Adapted from http://www.golangprograms.com/remove-duplicate-values-from-slice.html
|
||||
func Unique(elements []string) []string {
|
||||
func Unique(elements []string) []string {
|
||||
// Use map to record duplicates as we find them.
|
||||
encountered := map[string]bool{}
|
||||
result := []string{}
|
||||
encountered := map[string]bool{}
|
||||
result := []string{}
|
||||
|
||||
for v := range elements {
|
||||
if encountered[elements[v]] == true {
|
||||
|
@ -96,4 +95,4 @@ func Validate(state *State, strslice []string) (subdomains []string) {
|
|||
}
|
||||
|
||||
return subdomains
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
//
|
||||
// search.go : Contains helper functions for search engine logic
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -11,16 +11,16 @@ package helper
|
|||
// Configuration Structure which contains configuration for each
|
||||
// search engine.
|
||||
type BaseSearchConfiguration struct {
|
||||
MaxDomains int // Max subdomains per page
|
||||
MaxPages int // Max pages we should query
|
||||
MaxDomains int // Max subdomains per page
|
||||
MaxPages int // Max pages we should query
|
||||
|
||||
CurrentPageNo int // Current page we are checking
|
||||
CurrentRetries int // Retries we have already made
|
||||
CurrentPageNo int // Current page we are checking
|
||||
CurrentRetries int // Retries we have already made
|
||||
|
||||
PrevLinksFound []string // Links we have previously found
|
||||
CurrentSubdomains []string // Subdomains we have already found on a page
|
||||
PrevLinksFound []string // Links we have previously found
|
||||
CurrentSubdomains []string // Subdomains we have already found on a page
|
||||
|
||||
AllSubdomains []string // All Subdomains found so far
|
||||
AllSubdomains []string // All Subdomains found so far
|
||||
}
|
||||
|
||||
// CheckMaxSubdomains checks if maximum number of domains was found.
|
||||
|
@ -41,4 +41,4 @@ func CheckMaxPages(config *BaseSearchConfiguration) bool {
|
|||
}
|
||||
|
||||
return config.CurrentPageNo >= config.MaxPages
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
//
|
||||
// helper.go : Main sources driver. Contains helper functions for other sources.
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,14 +9,13 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"net/http/cookiejar"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
// GetHTTPResponse : Returns a HTTP Response object
|
||||
// It needs URL To Visit. Note, It needs full url with scheme and a timeout value.
|
||||
// It returns a HTTP Response object
|
||||
|
@ -48,9 +47,9 @@ func GetHTTPResponse(url string, timeout int) (resp *http.Response, err error) {
|
|||
}
|
||||
|
||||
// GetHTTPResponse : Returns a HTTP Response object
|
||||
// It needs URL To Visit and a cookie array to send with request.
|
||||
// It needs URL To Visit and a cookie array to send with request.
|
||||
// Note, It needs full url with scheme and a timeout value.
|
||||
// It returns a HTTP Response object with a cookie array.
|
||||
// It returns a HTTP Response object with a cookie array.
|
||||
func GetHTTPCookieResponse(urls string, cookies []*http.Cookie, timeout int) (resp *http.Response, cookie []*http.Cookie, err error) {
|
||||
|
||||
var curCookieJar *cookiejar.Jar
|
||||
|
@ -67,7 +66,7 @@ func GetHTTPCookieResponse(urls string, cookies []*http.Cookie, timeout int) (re
|
|||
|
||||
client := &http.Client{
|
||||
Transport: tr,
|
||||
Jar: curCookieJar,
|
||||
Jar: curCookieJar,
|
||||
Timeout: time.Duration(timeout) * time.Second,
|
||||
}
|
||||
|
||||
|
|
|
@ -50,4 +50,4 @@ func (set *StringSet) Stringify() string {
|
|||
values = append(values, s)
|
||||
}
|
||||
return strings.Join(values, ",")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,28 +9,28 @@
|
|||
package output
|
||||
|
||||
import (
|
||||
"os"
|
||||
"io"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// Write output to a normal text file
|
||||
func WriteOutputText(state *helper.State, subdomains []string) error {
|
||||
file, err := os.Create(state.Output)
|
||||
file, err := os.Create(state.Output)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
return err
|
||||
}
|
||||
|
||||
for _, subdomain := range subdomains {
|
||||
_, err := io.WriteString(file, subdomain+"\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := io.WriteString(file, subdomain+"\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,15 +9,15 @@
|
|||
package certdb
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
|
||||
// Parser subdomains from SSL Certificate Information Page
|
||||
func findSubdomains(link string, state *helper.State, channel chan []string) {
|
||||
|
@ -29,7 +29,7 @@ func findSubdomains(link string, state *helper.State, channel chan []string) {
|
|||
return
|
||||
}
|
||||
|
||||
// Get the response body
|
||||
// Get the response body
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
channel <- subdomainsfound
|
||||
|
@ -46,14 +46,13 @@ func findSubdomains(link string, state *helper.State, channel chan []string) {
|
|||
|
||||
match := SubdomainRegex.FindAllStringSubmatch(src, -1)
|
||||
|
||||
for _, link := range match {
|
||||
subdomainsfound = append(subdomainsfound, link[1])
|
||||
for _, link := range match {
|
||||
subdomainsfound = append(subdomainsfound, link[1])
|
||||
}
|
||||
|
||||
channel <- subdomainsfound
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
@ -69,7 +68,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
return
|
||||
}
|
||||
|
||||
// Get the response body
|
||||
// Get the response body
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
|
@ -88,11 +87,11 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
channel := make(chan []string, len(match))
|
||||
|
||||
for _, link := range match {
|
||||
go findSubdomains(link[1], state, channel)
|
||||
for _, link := range match {
|
||||
go findSubdomains(link[1], state, channel)
|
||||
}
|
||||
|
||||
for i:=0; i < len(match); i++ {
|
||||
for i := 0; i < len(match); i++ {
|
||||
subsReturned = <-channel
|
||||
|
||||
initialSubs = append(initialSubs, subsReturned...)
|
||||
|
@ -108,10 +107,9 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
}
|
||||
|
||||
subdomains = append(subdomains, subdomain)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result.Subdomains = subdomains
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,17 +9,17 @@
|
|||
package certspotter
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// Structure of a single dictionary of output by crt.sh
|
||||
type certspotter_object struct {
|
||||
Dns_names []string `json:"dns_names"`
|
||||
Dns_names []string `json:"dns_names"`
|
||||
}
|
||||
|
||||
// array of all results returned
|
||||
|
@ -31,7 +31,7 @@ var subdomains []string
|
|||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
||||
// Create a result object
|
||||
// Create a result object
|
||||
var result helper.Result
|
||||
result.Subdomains = subdomains
|
||||
|
||||
|
@ -78,10 +78,10 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
}
|
||||
|
||||
subdomains = append(subdomains, dns_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,10 +9,10 @@
|
|||
package crtsh
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
@ -20,14 +20,14 @@ import (
|
|||
// Structure of a single dictionary of output by crt.sh
|
||||
// We only need name_value object hence this :-)
|
||||
type crtsh_object struct {
|
||||
Name_value string `json:"name_value"`
|
||||
Name_value string `json:"name_value"`
|
||||
}
|
||||
|
||||
// array of all results returned
|
||||
var crtsh_data []crtsh_object
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
@ -71,7 +71,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
// {abc},
|
||||
// {abc}
|
||||
// ]
|
||||
json_output := "["+correct_format+"]"
|
||||
json_output := "[" + correct_format + "]"
|
||||
|
||||
// Decode the json format
|
||||
err = json.Unmarshal([]byte(json_output), &crtsh_data)
|
||||
|
@ -102,5 +102,5 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,19 +9,19 @@
|
|||
package dnsdumpster
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"net/http/cookiejar"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
var gCookies []*http.Cookie
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
|
@ -51,33 +51,33 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
src := string(body)
|
||||
|
||||
re := regexp.MustCompile("<input type='hidden' name='csrfmiddlewaretoken' value='(.*)' />")
|
||||
match := re.FindAllStringSubmatch(src, -1)
|
||||
|
||||
// CSRF Middleware token for POST Request
|
||||
csrfmiddlewaretoken := match[0]
|
||||
re := regexp.MustCompile("<input type='hidden' name='csrfmiddlewaretoken' value='(.*)' />")
|
||||
match := re.FindAllStringSubmatch(src, -1)
|
||||
|
||||
// Set cookiejar values
|
||||
u, _ := url.Parse("https://dnsdumpster.com")
|
||||
curCookieJar.SetCookies(u, gCookies)
|
||||
// CSRF Middleware token for POST Request
|
||||
csrfmiddlewaretoken := match[0]
|
||||
|
||||
hc := http.Client{Jar: curCookieJar}
|
||||
// Set cookiejar values
|
||||
u, _ := url.Parse("https://dnsdumpster.com")
|
||||
curCookieJar.SetCookies(u, gCookies)
|
||||
|
||||
hc := http.Client{Jar: curCookieJar}
|
||||
form := url.Values{}
|
||||
|
||||
form.Add("csrfmiddlewaretoken", csrfmiddlewaretoken[1])
|
||||
form.Add("targetip", state.Domain)
|
||||
|
||||
// Create a post request to get subdomain data
|
||||
req, err := http.NewRequest("POST", "https://dnsdumpster.com", strings.NewReader(form.Encode()))
|
||||
form.Add("csrfmiddlewaretoken", csrfmiddlewaretoken[1])
|
||||
form.Add("targetip", state.Domain)
|
||||
|
||||
req.PostForm = form
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Add("Referer", "https://dnsdumpster.com")
|
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1")
|
||||
// Create a post request to get subdomain data
|
||||
req, err := http.NewRequest("POST", "https://dnsdumpster.com", strings.NewReader(form.Encode()))
|
||||
|
||||
resp, err = hc.Do(req)
|
||||
req.PostForm = form
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Add("Referer", "https://dnsdumpster.com")
|
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1")
|
||||
|
||||
// Get the response body
|
||||
resp, err = hc.Do(req)
|
||||
|
||||
// Get the response body
|
||||
body, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
|
@ -90,12 +90,12 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
// Find the table holding host records
|
||||
Regex, _ := regexp.Compile("<td class=\"col-md-4\">(.*\\..*\\..*)<br>")
|
||||
match = Regex.FindAllStringSubmatch(src, -1)
|
||||
|
||||
// String to hold initial subdomains
|
||||
var initialSubs []string
|
||||
|
||||
for _, data := range match {
|
||||
initialSubs = append(initialSubs, data[1])
|
||||
// String to hold initial subdomains
|
||||
var initialSubs []string
|
||||
|
||||
for _, data := range match {
|
||||
initialSubs = append(initialSubs, data[1])
|
||||
}
|
||||
|
||||
validSubdomains := helper.Validate(state, initialSubs)
|
||||
|
@ -110,10 +110,9 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
}
|
||||
|
||||
subdomains = append(subdomains, subdomain)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result.Subdomains = subdomains
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,8 +9,8 @@
|
|||
package findsubdomains
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
|
@ -18,11 +18,11 @@ import (
|
|||
)
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
||||
|
||||
var result helper.Result
|
||||
result.Subdomains = subdomains
|
||||
|
||||
|
@ -44,13 +44,13 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
src := string(body)
|
||||
|
||||
re := regexp.MustCompile("<a class=\"aggregated-link\" rel=\"nofollow\" href=\"(.*)\" target=\"_blank\">")
|
||||
match := re.FindAllStringSubmatch(src, -1)
|
||||
|
||||
for _, subdomain := range match {
|
||||
// Dirty Logic
|
||||
finishedSub := strings.Split(subdomain[1], "//")[1]
|
||||
|
||||
re := regexp.MustCompile("<a class=\"aggregated-link\" rel=\"nofollow\" href=\"(.*)\" target=\"_blank\">")
|
||||
match := re.FindAllStringSubmatch(src, -1)
|
||||
|
||||
for _, subdomain := range match {
|
||||
// Dirty Logic
|
||||
finishedSub := strings.Split(subdomain[1], "//")[1]
|
||||
|
||||
if state.Verbose == true {
|
||||
if state.Color == true {
|
||||
fmt.Printf("\n[%sFINDSUBDOMAINS%s] %s", helper.Red, helper.Reset, finishedSub)
|
||||
|
@ -62,7 +62,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
subdomains = append(subdomains, finishedSub)
|
||||
}
|
||||
|
||||
result.Subdomains = subdomains
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,16 +9,16 @@
|
|||
package hackertarget
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
@ -57,5 +57,5 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,14 +9,14 @@
|
|||
package netcraft
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"crypto/sha1" // Required for netcraft challenge response
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"crypto/sha1" // Required for netcraft challenge response
|
||||
"net/url"
|
||||
"net/http"
|
||||
"io"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ var globalSubdomains []string
|
|||
var gCookies []*http.Cookie
|
||||
|
||||
// Local function to recursively enumerate subdomains until no subdomains
|
||||
// are left
|
||||
// are left
|
||||
func enumerate(state *helper.State, baseUrl string) (err error) {
|
||||
|
||||
// Make a http request to Netcraft
|
||||
|
@ -67,13 +67,13 @@ func enumerate(state *helper.State, baseUrl string) (err error) {
|
|||
|
||||
src := string(body)
|
||||
|
||||
re := regexp.MustCompile("<a href=\"http://toolbar.netcraft.com/site_report\\?url=(.*)\">")
|
||||
match := re.FindAllStringSubmatch(src, -1)
|
||||
|
||||
for _, subdomain := range match {
|
||||
// Dirty Logic
|
||||
finishedSub := strings.Split(subdomain[1], "//")[1]
|
||||
|
||||
re := regexp.MustCompile("<a href=\"http://toolbar.netcraft.com/site_report\\?url=(.*)\">")
|
||||
match := re.FindAllStringSubmatch(src, -1)
|
||||
|
||||
for _, subdomain := range match {
|
||||
// Dirty Logic
|
||||
finishedSub := strings.Split(subdomain[1], "//")[1]
|
||||
|
||||
if state.Verbose == true {
|
||||
if state.Color == true {
|
||||
fmt.Printf("\n[%sNETCRAFT%s] %s", helper.Red, helper.Reset, finishedSub)
|
||||
|
@ -83,28 +83,28 @@ func enumerate(state *helper.State, baseUrl string) (err error) {
|
|||
}
|
||||
|
||||
globalSubdomains = append(globalSubdomains, finishedSub)
|
||||
}
|
||||
}
|
||||
|
||||
// we have another page full of juicy subdomains
|
||||
if strings.Contains(src, "Next page") {
|
||||
// Checkout the link for the next page
|
||||
re_next := regexp.MustCompile("<A href=\"(.*?)\"><b>Next page</b></a>")
|
||||
match := re_next.FindStringSubmatch(src)
|
||||
// we have another page full of juicy subdomains
|
||||
if strings.Contains(src, "Next page") {
|
||||
// Checkout the link for the next page
|
||||
re_next := regexp.MustCompile("<A href=\"(.*?)\"><b>Next page</b></a>")
|
||||
match := re_next.FindStringSubmatch(src)
|
||||
|
||||
// Replace spaces with + characters in URL Query since they don't allow request to happen
|
||||
finalQuery := strings.Replace(match[1], " ", "+", -1)
|
||||
enumerate(state, "https://searchdns.netcraft.com"+finalQuery)
|
||||
}
|
||||
|
||||
// Finally, all subdomains found :-)
|
||||
return nil
|
||||
// Replace spaces with + characters in URL Query since they don't allow request to happen
|
||||
finalQuery := strings.Replace(match[1], " ", "+", -1)
|
||||
enumerate(state, "https://searchdns.netcraft.com"+finalQuery)
|
||||
}
|
||||
|
||||
// Finally, all subdomains found :-)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
||||
var result helper.Result
|
||||
|
||||
|
||||
// Initialize global cookie holder
|
||||
gCookies = nil
|
||||
|
||||
|
@ -117,7 +117,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
return
|
||||
}
|
||||
|
||||
result.Subdomains = globalSubdomains
|
||||
result.Subdomains = globalSubdomains
|
||||
result.Error = nil
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,17 +9,17 @@
|
|||
package passivetotal
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
type passivetotal_object struct {
|
||||
Subdomains []string `json:"subdomains"`
|
||||
Subdomains []string `json:"subdomains"`
|
||||
}
|
||||
|
||||
var passivetotal_data passivetotal_object
|
||||
|
@ -34,23 +34,23 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
// We have recieved an API Key
|
||||
// Now, we will use passiveTotal API key to fetch subdomain info
|
||||
if state.ConfigState.PassivetotalUsername != "" && state.ConfigState.PassivetotalKey != "" {
|
||||
if state.ConfigState.PassivetotalUsername != "" && state.ConfigState.PassivetotalKey != "" {
|
||||
|
||||
// Get credentials for performing HTTP Basic Auth
|
||||
username := state.ConfigState.PassivetotalUsername
|
||||
key := state.ConfigState.PassivetotalKey
|
||||
|
||||
// Create JSON Get body
|
||||
var request = []byte(`{"query":"`+state.Domain+`"}`)
|
||||
var request = []byte(`{"query":"` + state.Domain + `"}`)
|
||||
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", "https://api.passivetotal.org/v2/enrichment/subdomains", bytes.NewBuffer(request))
|
||||
req.SetBasicAuth(username, key)
|
||||
req, err := http.NewRequest("GET", "https://api.passivetotal.org/v2/enrichment/subdomains", bytes.NewBuffer(request))
|
||||
req.SetBasicAuth(username, key)
|
||||
|
||||
// Set content type as application/json
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
// Set content type as application/json
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
result.Subdomains = subdomains
|
||||
result.Error = err
|
||||
|
@ -78,7 +78,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
// Append each subdomain found to subdomains array
|
||||
for _, subdomain := range passivetotal_data.Subdomains {
|
||||
finalSubdomain := subdomain+"."+state.Domain
|
||||
finalSubdomain := subdomain + "." + state.Domain
|
||||
|
||||
if state.Verbose == true {
|
||||
if state.Color == true {
|
||||
|
@ -93,7 +93,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
return
|
||||
} else {
|
||||
result.Subdomains = subdomains
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,15 +9,15 @@
|
|||
package ptrarchive
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
@ -33,7 +33,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
return
|
||||
}
|
||||
|
||||
// Get the response body
|
||||
// Get the response body
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
|
@ -46,12 +46,12 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
// Parse Subdomains found
|
||||
Regex, _ := regexp.Compile("] (.*) \\[")
|
||||
match := Regex.FindAllStringSubmatch(src, -1)
|
||||
|
||||
// String to hold initial subdomains
|
||||
var initialSubs []string
|
||||
|
||||
for _, data := range match {
|
||||
initialSubs = append(initialSubs, data[1])
|
||||
// String to hold initial subdomains
|
||||
var initialSubs []string
|
||||
|
||||
for _, data := range match {
|
||||
initialSubs = append(initialSubs, data[1])
|
||||
}
|
||||
|
||||
validSubdomains := helper.Validate(state, initialSubs)
|
||||
|
@ -66,10 +66,9 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
}
|
||||
|
||||
subdomains = append(subdomains, subdomain)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result.Subdomains = subdomains
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,16 +9,16 @@
|
|||
package securitytrails
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
type securitytrails_object struct {
|
||||
Subdomains []string `json:"subdomains"`
|
||||
Subdomains []string `json:"subdomains"`
|
||||
}
|
||||
|
||||
var securitytrails_data securitytrails_object
|
||||
|
@ -38,11 +38,11 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
securitytrailsKey := state.ConfigState.SecurityTrailsKey
|
||||
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", "https://api.securitytrails.com/v1/domain/"+state.Domain+"/subdomains", nil)
|
||||
req, err := http.NewRequest("GET", "https://api.securitytrails.com/v1/domain/"+state.Domain+"/subdomains", nil)
|
||||
|
||||
req.Header.Add("APIKEY", securitytrailsKey)
|
||||
req.Header.Add("APIKEY", securitytrailsKey)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
result.Subdomains = subdomains
|
||||
result.Error = err
|
||||
|
@ -70,7 +70,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
// Append each subdomain found to subdomains array
|
||||
for _, subdomain := range securitytrails_data.Subdomains {
|
||||
finalSubdomain := subdomain+"."+state.Domain
|
||||
finalSubdomain := subdomain + "." + state.Domain
|
||||
|
||||
if state.Verbose == true {
|
||||
if state.Color == true {
|
||||
|
@ -85,7 +85,7 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
return
|
||||
} else {
|
||||
result.Subdomains = subdomains
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
@ -9,31 +9,31 @@
|
|||
package threatcrowd
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
// Struct containing json data we actually need
|
||||
type threatcrowd_object struct {
|
||||
Subdomains []string `json:"subdomains"`
|
||||
Subdomains []string `json:"subdomains"`
|
||||
}
|
||||
|
||||
// array of all results returned
|
||||
var threatcrowd_data threatcrowd_object
|
||||
|
||||
// all subdomains found
|
||||
var subdomains []string
|
||||
var subdomains []string
|
||||
|
||||
// Query function returns all subdomains found using the service.
|
||||
func Query(state *helper.State, ch chan helper.Result) {
|
||||
|
||||
var result helper.Result
|
||||
result.Subdomains = subdomains
|
||||
|
||||
|
||||
// Make a http request to Threatcrowd
|
||||
resp, err := helper.GetHTTPResponse("https://www.threatcrowd.org/searchApi/v2/domain/report/?domain="+state.Domain, state.Timeout)
|
||||
if err != nil {
|
||||
|
@ -75,9 +75,9 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
}
|
||||
|
||||
subdomains = append(subdomains, subdomain)
|
||||
}
|
||||
}
|
||||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
ch <- result
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//
|
||||
// Written By : @ice3man (Nizamul Rana)
|
||||
//
|
||||
//
|
||||
// Distributed Under MIT License
|
||||
// Copyrights (C) 2018 Ice3man
|
||||
//
|
||||
|
||||
// NOTE : We are using Virustotal API here Since we wanted to eliminate the
|
||||
// NOTE : We are using Virustotal API here Since we wanted to eliminate the
|
||||
// rate limiting performed by Virustotal on scraping.
|
||||
// Direct queries and parsing can be also done :-)
|
||||
|
||||
|
@ -13,21 +13,20 @@
|
|||
package virustotal
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
)
|
||||
|
||||
type virustotalapi_object struct {
|
||||
Subdomains []string `json:"subdomains"`
|
||||
Subdomains []string `json:"subdomains"`
|
||||
}
|
||||
|
||||
var virustotalapi_data virustotalapi_object
|
||||
|
||||
|
||||
// Local function to query virustotal API
|
||||
// Requires an API key
|
||||
func queryVirustotalApi(state *helper.State) (subdomains []string, err error) {
|
||||
|
@ -67,7 +66,7 @@ func queryVirustotalApi(state *helper.State) (subdomains []string, err error) {
|
|||
}
|
||||
|
||||
subdomains = append(subdomains, subdomain)
|
||||
}
|
||||
}
|
||||
|
||||
return subdomains, nil
|
||||
}
|
||||
|
@ -103,8 +102,8 @@ func Query(state *helper.State, ch chan helper.Result) {
|
|||
|
||||
result.Subdomains = subdomains
|
||||
result.Error = nil
|
||||
ch <-result
|
||||
return
|
||||
ch <- result
|
||||
return
|
||||
} else {
|
||||
var subdomains []string
|
||||
//subdomains, err := queryVirustotal(state)
|
||||
|
|
31
main.go
31
main.go
|
@ -9,17 +9,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/ice3man543/subfinder/libsubfinder/engines/passive"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/helper"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/output"
|
||||
"github.com/ice3man543/subfinder/libsubfinder/engines/passive"
|
||||
//"github.com/ice3man543/subfinder/libsubfinder/engines/bruteforce"
|
||||
)
|
||||
|
||||
|
||||
var banner = `
|
||||
__ ___ __ __
|
||||
.-----.--.--| |--.' _|__.-----.--| .-----.----.
|
||||
|
@ -43,9 +42,10 @@ func ParseCmdLine() (state *helper.State, err error) {
|
|||
flag.StringVar(&s.Output, "o", "", "Name of the output file (optional)")
|
||||
flag.BoolVar(&s.IsJSON, "oJ", false, "Write output in JSON Format")
|
||||
flag.BoolVar(&s.Alive, "nw", false, "Remove Wildcard Subdomains from output")
|
||||
flag.BoolVar(&s.Silent, "silent", false, "Show only subdomains in output")
|
||||
flag.BoolVar(&s.Recursive, "r", true, "Use recursion to find subdomains")
|
||||
flag.StringVar(&s.Wordlist, "w", "", "Wordlist for doing subdomain bruteforcing")
|
||||
flag.StringVar(&s.Sources, "sr", "all", "Comma separated list of sources to use")
|
||||
flag.StringVar(&s.Sources, "sources", "all", "Comma separated list of sources to use")
|
||||
flag.BoolVar(&s.Bruteforce, "b", false, "Use bruteforcing to find subdomains")
|
||||
flag.BoolVar(&s.WildcardForced, "fw", false, "Force Bruteforcing of Wildcard DNS")
|
||||
|
||||
|
@ -54,21 +54,24 @@ func ParseCmdLine() (state *helper.State, err error) {
|
|||
return &s, nil
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println(banner)
|
||||
fmt.Printf("\nSubFinder v0.1.0 Made with %s❤%s by @Ice3man", helper.Green, helper.Reset)
|
||||
fmt.Printf("\n==================================================")
|
||||
|
||||
state, err := ParseCmdLine()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if state.Silent != true {
|
||||
fmt.Println(banner)
|
||||
fmt.Printf("\nSubFinder v0.1.0 Made with %s❤%s by @Ice3man", helper.Green, helper.Reset)
|
||||
fmt.Printf("\n==================================================")
|
||||
}
|
||||
|
||||
if state.Domain == "" {
|
||||
fmt.Printf("\n\nsubfinder: Missing domain argument\nTry './subfinder -h' for more information\n")
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n\nsubfinder: Missing domain argument\nTry './subfinder -h' for more information\n")
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
@ -76,9 +79,13 @@ func main() {
|
|||
if state.Output != "" {
|
||||
err := output.WriteOutputText(state, passiveSubdomains)
|
||||
if err != nil {
|
||||
fmt.Printf("\nerror : %v", err)
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\nerror : %v", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("\n[#] Successfully Written Output to File : %s\n", state.Output)
|
||||
if state.Silent != true {
|
||||
fmt.Printf("\n[#] Successfully Written Output to File : %s\n", state.Output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue