Skip to content

ahadx-12/pphunter

Repository files navigation

PPHunter — Prototype Pollution Intelligence Scanner

Client-side + Server-side + Gadget-aware + WAF-evasive + DoS + Sustained Assault

PPHunter is a professional security research tool that finds, confirms, and weaponizes prototype pollution vulnerabilities across the full stack — from client-side JavaScript heap pollution to server-side Node.js/PHP/Python injection, through gadget chains, sanitizer bypasses, and (when authorized) sustained denial-of-service.


Installation

pip install -r requirements.txt --break-system-packages
playwright install chromium

Requires Python 3.10+ and ANTHROPIC_API_KEY set in environment for AI analysis features.


Quick Start

Full Scan (all modules)

python -m pphunter "https://target.example.com/"

Runs: crawl → WAF fingerprint → library detection → CSPP → SSPP → CORS → JWT → DOM-XSS → gadget matching → PoC synthesis → AI analysis → HTML/MD/JSON report.

Targeted Scan

python -m pphunter "https://target.example.com/" --modules cspp

Modules: cspp, sspp, gadgets, xss, poc, or all (default).

DoS Module (requires explicit authorization)

python -m pphunter "https://target.example.com/" --dos

Actively exploits prototype pollution to cause denial-of-service conditions against discovered endpoints.

Sustained Crash Test (requires explicit authorization)

python -m pphunter "https://target.example.com/" --sustain --sustain-workers 10 --sustain-duration 60

Auto-detects backend, runs escalating assault phases until server is crashed or sustained DoS is achieved. See Sustained Assault Mode for full details.

Smoke Scan (passive, no injection)

python -m pphunter "https://target.example.com/" --smoke

Command Reference

