techdetect

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: MIT Imports: 23 Imported by: 0

README ΒΆ

TechDetect

A enhanced web technology detection engine inspired by ProjectDiscovery's wappalyzergo, featuring improved fingerprint organization, MongoDB-style query evaluation, and browser-based detection capabilities.

Key Features

  • 🎯 Dual-Stage Detection: HTTP-based (fast) + Browser-based (accurate) detection
  • πŸ–ΌοΈ Favicon Hash Detection: Shodan mmh3 and OWASP/WhatWeb MD5 hashes of /favicon.ico and HTML icon links
  • πŸ“ Organized Fingerprints: Technologies categorized into separate files for easier management
  • πŸ“¦ Embedded Fingerprints: All fingerprints bundled into binary - no external dependencies needed
  • πŸ” MongoDB-Style Queries: Advanced query evaluation with 9 operators ($or, $and, $not, $nor, $regex, $eq, $ne, $exists, $in, $nin) for precise detection and reduced false positives
  • 🌐 Browser Detection: Chromedp integration for JavaScript execution and accurate version extraction (e.g., Next.js, React)
  • πŸ”„ Smart Redirect Handling: Follows same-domain redirects with data accumulation
  • πŸš€ Pipeline-Friendly: Clean JSON/JSONL output for seamless integration with other tools
  • 🌐 Proxy Support: HTTP and SOCKS5 proxies with authentication
  • πŸ”’ SSL Options: Skip verification for self-signed certificates

Installation

Download the pre-built binary from releases. All fingerprints are embedded - no additional files needed!

# Just run it
./techdetect https://example.com
Option 2: Build from Source
git clone <repository-url>
cd wappalyzergo_extra
go mod tidy
go build -o techdetect ./cmd/techdetect

Quick Start

# Basic HTTP detection
./techdetect https://example.com

# With browser detection
./techdetect -browser https://example.com

# JSON output
./techdetect -format json https://example.com

# JSONL output (streaming)
./techdetect -format jsonl https://example.com

# Skip SSL verification
./techdetect -insecure true https://self-signed.example.com

# Using HTTP proxy
./techdetect -proxy http://proxy.example.com:8080 https://example.com

# Using HTTP proxy with authentication
./techdetect -proxy http://user:pass@proxy.example.com:8080 https://example.com

# Using SOCKS5 proxy
./techdetect -proxy socks5://proxy.example.com:1080 https://example.com

# Using SOCKS5 proxy with authentication
./techdetect -proxy socks5://user:pass@proxy.example.com:1080 https://example.com

# Pipe input from other tools
cat urls.txt | ./techdetect -format jsonl
echo https://example.com | ./techdetect -format json

Output Formats

Text (Human-Readable)
πŸ” https://nextjs.org - Detected 11 technologies:

  βœ“ Turbopack
  βœ“ Next.js (v16.2.0-canary.19)
  βœ“ Framer Motion
  βœ“ Webpack
  βœ“ HSTS
  βœ“ Next.js App Router
  βœ“ Vercel Speed Insights
  βœ“ Node.js
  βœ“ Vercel
  βœ“ React
  βœ“ Vercel Analytics
JSON (Batch)
{
  "results": [
    {
      "url": "https://example.com",
      "technologies": {
        "React": "18.2.0",
        "Next.js": "13.4.0"
      },
      "mode": "http"
    }
  ]
}
JSONL (Streaming)
{"url":"https://example.com","technologies":{"React":"18.2.0"},"mode":"http"}
{"url":"https://another.com","technologies":{"Vue.js":"3.0"},"mode":"http"}

Command-Line Options

Flag Description Default
-url Target URL to analyze -
-format Output format: text, json, or jsonl text
-browser Enable browser detection (slower but more accurate) false
-insecure Skip SSL certificate verification false
-fingerprints Path to fingerprints directory ./data/fingerprints
-proxy Proxy URL (http://[user:pass@]host:port or socks5://[user:pass@]host:port) -

Integration with ProjectDiscovery Tools

# Subdomain discovery β†’ Tech detection
subfinder -d target.com | httpx -silent | ./techdetect -format jsonl

# Port scanning β†’ Tech detection
echo target.com | naabu -silent | ./techdetect -format jsonl

# URL probing β†’ Tech detection
cat urls.txt | httpx -silent | ./techdetect -format jsonl -browser

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       Technology Detection Engine        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  HTTP Detector  β”‚    β”‚ Browser Detectorβ”‚
β”‚                 β”‚    β”‚                 β”‚
β”‚ β€’ Path classify β”‚    β”‚ β€’ Chromedp      β”‚
β”‚ β€’ Favicon hash  β”‚    β”‚ β€’ JS execution  β”‚
β”‚ β€’ Retry logic   β”‚    β”‚ β€’ Version       β”‚
β”‚ β€’ Query eval    β”‚    β”‚   extraction    β”‚
β”‚ β€’ Redirects     β”‚    β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                      β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚   Query Evaluator    β”‚
         β”‚                      β”‚
         β”‚ MongoDB-Style:       β”‚
         β”‚ $or, $and, $not,     β”‚
         β”‚ $nor, $regex, $eq,   β”‚
         β”‚ $ne, $exists, $in,   β”‚
         β”‚ $nin                 β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Fingerprint Structure

Fingerprints are organized by technology category in data/fingerprints/:

data/
β”œβ”€β”€ categories.json
└── fingerprints/
    β”œβ”€β”€ 001-cms.json
    β”œβ”€β”€ 012-javascript-frameworks.json
    β”œβ”€β”€ 035-maps.json
    └── ...

Each fingerprint supports MongoDB-style queries for precise detection:

{
  "apps": {
    "WordPress": {
      "cats": [1, 11],
      "implies": ["MySQL", "PHP"],
      "paths": [
        {
          "path": "/",
          "detect": {
            "$or": [
              {"body": {"$regex": "/wp-content/"}},
              {"headers.x-pingback": {"$regex": "/xmlrpc\\.php$"}}
            ]
          },
          "extract_version": [
            {"body": "<meta[^>]+WordPress\\s+([\\d.]+)"}
          ]
        }
      ],
      "browser": [
        {
          "path": "/",
          "detection": "return typeof wp !== 'undefined';",
          "version": "try { return String(wp.version || ''); } catch(e){ return ''; }"
        }
      ]
    }
  }
}

Detection Operators

Logical Operators
  • $or - Match ANY condition
  • $and - Match ALL conditions
  • $not - Negate condition
  • $nor - Match NONE
Comparison Operators
  • $regex - Regular expression match (supports version extraction)
  • $eq - Exact equality
  • $ne - Not equal
  • $exists - Field existence check
  • $in - Value in array
  • $nin - Value NOT in array

See SCHEMA_GUIDE.md for detailed documentation.

Advanced Features

Smart Redirect Detection
  • Follows same-domain redirects (max 3)
  • Accumulates bodies and headers from all redirect steps
  • Performs technology detection at each redirect
Fatal Error Detection
  • Stops immediately on fatal network errors (no such host, network unreachable)
  • Avoids wasting time on unreachable domains
Browser Detection
  • Executes JavaScript to detect client-side technologies
  • Extracts accurate version information
  • Conditional execution based on HTTP detection results

Performance

  • HTTP Detection: < 2s for 10 paths
  • Browser Detection: < 5s per page
  • Memory Usage: < 100MB for 100 technologies

Project Structure

.
β”œβ”€β”€ cmd/
β”‚   └── techdetect/
β”‚       └── main.go              # CLI application
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ categories.json          # Technology categories
β”‚   └── fingerprints/
β”‚       └── *.json               # Organized fingerprint files
β”œβ”€β”€ browser_detector.go          # Browser-based detection (Chromedp)
β”œβ”€β”€ detector.go                  # Main detector orchestration
β”œβ”€β”€ favicon.go                   # Favicon mmh3 and MD5 hash detection
β”œβ”€β”€ http_detector.go             # HTTP-based detection
β”œβ”€β”€ loader.go                    # Fingerprint loader
β”œβ”€β”€ query.go                     # MongoDB-style query evaluator
β”œβ”€β”€ types.go                     # Core data structures
β”œβ”€β”€ go.mod
└── README.md

Credits

This project is inspired by and uses fingerprint data converted from ProjectDiscovery's wappalyzergo.

Key Enhancements:

  • Reorganized fingerprints into categorized files for better maintainability
  • Implemented MongoDB-style query evaluation for more accurate detection
  • Added browser detection capabilities with JavaScript execution
  • Enhanced redirect handling and error detection

License

MIT

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

View Source
const (
	MaxRetries     = 1
	RequestTimeout = 10 * time.Second
	MaxRedirects   = 3
	InitialBackoff = 1 * time.Second
)

Variables ΒΆ

This section is empty.

Functions ΒΆ

func ComputeFaviconHash ΒΆ added in v1.0.2

func ComputeFaviconHash(data []byte) int32

ComputeFaviconHash returns the Shodan-compatible MurmurHash3 x86/32 of a favicon: standard base64 with a newline every 76 characters and a trailing newline, then signed mmh3 (seed 0).

func ComputeFaviconMD5 ΒΆ added in v1.0.2

func ComputeFaviconMD5(data []byte) string

ComputeFaviconMD5 returns the hex MD5 of raw favicon bytes (OWASP/WhatWeb style).

func ShouldRunBrowserDetection ΒΆ

func ShouldRunBrowserDetection(techName string, results map[string]*Technology, probe BrowserProbe) bool

ShouldRunBrowserDetection determines if browser detection should run for a technology

Types ΒΆ

type BatchResults ΒΆ

type BatchResults struct {
	Results []ScanResult `json:"results"`
}

BatchResults wraps multiple scan results for JSON array output

type BrowserDetector ΒΆ

type BrowserDetector struct {
	// contains filtered or unexported fields
}

BrowserDetector performs browser-based detection

func NewBrowserDetector ΒΆ

func NewBrowserDetector() *BrowserDetector

NewBrowserDetector creates a new browser detector

func NewBrowserDetectorWithOptions ΒΆ

func NewBrowserDetectorWithOptions(proxyURL string) *BrowserDetector

NewBrowserDetectorWithOptions creates a new browser detector with proxy support

func (*BrowserDetector) DetectBrowser ΒΆ

func (bd *BrowserDetector) DetectBrowser(baseURL string, fingerprints map[string]Fingerprint, httpResults map[string]*Technology) (map[string]*Technology, error)

DetectBrowser performs browser-based detection

type BrowserPathClassification ΒΆ

type BrowserPathClassification struct {
	Path         string
	Technologies map[string][]BrowserProbe // tech name -> probes
}

BrowserPathClassification groups browser probes by path

func ClassifyBrowserByPath ΒΆ

func ClassifyBrowserByPath(fingerprints map[string]Fingerprint) []BrowserPathClassification

ClassifyBrowserByPath groups browser fingerprints by path

type BrowserProbe ΒΆ

type BrowserProbe struct {
	Path      string `json:"path"`
	Detection string `json:"detection,omitempty"`
	Version   string `json:"version,omitempty"`
}

BrowserProbe represents a browser-based detection probe

func (*BrowserProbe) HasDetectionCapability ΒΆ

func (bp *BrowserProbe) HasDetectionCapability() bool

HasDetectionCapability checks if browser probe can detect technology

func (*BrowserProbe) HasVersionCapability ΒΆ

func (bp *BrowserProbe) HasVersionCapability() bool

HasVersionCapability checks if browser probe can extract version

type DetectResult ΒΆ

type DetectResult struct {
	Technologies []Technology `json:"technologies"`
	FailedPaths  []string     `json:"failed_paths,omitempty"`
}

DetectResult contains detection results

type DetectionContext ΒΆ

type DetectionContext struct {
	Body       string
	Headers    map[string]string
	StatusCode int
}

DetectionContext holds data available for detection

type Detector ΒΆ

type Detector struct {
	// contains filtered or unexported fields
}

Detector is the main detection engine

func NewDetector ΒΆ

func NewDetector(fingerprintsDir string) (*Detector, error)

NewDetector creates a new detection engine

func NewDetectorWithOptions ΒΆ

func NewDetectorWithOptions(fingerprintsDir string, insecureSkipVerify bool, proxyURL string) (*Detector, error)

NewDetectorWithOptions creates a new detection engine with custom options

func (*Detector) Detect ΒΆ

func (d *Detector) Detect(url string, useBrowser bool) (*DetectResult, error)

Detect performs full detection (HTTP + Browser) on a target URL

func (*Detector) DetectFull ΒΆ

func (d *Detector) DetectFull(url string) (*DetectResult, error)

DetectFull performs full detection including browser stage

func (*Detector) DetectHTTPOnly ΒΆ

func (d *Detector) DetectHTTPOnly(url string) (*DetectResult, error)

DetectHTTPOnly performs HTTP-only detection (fast, no browser)

type Fingerprint ΒΆ

type Fingerprint struct {
	Cats          []int          `json:"cats"`
	Implies       []string       `json:"implies,omitempty"`
	FaviconHashes []int32        `json:"favicon_hashes,omitempty"`
	FaviconMD5    []string       `json:"favicon_md5,omitempty"`
	Paths         []PathProbe    `json:"paths,omitempty"`
	Browser       []BrowserProbe `json:"browser,omitempty"`
	Description   string         `json:"description,omitempty"`
	Website       string         `json:"website,omitempty"`
	Icon          string         `json:"icon,omitempty"`
	CPE           string         `json:"cpe,omitempty"`
}

Fingerprint represents the detection rules for a technology

type FingerprintDB ΒΆ

type FingerprintDB struct {
	Apps map[string]Fingerprint `json:"apps"`
}

FingerprintDB represents the entire fingerprint database

type HTTPDetector ΒΆ

type HTTPDetector struct {
	// contains filtered or unexported fields
}

HTTPDetector performs HTTP-based detection

func NewHTTPDetector ΒΆ

func NewHTTPDetector() *HTTPDetector

NewHTTPDetector creates a new HTTP detector

func NewHTTPDetectorWithOptions ΒΆ

func NewHTTPDetectorWithOptions(insecureSkipVerify bool, proxyURL string) *HTTPDetector

NewHTTPDetectorWithOptions creates a new HTTP detector with custom options

func (*HTTPDetector) DetectHTTP ΒΆ

func (hd *HTTPDetector) DetectHTTP(baseURL string, fingerprints map[string]Fingerprint) (map[string]*Technology, []string)

DetectHTTP performs HTTP-based detection on a target URL

type Loader ΒΆ

type Loader struct {
	// contains filtered or unexported fields
}

Loader handles loading fingerprints from disk or embedded FS

func NewLoader ΒΆ

func NewLoader(fingerprintsDir string) *Loader

NewLoader creates a new fingerprint loader that uses embedded fingerprints

func (*Loader) LoadAll ΒΆ

func (l *Loader) LoadAll() (map[string]Fingerprint, error)

LoadAll loads all fingerprints from either embedded FS or external directory

type PathClassification ΒΆ

type PathClassification struct {
	Path         string
	RequestConf  *RequestConfig
	Technologies map[string][]PathProbe // tech name -> probes
}

PathClassification groups fingerprints by path

func ClassifyByPath ΒΆ

func ClassifyByPath(fingerprints map[string]Fingerprint) []PathClassification

ClassifyByPath groups all fingerprints by their request paths

type PathProbe ΒΆ

type PathProbe struct {
	Path           string                 `json:"path"`
	Request        *RequestConfig         `json:"request,omitempty"`
	Detect         map[string]interface{} `json:"detect"`
	ExtractVersion []map[string]string    `json:"extract_version,omitempty"`
}

PathProbe represents an HTTP-based detection probe

type QueryEvaluator ΒΆ

type QueryEvaluator struct{}

QueryEvaluator evaluates MongoDB-style queries against a context

func NewQueryEvaluator ΒΆ

func NewQueryEvaluator() *QueryEvaluator

NewQueryEvaluator creates a new query evaluator

func (*QueryEvaluator) Evaluate ΒΆ

func (qe *QueryEvaluator) Evaluate(query map[string]interface{}, ctx *DetectionContext) (bool, string)

Evaluate evaluates a query against the detection context

func (*QueryEvaluator) ExtractVersion ΒΆ

func (qe *QueryEvaluator) ExtractVersion(rules []map[string]string, ctx *DetectionContext) string

ExtractVersion attempts to extract version from context using extraction rules

type RequestConfig ΒΆ

type RequestConfig struct {
	Method  string            `json:"method,omitempty"`
	Headers map[string]string `json:"headers,omitempty"`
	Body    interface{}       `json:"body,omitempty"`
}

RequestConfig represents optional HTTP request configuration

type ScanResult ΒΆ

type ScanResult struct {
	URL          string            `json:"url"`
	Technologies map[string]string `json:"technologies"`    // tech name -> version
	Mode         string            `json:"mode"`            // "http", "browser", or "hybrid"
	Error        string            `json:"error,omitempty"` // error message if scan failed
}

ScanResult represents the result for a single URL in JSON/JSONL format

type Technology ΒΆ

type Technology struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

Technology represents a detected technology

Directories ΒΆ

Path Synopsis
cmd
techdetect command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL