Files
assetfinder/scanner.go

131 lines
2.5 KiB
Go

package assetfinder
import (
"fmt"
"io/ioutil"
"log"
"net/url"
"strings"
)
func Scanner(verboseLogging, checkHTTPS, disableStatusCheck bool, outputFile, domain string) error {
results := []string{}
for _, source := range LoadedSources {
subdomains, err := source.FetchSubDomains(domain)
if err != nil {
continue
}
results = append(results, subdomains...)
}
sortedDomains := sortDomains(results)
ress := []Result{}
if !disableStatusCheck {
for _, r := range sortedDomains {
// http
u, err := url.Parse("http://" + r)
if err != nil {
if verboseLogging {
log.Println(err)
}
continue
}
re := fetchStatus(u.String())
ress = append(ress, re)
if checkHTTPS && re.StatusCode != 0 {
u.Scheme = "https"
re := fetchStatus(u.String())
ress = append(ress, re)
}
}
} else {
ress = convertToResults(results)
}
if outputFile == "" {
for _, r := range ress {
if r.StatusCode == 0 || r.Error != nil {
continue
}
log.Printf("| %d | %s\n", r.StatusCode, r.Domain)
}
return nil
}
return writeFile(outputFile, ress, disableStatusCheck)
}
func writeFile(outputFile string, res []Result, disableStatusCheck bool) error {
resBytes := []byte("domain, status code")
for _, r := range res {
if r.StatusCode == 0 || r.Error != nil {
continue
}
if disableStatusCheck {
resBytes = append(resBytes, []byte(fmt.Sprintf("%s\n", r.Domain))...)
} else {
resBytes = append(resBytes, []byte(fmt.Sprintf("%s, %d\n", r.Domain, r.StatusCode))...)
}
}
err := ioutil.WriteFile(outputFile, resBytes, 0775)
if err != nil {
return err
}
return nil
}
func sortDomains(domains []string) []string {
encountered := map[string]string{}
fixedList := []string{}
for _, d := range domains {
if strings.Contains(d, "\n") {
for _, d := range strings.Split(d, "\n") {
d = cleanDomain(d)
fixedList = append(fixedList, d)
}
} else {
d = cleanDomain(d)
fixedList = append(fixedList, d)
}
}
// dedup
newList := []string{}
for _, d := range fixedList {
_, ok := encountered[d]
if !ok {
encountered[d] = d
newList = append(newList, d)
}
}
return newList
}
func convertToResults(strRes []string) []Result {
ress := []Result{}
for _, r := range strRes {
ress = append(ress, Result{
Domain: r,
})
}
return ress
}
func cleanDomain(d string) string {
d = strings.ToLower(d)
if len(d) < 2 {
return d
}
if d[0] == '*' || d[0] == '%' {
d = d[1:]
}
if d[0] == '.' {
d = d[1:]
}
return d
}