Updated Formatting and Added Silent Switch

master
ice3man 2018-04-17 15:45:36 +05:30
parent 158472f53a
commit 477e349b6f
22 changed files with 379 additions and 326 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,4 +50,4 @@ func (set *StringSet) Stringify() string {
values = append(values, s)
}
return strings.Join(values, ",")
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View File

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