Back to Articles

Finding Hidden Assets Through Google Analytics IDs: A Look at udon

[ View on GitHub ]

Finding Hidden Assets Through Google Analytics IDs: A Look at udon

Hook

Every Google Analytics tracking code you embed in your website becomes a breadcrumb trail connecting all your digital properties. For security researchers, this makes UA-IDs one of the most reliable pivoting points in reconnaissance.

Context

In the world of bug bounty hunting and security research, the hardest part isn't finding vulnerabilities—it's discovering all the assets in scope. Modern organizations sprawl across dozens or hundreds of domains: legacy acquisitions, regional sites, development servers, and forgotten subdomains. Traditional enumeration techniques like DNS brute-forcing or certificate transparency logs help, but they miss a crucial category: logically related domains that share no DNS or certificate infrastructure.

This is where Google Analytics becomes an unexpected reconnaissance goldmine. Organizations typically reuse the same UA-XXXXX tracking ID across their entire web presence for centralized analytics. A corporate site, customer portal, and partner dashboard might share nothing in their technical stack except that single JavaScript snippet. Multiple OSINT services catalog these relationships by crawling the web and indexing analytics IDs, but querying them individually is tedious. udon solves this by aggregating four different OSINT sources (Hackertarget, OSINT.sh, Site-Overview, and SpyOnWeb) into a single command-line tool, transforming what would be manual API calls and spreadsheet correlation into a one-liner that reveals an organization's full digital footprint.

Technical Insight

udon's architecture is deliberately minimal—a single Go binary with no external dependencies beyond the standard library and basic HTTP client functionality. The tool makes concurrent requests to four different OSINT APIs, aggregates their responses, deduplicates results, and outputs either plain text or structured JSON. This simplicity is its strength: you can compile it once and run it anywhere without worrying about Python virtual environments or Node module conflicts.

The core workflow follows a straightforward pattern. You provide a Google Analytics ID in the UA-XXXXX format, and udon fans out requests to each service. Here's what typical usage looks like:

# Basic usage - output discovered domains
./udon -ua UA-123456-1

# JSON output with source attribution
./udon -ua UA-123456-1 -json

# Silent mode for piping to other tools
./udon -ua UA-123456-1 -silent | httpx -title

The JSON output provides valuable source attribution, showing which OSINT services confirmed each domain. When multiple independent sources report the same domain, confidence increases significantly:

[
  {
    "domain": "example.com",
    "sources": ["hackertarget", "spyonweb", "osint.sh"]
  },
  {
    "domain": "blog.example.com",
    "sources": ["spyonweb"]
  }
]

The tool's real power emerges when integrated into reconnaissance pipelines. A common workflow pairs udon with nuclei templates that automatically extract Google Analytics IDs from web pages. First, you crawl your target with a tool like katana or gospider, then run nuclei to extract UA-IDs, and finally feed those IDs to udon:

# Extract GA IDs from a target
echo "https://target.com" | katana -silent | \
  nuclei -t google-analytics-id.yaml -silent | \
  cut -d':' -f2 | sort -u > ua-ids.txt

# Discover related domains for each UA-ID
cat ua-ids.txt | while read ua; do
  echo "[+] Checking $ua"
  ./udon -ua "$ua" -silent
done | sort -u > discovered-assets.txt

This pipeline transforms a single target URL into potentially dozens of related domains in minutes. Each discovered domain becomes a new reconnaissance target, often revealing forgotten staging environments, regional sites, or acquired properties that share the parent organization's analytics infrastructure but nothing else.

From an implementation perspective, the Go concurrency model makes the multi-source aggregation efficient. Each API call runs in its own goroutine, and the tool waits for all responses before deduplicating and formatting output. This parallel execution means you're limited by the slowest API response, not the cumulative time of serial requests. For developers looking to extend udon, adding new OSINT sources is straightforward: implement the HTTP request logic, parse the response format, and add the goroutine to the existing concurrent execution pattern.

The deduplication logic is basic string comparison, which means variations like 'example.com' and 'www.example.com' appear as separate entries. Depending on your use case, this might be intentional—subdomain variations could represent different applications with distinct attack surfaces. However, if you're generating asset counts or feeding results into automation, you'll want to normalize domains with a tool like dnsx before further processing.

Gotcha

udon's most significant limitation is its complete dependence on third-party APIs. You're at the mercy of their uptime, rate limits, and data freshness. If SpyOnWeb is down or rate-limiting your IP, you lose 25% of your potential coverage with no fallback mechanism. The tool has no visible retry logic, exponential backoff, or error handling beyond basic HTTP failures. In high-volume reconnaissance scenarios—say, processing hundreds of UA-IDs from a large organization—you'll quickly hit rate limits and need to implement your own throttling and rotation logic.

The bigger strategic limitation is the sunset of Google Analytics Universal Analytics. As of July 2023, Google stopped processing data for UA properties, pushing organizations toward GA4 with its completely different measurement ID format (G-XXXXXXXXXX instead of UA-XXXXX). While existing UA-IDs remain in website code during transition periods, every site migration to GA4 removes a potential pivot point. Within the next year or two, udon's effectiveness will decline significantly as the web moves away from the tracking ID format it targets. There's no indication the tool supports GA4 measurement IDs, and the OSINT services it queries may not have updated their indexing strategies either.

Another subtle issue: the tool provides no confidence scoring or data freshness indicators. A domain discovered by all four sources from recent crawls is far more reliable than one reported by a single source from a years-old index. Without timestamps or confidence metrics, you can't distinguish between actively used properties and domains that removed the tracking code years ago. This creates noise in reconnaissance workflows and potentially wastes time investigating defunct assets.

Verdict

Use if: You're conducting bug bounty reconnaissance or red team engagements where passive asset discovery is critical, you're targeting organizations still using Universal Analytics (check a few known domains first), you need quick correlation across multiple OSINT sources without manual API juggling, or you're building automated reconnaissance pipelines that can incorporate external data sources. The tool excels in early-stage enumeration when you're mapping out an organization's digital footprint and need to cast a wide net quickly. Skip if: Your targets have fully migrated to GA4 (check their source code for G-XXXXXXXXXX IDs instead of UA-XXXXX), you need real-time or high-volume scanning beyond what free API tiers support, you require confidence scoring or data freshness guarantees for compliance or reporting purposes, or you're working in environments where third-party API dependencies violate operational security constraints. In those cases, invest in paid OSINT platforms with SLAs or build custom scrapers with more control over data sources and rate limiting.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/dhn-udon.svg)](https://starlog.is/api/badge-click/developer-tools/dhn-udon)