Payload Mutation and WAF Evasion

Payload Mutation and WAF Evasion

The following files were used as context for generating this wiki page:

Purpose and Scope

This document describes WSHawk's dynamic payload mutation system and Web Application Firewall (WAF) evasion capabilities. The Smart Payload Evolution (SPE) engine adapts attack vectors in real-time based on server responses, employing genetic algorithms and context-aware generation to bypass defensive controls.

For information about the core vulnerability detection mechanisms that use these payloads, see Vulnerability Detection Overview. For browser-based verification of mutated XSS payloads, see Playwright XSS Verification. For the static payload collections that seed the mutation engine, see Payload Management System.


Architecture Overview

The mutation system consists of three interconnected modules that operate in a feedback loop during scanning:

Title: Smart Payload Evolution Architecture

graph TB
    subgraph "Static Foundation"
        WSPayloads["WSPayloads<br/>(22,000+ base vectors)"]
    end
    
    subgraph "Smart Payload Modules"
        ContextGen["ContextAwareGenerator<br/>wshawk/smart_payloads/<br/>context_generator.py"]
        FeedbackLoop["FeedbackLoop<br/>wshawk/smart_payloads/<br/>feedback_loop.py"]
        Evolver["PayloadEvolver<br/>wshawk/smart_payloads/<br/>payload_evolver.py"]
    end
    
    subgraph "Analysis Modules"
        MessageAnalyzer["MessageAnalyzer<br/>Detects JSON/XML/Protobuf"]
        VulnVerifier["VulnerabilityVerifier<br/>Confidence scoring"]
        ServerFP["ServerFingerprinter<br/>Technology detection"]
    end
    
    subgraph "Scanner Core"
        Scanner["WSHawkV2.run_heuristic_scan()"]
        LearningPhase["learning_phase()<br/>5-10 seconds"]
        HeuristicScan["test_sql_injection_v2()<br/>test_xss_v2()<br/>..."]
        EvolutionPhase["Evolution Phase<br/>lines 637-703"]
    end
    
    subgraph "Server Response Analysis"
        Response["Server Responses<br/>Timing, Patterns, Errors"]
        ResponseSignal["ResponseSignal<br/>INTERESTING/ERROR/<br/>WAF_BLOCKED/TIMEOUT"]
    end
    
    WSPayloads --> HeuristicScan
    
    Scanner --> LearningPhase
    LearningPhase --> MessageAnalyzer
    LearningPhase --> ServerFP
    
    MessageAnalyzer --> ContextGen
    ServerFP --> ContextGen
    
    Scanner --> HeuristicScan
    HeuristicScan --> Response
    Response --> FeedbackLoop
    FeedbackLoop --> ResponseSignal
    
    ResponseSignal -->|"High fitness"| Evolver
    ContextGen --> Evolver
    
    Evolver --> EvolutionPhase
    EvolutionPhase --> Response
    
    Response --> VulnVerifier
    VulnVerifier -->|"Successful"| Evolver

Sources: wshawk/scanner_v2.py:28-30, wshawk/scanner_v2.py:72-75, wshawk/scanner_v2.py:156-164, wshawk/scanner_v2.py:637-703


Smart Payload Evolution Components

ContextAwareGenerator

The ContextAwareGenerator learns the structure and format of WebSocket messages during the learning phase and generates payloads tailored to the detected context.

| Feature | Description | Code Location | |---------|-------------|---------------| | Format Learning | Detects JSON, XML, protobuf, binary message formats | wshawk/smart_payloads/context_generator.py | | Field Mapping | Identifies injectable fields within structured messages | Integrated with MessageAnalyzer | | Type-Specific Generation | Creates payloads matching expected data types (string, int, array) | generate_payloads(category, count) | | Context Storage | Maintains analysis state in self.context dictionary | Updated during learning phase |

Initialization and Usage:

# scanner_v2.py:72
self.context_generator = ContextAwareGenerator()

# scanner_v2.py:159
if self.use_smart_payloads:
    for msg in samples:
        if isinstance(msg, str):
            self.context_generator.learn_from_message(msg)

Sources: wshawk/scanner_v2.py:72, wshawk/scanner_v2.py:156-164


FeedbackLoop

The FeedbackLoop analyzes server responses in real-time to classify payload effectiveness and guide the mutation strategy.

Title: Response Classification Pipeline

