原创 | 在XML中测试Fastjson反序列化

Posted SecIN技术平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原创 | 在XML中测试Fastjson反序列化相关的知识,希望对你有一定的参考价值。

点击上方蓝字 关注我吧

原创 | 在XML中测试Fastjson反序列化
引言
原创 | 在XML中测试Fastjson反序列化

在实际业务开发中,经常会对xml或者json类型的请求数据进行解析。例如微信扫码支付的功能,按照微信开发文档与支付平台进行数据交互就需要使用XML格式的数据。针对XML传输的数据,最容易想到的就是XXE攻击了。通过XXE的利用,可以达到以下的目的:

  • 敏感信息泄漏(使用file协议读取敏感文件、列目录)
  • 递归调用造成拒绝服务攻击
  • SSRF
  • php开启expect拓展的前提下可能会导致远程代码执行
  • ……

在一定条件下是可以达到RCE的效果的,但是远不及任意文件上传和反序列化等漏洞那么粗暴。以下是记一次内部安全测试中的相关过程。

原创 | 在XML中测试Fastjson反序列化

在XML中测试Fastjson反序列化

原创 | 在XML中测试Fastjson反序列化

目标主要的交互方式是以
Content-Type:application/xml;charset=UTF-8 的方式进行请求的,主要以xml的方式进行数据传输。最先想到的就是通过引入外部实体的方式进行XXE的检测。但是比较可惜禁用了。

原创 | 在XML中测试Fastjson反序列化


另寻出路,看看有没有类似上传的功能点,比较幸运的是在文件操作功能处找到了任意文件下载的缺陷,这里尝试下载相关代码进行审计,看看有没有别的突破口。下载源码的过程可以参考https://sec-in.com/article/537。

系统是通过jar启动部署的,基于springboot进行开发。拿到代码后习惯性的看了一下导入的组件,引入的fastjson版本为1.2.24,还是那个熟悉的配方:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.24</version></dependency>


在Spring中@RequestBody主要用来接收前端传递给后端的json字符串中的数据的,既然使用了fastjson依赖,那么猜测可能部分接口是存在json方式交互的。直接全局搜索@RequestBody,但是发现@RequestBody也修饰了之前文件下载的接口:

@RequestMapping("/fileOper/download")@ResponseBodypublic String getOrderDetails(@RequestBody FileOper fileOper){ //......}


这里猜测系统可能是做了xml和json数据的互相转化?既然使用了fastjson依赖,换一个思路先去看看fastjson是如何集成的。Springboot默认将jackson作为数据转换的工具,而且默认也是以json格式进行处理的。找到相关的配置文件WebMvcConfig,在这通过操作HttpMessageConverter消息转换器的方式对fastjson进行了集成:

@Configurationpublic class WebMvcConfig extends WebMvcConfigurationSupport{
@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fjc = new FastJsonHttpMessageConverter(); FastJsonConfig fj = new FastJsonConfig(); fj.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); fjc.setFastJsonConfig(fj); converters.add(fjc); for (int i = converters.size() - 1; i >= 0; i--) { if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) { converters.remove(i); } } }}
 
   
   
 

在Springboot中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,底层这种灵活的消息转换机制就是利用HttpMessageConverter来实现的,Spring内置了很多消息转换器。


比如MappingJackson2HttpMessageConverter,StringHttpMessageConverter等来满足特定的需求。


首先重写了
extendMessageConverters(List<HttpMessageConverter<?>>converters)方法。

将FastJsonHttpMessageConverter加入到原有的消息转换器列表中:
FastJsonHttpMessageConverter fjc = new FastJsonHttpMessageConverter();FastJsonConfig fj = new FastJsonConfig();fj.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);fjc.setFastJsonConfig(fj);converters.add(fjc);


此时FastJsonHttpMessageConverter会在列表最后,根据消息转换器的使用规则,会按照相关顺序选择符合要求的消息转换器,默认的

MappingJackson2HttpMessageConverter在新加入的转换器之前,默认还是使用MappingJackson消息转换器,所以这里要将移除,保证使用fastjson进行解析:

for (int i = converters.size() - 1; i >= 0; i--) { if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) { converters.remove(i); }        }

到这里能确认fastjson的确是引入并使用的了,至少能保证@ResponseBody注解解析时使用的就是fastjson的消息转换器(系统response返回是json格式的)。顺着上面的思路,到底是什么解析了xml请求数据呢?@RequestBody为何也对xml内容进行了解析?继续去看代码,在依赖导入里看到了jackson-dataformat-xml组件:

<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.9.8</version></dependency>


查阅相关的资料,jackson转换XML会用到jackson-dataformat-xml组件,本质上其实是引入了对应的消息转换器

org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter,这样就可以完成对应请求的解析了,再结合实际需要在对应方法的@RequestMappping注解中添加类似参数:produces=“application/json;charset=UTF-8”,这样就可以控制返回数据的格式为json或者其他类型了,这里搭建了一个环境进行验证:


原创 | 在XML中测试Fastjson反序列化


综上,现在目标系统应该引入了两个消息转换器:

  • org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter

  • FastJsonHttpMessageConverter


根据Spring消息转换器的使用规则,会按照相关顺序选择符合要求的消息转换器。猜想此时系统的request请求是可以接受xml和json格式互转的(request请求既可以解析xml又可以解析json数据)。尝试在自己搭建的环境里集成fastjson,在在上述基础上输出加载的消息转换器,相关代码如下:

@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) { for (HttpMessageConverter<?> messageConverter : converters) { System.out.println(messageConverter); }    }


加载的消息转换器列表:
org.springframework.http.converter.ByteArrayHttpMessageConverter@c074c0corg.springframework.http.converter.StringHttpMessageConverter@58a55449org.springframework.http.converter.ResourceHttpMessageConverter@5949eba8org.springframework.http.converter.ResourceRegionHttpMessageConverter@6e0ff644org.springframework.http.converter.xml.SourceHttpMessageConverter@58dea0a5org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@2a2bb0eborg.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@3c291aadcom.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter@2d0566ba


那么也就是说可以尝试将request请求的xml数据转换成json,进行反序列化测试的。这里附上测试环境的实操结果:

正常情况下是xml传输:

原创 | 在XML中测试Fastjson反序列化


转换成json格式传输同样可以解析:


原创 | 在XML中测试Fastjson反序列化


此时尝试转换成json格式,结合dnslog进行反序列化测试:


原创 | 在XML中测试Fastjson反序列化


dnslog成功接收到记录:

原创 | 在XML中测试Fastjson反序列化


把结果告诉给同事,剩下的就是解决目标系统的gadget或者不出网的问题了,下班:


原创 | 在XML中测试Fastjson反序列化


原创 | 在XML中测试Fastjson反序列化

结语

原创 | 在XML中测试Fastjson反序列化


综上,在测试XML类型传输的请求时,可以尝试进行格式转换,如果JSON格式同样可以解析的话,那么可以尝试进行fastjson反序列化的利用尝试,当然jackson同理(因为springboot2默认采用的json converter是 MappingJackson2HttpMessageConverter )。

针对SpringMVC的应用,通过配置<mvc:annotation-driven>的子元素<message-converters>标签,可以增加自定义的消息转换器,也可以覆盖默认的消息转换器,在审计时同样可以进行关注:

 <mvc:annotation-driven> <mvc:message-converters register-defaults="false">  ... ... <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <!-- 加入支持的媒体类型:返回contentType --> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters></mvc:annotation-driven>


同理,在黑盒测试时,json传输的数据包也可以试试转换成xml,进行XXE的相关测试。jackson-dataformat-xml组件相关版本也是存在XXE风险的:

原创 | 在XML中测试Fastjson反序列化


原创 | 在XML中测试Fastjson反序列化

参考资料

原创 | 在XML中测试Fastjson反序列化


https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-message-converters
原创 | 在XML中测试Fastjson反序列化
原创 | 在XML中测试Fastjson反序列化

你要的分享、在看与点赞都在这儿~

以上是关于原创 | 在XML中测试Fastjson反序列化的主要内容,如果未能解决你的问题,请参考以下文章

搞懂fastjson 对泛型的反序列化原理

原来不只是fastjson,这个你每天都在用的类库也被爆过反序列化漏洞!

FastJson 解析序列化及反序列化

Java中使用FastJSON进行对象的序列化和反序列化

FastJSON2 学习笔记

FastJSON2 学习笔记