java安全 反序列化(二)

java安全 反序列化(二)

前言

寻找反序列化链(Gadget)

  1. 在项目里找漏洞

    readObject里的漏洞一般比较少

  2. 寻找项目的依赖库类中的Gadget

    一些依赖也会有反序列化的操作,如果jar包中的某些类在进行反序列化时有可控的点,就可以利用jar包中存在的漏洞来构造调用链

ysoserial工具

ysoserial工具可以帮助我们在依赖库里面找到利用链。

git clone https://github.com/frohoff/ysoserial.git

进入ysoserial目录,编译jar包

mvn clean package -DskipTests

image-20221128161645257

出现BUILD SUCCESS表示编译成功,在target文件夹下

注意:要使用java 1.7+ 的jdk环境

最经典的反序列化利用链

Apache Commons Collections.jar中的一条pop链,这个类库使用广泛,所以很多大型的应用也存在着这个漏洞。

Commons Collections 在3.x < 3.2.2 以及4.0这些版本范围里,存在反序列化漏洞

当目标Java应用依赖库里包含存在漏洞的Commons Collections库,且对由攻击者可控的数据进行反序列化时,即会造成任意代码执行。

我们以ysoserial里CommonsCollections6这个payload为例,进行分析。

先使用ysoserial生成反序列化的payload

image-20221128161942308

使用maven导入commons-collections依赖

pom.xml

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>

在创建测试代码

TestCC6

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.InvocationTargetException;

public class TestCC6 {
   
    public static void main(String[] args) throws IOException, ClassNotFoundException{
   
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc6.ser"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

把生成的cc6.ser放在项目根目录下执行代码,弹出计算机

image-20221128172245115

运行环境为java11

要解析cc6链的结构代码要先学习下java反射相关,我们可以在很多java漏洞的POC中看到反射的利用,所以学习java安全是绕不开反射的。

java反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性(包括私有的方法和属性);这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

涉及到java中的几个类:

Class类	代表类的实体,在运行的java应用程序中表示类和接口

Field类:代表类的成员变量(成员变量也称为类的属性)

Method类:代表类的方法

Constructor类:代表类的构造方法

在Java中你看到的绝大部分成员,其实都可以称之为对象(除了普通数据类型和静态成员)。

类也是对象,类是java.lang.Class类的实例对象

Class类抽象出了java中类的特征并提供了一些方法

有三种方式获得Class类实例:

1.如果知道class的完整类名,可以调用Class类的静态方法Class.forName获取
Class clz = Class.forName("com.dong.User");

2.任何一个类都有一个隐含的静态成员class,这个属性就存储着这个类对应的Class类的实例:
Class clz = com.dong.User.class;

3.调用这个对象的getClass()方法:
Class clz = (new User()).getClass();

测试获取,调用方法

User

public class User {
   
        public void test(String name){
   
            System.out.println("Hello:"+name);
        }
    }
获取方法:

我们之前已经提到了Method这个类,java中所有的方法都是Method类型,所以我们通过反射机制获取到某个对象的方法也是Method类型的。通过Class对象获取某个方法:

方法的名称和方法的参数列表,两者信息才能确定某一个方法

clz.getMethod(方法名,这个方法的参数类型)
调用方法:

Method类中有一个invoke方法,就是用来调用特定方法的,用法如下:

public Object invoke(Object obj, Object... args)

第一个参数是调用该方法的对象,第二个参数是一个可变长参数,是这个方法的需要传入的参数

testUser

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class testUser {
   
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
   
        Class user = (new User()).getClass();
        //第二个参数要传class类,如果参数有多个传入:new Class[]{String.class,String.class} 
        Method test = user.getMethod("test",String.class);
        //如果第二个参数有多个传入:new Object[]{"1","2"}
        test.invoke((new User()),"liangBan");
    }
}
image-20221129140628374

修改变量

User

public class User {
   
    private String pass = "123321";
    @Override
    public String toString() {
   
        return "User{" +
                "pass='" + pass + '\'' +
                '}';
    }
}

testUser

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class testUser {
   
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
   
        Class user = (new User()).getClass();
        //获取私有属性对象
        Field pass = user.getDeclaredField("pass");
        //关闭java访问控制检查,就可以给private属性赋值调用
        pass.setAccessible(true);
        User u = new User();
		System.out.println(u);
        pass.set(u,"liangban");
        System.out.println(u);
        System.out.println(pass.get(u));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值