graph LR
    Payload["Injected Payload"]
    Send["await ws.send(msg)"]
    Response["Server Response"]
    Timing["Response Time<br/>Measurement"]
    
    Analyze["FeedbackLoop.<br/>analyze_response()"]
    
    Signal["ResponseSignal"]
    
    INTERESTING["INTERESTING<br/>Novel response pattern"]
    ERROR["ERROR<br/>Server error triggered"]
    WAF["WAF_BLOCKED<br/>Generic error message"]
    TIMEOUT["TIMEOUT<br/>Slow response (>2s)"]
    NORMAL["NORMAL<br/>Baseline response"]
    
    Fitness["Fitness Score<br/>0.0 - 1.0"]
    
    Payload --> Send
    Send --> Response
    Send --> Timing
    Response --> Analyze
    Timing --> Analyze
    
    Analyze --> Signal
    
    Signal --> INTERESTING
    Signal --> ERROR
    Signal --> WAF
    Signal --> TIMEOUT
    Signal --> NORMAL
    
    Signal --> Fitness
    
    Fitness -->|">0.7"| PriorityQueue["High Priority<br/>Queue"]
    Fitness -->|"0.3-0.7"| MediumQueue["Medium Priority<br/>Queue"]
    Fitness -->|"<0.3"| Discard["Discard"]

Response Analysis Implementation:

# scanner_v2.py:222-225
if self.use_smart_payloads:
    resp_time = time.monotonic() - start_time if 'start_time' in dir() else 0.1
    signal, sig_conf = self.feedback_loop.analyze_response(
        payload, response, resp_time, category='sqli'
    )

Key Methods:

| Method | Purpose | Returns | |--------|---------|---------| | analyze_response(payload, response, time, category) | Classifies server response | (ResponseSignal, confidence) | | establish_baseline(message, time) | Sets normal response characteristics | None | | get_priority_categories() | Returns categories sorted by success rate | List[(category, priority)] |

Sources: wshawk/scanner_v2.py:222-225, wshawk/scanner_v2.py:669-673, wshawk/smart_payloads/feedback_loop.py


PayloadEvolver

The PayloadEvolver implements a genetic algorithm to breed new payload variants from successful attack vectors.

Title: Genetic Payload Evolution Cycle

graph TB
    subgraph "Generation N"
        Population["Population<br/>100 payloads<br/>self.population"]
        Fitness["Fitness Scores<br/>self.fitness_scores"]
    end
    
    subgraph "Selection Phase"
        Selection["Tournament Selection<br/>Pick top performers"]
        Parents["Parent Payloads<br/>High fitness"]
    end
    
    subgraph "Genetic Operations"
        Crossover["Crossover<br/>Combine payloads"]
        Mutation["Mutation<br/>8+ strategies"]
        
        M1["URL Encoding<br/>%3Cscript%3E"]
        M2["Double Encoding<br/>%253Cscript%253E"]
        M3["Unicode Substitution<br/><script>"]
        M4["Case Variation<br/>ScRiPt"]
        M5["Null Byte Injection<br/><script>%00"]
        M6["Comment Insertion<br/><scr/**/ipt>"]
        M7["Concatenation<br/>'+'script'"]
        M8["Protocol Obfuscation<br/>Temporal spacing"]
    end
    
    subgraph "Generation N+1"
        NewPop["New Population<br/>Evolved variants"]
        Test["Test in Scanner<br/>lines 652-700"]
        Results["Server Responses"]
    end
    
    Population --> Selection
    Fitness --> Selection
    Selection --> Parents
    
    Parents --> Crossover
    Parents --> Mutation
    
    Mutation --> M1
    Mutation --> M2
    Mutation --> M3
    Mutation --> M4
    Mutation --> M5
    Mutation --> M6
    Mutation --> M7
    Mutation --> M8
    
    Crossover --> NewPop
    M1 --> NewPop
    M2 --> NewPop
    M3 --> NewPop
    M4 --> NewPop
    M5 --> NewPop
    M6 --> NewPop
    M7 --> NewPop
    M8 --> NewPop
    
    NewPop --> Test
    Test --> Results
    Results -->|"Update fitness"| Fitness

Initialization:

# scanner_v2.py:74
self.payload_evolver = PayloadEvolver(population_size=100)

Seeding with Successful Payloads:

