GoGrabber: The Web Recon Tool That Screenshots Without Making Network Requests
Hook
Most screenshot tools hit your target twice—once to discover content, again to capture it. GoGrabber found a way to render screenshots from already-downloaded HTML by hijacking Chromium's network layer, cutting reconnaissance traffic in half.
Context
Modern web reconnaissance follows a predictable pattern: scan ports to find web services, bruteforce directories to discover hidden endpoints, then screenshot everything for manual review. This workflow typically requires chaining three separate tools—something like masscan for port discovery, ffuf for directory enumeration, and gowitness for visual capture. Each handoff introduces friction: converting output formats, managing intermediate files, and orchestrating execution order.
But there's a more insidious problem. Traditional screenshot tools make redundant network requests. When you enumerate /admin/login.php with a directory bruteforcer, you've already downloaded the HTML. Yet when gowitness or Aquatone screenshots that same URL, they fetch it again through headless Chrome. On large engagements with thousands of discovered endpoints, you're effectively doubling your network footprint—increasing detection risk, triggering rate limits, and wasting time. GoGrabber emerged from the penetration testing world to solve both problems: unify the reconnaissance pipeline and eliminate duplicate requests through a clever network interception technique.
Technical Insight
GoGrabber implements a three-stage pipeline architecture where each phase feeds the next through shared data structures. The port scanner generates URLs from discovered services, the directory bruteforcer validates paths against those URLs, and the screenshotter captures visual evidence. All stages use goroutine-based worker pools for concurrency, configurable through command-line flags like -pc for port check workers and -dc for directory check workers.
The real innovation lives in the screenshot phase. Instead of letting headless Chrome make fresh HTTP requests, GoGrabber uses go-rod (a DevTools Protocol library) to hijack the browser's network layer. Here's the conceptual flow:
// Pseudocode based on architecture analysis
func screenshotWithHijacking(url string, htmlContent []byte) error {
browser := rod.New().MustConnect()
page := browser.MustPage()
// Intercept ALL network requests from the browser
router := page.HijackRequests()
router.MustAdd("*", func(ctx *rod.Hijack) {
// Instead of letting Chrome fetch from network,
// serve the HTML we already downloaded
if ctx.Request.URL().String() == url {
ctx.Response.SetBody(htmlContent)
ctx.Response.SetHeader("Content-Type", "text/html")
ctx.MustLoadResponse()
} else {
// Allow other requests (CSS, JS, images) to proceed normally
ctx.MustLoadResponse()
}
})
go router.Run()
page.MustNavigate(url)
page.MustWaitLoad()
page.MustScreenshot("output.png")
return nil
}
This network hijacking eliminates the duplicate HTTP GET that traditional tools make. When the directory bruteforcer discovers /admin/dashboard, it stores both the URL and the response body. The screenshot phase navigates Chrome to that URL, but intercepts the request before it leaves the machine and serves the cached HTML instead. Chrome renders what it receives—visually identical to the original—without your target server ever seeing a second request.
The soft-404 detection mechanism shows similar pragmatism. Many web servers return 200 OK for nonexistent paths, rendering traditional status code filtering useless. GoGrabber addresses this by fetching a canary URL with a random string (like /aHR0cDovL2dvb2dsZS5jb20K), then comparing discovered pages against this baseline using similarity ratios:
// Conceptual soft-404 detection
baselineHTML := fetchRandomURL(target)
baselineFingerprint := computeSimilarityHash(baselineHTML)
for _, discoveredURL := range results {
pageHTML := fetch(discoveredURL)
pageFingerprint := computeSimilarityHash(pageHTML)
similarity := compareFingerprints(baselineFingerprint, pageFingerprint)
if similarity > 0.95 {
// Likely a wildcard response, discard
continue
}
validResults = append(validResults, discoveredURL)
}
If a discovered page is 95% similar to the random URL response, it's probably a custom 404 page and gets filtered out. This probabilistic approach handles environments where admins configure creative error pages without relying on status codes.
The tool's input flexibility deserves attention. The -i flag triggers full pipeline execution (port scan → directory bruteforce → screenshot), suitable when starting from just IP addresses or domains. But you can bypass stages with -U (direct URL list) or -p (specific ports), making it practical to integrate into existing workflows. If you've already run masscan separately and have a port list, GoGrabber won't waste time re-scanning.
Output organization follows a structured approach: a timestamped directory contains screenshots/ with PNG files, results.md with Markdown summaries, and optional JSON/CSV/XML exports. This makes it straightforward to feed results into report generation pipelines or SIEM systems—a critical but often overlooked aspect of reconnaissance tools that developers frequently hack together with jq and awk scripts afterward.
Gotcha
The port scanning capabilities are rudimentary compared to specialized tools. There's no mention of service version detection, OS fingerprinting, or sophisticated timing controls that nmap provides. If you're assessing a hardened environment where you need to fingerprint an SSH version to identify specific vulnerabilities, GoGrabber won't help. The scanner appears focused purely on identifying open ports to generate HTTP/HTTPS URLs—which is sufficient for web reconnaissance but limiting for comprehensive network assessments.
Directory bruteforcing lacks advanced features that dedicated tools offer. There's no recursive scanning (finding /admin/ then automatically bruteforcing /admin/*), no filtering by response size or word count, and no mutation strategies for discovering backups (like testing admin.php.bak when finding admin.php). The tool appears to perform straightforward wordlist enumeration, which works for standard engagements but struggles with complex applications that require adaptive discovery strategies. Documentation is also sparse on error handling specifics—what happens when a target rate-limits you mid-scan, or how the tool behaves if Chrome crashes during screenshot capture. For production-grade reconnaissance workflows, you'd want clearer guarantees about resumability and fault tolerance.
Verdict
Use if: You're conducting bug bounty reconnaissance or penetration testing where you need a streamlined workflow that goes from IP addresses to categorized screenshots without tool-chaining overhead, you're working at scale where reducing network requests matters for stealth or bandwidth constraints, or you value the convenience of unified output formats over specialized features. The network hijacking screenshot technique alone justifies adoption for teams doing high-volume web assessments. Skip if: You need enterprise-grade port scanning with service detection and OS fingerprinting—stick with nmap, you require advanced directory enumeration like recursive scanning or complex filtering rules where ffuf or gobuster excel, you're working in environments with heavy rate limiting where you need fine-grained request timing controls, or you prefer modular tool chains where you can swap components (the ProjectDiscovery suite's httpx + nuclei + katana offers more flexibility despite coordination overhead).