Payload Mutation and WAF Evasion
Payload Mutation and WAF Evasion
The following files were used as context for generating this wiki page:
- .github/workflows/ghcr-publish.yml
- README.md
- RELEASE_3.0.0.md
- RELEASE_SUMMARY.md
- docs/V3_COMPLETE_GUIDE.md
- requirements.txt
- wshawk/advanced_cli.py
- wshawk/scanner_v2.py
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: int → List[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 | < → < or < | 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