# scanner_v2.py:231-235 (SQL Injection)
if self.use_smart_payloads:
    self.payload_evolver.seed([payload])
    self.payload_evolver.update_fitness(payload, 1.0)

# scanner_v2.py:317-319 (XSS)
if self.use_smart_payloads:
    self.payload_evolver.seed([payload])
    self.payload_evolver.update_fitness(payload, 1.0)

Evolution Execution:

# scanner_v2.py:638-646
if self.use_smart_payloads and len(self.payload_evolver.population) > 0:
    Logger.info("Running evolved payload phase...")
    evolved = self.payload_evolver.evolve(count=30)
    
    # Also generate context-aware payloads
    priorities = self.feedback_loop.get_priority_categories()
    for category, _ in priorities[:3]:
        ctx_payloads = self.context_generator.generate_payloads(category, count=10)
        evolved.extend(ctx_payloads)

Key Methods:

| Method | Purpose | Parameters | |--------|---------|------------| | seed(payloads) | Add successful payloads to population | List[str] | | update_fitness(payload, score) | Update fitness score | payload: str, score: float | | evolve(count) | Generate evolved variants | count: intList[str] | | _mutate(payload) | Apply random mutation | Internal | | _crossover(p1, p2) | Combine two payloads | Internal |

Sources: wshawk/scanner_v2.py:74, wshawk/scanner_v2.py:231-235, wshawk/scanner_v2.py:637-703, wshawk/smart_payloads/payload_evolver.py


Mutation Strategies

WSHawk implements 8+ evasion strategies that can be applied individually or in combination:

Encoding-Based Evasion

| Strategy | Technique | Example Transform | Use Case | |----------|-----------|-------------------|----------| | URL Encoding | Percent-encode special characters | <script>%3Cscript%3E | Bypass basic pattern matching | | Double Encoding | Apply URL encoding twice | <%253C | Evade WAFs that decode once | | Hex Encoding | Convert to hexadecimal | alert\x61\x6c\x65\x72\x74 | JavaScript execution | | Base64 Obfuscation | Encode payload, decode at runtime | eval(atob('YWxlcnQ=')) | Hide malicious keywords |

Character Substitution

| Strategy | Technique | Example Transform | Use Case | |----------|-----------|-------------------|----------| | Unicode Equivalents | Use Unicode lookalikes | < (U+FF1C) | Bypass ASCII-only filters | | Case Variation | Mixed case | <ScRiPt> | Evade case-sensitive rules | | HTML Entities | Named/numeric entities | <&lt; or &#60; | XML/HTML context |

Structural Mutation

| Strategy | Technique | Example Transform | Use Case | |----------|-----------|-------------------|----------| | Null Byte Injection | Insert null bytes | <script>%00.jpg | Truncation vulnerabilities | | Comment Insertion | Break keywords with comments | <scr/**/ipt> | Regex bypass | | Concatenation | Split strings | 'scr'+'ipt' | JavaScript context | | Whitespace Injection | Insert tabs, newlines | <script\n> | Whitespace normalization |

Protocol-Level Evasion

| Strategy | Technique | Description | Implementation | |----------|-----------|-------------|----------------| | Temporal Evasion | Spread payload across multiple frames | Sends malicious characters in separate messages over time | Exploits frame-by-frame analysis | | Frame Fragmentation | Split payload into minimal frames | Each frame contains 1-2 bytes | Overwhelms reassembly buffers | | Protocol Obfuscation | Manipulate WebSocket frame headers | Modify masking, payload length encoding | Low-level WAF bypass |

Sources: docs/V3_COMPLETE_GUIDE.md:196-201, README.md:35, RELEASE_SUMMARY.md:26-28


WAF Detection and Fingerprinting

WSHawk detects the presence and type of WAF through response analysis during the learning phase and initial testing.

Title: WAF Detection Workflow

graph TB
    Start["Initial Connection"]
    
    SendCanary["Send Canary Payloads<br/><script>test</script><br/>1' OR '1'='1"]
    
    Response["Analyze Response"]
    
    CheckBlocked{"Response indicates<br/>blocking?"}
    
    FingerprintWAF["Fingerprint WAF Type"]
    
    subgraph "WAF Signatures"
        Cloudflare["Cloudflare<br/>Ray ID in headers"]
        AWS["AWS WAF<br/>X-Amzn-RequestId"]
        Akamai["Akamai<br/>AkamaiGHost"]
        Imperva["Imperva<br/>incap_ses cookie"]
        ModSecurity["ModSecurity<br/>406 Not Acceptable"]
        F5["F5 BIG-IP<br/>TS cookie"]
        Barracuda["Barracuda<br/>barra_counter_session"]
        Generic["Generic WAF<br/>403 Forbidden pattern"]
    end
    
    ActivateEvasion["Activate Evasion Module<br/>Select strategies based on WAF"]
    
    NoWAF["No WAF Detected<br/>Standard mutation only"]
    
    Start --> SendCanary
    SendCanary --> Response
    Response --> CheckBlocked
    
    CheckBlocked -->|"Yes"| FingerprintWAF
    CheckBlocked -->|"No"| NoWAF
    
    FingerprintWAF --> Cloudflare
    FingerprintWAF --> AWS
    FingerprintWAF --> Akamai
    FingerprintWAF --> Imperva
    FingerprintWAF --> ModSecurity
    FingerprintWAF --> F5
    FingerprintWAF --> Barracuda
    FingerprintWAF --> Generic
    
    Cloudflare --> ActivateEvasion
    AWS --> ActivateEvasion
    Akamai --> ActivateEvasion
    Imperva --> ActivateEvasion
    ModSecurity --> ActivateEvasion
    F5 --> ActivateEvasion
    Barracuda --> ActivateEvasion
    Generic --> ActivateEvasion

WAF-Specific Bypass Strategies

Based on the detected WAF, WSHawk applies optimized evasion techniques:

| WAF Type | Primary Detection Method | Recommended Evasion | Success Rate | |----------|-------------------------|---------------------|--------------| | Cloudflare | cf-ray header, error page signature | Protocol obfuscation, temporal evasion | High | | AWS WAF | X-Amzn-RequestId header | Character substitution, case variation | Medium | | ModSecurity | 406 Not Acceptable status | Comment insertion, concatenation | High | | F5 BIG-IP | TS cookie, BigIP header | Double encoding, null bytes | Medium | | Imperva | incap_ses cookie | Unicode substitution, hex encoding | Medium | | Akamai | AkamaiGHost header | Whitespace injection, fragmentation | Low | | Barracuda | barra_counter_session cookie | Base64 obfuscation | Medium |

WAF Detection in Code:

The ServerFingerprinter class identifies WAF presence through header and response analysis during the learning phase.

# scanner_v2.py:130-131
# Add to fingerprinter
self.fingerprinter.add_response(message)

# scanner_v2.py:166-170
fingerprint = self.fingerprinter.fingerprint()
if fingerprint.language:
    Logger.success(f"Server: {fingerprint.language or 'unknown'} / {fingerprint.framework or 'unknown'}")
if fingerprint.database:
    Logger.info(f"Database: {fingerprint.database}")

Sources: wshawk/scanner_v2.py:130-131, wshawk/scanner_v2.py:166-170, wshawk/server_fingerprint.py, docs/V3_COMPLETE_GUIDE.md:196-201


Context-Aware Payload Generation

The ContextAwareGenerator tailors payloads to the detected message structure, significantly improving bypass success rates.

Title: Context-Aware Generation Pipeline

graph TB
    subgraph "Learning Phase"
        SampleMsgs["Sample Messages<br/>Collected during<br/>learning_phase()"]
        
        FormatDetect["Format Detection<br/>JSON/XML/Protobuf/Binary"]
        
        FieldExtract["Field Extraction<br/>Identify injectable fields"]
        
        TypeAnalysis["Type Analysis<br/>String/Int/Array/Object"]
    end
    
    subgraph "Context Building"
        Context["Context Dictionary<br/>self.context<br/>{<br/>  format: 'json',<br/>  fields: [...],<br/>  types: {...}<br/>}"]
    end
    
    subgraph "Generation Phase"
        Category["Vulnerability Category<br/>sql, xss, cmd, xxe"]
        
        Template["Select Template<br/>Based on format+type"]
        
        Inject["Inject Payload<br/>Into structure"]
        
        Examples["Generated Payloads"]
    end
    
    subgraph "Example Outputs"
        JSONEx["JSON:<br/>{username: '1 OR 1=1--'}"]
        XMLEx["XML:<br/><user>admin</user>"]
        NestedEx["Nested:<br/>{data: {id: payload}}"]
    end
    
    SampleMsgs --> FormatDetect
    FormatDetect --> FieldExtract
    FieldExtect --> TypeAnalysis
    
    TypeAnalysis --> Context
    
    Category --> Template
    Context --> Template
    Template --> Inject
    Inject --> Examples
    
    Examples --> JSONEx
    Examples --> XMLEx
    Examples --> NestedEx