Flag Description
target Target URL (positional, required for scan mode)
--scope Allowed hosts/CIDRs. Inferred from target's registered domain if omitted
--modules cspp, sspp, gadgets, xss, poc, or all (default)
--output Output base path (default: ./pphunter_report_TIMESTAMP)
--format json, md, html, or all (default)
--timeout Navigation timeout in ms (default: 30000)
--rate Requests per second for rate limiting (default: 2.0, min: 0.1)
--stealth Stealth mode: 0.5 rps, jitter, UA rotation, browser-like headers
--smoke Passive checks only — no injection, no payloads sent
--wayback Query Wayback Machine for historical endpoints
--graphql Enable GraphQL schema reconstruction (auto-runs when GraphQL detected)
--oob Enable OOB DNS callback via local mock (for --oob-server production, see below)
--oob-server Interactsh server URL for production OOB (e.g. https://oast.pro)
--oob-token Interactsh authentication token
--auth Auth mode: cookie, bearer, or form
--auth-value Cookie string or Bearer token value
--auth-login-url Login URL for form-based auth
--auth-username-selector CSS selector for username field
--auth-password-selector CSS selector for password field
--auth-submit-selector CSS selector for submit button
--auth-username Username for form auth
--auth-password Password for form auth
--dos Run DoS exploitation module (stress testing — explicit authorization required)
--sustain Run full sustained crash assault (explicit authorization required)
--sustain-workers Parallel workers for Phase 2+ (default: 10)
--sustain-duration Duration in seconds for assault phases (default: 30)
--analyze Enable AI interpretation via Claude (requires ANTHROPIC_API_KEY)
--session-id Save/resume scan session by ID
--list-sessions List all saved sessions
--delete-session Delete a saved session
--no-bundle Disable disclosure ZIP bundling
--diff Compare two scan reports

What PPHunter Does (Full Pipeline)

PPHunter runs in four stages across six independent capability areas:

graph TD
    classDef stage fill:#2e3440,stroke:#88c0d0,stroke-width:2px,color:#eceff4,border-radius:5px;
    classDef module fill:#3b4252,stroke:#5e81ac,stroke-width:1px,color:#d8dee9;

    subgraph Stage1[Stage 1: Reconnaissance]
        C[Crawler]:::module
        W[WAF Fingerprinting]:::module
        L[Library Intel]:::module
    end
    
    subgraph Stage2[Stage 2: Detection]
        CSPP[Client-Side PP & XSS]:::module
        SSPP[Server-Side PP]:::module
    end
    
    subgraph Stage3[Stage 3: Confirmation]
        GM[Gadget Matching]:::module
        OOB[OOB Callback]:::module
    end
    
    subgraph Stage4[Stage 4: Reporting]
        PoC[PoC Synthesis]:::module
        AI[AI Interpretation]:::module
    end

    Stage1 --> Stage2
    Stage2 --> Stage3
    Stage3 --> Stage4
    
    class Stage1,Stage2,Stage3,Stage4 stage;
Loading

Stage 1 — Reconnaissance

Crawler (crawler.py)

  • Headless Chromium (Playwright) crawls the target, collecting: all URLs, JSON endpoints, JavaScript files, URL parameters, form inputs, and postMessage listeners.
  • Establishes a prototype pollution baseline by snapshotting Object.prototype keys before any payload is injected.

WAF Fingerprinting (waf_fingerprinter.py)

  • Analyzes HTTP response headers and body to identify the WAF vendor: Cloudflare, AWS WAF, Azure WAF, Google Cloud Armor, ModSecurity, Imperva, Akamai, or F5 BIG-IP.
  • Fingerprints the backend framework: Express, Flask, Laravel, FastAPI, Spring Boot, Django, Rails, Gin.
  • Probes content-type acceptance (JSON, multipart, XML, form-urlencoded, plain text).
  • Sets recommended_bypass_category per WAF vendor — guides the bypass engine's mutation strategy ranking.

Library Intelligence (libintel.py)

  • Matches detected JavaScript libraries against an embedded CVE database covering 40+ libraries (jQuery, lodash, Handlebars, React, Moment.js, Chart.js, Vue, and more).
  • Returns: CVE ID, severity (critical/high/medium/low), vulnerability class (XSS, PROTOTYPE_POLLUTION, RCE, REDOS, SSRF, AUTH_BYPASS), and description.
  • Also detects sanitizer libraries (DOMPurify, sanitize-html) for sanitizer bypass analysis.

Endpoint Classification (endpoint_classifier.py)

  • Classifies every discovered endpoint as: JSON API, HTML page, or static asset.
  • Identifies sensitive endpoints (auth, admin, payment, API) regardless of content type.
  • Extracts top-level JSON keys so SSPP detection knows exactly what response fields to probe.

GraphQL Schema Reconstruction (graphql_recon.py)

  • Auto-runs when GraphQL is detected. Introspects the full schema, enumerates all queries/mutations/subscriptions, and identifies high-value operations for targeted testing.

CORS Misconfiguration Scan (cors_scanner.py)

  • Tests all discovered JSON endpoints against foreign origins (evil.com, attacker.example.com, null).
  • Detects: unrestricted Access-Control-Allow-Origin, credentials + wildcard origin, missing Access-Control-Allow-Methods restrictions.

JWT Analysis (jwt_analyzer.py)

  • Extracts JWT tokens from responses, cookies, and localStorage.
  • Decodes and analyzes algorithm (none, HS256, RS256, etc.), expiry, and payload contents.
  • Detects: algorithm confusion attacks, missing expiry, weak symmetric keys, and token leakage patterns.

WebSocket Surface Detection (websocket_surface.py)

  • Detects WebSocket connections in JavaScript code and tests them for prototype pollution via WS frame injection.

Stage 2 — Detection

Client-Side Prototype Pollution (cspp_detector.py)

  • Uses headless Chromium. Takes a heap baseline snapshot of Object.prototype, injects payloads through URL hash parameters and postMessage, then takes a second heap snapshot.
  • Uses heap diffing — any new key appearing in Object.prototype after injection = confirmed CSPP.
  • Tests 4 payload tiers:
    • Tier 1 (canonical): __proto__[key]=value, constructor[prototype][key]=value
    • Tier 2 (encoded): URL-encoded variants, parameter pollution combos
    • Tier 3 (JSON): {"__proto__": {"key": value}}
    • Tier 4 (depth): __proto__.__proto__[key]=value

Server-Side Prototype Pollution (sspp_detector.py)

  • Probes JSON API endpoints with three black-box detection techniques — no code execution required:
    • JSON spaces: Injects {"__proto__": {"json spaces": 10}} → if follow-up responses are indented, server is vulnerable (parsers that merge Object.prototype apply the spacing).
    • Charset override: Injects {"__proto__": {"content-type": "application/json; charset=utf-7"}} → if follow-up Content-Type header changes to utf-7, confirmed.
    • Status code override: Injects {"__proto__": {"status": 555}} → if follow-up returns 555, confirmed.
  • All three techniques are non-destructive and include automatic cleanup payloads.
  • WAF bypass is automatic — if any request is blocked (403/406), the WAF Bypass Engine takes over and finds a working structural mutation before retrying.

DOM-Based XSS (dom_xss_detector.py)

  • After CSPP is confirmed and gadgets are matched, tests confirmed gadget chains in a real Chromium DOM context.
  • Uses known sink patterns: innerHTML, outerHTML, document.write, eval, setTimeout, setInterval, location, href, src, formaction.

Stage 3 — Confirmation & Gadgets

Gadget Matching (gadget_matcher.py)

  • Takes confirmed library + version and queries the gadget database (60+ gadgets across jQuery, lodash, Handlebars, Mongoose, Express, etc.).
  • Each gadget has: gadget_id, CVSS score, impact (XSS/RCE/AUTHBYPASS/DOS), payload template, sink function.
  • Matches are ranked by CVSS and passed to the PoC synthesizer.

Sanitizer Bypass Detection (sanitizer_bypass.py)

  • Detects DOMPurify and sanitize-html in JavaScript bundles.
  • Checks detected version against known bypass CVEs (e.g. DOMPurify bypass via xlink:href, style tag mutation).
  • Confirmed bypasses are reported alongside the base CSPP finding.

OOB Callback Confirmation (oob_handler.py)

  • When --oob is set, runs a local mock interactsh server for DNS callbacks.
  • When --oob-server is set, uses a production Interactsh server (oast.pro or self-hosted).
  • Used to confirm RCE viability: if the server-side payload can trigger an OOB DNS lookup to your server, remote code execution is viable (not proof-of-concept RCE — just a viability probe).

Stage 4 — Reporting

PoC Synthesis (poc_synthesizer.py)

  • Generates submission-ready proof-of-concept packages per confirmed gadget chain.
  • Output formats: curl command, fetch call, HTML exploit page, or full automated exploit script.
  • All PoCs are WAF-encoded using the confirmed bypass strategy.
  • Includes CVSS 3.1 vector, severity label, and remediation recommendation.

AI Interpretation (ai_layer.py)

  • When --analyze is set and ANTHROPIC_API_KEY is in the environment, PPHunter sends the full structured report to Claude for natural language interpretation.
  • Output includes: executive summary, critical risks, recommended remediation steps, and chained attack paths.
  • Falls back to [AI analysis unavailable — set ANTHROPIC_API_KEY to enable] if no key is found.

Disclosure Bundling (evidence_bundler.py)

  • Automatically bundles: JSON report, Markdown summary, HTML report, and PoC files into a timestamped ZIP archive.
  • Disabled with --no-bundle.

Report Diffing (diff_scanner.py)

python -m pphunter --diff old_report.json new_report.json

Shows: new/resolved CSPP findings, library version changes (with regression flag), new gadget chains, and delta severity.


WAF Bypass Engine

PPHunter's WAF bypass system is built on WAFFLED (ACSAC 2025) research — 1,207 confirmed bypasses across Cloudflare, AWS WAF, Azure WAF, Google Cloud Armor, and ModSecurity.

How It Works

The bypass engine runs a 4-step pipeline for every blocked request:

sequenceDiagram
    participant P as PPHunter
    participant M as Mutator Engine
    participant W as WAF
    participant B as Target Backend

    P->>W: Initial Injection Probe
    W-->>P: 403 Forbidden / 406 Not Acceptable
    P->>M: Request Bypass Strategy
    Note over M: Generate 12 Structural Mutations
    M-->>P: Ranked Strategies (by WAF Vendor)
    
    loop Bypass Validation Pipeline
        P->>W: Send Mutated Request
        alt Blocked
            W-->>P: 403 / 406
        else Bypassed
            W->>B: Mutated Request Pass-through
            B-->>P: 200 OK / Target Response
            Note over P: Lock in successful strategy
        end
    end
Loading
  1. FingerprintWAFFingerprinter identifies WAF vendor and backend framework (1-3 probe requests).
  2. MutateStructuralMutator generates 12 distinct structural mutations that change how the request is encoded without changing the payload content.
  3. RankBypassSelector orders mutations by likelihood of success against the detected WAF.
  4. ValidateBypassValidator sends mutations live until one produces a non-blocked (non-403/406) response.

The 12 Structural Mutation Strategies

Strategy Technique Best Against
JSON-01 Null byte in JSON key ("__pro\x00to__") Generic WAFs
JSON-02 Duplicate JSON key (WAF uses first, backend uses last) Cloudflare, AWS WAF
JSON-03 Gzip-compressed JSON body ModSecurity
JSON-04 JSON key with Unicode normalization (\u005f = _) Cloudflare
STRUCT-01 Multipart/form-data with JSON inside form field Cloudflare, AWS WAF
STRUCT-02 application/xml content type Azure WAF, Imperva
STRUCT-03 application/x-www-form-urlencoded Akamai
STRUCT-04 Null byte in header name Generic WAFs
STRUCT-05 HTTP method override via _method parameter Generic
STRUCT-06 Phantom Version cookie (PHP/laravel) Cloudflare
STRUCT-07 UTF-7 charset in Content-Type Azure WAF
STRUCT-08 Charset x-user-defined (allows raw bytes) Google Cloud Armor

When PPHunter finds a working strategy, all subsequent requests in that scan session use it automatically — no manual configuration needed.


DoS Module (--dos)

The DoS module actively exploits prototype pollution to create denial-of-service conditions. It requires --dos to be explicitly set and only runs against explicitly authorized targets.

The 10 DoS Techniques

Technique Vector Severity Backend
eval_injection process.exit(1) via eval PP crash Node.js
unhandled_exception Unhandled exception getter chain crash Node.js
reference_error Cascading ReferenceError chain crash Node.js
type_confusion Number used as function call crash Node.js
memory_exhaustion 10MB string injected into prototype memory All
infinite_recursion Self-calling function in prototype crash Node.js
cpu_spin Tight CPU loop in prototype getter degradation Node.js
json_bomb 100K-level deeply nested JSON degradation All
redos Catastrophic regex backtracking injected via PP degradation All
pool_exhaust Slow trickle body holds worker for 120s degradation PHP, Python, Node

All techniques include automatic cleanup payloads (setting the injected key to null). The module reports: severity (crash/degradation/memory/none), response time, whether cleanup failed (sustained=true).

Each technique uses the WAF Bypass Engine — if a request is blocked, PPHunter automatically finds a working bypass and retries before declaring a technique ineffective.


Sustained Assault Mode (--sustain)

The --sustain flag runs the full autonomous crash assault. It auto-detects the backend, runs reconnaissance, tests escalating DoS phases, and verifies whether the server remains down after the attack stops.

WARNING: This mode is for authorized stress testing only. Do not run against targets you do not have explicit written permission to test.

How It Works

stateDiagram-v2
    [*] --> Phase0: Reconnaissance
    
    Phase0 --> Phase1: Fingerprint & Detect
    
    state Phase1 {
        [*] --> SequentialSweep: Send DoS Techniques
    }
    
    Phase1 --> Phase2: Server still up
    
    state Phase2 {
        [*] --> RotatingPool: N workers (Trickle/Chunked)
    }
    
    Phase2 --> Phase3: Server still up
    
    state Phase3 {
        [*] --> EscalatedPool: 2N workers (1.6x waves)
    }
    
    Phase3 --> Phase4: Server still up
    
    state Phase4 {
        [*] --> MultiAssault: All techniques in tight loop
    }
    
    Phase4 --> Verification: Assault complete
    
    Verification --> [*]: Sustained Crash Confirmed
Loading

The sustain orchestrator runs 4 phases:

Phase 0 — Reconnaissance

  • Crawls target, discovers JSON endpoints
  • Fingerprints WAF vendor and backend framework
  • Runs library intelligence and CSPP/SSPP detection
  • Results feed into Phases 1-4

Phase 1 — Sequential Sweep

  • Sends each of the 10 DoS techniques sequentially (3 rounds each)
  • Best technique is selected by severity (crash > degradation > memory)
  • All requests use WAF bypass automatically

Phase 2 — Rotating Pool Exhaustion (if server still up)

  • Sends N slow-trickle requests simultaneously, where N = --sustain-workers (default: 10)
  • Each request holds a worker busy for 120 seconds by streaming 120KB at 1KB/s using true chunked transfer encoding (no Content-Length header — forces Transfer-Encoding: chunked so the server reads chunk-by-chunk and blocks between reads)
  • Wave 2 fires every 60 seconds via fire-and-forget asyncio.create_task() — waves genuinely overlap, keeping the pool perpetually saturated
  • Total duration: waves × rotate_every seconds (e.g., 5 waves × 60s = 300s with default --sustain-duration 30)

Phase 3 — Escalated Pool Exhaustion (if server still up)

  • Same as Phase 2 but with N = --sustain-workers × 2 and waves × 1.6×
  • Brings in fresh worker saturation if Phase 2 degraded but didn't crash

Phase 4 — Combined Multi-Technique Assault (if server still up)

  • N parallel workers (default: 25), each running all effective techniques in a tight loop
  • Runs for --sustain-duration × 2 seconds (default: 60s)
  • Uses a while time.time() < deadline loop so workers genuinely sustain for the full duration

Verification

  • 5 health checks at 2-second intervals after all assault phases end
  • If server returns HTTP 200 on 3+ checks = recovered (temporary degradation)
  • If server fails 3+ checks = sustained crash confirmed

Parameters

Flag Effect
--sustain-workers 10 Phase 2: 10 workers per wave; Phase 3: 20; Phase 4: 25
--sustain-duration 60 Phase 2: 60/60 = 1 wave; Phase 3: 120/60 = 2 waves; Phase 4: 120s

Backend Auto-Detection

PPHunter detects the backend from response headers and error pages:

Backend Signatures Pool Size Default
PHP/Laravel X-Powered-By: PHP, laravel_session cookie 10
Node.js/Express x-powered-by: express, Cannot GET errors 4
Python/Flask server: werkzeug 4
Python/FastAPI server: uvicorn 4
Java/Spring x-application-context header 20

Session Management

# Save a scan session
python -m pphunter "https://target.example.com/" --session-id my_scan_001

# Resume a saved session
python -m pphunter "https://target.example.com/" --session-id my_scan_001

# List all saved sessions
python -m pphunter --list-sessions

# Delete a saved session
python -m pphunter --delete-session my_scan_001

Rate Limiting & Stealth

PPHunter includes a configurable rate limiter (rate_limiter.py):

RateLimitConfig(
    requests_per_second=2.0,   # default
    jitter_ms=200,             # ± random jitter
    stealth_mode=False,        # 0.5 rps, 500-2000ms jitter, UA rotation
    user_agent_rotation=False,
    burst_limit=5,
)

Stealth mode (--stealth):

  • Reduces to 0.5 requests/second
  • Adds 500-2000ms jitter between requests
  • Rotates User-Agent across a curated list of real browser UAs (Chrome/Firefox/Safari/Linux)
  • Injects realistic browser headers: Accept, Accept-Language, Accept-Encoding, Sec-Fetch-*

NoOp limiter — used internally for Phase 0 reconnaissance (smoke scans) where rate limiting is undesirable. Satisfies the same acquire()/release() interface but never sleeps.


Architecture Overview

cli.py                    CLI entry point, argument parsing, run_scan() pipeline
├── crawler.py            Headless Chromium session, URL/JS/endpoint discovery
├── waf_fingerprinter.py  WAF vendor + backend framework fingerprinting
├── js_analyzer.py        Library detection (regex, CDN headers, package.json)
├── libintel.py           CVE database for 40+ libraries (XSS, PP, RCE, DoS)
├── input_surface.py      Attack surface: URL params, forms, postMessage
├── dom_sink_scanner.py   DOM sink patterns in JavaScript source
├── property_access_hooker.py  Runtime prototype property access tracking
├── cspp_detector.py      Client-side PP via heap diff (Playwright)
├── sspp_detector.py      Server-side PP via black-box response diff
│   └── waf_bypass_engine.py   Auto-bypass when requests are blocked
│       ├── waf_fingerprinter.py
│       ├── structural_mutator.py  12 bypass strategies
│       ├── bypass_selector.py    WAF-aware ranking
│       └── bypass_validator.py   Live validation
├── dom_xss_detector.py   DOM XSS via confirmed gadget chains
├── sanitizer_bypass.py   DOMPurify / sanitize-html bypass CVE detection
├── gadget_matcher.py     Gadget database (60+ chains), version matching
├── gadget_confirmer.py   Confirms gadget + CSPP + sink chain in browser
├── poc_synthesizer.py    WAF-encoded PoC generation (curl/fetch/HTML/script)
├── cors_scanner.py       CORS misconfiguration detection
├── jwt_analyzer.py       JWT algorithm analysis, token extraction
├── graphql_recon.py       GraphQL schema introspection + operation enum
├── websocket_surface.py   WebSocket PP detection
├── oob_handler.py        Local mock Interactsh + production OOB integration
├── waf_encoder.py        WAF-safe payload encoding (base64, URL, XML variants)
├── dos.py                10 DoS exploitation techniques
├── sustain.py             Unified sustain orchestrator (4-phase assault)
├── ai_layer.py            Claude-powered report interpretation
├── reporter.py            Structured findings → report dict
├── report_formats.py      JSON / Markdown / HTML formatters
├── evidence_bundler.py    Disclosure ZIP bundler
├── session_store.py       Save/resume scan sessions
├── diff_scanner.py        Compare two scan reports
└── tests/                 349 unit + integration tests

Testing

# Run all tests
pytest tests/ -x -q

# Run with verbose output
pytest tests/ -v --asyncio-mode=auto

# Run integration tests (against lab targets)
pytest integration_tests/ -v

# Validate gadget database
python scripts/validate_gadget_db.py

Lab Targets (for Testing)

PPHunter ships with a test lab (lab/app.py) containing vulnerable endpoints for integration testing:

# Start the lab
python -m pphunter.lab.app

# Run integration tests against the lab
pytest integration_tests/ -v

The lab includes: SSPP-vulnerable JSON endpoints, CSPP-vulnerable JavaScript, GraphQL endpoint, CORS-misconfigured endpoint, JWT endpoint, and a DoS-vulnerable WooCommerce-style AJAX endpoint.


Environment Variables

Variable Purpose
ANTHROPIC_API_KEY Enables AI-powered report interpretation (--analyze)
HTTP_PROXY / HTTPS_PROXY Proxy all HTTP/HTTPS traffic through a proxy
INTERACTSH_TOKEN Auth token for production OOB (--oob-server)

Output Files

A full scan produces:

File Description
pphunter_report_TIMESTAMP.json Full structured findings in JSON
pphunter_report_TIMESTAMP.md Human-readable Markdown report
pphunter_report_TIMESTAMP.html Styled HTML report with severity indicators
pphunter_disclosure_TIMESTAMP.zip Bundled ZIP containing all of the above + PoC files

Ethical Notice

PPHunter is a professional security research tool. Its DoS and sustained assault features must only be used against:

ANYONE YOU WISH TO USE IT ON :)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages