Skip to content

Commit

Permalink
Merge pull request Josue87#4 from PinkDev1/main
Browse files Browse the repository at this point in the history
Introduced "--chain-mode" and some upgrades
  • Loading branch information
Josue87 committed Dec 24, 2021
2 parents c920eed + a396ca4 commit 387844b
Showing 1 changed file with 108 additions and 29 deletions.
137 changes: 108 additions & 29 deletions analyticsrelationships.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ import (
"time"
)

const colorReset = "\033[0m"
const colorYellow = "\033[33m"
const colorRed = "\033[31m"

func crash(message string, err error) {
fmt.Print(string(colorRed) + "[ERROR]: " + message + string(colorReset) + "\n")
panic(err)
}

func warning(message string) {
fmt.Print(string(colorYellow) + "[WARNING]: " + message + string(colorReset) + "\n")
}

func info(message string) {
fmt.Print("[-]: " + message + "\n")
}

func banner() {
data := `
██╗ ██╗ █████╗ ██╗██████╗
Expand All @@ -32,7 +49,7 @@ func banner() {
`
data += "\033[32m> \033[0mGet related domains / subdomains by looking at Google Analytics IDs\n"
data += "\033[32m> \033[0mGO Version\n"
data += "\033[32m> \033[0mBy @JosueEncinar\n"
data += "\033[32m> \033[0mBy @JosueEncinar and Pinkdev1\n"

println(data)
}
Expand Down Expand Up @@ -60,7 +77,7 @@ func getGoogleTagManager(targetURL string) (bool, []string) {
var resultTagManager []string
response := getURLResponse(targetURL)
if response != "" {
pattern := regexp.MustCompile("www\\.googletagmanager\\.com/ns\\.html\\?id=[A-Z0-9\\-]+")
pattern := regexp.MustCompile(`www\.googletagmanager\.com/ns\.html\?id=[A-Z0-9\-]+`)
data := pattern.FindStringSubmatch(response)
if len(data) > 0 {
resultTagManager = append(resultTagManager, "https://"+strings.Replace(data[0], "ns.html", "gtm.js", -1))
Expand All @@ -70,7 +87,7 @@ func getGoogleTagManager(targetURL string) (bool, []string) {
if len(data) > 0 {
resultTagManager = append(resultTagManager, "https://www.googletagmanager.com/gtm.js?id="+data[0])
} else {
pattern = regexp.MustCompile("UA-\\d+-\\d+")
pattern = regexp.MustCompile(`UA-\d+-\d+`)
aux := pattern.FindAllStringSubmatch(response, -1)
var result []string
for _, r := range aux {
Expand Down Expand Up @@ -107,7 +124,7 @@ func cleanRelationShips(domains [][]string) []string {
}

func getDomainsFromBuiltWith(id string) []string {
pattern := regexp.MustCompile("/relationships/[a-z0-9\\-\\_\\.]+\\.[a-z]+")
pattern := regexp.MustCompile(`/relationships/[a-z0-9\-\_\.]+\.[a-z]+`)
url := "https://builtwith.com/relationships/tag/" + id
response := getURLResponse(url)
var allDomains []string = nil
Expand All @@ -130,7 +147,7 @@ func getDomainsFromHackerTarget(id string) []string {
func getDomains(id string) []string {
var allDomains []string = getDomainsFromBuiltWith(id)
domains2 := getDomainsFromHackerTarget(id)
if domains2 != nil {
if len(domains2) != 0 {
for _, domain := range domains2 {
if !contains(allDomains, domain) {
allDomains = append(allDomains, domain)
Expand All @@ -149,59 +166,121 @@ func contains(data []string, value string) bool {
return false
}

func showDomains(ua string) {
fmt.Println(">> " + ua)
func showDomains(ua string, chainMode bool) {
allDomains := getDomains(ua)
if len(allDomains) == 0 {
fmt.Println("|__ NOT FOUND")
}
for _, domain := range allDomains {
fmt.Println("|__ " + domain)
if !chainMode {
fmt.Println(">> " + ua)
if len(allDomains) == 0 {
fmt.Println("|__ NOT FOUND")
}
for _, domain := range allDomains {
fmt.Println("|__ " + domain)
}
fmt.Println("")
} else {
if len(allDomains) == 0 {
warning("NOT FOUND")
}
for _, domain := range allDomains {
if domain == "error getting results" {
var err error
crash("Server-side error on builtwith.com: error getting results", err)
}
fmt.Println(domain)
}
}
fmt.Println("")

}

func start(url string) {
func start(url string, chainMode bool) {
if !strings.HasPrefix(url, "http") {
url = "https://" + url
}
println("[+] Analyzing url: " + url)
if !chainMode {
info("Analyzing url: " + url)
}
uaResult, resultTagManager := getGoogleTagManager(url)
if len(resultTagManager) > 0 {
var visited = []string{}
var allUAs []string
if !uaResult {
urlGoogleTagManager := resultTagManager[0]
println("[+] URL with UA: " + urlGoogleTagManager)
if !chainMode {
info("URL with UA: " + urlGoogleTagManager)
}
allUAs = getUA(urlGoogleTagManager)
} else {
println("[+] Found UA directly")
if !chainMode {
info("Found UA directly")
}
allUAs = resultTagManager
}
println("[+] Obtaining information from builtwith and hackertarget\n")
if !chainMode {
info("Obtaining information from builtwith and hackertarget\n")
}
for _, ua := range allUAs {
baseUA := strings.Join(strings.Split(ua, "-")[0:2], "-")
if !contains(visited, baseUA) {
visited = append(visited, baseUA)
showDomains(baseUA)
showDomains(baseUA, chainMode)
}
}
println("\n[+] Done!")
if !chainMode {
info("Done!")
}
} else {
println("[-] Tagmanager URL not found")
warning("Tagmanager URL not found")
//Now, the program exits
}
}

//needs to be a global variable
var chainMode bool

func main() {
url := flag.String("url", "", "URL to extract Google Analytics ID")
var url string

flag.StringVar(&url, "u", "", "URL to extract Google Analytics ID")
flag.StringVar(&url, "url", "", "URL to extract Google Analytics ID")
flag.BoolVar(&chainMode, "ch", false, "In \"chain-mode\" we only output the important information. No decorations.")
flag.BoolVar(&chainMode, "chain-mode", false, "In \"chain-mode\" we only output the important information. No decorations.")

const usage = `Usage: ./analyticsrelationships -u URL [--chain-mode]
-u, --url string
URL to extract Google Analytics ID
-ch, --chain-mode
In "chain-mode" we only output the important information. No decorations.
Default: false
`

//https://www.antoniojgutierrez.com/posts/2021-05-14-short-and-long-options-in-go-flags-pkg/
flag.Usage = func() { fmt.Print(usage) }
//parse CLI arguments
flag.Parse()
banner()
if *url != "" {
start(*url)
if !chainMode {
//display banner
banner()
}
if url != "" {
//start main processing
start(url, chainMode)
} else {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
start(scanner.Text())
}
//read from standard input (stdin)

stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
//data is being piped to stdin
//read stdin
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
if err := scanner.Err(); err != nil {
crash("bufio couldn't read stdin correctly.", err)
} else {
start(scanner.Text(), chainMode)
}
}

} //else { //stdin is from a terminal }

}
}

0 comments on commit 387844b

Please sign in to comment.