Format-Specific Generation

JSON Context:

When MessageFormat.JSON is detected, payloads are injected into appropriate fields:

# scanner_v2.py:200-206
if self.learning_complete and self.message_analyzer.detected_format == MessageFormat.JSON:
    injected_messages = self.message_analyzer.inject_payload_into_message(
        base_message, payload
    )
else:
    injected_messages = [payload]

Example Transformations:

| Base Message | Payload | Generated Message | Strategy | |--------------|---------|-------------------|----------| | {"user": "admin"} | ' OR '1'='1 | {"user": "admin' OR '1'='1"} | Direct field injection | | {"id": 123} | 1 OR 1=1 | {"id": "1 OR 1=1"} | Type coercion | | {"query": {}} | {"$ne": null} | {"query": {"$ne": null}} | Object replacement | | {"data": "test"} | <script>alert(1)</script> | {"data": "<script>alert(1)</script>"} | XSS injection |

XML Context:

For XML-formatted messages, payloads are wrapped in appropriate tags:

| Detection | Generated Structure | Purpose | |-----------|---------------------|---------| | <user>...</user> | <user>payload</user> | Element injection | | <data value="..."> | <data value="payload"> | Attribute injection | | XML declaration present | <?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> | XXE exploitation |

Sources: wshawk/scanner_v2.py:156-164, wshawk/scanner_v2.py:200-206, wshawk/message_intelligence.py, wshawk/smart_payloads/context_generator.py


Feedback-Driven Evolution Cycle

The complete evolution cycle integrates all components in a continuous improvement loop.

Title: Complete Mutation and Evolution Pipeline

graph TB
    subgraph "Phase 1: Initial Scan"
        Static["Static Payloads<br/>WSPayloads (22,000+)"]
        
        Inject1["Inject + Send<br/>test_*_v2() methods"]
        
        Response1["Server Responses"]
        
        Verify["VulnerabilityVerifier<br/>Confidence scoring"]
    end
    
    subgraph "Phase 2: Feedback Analysis"
        FeedbackAnalysis["FeedbackLoop.<br/>analyze_response()"]
        
        Classify["Classify Response<br/>Signal + Confidence"]
        
        Baseline["Compare to Baseline<br/>Detect anomalies"]
    end
    
    subgraph "Phase 3: Fitness Scoring"
        UpdateFitness["Update Fitness Scores<br/>payload_evolver.<br/>update_fitness()"]
        
        Seed["Seed Population<br/>payload_evolver.<br/>seed()"]
        
        PriorityQueue["Priority Categories<br/>feedback_loop.<br/>get_priority_categories()"]
    end
    
    subgraph "Phase 4: Evolution"
        Selection["Selection<br/>Tournament selection"]
        
        Genetic["Genetic Operations<br/>Crossover + Mutation"]
        
        ContextGen["Context-Aware<br/>Generation<br/>context_generator.<br/>generate_payloads()"]
        
        NewPopulation["New Population<br/>~40-50 payloads"]
    end
    
    subgraph "Phase 5: Evolved Testing"
        InjectEvolved["Inject Evolved<br/>lines 652-700"]
        
        ResponseEvolved["Server Responses"]
        
        VerifyEvolved["Multi-Check<br/>SQL/XSS/Cmd"]
        
        Success{"Vulnerability<br/>Found?"}
    end
    
    Static --> Inject1
    Inject1 --> Response1
    Response1 --> Verify
    
    Verify -->|"HIGH confidence"| Seed
    Response1 --> FeedbackAnalysis
    
    FeedbackAnalysis --> Classify
    Classify --> Baseline
    Baseline --> UpdateFitness
    
    UpdateFitness --> PriorityQueue
    PriorityQueue --> Selection
    Seed --> Selection
    
    Selection --> Genetic
    Genetic --> NewPopulation
    
    PriorityQueue --> ContextGen
    ContextGen --> NewPopulation
    
    NewPopulation --> InjectEvolved
    InjectEvolved --> ResponseEvolved
    ResponseEvolved --> VerifyEvolved
    
    VerifyEvolved --> Success
    Success -->|"Yes"| UpdateFitness
    Success -->|"Yes"| Report["Add to<br/>self.vulnerabilities"]
    Success -->|"No"| Discard["Discard"]

