记一次刨根问底的HTTP包WAF绕过
字数 1143 2025-08-10 08:29:04
HTTP包WAF绕过技术深度分析
1. 背景与概述
本文详细分析了一种通过精心构造HTTP multipart/form-data请求包来绕过Web应用防火墙(WAF)的技术。该技术利用了PHP处理multipart/form-data请求时的特性,通过特殊字符转义和参数构造实现WAF绕过。
2. 关键HTTP请求分析
攻击者构造的特殊HTTP请求如下:
POST /sql/post.php HTTP/1.1
Host: 192.168.1.72
Content-Type: multipart/form-data; boundary=--------1721837650
Content-Length: 156
----------1721837650
Content-Disposition: form-data; name="name\"; filename=";name='username'"
Content-Type: image/jpeg
admin
----------1721837650--
关键点解析:
-
name="name\"; filename=";name='username'"构造:- 使用反斜杠
\转义第一个双引号 - 在filename参数中嵌入第二个name参数
- 使用反斜杠
-
请求体结构:
- 看似文件上传,实际是普通参数传递
- 通过特殊构造使WAF解析与后端解析不一致
3. PHP处理机制深度分析
PHP通过rfc1867_post_handler函数处理multipart/form-data请求,关键处理流程如下:
3.1 边界解析
boundary = strstr(content_type_dup, "boundary");
if (!boundary || !(boundary = strchr(boundary, '='))) {
sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data");
return;
}
3.2 Content-Disposition解析
while (*cd && (pair = getword(mbuff->input_encoding, &cd, ';'))) {
char *key = NULL, *word = pair;
if (strchr(pair, '=')) {
key = getword(mbuff->input_encoding, &pair, '=');
if (!strcasecmp(key, "name")) {
param = getword_conf(mbuff->input_encoding, pair);
} else if (!strcasecmp(key, "filename")) {
filename = getword_conf(mbuff->input_encoding, pair);
}
}
// ...
}
3.3 关键函数php_ap_getword
static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop) {
char *pos = *line, quote;
char *res;
while (*pos && *pos != stop) {
if ((quote = *pos) == '"' || quote == '\'') {
++pos;
while (*pos && *pos != quote) {
if (*pos == '\\' && pos[1] && pos[1] == quote) {
pos += 2;
} else {
++pos;
}
}
if (*pos) {
++pos;
}
} else ++pos;
}
// ...
}
4. 绕过原理详解
-
转义字符处理:
- PHP的
php_ap_getword函数会跳过被反斜杠转义的双引号 - 导致
name="name\"; filename="被解析为一个整体
- PHP的
-
参数优先级:
- 最终解析结果为两个name参数:
name="name\"; filename="name='username'
- PHP会选择最后一个有效参数,即
username=admin
- 最终解析结果为两个name参数:
-
WAF解析差异:
- WAF可能将整个内容视为文件名部分
- 而PHP实际解析为两个独立参数
5. 实际影响与防御
5.1 影响范围
- 使用PHP处理multipart/form-data请求的应用
- 依赖WAF进行输入验证的场景
- 参数解析不一致的安全设备
5.2 防御措施
-
WAF层面:
- 实现与PHP一致的解析逻辑
- 对转义字符进行特殊处理
- 检查参数名中的特殊字符
-
应用层面:
- 直接验证输入参数,不依赖WAF
- 对multipart/form-data请求进行严格校验
- 使用最新版PHP,关注安全更新
-
配置层面:
; php.ini配置 file_uploads = Off ; 如不需要文件上传则关闭 max_input_vars = 1000 ; 限制输入变量数量
6. 技术验证与复现
验证步骤:
- 搭建PHP环境(5.x-8.x均受影响)
- 构造特殊multipart/form-data请求
- 观察
$_POST和$_FILES变量的差异 - 对比WAF日志与实际接收的参数
7. 总结
该技术展示了WAF绕过的一个典型案例,核心在于:
- 利用PHP解析multipart/form-data的特殊逻辑
- 构造WAF与后端解析不一致的场景
- 通过转义字符和参数覆盖实现绕过
防御关键在于确保安全设备与后端应用的解析逻辑一致性,以及对特殊字符的严格处理。