Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
目录
Java安全之BCEL ClassLoader
写在前面
BCEL平常在测试反序列化的时候也经常会用到,比如延时测Gadget以及在某些场景下执行命令不是那么顺手的情况下选择BCEL去打内存马,就像Fastjson和Thymeleaf SSTI这种。以前也只是用到这个BCEL但是没有仔细学习过,下面简单学习记录下BCEL。
About BCEL
BCEL Classloader在 JDK < 8u251之前是在rt.jar里面。
同时在Tomcat中也会存在相关的依赖
tomcat7
org.apache.tomcat.dbcp.dbcp.BasicDataSource
tomcat8及其以后
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
而在rt.jar!/com/sun/org/apache/bcel/internal/util/
包下,有Classloader
这么一个类,可以实现加载字节码并初始化一个类的功能,该类也是个Classloader(继承了原生的Classloader类)重写了loadClass()
方法,源码如下:
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, bytes, 0, bytes.length);
} else // Fourth try: Use default class loader
cl = Class.forName(class_name);
}
if(resolve)
resolveClass(cl);
}
classes.put(class_name, cl);
return cl;
}
首先会判断类名是否以$$BCEL$$
开头,之后调用createClass()
方法拿到一个JavaClass
对象最终通过defineClass()
加载字节码还原类。
调试分析
先来看下简单的使用,在同一包下,准备一个恶意类
package MemoryShell.BCEL;
import java.io.IOException;
public class calc {
static{
try {
Runtime.getRuntime().exec("open -a Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}
}
准备一个BCEL的demo,运行即可。
package MemoryShell.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;
public class BCELDemo {
public static void main(String[] args) throws Exception {
JavaClass cls = Repository.lookupClass(calc.class);
String code = Utility.encode(cls.getBytes(), true);
System.out.println(code);
new ClassLoader().loadClass("$$BCEL$$" + code).newInstance();
}
}