Evolution Phase Implementation:

# scanner_v2.py:637-703
if self.use_smart_payloads and len(self.payload_evolver.population) > 0:
    Logger.info("Running evolved payload phase...")
    evolved = self.payload_evolver.evolve(count=30)
    
    # Also generate context-aware payloads
    priorities = self.feedback_loop.get_priority_categories()
    for category, _ in priorities[:3]:
        ctx_payloads = self.context_generator.generate_payloads(category, count=10)
        evolved.extend(ctx_payloads)
    
    if evolved:
        Logger.info(f"Testing {len(evolved)} evolved/context payloads...")
        base_message = self.sample_messages[0] if self.sample_messages else '{"test": "value"}'
        
        for payload in evolved:
            # ... injection and testing logic ...
            
            # Check all vulnerability types
            for check_fn, vuln_type in [
                (self.verifier.verify_sql_injection, 'SQL Injection'),
                (self.verifier.verify_xss, 'Cross-Site Scripting (XSS)'),
                (self.verifier.verify_command_injection, 'Command Injection'),
            ]:
                is_vuln, confidence, desc = check_fn(response, payload)
                if is_vuln and confidence != ConfidenceLevel.LOW:
                    Logger.vuln(f"[EVOLVED] {vuln_type} [{confidence.value}]: {desc}")
                    self.payload_evolver.update_fitness(payload, 1.0)
                    self.vulnerabilities.append({
                        'type': f'{vuln_type} (Evolved)',
                        'severity': confidence.value,
                        'confidence': confidence.value,
                        'description': f'[Smart Payload] {desc}',
                        'payload': payload,
                        'response_snippet': response[:200],
                        'recommendation': f'Novel payload discovered by evolutionary mutation'
                    })

Sources: wshawk/scanner_v2.py:637-703, wshawk/scanner_v2.py:669-694


Configuration and Usage

Enabling Smart Payloads

Smart payload evolution is disabled by default and can be enabled through multiple interfaces:

Command Line (Advanced CLI):

wshawk-advanced ws://target.com --smart-payloads

Python API:

from wshawk.scanner_v2 import WSHawkV2

scanner = WSHawkV2("ws://target.com")
scanner.use_smart_payloads = True
await scanner.run_heuristic_scan()

Configuration File (wshawk.yaml):

scanner:
  features:
    smart_payloads: true
    
  smart_evolution:
    population_size: 100
    generations: 5
    mutation_rate: 0.3
    crossover_rate: 0.7

Sources: wshawk/advanced_cli.py:73-74, wshawk/scanner_v2.py:75, wshawk/config.py


Performance Characteristics

Computational Cost

| Component | Time Complexity | Memory Usage | Notes | |-----------|----------------|--------------|-------| | ContextAwareGenerator | O(n) per message | ~1MB | Learning from sample messages | | FeedbackLoop | O(1) per response | ~2MB | Real-time classification | | PayloadEvolver | O(p²) per generation | ~5MB for 100 payloads | Crossover operations | | Evolution Phase | +30-60 seconds | +10MB | Executed after heuristic scan |

Effectiveness Metrics

Based on testing against common WAFs (from documentation):

| Scenario | Without Mutation | With Smart Evolution | Improvement | |----------|------------------|---------------------|-------------| | Cloudflare WAF | 15% bypass rate | 68% bypass rate | 4.5x | | ModSecurity | 22% bypass rate | 79% bypass rate | 3.6x | | AWS WAF | 31% bypass rate | 73% bypass rate | 2.4x | | Custom Rules | 8% bypass rate | 54% bypass rate | 6.8x |

Sources: docs/V3_COMPLETE_GUIDE.md:176-201


Integration with Verification Systems

Mutated payloads integrate with WSHawk's advanced verification systems:

Browser-Based XSS Verification

# scanner_v2.py:294-314
if confidence == ConfidenceLevel.HIGH and self.use_headless_browser:
    try:
        if not self.headless_verifier:
            self.headless_verifier = HeadlessBrowserXSSVerifier()
            await self.headless_verifier.start()
        
        is_executed, evidence = await self.headless_verifier.verify_xss_execution(
            response, payload
        )
        
        if is_executed:
            browser_verified = True
            confidence = ConfidenceLevel.CRITICAL
            description = f"REAL EXECUTION: {evidence}"

Mutated XSS payloads that successfully evade WAF filters are then verified in a real Chromium browser via Playwright. See Playwright XSS Verification for details.

OAST Integration for Blind Vulnerabilities

# scanner_v2.py:458-474
if self.use_oast and self.oast_provider:
    oast_payload = self.oast_provider.generate_payload('xxe', f'test{len(results)}')
    msg = json.dumps({"action": "parse_xml", "xml": oast_payload})

Evolved payloads for XXE and SSRF are enhanced with OAST callbacks for blind detection. See OAST Blind Vulnerability Detection for details.

Sources: wshawk/scanner_v2.py:294-314, wshawk/scanner_v2.py:458-474


Limitations and Considerations

Known Limitations

| Limitation | Impact | Workaround | |------------|--------|------------| | Population Size | Fixed at 100 payloads | Increase via population_size parameter | | Generation Count | Typically 1-2 generations per scan | Multiple scans for deeper evolution | | Context Learning | Requires message samples (5s wait) | Provide pre-captured samples via API | | Genetic Diversity | Can converge to local optima | Manual seed injection with diverse payloads |

Security Considerations

Rate Limiting Impact:

Evolved payloads are subject to the same rate limiting as standard payloads:

# scanner_v2.py:62-66
self.rate_limiter = TokenBucketRateLimiter(
    tokens_per_second=rate_limit,
    bucket_size=rate_limit * 2,
    enable_adaptive=True
)

The adaptive rate limiter reduces speed when server errors are detected, ensuring evolution doesn't overwhelm the target.

Ethical Scanning:

The mutation engine is designed for authorized penetration testing only. Aggressive mutation can:

  • Trigger intrusion detection systems
  • Generate significant server load
  • Leave distinctive patterns in logs
  • Cause application crashes if vulnerabilities are severe

Always obtain explicit authorization before using smart payload evolution against production systems.

Sources: wshawk/scanner_v2.py:62-66, README.md:269-275


Troubleshooting

Common Issues

Issue: "Smart payloads not generating"

[!] Evolution phase skipped - no successful payloads seeded

Cause: No payloads achieved HIGH confidence during heuristic scan.

Solution: The target may not be vulnerable, or WAF blocking is 100% effective. Review initial scan results and consider disabling WAF detection temporarily.


Issue: "Evolution phase too slow"

Cause: Large population size or many generations.

Solution: Reduce computational cost:

scanner:
  smart_evolution:
    population_size: 50  # Default: 100
    generations: 3        # Default: 5

Issue: "Context learning failed"

[!] No messages received during learning phase
[!] Will use basic payload injection

Cause: Server doesn't send proactive messages, or connection dropped.

Solution: Increase learning duration or send initial messages:

await scanner.learning_phase(ws, duration=10)  # Increase from 5s

Sources: wshawk/scanner_v2.py:172-175, wshawk/scanner_v2.py:637-646


Summary Table: Mutation Components

| Component | File Location | Primary Function | Input | Output | |-----------|---------------|------------------|-------|--------| | ContextAwareGenerator | wshawk/smart_payloads/context_generator.py | Learns message structure | Sample messages | Context-aware payloads | | FeedbackLoop | wshawk/smart_payloads/feedback_loop.py | Analyzes response effectiveness | Response + timing | ResponseSignal + confidence | | PayloadEvolver | wshawk/smart_payloads/payload_evolver.py | Genetic algorithm evolution | Successful payloads | Mutated variants | | MessageAnalyzer | wshawk/message_intelligence.py | Format detection | WebSocket messages | MessageFormat + fields | | VulnerabilityVerifier | wshawk/vulnerability_verifier.py | Vulnerability confirmation | Response + payload | ConfidenceLevel | | ServerFingerprinter | wshawk/server_fingerprint.py | Technology/WAF detection | Response headers | Fingerprint object |

Sources: wshawk/scanner_v2.py:14-30, wshawk/scanner_v2.py:58-75